#============================================================= -*-perl-*- # # Template::Config # # DESCRIPTION # Template Toolkit configuration module. # # AUTHOR # Andy Wardley # # COPYRIGHT # Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. # # This module is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # #======================================================================== package Template::Config; use strict; use warnings; use base 'Template::Base'; use vars qw( $VERSION $DEBUG $ERROR $INSTDIR $PARSER $PROVIDER $PLUGINS $FILTERS $ITERATOR $LATEX_PATH $PDFLATEX_PATH $DVIPS_PATH $STASH $SERVICE $CONTEXT $CONSTANTS @PRELOAD ); $VERSION = 2.75; $DEBUG = 0 unless defined $DEBUG; $ERROR = ''; $CONTEXT = 'Template::Context'; $FILTERS = 'Template::Filters'; $ITERATOR = 'Template::Iterator'; $PARSER = 'Template::Parser'; $PLUGINS = 'Template::Plugins'; $PROVIDER = 'Template::Provider'; $SERVICE = 'Template::Service'; $STASH = 'Template::Stash'; $CONSTANTS = 'Template::Namespace::Constants'; @PRELOAD = ( $CONTEXT, $FILTERS, $ITERATOR, $PARSER, $PLUGINS, $PROVIDER, $SERVICE, $STASH ); # the following is set at installation time by the Makefile.PL $INSTDIR = ''; #======================================================================== # --- CLASS METHODS --- #======================================================================== #------------------------------------------------------------------------ # preload($module, $module, ...) # # Preloads all the standard TT modules that are likely to be used, along # with any other passed as arguments. #------------------------------------------------------------------------ sub preload { my $class = shift; foreach my $module (@PRELOAD, @_) { $class->load($module) || return; }; return 1; } #------------------------------------------------------------------------ # load($module) # # Load a module via require(). Any occurences of '::' in the module name # are be converted to '/' and '.pm' is appended. Returns 1 on success # or undef on error. Use $class->error() to examine the error string. #------------------------------------------------------------------------ sub load { my ($class, $module) = @_; $module =~ s[::][/]g; $module .= '.pm'; eval { require $module; }; return $@ ? $class->error("failed to load $module: $@") : 1; } #------------------------------------------------------------------------ # parser(\%params) # # Instantiate a new parser object of the class whose name is denoted by # the package variable $PARSER (default: Template::Parser). Returns # a reference to a newly instantiated parser object or undef on error. # The class error() method can be called without arguments to examine # the error message generated by this failure. #------------------------------------------------------------------------ sub parser { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($PARSER); return $PARSER->new($params) || $class->error("failed to create parser: ", $PARSER->error); } #------------------------------------------------------------------------ # provider(\%params) # # Instantiate a new template provider object (default: Template::Provider). # Returns an object reference or undef on error, as above. #------------------------------------------------------------------------ sub provider { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($PROVIDER); return $PROVIDER->new($params) || $class->error("failed to create template provider: ", $PROVIDER->error); } #------------------------------------------------------------------------ # plugins(\%params) # # Instantiate a new plugins provider object (default: Template::Plugins). # Returns an object reference or undef on error, as above. #------------------------------------------------------------------------ sub plugins { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($PLUGINS); return $PLUGINS->new($params) || $class->error("failed to create plugin provider: ", $PLUGINS->error); } #------------------------------------------------------------------------ # filters(\%params) # # Instantiate a new filters provider object (default: Template::Filters). # Returns an object reference or undef on error, as above. #------------------------------------------------------------------------ sub filters { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($FILTERS); return $FILTERS->new($params) || $class->error("failed to create filter provider: ", $FILTERS->error); } #------------------------------------------------------------------------ # iterator(\@list) # # Instantiate a new Template::Iterator object (default: Template::Iterator). # Returns an object reference or undef on error, as above. #------------------------------------------------------------------------ sub iterator { my $class = shift; my $list = shift; return undef unless $class->load($ITERATOR); return $ITERATOR->new($list, @_) || $class->error("failed to create iterator: ", $ITERATOR->error); } #------------------------------------------------------------------------ # stash(\%vars) # # Instantiate a new template variable stash object (default: # Template::Stash). Returns object or undef, as above. #------------------------------------------------------------------------ sub stash { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($STASH); return $STASH->new($params) || $class->error("failed to create stash: ", $STASH->error); } #------------------------------------------------------------------------ # context(\%params) # # Instantiate a new template context object (default: Template::Context). # Returns object or undef, as above. #------------------------------------------------------------------------ sub context { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($CONTEXT); return $CONTEXT->new($params) || $class->error("failed to create context: ", $CONTEXT->error); } #------------------------------------------------------------------------ # service(\%params) # # Instantiate a new template context object (default: Template::Service). # Returns object or undef, as above. #------------------------------------------------------------------------ sub service { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($SERVICE); return $SERVICE->new($params) || $class->error("failed to create context: ", $SERVICE->error); } #------------------------------------------------------------------------ # constants(\%params) # # Instantiate a new namespace handler for compile time constant folding # (default: Template::Namespace::Constants). # Returns object or undef, as above. #------------------------------------------------------------------------ sub constants { my $class = shift; my $params = defined($_[0]) && ref($_[0]) eq 'HASH' ? shift : { @_ }; return undef unless $class->load($CONSTANTS); return $CONSTANTS->new($params) || $class->error("failed to create constants namespace: ", $CONSTANTS->error); } #------------------------------------------------------------------------ # instdir($dir) # # Returns the root installation directory appended with any local # component directory passed as an argument. #------------------------------------------------------------------------ sub instdir { my ($class, $dir) = @_; my $inst = $INSTDIR || return $class->error("no installation directory"); $inst =~ s[/$][]g; $inst .= "/$dir" if $dir; return $inst; } #======================================================================== # This should probably be moved somewhere else in the long term, but for # now it ensures that Template::TieString is available even if the # Template::Directive module hasn't been loaded, as is the case when # using compiled templates and Template::Parser hasn't yet been loaded # on demand. #======================================================================== #------------------------------------------------------------------------ # simple package for tying $output variable to STDOUT, used by perl() #------------------------------------------------------------------------ package Template::TieString; sub TIEHANDLE { my ($class, $textref) = @_; bless $textref, $class; } sub PRINT { my $self = shift; $$self .= join('', @_); } 1; __END__ =head1 NAME Template::Config - Factory module for instantiating other TT2 modules =head1 SYNOPSIS use Template::Config; =head1 DESCRIPTION This module implements various methods for loading and instantiating other modules that comprise the Template Toolkit. It provides a consistent way to create toolkit components and allows custom modules to be used in place of the regular ones. Package variables such as C<$STASH>, C<$SERVICE>, C<$CONTEXT>, etc., contain the default module/package name for each component (L, L and L, respectively) and are used by the various factory methods (L, L and L) to load the appropriate module. Changing these package variables will cause subsequent calls to the relevant factory method to load and instantiate an object from the new class. =head1 PUBLIC METHODS =head2 load($module) Load a module using Perl's L. Any occurences of 'C<::>' in the module name are be converted to 'C', and 'C<.pm>' is appended. Returns 1 on success or undef on error. Use C<$class-Eerror()> to examine the error string. =head2 preload() This method preloads all the other C modules that are likely to be used. It is called automatically by the L