Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Template::Magic(3)    User Contributed Perl Documentation   Template::Magic(3)

NAME
       Template::Magic - Magic merger of runtime values	with templates

VERSION	1.39
       Included	in Template-Magic 1.39 distribution.

       The latest version changes are reported in the Changes file in this
       distribution.

INSTALLATION
       Prerequisites
	       Perl version >= 5.6.1
	       OOTools	    >= 2
	       IO::Util	    >= 1.46
	       File::Spec   >= 0

       CPAN
	   If you want to install Template::Magic plus all related extensions
	   (the	prerequisites to use also Template::Magic::HTML), all in one
	   easy	step:

	       perl -MCPAN -e 'install Bundle::Template::Magic'

       Standard	installation
	   From	the directory where this file is located, type:

	       perl Makefile.PL
	       make
	       make test
	       make install

	   Note: this installs just the	main distribution and does not install
	   the prerequisites of	Template::Magic::HTML.

       Distribution structure
	       Bundle::Template::Magic	    a bundle to	install	everything in one step
	       Template::Magic		    the	main module
	       Template::Magic::Zone	    defines the	zone object
	       Template::Magic::HTML	    handlers useful in HTML environment

SYNOPSIS
       Just add	these 2	magic lines to your code...

	   use Template::Magic;
	   Template::Magic->new->print(	'/path/to/template' );

       to have all your	variable and subroutines merged	with the template
       file, or	set one	or more	constructor array to customize the output
       generation as you need:

	   use Template::Magic qw( -compile );

	   $tm = new Template::Magic
		     paths	     =>	[ qw(/any/path /any/other/path)	] ,
		     markers	     =>	[ qw( <	/ > ) ]			  ,
		     lookups	     =>	[ \%my_hash, $my_obj, 'main'	] ,
		     zone_handlers   =>	[ \&my_zone_handler, '_EVAL_'	] ,
		     value_handlers  =>	[ 'DEFAULT', \&my_value_handler	] ,
		     text_handlers   =>	  sub {print lc	$_[1]}		  ,
		     output_handlers =>	  sub {print uc	$_[1]}		  ,
		     post_handlers   =>	  \&my_post_handler		  ,
		     options	     =>	  'no_cache'			  ;

	   $tm->nprint(	template => '/path/to/template'
			lookups	 => \%my_special_hash );

DESCRIPTION
       Template::Magic is a "magic" interface between programming and design.
       It makes	"magically" available all the runtime values - stored in your
       variables or returned by	your subroutines - inside a static template
       file. In	simple cases there is no need to assign	values to the object.
       Template	outputs	are linked to runtime values by	their identifiers,
       which are added to the template in the form of simple labels or blocks
       of content.

	   a label: {identifier}
	   a block: {identifier} content of the	block {/identifier}

       From the	designer point of view,	this makes things very simple. The
       designer	has just to decide what	value and where	to put it. Nothing
       else is required, no complicated	new syntax to learn! This feature make
       this template system the	perfect	choice when the	templates file has to
       be edited by unskilled people.

       On the other side, the programmer has just to define variables and
       subroutines as usual and	their values will appear in the	right place
       within the output. The automatic	interface allows the programmer	to
       focus just on the code, saving him the hassle of	interfacing code with
       output, and even	complicated output - with complex switch branching and
       nested loops - can be easily organized by minding just a	few simple
       concepts.

       1.  The object parses the template and searches for any labeled zone

       2.  When	a zone is found, the object looks into your code and searches
	   for any variable or sub with	the same identifier (name)

       3.  When	a match	is found the object replaces the label or the block
	   with	the value returned by the variable or sub found	into your code
	   (dereferencing and/or executing code	as needed). (see "Understand
	   the output generation" for details)

       Note: If	you are	planning to use	this module in CGI environment,	take a
       look at CGI::Builder::Magic that	transparently integrates this module
       in a very handy and powerful framework.

   Simple example
       The following is	a very simple example only aimed to better understand
       how it works: obviously,	the usefulness of Template::Magic comes	up
       when the	output become more complex.

       Imagine you need	an output that looks like this template	file:

	   City: {city}
	   Date	and Time: {date_and_time}

       where {city} and	{date_and_time}	are just placeholder that you want to
       be replaced in the output by some real runtime values. Somewhere	in
       your code you have defined a scalar and a sub to	return the 'city' and
       the 'date_and_time' values:

	   $city = 'NEW	YORK';
	   sub date_and_time { localtime }

       you have	just to	add these 2 magic lines	to the code:

	   use Template::Magic;
	   Template::Magic->new->print(	'my_template_file' );

       to generate this	output:

	   City: NEW YORK
	   Date	and Time: Sat Nov 16 21:03:31 2002

       With the	same 2 magic lines of code, Template::Magic can	automatically
       look up values from scalars, arrays, hashes, references and objects
       from your code and produce very complex outputs.	The default settings
       are usually smart enough	to do the right	job for	you, however if	you
       need complete control over the output generation, you can fine tune
       them by controlling them	explicitly. See	"CUSTOMIZATION"	for details.

   More	complex	example
       the template
	   The template	file 'my_template_file'... (this example uses plain
	   text	for clarity, but Template::Magic works with any	type of	text
	   file)

	       A scalar	variable: {a_scalar}.
	       A reference to a	scalar variable: {a_ref_to_scalar}.
	       A subroutine: {a_sub}
	       A reference to subroutine: {a_ref_to_sub}
	       A reference to reference: {a_ref_to_ref}
	       A hash: {a_hash}this block contains a {a_scalar}	and a {a_sub}{/a_hash}

	       A loop:{an_array_of_hashes}
	       Iteration #{ID}:	{guy} is a {job}{/an_array_of_hashes}

	       An included file:
	       {INCLUDE_TEMPLATE my_included_file}

	   ... and another template file 'my_included_file' that will be
	   included...

	       this is the included file 'my_included_file'
	       that contains a label: {a_scalar}

       the code
	   ... some variables and subroutines already defined somewhere	in
	   your	code...

	   Note: This example uses globals just	for simplicity.	Please notice
	   that	Template::Magic	can be used to write sloppy code or very
	   strict code,	exactly	as perl	itself can. Magic lookups is a very
	   handly feature for simple scripts, while it is not recommended for
	   complex script where	you should explicitly limit the	lookups	to
	   some	specific package or hash (see "lookups").

	       $a_scalar	   = 'THIS IS A	SCALAR VALUE';
	       $a_ref_to_scalar	   = \$a_scalar;
	       @an_array_of_hashes = ( { ID => 1, guy => 'JOHN SMITH',	job => 'PROGRAMMER' },
				       { ID => 2, guy => 'TED BLACK',	job => 'WEBMASTER' },
				       { ID => 3, guy => 'DAVID	BYRNE',	job => 'MUSICIAN' }  );
	       %a_hash		   = ( a_scalar	=> 'NEW	SCALAR VALUE'
				       a_sub	=> sub { 'NEW SUB RESULT' } );

	       sub a_sub	 { 'THIS SUB RETURNS A SCALAR' }
	       sub a_ref_to_sub	 { \&a_sub }
	       sub a_ref_to_ref	 { $a_ref_to_scalar }

	   Just	add these 2 magic lines...

	       use Template::Magic;
	       Template::Magic->new->print( 'my_template_file' );

       the output
	   (in this example Lower case are from	templates and Upper case are
	   from	code):

	       A scalar	variable: THIS IS A SCALAR VALUE.
	       A reference to a	scalar variable: THIS IS A SCALAR VALUE.
	       A subroutine: THIS SUB RETURNS A	SCALAR
	       A reference to subroutine: THIS SUB RETURNS A SCALAR
	       A reference to reference: THIS IS A SCALAR VALUE
	       A hash: this block contains a NEW SCALAR	VALUE and a NEW	SUB RESULT

	       A loop:
	       Iteration #1: JOHN SMITH	is a PROGRAMMER
	       Iteration #2: TED BLACK is a WEBMASTER
	       Iteration #3: DAVID BYRNE is a MUSICIAN

	       An included file:
	       this is the included file 'my_included_file'
	       that contains a label: THIS IS A	SCALAR VALUE.

   Features
       Since syntax and	coding related to this module are very simple and
       mostly automatic, you should careful read this section to have the
       right idea about	its features and power.	This is	a list - with no
       particular order	- of the most useful features and advantages:

       o   Simple, flexible and	powerful to use

	   In simple cases, you	will have just to use new() and
	   print(template) methods, without having to pass any other value to
	   the object: it will do the right job	for you. However you can fine
	   tune	the behaviour as you need. (see	"CUSTOMIZATION")

       o   Extremely simple and	configurable template syntax

	   The template	syntax is so simple and	code-independent that even the
	   less	skilled	webmaster will manage it without bothering you :-). By
	   default Template::Magic recognizes labels in	the form of simple
	   identifiers surrounded by braces ({my_identifier}), but you can
	   easily use different	markers	(see "Redefine Markers").

       o   Automatic or	manual lookup of values

	   By default, Template::Magic compares	any label identifier defined
	   in your template with any variable or subroutine identifier defined
	   in the caller namespace. However, you can explicitly	define the
	   lookup otherwise, by	passing	a list of package namespaces, hash
	   references and blessed objects to the "lookups" constructor array.

       o   Unlimited nested included templates

	   Sometimes it	can be useful to split a template into differents
	   files. No nesting limit when	including files	into files. (see
	   "Include and	process	a template file")

       o   Branching

	   You can easily create simple	or complex if-elsif-else conditions to
	   print just the blocks linked	with the true conditions (see "Setup
	   an if-else condition" and "Setup a switch condition")

       o   Unlimited nested loops

	   When	you need complex outputs you can build any immaginable nested
	   loop, even mixed with control switches and included templates (see
	   "Build a loop" and "Build a nested loop")

       o   Scalable and	expandable extensions system

	   You can load	only the handlers you need, to gain speed, or you can
	   add as many handlers	you will use, to gain features.	You can	even
	   write your own extension handler in just 2 or 3 lines of code,
	   expanding its capability for	your own purpose. (see "CUSTOMIZATION"
	   )

       o   Efficient and fast

	   The internal	rapresentation and storage of templates	allows minimum
	   memory requirement and completely avoid wasting copies of content.
	   You can even	include	external (and probably huge) text files	in the
	   output without memory charges. (see "Include	(huge) text files
	   without memory charges")

       o   Automatic caching of	template files

	   Under mod_perl it could be very useful to have the template
	   structure cached in memory, already parsed and ready	to be used
	   (almost) without any	other process. Template::Magic opens and
	   parses a template file only the first time or if the	file has been
	   modified.

       o   Perl	embedding

	   Even	if I don't encourage this approach, however you	can very
	   easily embed	any quantity of	perl code into any template. (see
	   "Embed perl into a template")

       o   Placeholders	and simulated areas

	   Placeholders	and simulated areas can	help in	designing the template
	   for a more consistent preview of the	final output. (see "Setup
	   placeholders" and "Setup simulated areas")

       o   Labels and block list

	   When	you have to deal with a	webmaster, you can easily print	a
	   pretty formatted output of all the identifiers present in a
	   template. Just add your description of each label and block and
	   save	hours of explanations ;-)  (see	ID_list() static method)

       o   Simple to maintain

	   Change your code and	Template::Magic	will change its	behaviour
	   accordingly.	In most	cases you will not have	to reconfigure,	either
	   the object, or the template.

       o   Simply portable

	   This	module and its extensions are written in pure perl. You	don't
	   need	any compiler in	order to install it on any platform so you can
	   distribute it with your own applications by just including a	copy
	   of its files	(in this case just remember to AutoSplit the modules
	   or take off the '__END__').

   Policy
       The main	principle of Template::Magic is: keeping the designing
       separated from the coding, giving all the power to the programmer and
       letting designer	do only	design.	In other words:	while the code
       includes	ALL the	active and dynamic directions to generate the output,
       the template is a mere passive and static file, containing just
       placeholder (zones) that	the code will replace with real	data.

       This philosophy keeps both jobs very tidy and simple to do, avoiding
       confusion and enforcing clearness, specially when programmer and
       designer	are 2 different	people.	But another aspect of the philosophy
       of Template::Magic is flexibility, something that gives you the
       possibility to easily bypass the	rules.

       Even if I don't encourage breaking the main principle (keeping the
       designing separated from	the coding), sometimes you might find useful
       to put inside a template	some degree of perl code, or may be you	want
       just to interact	DIRECTLY with the content of the template. See "Use
       subroutines to rewrite links" and "Embed	perl into a template" for
       details.

       Other important principles of Template::Magic are scalability and
       expandability. The whole	extension system is built on these principles,
       giving you the possibility of control the behaviour of this module by
       omitting, changing the orders and/or adding your	own handlers, without
       the need	of subclassing the module. See "CUSTOMIZATION".

   Useful links
       o   A simple and	useful navigation system between my modules is
	   available at	this URL: http://perl.4pro.net

       o   More	practical topics are discussed in the mailing list at this
	   URL:
	   http://lists.sourceforge.net/lists/listinfo/template-magic-users

METHODS
   new ( [constructor_arrays] )
       If you use just the defaults, you can construct the new object by
       writing this:

	   $tm = new Template::Magic ;

       If you don't pass any parameter to the constructor method, the
       constructor defaults are	usually	smart enough to	do the right job for
       you, but	if you need complete control over the output generation, you
       can fine	tune it	by controlling it explicitly. (see the section
       "Constructor Arrays").

   output ( template [,	temporary lookups ] )
       WARNING:	this method is here for	historical reasons, but	it is not the
       maximum of efficiency. Please consider to use the print() method	when
       possible	(see "EFFICIENCY"). You	can also consider to write an output
       handler that fits your needs but	process	the output content on the fly
       and without the need to collect the whole output	as this	method does.

       Note: If	you need to use	"Template::Magic" with "CGI::Application"
       (that requires the run modes method to collect the whole	output)	you
       may use CGI::Application::Magic or Apache::Application::Magic that
       transparently integrates	the template system with the application and
       avoid this method.

       This method merges the runtime values with the template and returns a
       reference to the	whole collected	output.	It accepts one template
       parameter that can be a reference to a SCALAR content, a	path to	a
       template	file or	a filehandle.

       This method accepts any number of temporary lookups elements that could
       be package names, blessed objects and hash references (see "lookups" to
       a more detailed explanation).

	   # template is a path
	   $output = $tm->output( '/path/to/template' )	;

	   # template is a reference (not efficient but	possible)
	   $output = $tm->output( \$tpl_content	) ;

	   # template is a filehandler
	   $output = $tm->output( \*FILEHANDLER	) ;

	   # this adds some lookups location to	the print method
	   $my_block_output = $tm->output( '/path/to/template',	\%special_hash );

       Note: if	template is a path, the	object will cache it automatically, so
       Template::Magic will open and parse the template	file only the first
       time or if the file has been modified. If for any reason	you don't want
       to cache	the template structure,	you can	use the	'cache / no_cache'
       "options".

   noutput ( arguments )
       A named arguments interface for the output() method, which add also the
       possibility to pass the 'container_template' argument.

	   $tm->nprint(	template => '/path/to/template',
			lookups	 => [ \%special_hash, 'My::lookups'],
			container_template => '/path/to/container_template') ;

   print ( template [, temporary lookups ] )
       This method merges the runtime values with the template and prints the
       output. It accepts one template parameter that can be a reference to a
       SCALAR content, a path to a template file or a filehandle.

       This method accepts any number of temporary lookups elements that could
       be package names, blessed objects and hash references (see "lookups" to
       a more detailed explanation).

	   # template is a path
	   $tm->print( '/path/to/template' );

	   # template is a reference (not efficient but	possible)
	   $tm->print( \$tpl_content ) ;

	   # template is a filehandler
	   $tm->print( \*FILEHANDLER );

	   # this adds some lookups location to	the print method
	   $tm->print( '/path/to/template', \%special_hash );

       Note: if	template is a path, the	object will cache it automatically, so
       Template::Magic will open and parse the template	file only the first
       time or if the file has been modified. If for any reason	you don't want
       to cache	the template structure,	you can	use the	'cache / no_cache'
       "options". (see "EFFICIENCY").

   nprint ( arguments )
       A named arguments interface for the print() method, which add also the
       possibility to pass the 'container_template' argument.

	   $tm->nprint(	template => '/path/to/template',
			lookups	 => [ \%special_hash, 'My::lookups'],
			container_template => '/path/to/container_template') ;

   ID_list ( [indentation_string [, end_marker]] )
       Calling this method (before the output()	or print() methods) will
       redefine	the behaviour of the module, so	your program will print	a
       pretty formatted	list of	only the identifiers present in	the template,
       thus the	programmer can pass a description of each label	and block
       within a	template to a designer.

       The method accepts an indentation string	(usually a tab character or a
       few spaces), that will be used to indent	nested blocks. If you omit the
       indentation string 4 spaces will	be used. The method accepts also as
       second parameter	an end marker string, which is used to distinguish the
       end label in a container	block. If you omit this, a simple '/' will be
       used.

	   # defalut
	   $tm->ID_list;

	   # custom indentation
	   $tm->ID_list("\t", 'END OF ');

       See also	"Prepare the identifiers description list".

   load( template )
       This method explicitly (pre)loads and parses the	template in order to
       cache it	for future use.	 You shouldn't need to use this	method unless
       you want	to build the cache in advance (e.g the startup.pl for
       "mod_perl" advanced users).

   purge_cache ( [template_path] )
       Template::Magic opens and parses	a template file	only the first time or
       if the file has been modified. Since the	template caching is automatic
       you shouldn't need to use this method under normal situations, anyway
       with this method	you can	purge the template_path	from the cache.
       Without any template_path parameter the method purges all the stored
       templates.

   find_file ( template	)
       This method is internally used to find the templates you	pass with
       "print(), nprint(), output(), noutput()"	methods	or an
       'INCLUDE_TEMPLATE' label	(and its relative Zone method
       "include_template").

       You usually don't need to use this method explicitly, unless you	want
       to check	if a template exists on	your own. If a non-zero	size file
       exists it returns the path of the found template, or undef if it
       doesn't.

       The template specified can be an	absolute path (beginning with a	'/'
       under Unix, for example). If it isn't absolute, the path	in the
       environment variable TEMPLATE_MAGIC_ROOT	is tried, if it	exists.	Next
       the paths in the	paths constructor array	are tried, first as they are,
       and then	with TEMPLATE_MAGIC_ROOT prepended if available. As a final
       attempt,	the template is	checked	directly.

CUSTOMIZATION
       Note: You can completely	skip this section if you plan to use just the
       defaults.

       The output generation can be completely customized during the creation
       of the new object by passing to the "new()" method one or more
       "Constructor Arrays".

   Constructor Arrays
       The new() method	accepts	one optional hash that can contain the
       following optionals constructor arrays:

	   markers
	   lookups
	   zone_handlers
	   value_handlers
	   text_handlers
	   output_handlers
	   post_handlers
	   paths
	   options
	   container_template

       Constructor Arrays are array references containing elements that	can
       completely change the behaviour of the object and even add code not
       directly	related	with the output	generation but executed	during the
       process.

       All the constructor arrays should be array references, but if you have
       to pass just one	element, you can pass it as a plain element as well:

	   $tm = new Template::Magic
		     lookups =>	[\%my_hash] ,
		     markers =>	['HTML_MARKERS'	  ] ;

	   # same thing	less noisy
	   $tm = new Template::Magic
		     lookups =>	\%my_hash ,
		     markers =>	'HTML'	  ;

       All the handlers	in "-*_handlers" (zone handlers, value handlers,
       output handlers,	text handlers, post handlers) receive the zone object
       as $_[0]	parameter. Besides, the	text handlers and the output handlers
       receive also the	processed text as $_[1]	parameter.

       Note: the old constructor arrays	identifiers with the prepended '-'
       and/or the parameters passed as a reference to a	hash are deprecated
       but still working:

	   # old style with '-flag' and	brackets
	   $tm = new Template::Magic
		     {
		       -markers		=>   qw( < / > )		     ,
		       -lookups		=> [ \%my_hash,	$my_obj, 'main'	   ] ,
		       -zone_handlers	=> [ \&my_zone_handler,	'_EVAL_'   ] ,
		       -value_handlers	=> [ 'DEFAULT',	\&my_value_handler ] ,
		       -text_handlers	=>   sub {print	lc $_[1]}	     ,
		       -output_handlers	=>   sub {print	uc $_[1]}	     ,
		       -post_handlers	=>   \&my_post_handler		     ,
		     } ;

       paths

       Use this	constructor array to supply a list of paths to search for
       templates. This list will be used when you pass a relative path as the
       template	name.

       See find_file() method for details about	how the	paths are searched.

       markers

       Use this	constructor array to define the	3 label	markers	-
       START_MARKER, END_MARKER_ID, END_MARKER - you want to use in your
       template. The "markers" constructor array can contain a name of
       "standard markers", or a	reference to an	array containing the 3
       explicit	markers.

       If you want to use the default markers, just call the new() method
       without any "markers" constructor array:

	   # default markers
	   $tm = new Template::Magic;

	   # same but explicit extension name
	   $tm = new Template::Magic
		     markers =>	'DEFAULT_MARKERS';

	   # same but 3	explicit default markers
	   $tm = new Template::Magic
		     markers =>	[ '{', '/', '}'	] ;

	   # HTML markers extension name
	   $tm = new Template::Magic
		     markers =>	'HTML_MARKERS' };

	   # same but 3	explicit HTML markers
	   $tm = new Template::Magic
		     markers =>	[ qw( <!--{ / }--> ) ] ;

	   # custom explicit markers
	   $tm = new Template::Magic
		     markers =>	[ qw( __ END_ __ ) ] ;

       Since each element of the markers array is parsed as a regular
       expression as: "qr/element/", you can extend the	markers	beyond a
       static string marker.

       These markers:

	   # 3 weird explicit markers
	   $tm = new Template::Magic
		     markers =>	[ '<\d+<', '\W', '>' ];

       will match these	blocks labeled 'identifier':

	   <35<identifier> content of block <0<-identifier>
	   <26<identifier> content of block <15<#identifier>

       You can also pass compiled RE:

	   # 3 weird explicit markers
	   $start  = qr/<\d+</ ;
	   $end_ID = qr/\W/    ;
	   $end	   = qr/>/     ;
	   $tm = new Template::Magic
		     markers =>	[ $start, $end_ID, $end	];

       Note: Remember that if the characters you chose as the markers have a
       special meaning in RE (e.g. the '[' and ']'), you need to escape	them
       as you would do inside a	pattern	match.

	   # this would	generate an error
	   $tm = Template::Magic->new( markers => [ '[', '/', ']' ] )

	   # you probably mean this
	   $tm = Template::Magic->new( markers => [ '\[', '/', '\]' ] )

       standard	markers

       Template::Magic offers 3	standard markers: DEFAULT_MARKERS,
       CODE_MARKERS and	HTML_MARKERS:

       DEFAULT_MARKERS
	   The default markers:

	       START MARKER:  {
	       END_MARKER_ID: /
	       END_MARKER:    }

	   Example of block:

	       {identifier} content of the block {/identifier}

       CODE_MARKERS
	   This	markers	are useful when	you deal with templates	which contain
	   code, because they reduces the possible conflict with the content:

	       START MARKER:  <-
	       END_MARKER_ID: /
	       END_MARKER:    ->

	   Example of block:

	       <-identifier-> content of the block <-/identifier->

       HTML_MARKERS
	   HTML-comment-like markers. If your output is	a HTML text - or just
	   because you prefer that particular look - you can use it instead of
	   using the default markers.

	       START MARKER:  <!--{
	       END_MARKER_ID: /
	       END_MARKER:    }-->

	   Example of block:

	       <!--{identifier}--> content of the block	<!--{/identifier}-->

	   Usage:

	       $tm = new Template::Magic
			 markers => 'HTML_MARKERS' ;

	   The main advantages to use it are:

	   o   You can add labels and blocks and the template will still be a
	       valid HTML file.

	   o   You can edit the	HTML template with a WYSIWYG editor, keeping a
	       consistent preview of the final output

	   o   The normal HTML comments	will be	preserved in the final output,
	       while the labels	will be	wiped out.

	   If you want to use the HTML handlers	too, you could use
	   Template::Magic::HTML. See Template::Magic::HTML for	details.

       See also	"Redefine Markers"

       lookups

       Use this	constructor array to explicitly	define where to	look up	the
       values in your code. This array can contain package names, blessed
       objects and hash	references. If no lookups construction array is
       passed, the package namespace of	the caller will	be used	by default.

       With packages names the lookup is done with all the IDENTIFIERS
       (variables and subroutines) defined in the package namespace.

       Note: Please, notice that the lexical variables (those declared with
       "my") are unaccessible from outside the enclosing block,	file, or eval,
       so don't	expect that the	lookup could work with these variables:	it is
       a perl intentional restriction, not a limitation	of this	module.
       However,	you could declare them	with the old "vars" pragma or "our"
       declaration instead, and	the lookup will	work as	expected.

       With blessed objects the	lookup is done with all	the IDENTIFIERS
       (variables and methods) defined in the class namespace. Note: Use this
       type of location	when you want to call an object	method from a
       template: the method will receive the blessed object as the first
       parameter and it	will work as expected.

       With hash references the	lookup is done with the	KEYS existing in the
       hash.

       If you want to make available all the identifiers of your current
       package,	just call the constructor without any "lookups"	parameter:

	   # default lookup in the caller package
	   $tm = new Template::Magic ;

	   # same thing	but explicit
	   $tm = new Template::Magic
		     lookups =>	__PACKAGE__ ;

       Warning:	Template::Magic	can be used to write sloppy code or very
       strict code, exactly as perl itself can.	Magic lookups is a very	handly
       feature for simple scripts, while it is not recommended for complex
       script where you	should explicitly limit	the lookups to some specific
       package or hash.

       If you want to keep unavailable some variable or	subroutine from	the
       template, you can pass just the reference of some hash containing just
       the identifiers used in the template. This is the best method to	use
       the module IF you allow untrustworthy people to edit the	template AND
       if you have any potentially dangerous subroutine	in your	code. (see
       "Allow untrustworthy people to edit the template").

	   # lookup in %my_hash	only
	   $tm = new Template::Magic
		     lookups =>	\%my_hash ;

       You can also define an arbitrary	list of	packages, references to	hashes
       and blessed object as the lookup: the precedence	of the lookup will be
       inherited from the order	of the items passed, and the first found mach
       will return the value.

       Note: If	you have multiple symbols in your code that maches the label
       id in your template, don't expect any warning: to be fast,
       Template::Magic does not	check your errors and consider OK the first
       symbol it founds.

	   # lookup in several locations
	   $tm = new Template::Magic
		     lookups =>	[ \%my_hash, 'My::Pack', \%my_other_hash ] ;

       In this example,	the lookup will	be done	in %my_hash first - if
       unsuccessful - it will be done in the "My::Pack"	package	and - if
       unsuccessful - it will be done in %my_other_hash.

       If you use Template::Magic inside another module, you can pass the
       blessed object as the location:

	   use Template::Magic;
	   package Local::foo;
	   sub new
	   {
	       my $s = bless {data=>'THE OBJECT	DATA'},	shift;
	       $$s{tm} = new Template::Magic
			     lookups =>	$s;
	       $s;
	   }

	   sub method_triggered_by_lookup
	   {
	       my ($s, $zone) =	@_; # correct object passed + zone object
	       ...
	       $$s{data};
	   }

       so that if some zone identifier will trigger
       'method_triggered_by_lookup', it	will receive the blessed object	as the
       first parameter and it will work	as expected.

       (see also "lookup_process()" in Template::Magic::Zone).

       Temporary Lookups

       You can also pass some temporary	lookups	along with the print(),
       nprint(), output(), noutput() methods (i.e. lookups that	will be	used
       only for	one template processing). This capability is useful when you
       want to use the same object but you don't want to use the same lookups
       e.g. to have some sort of lookup	inheritance as this:

	  $tm =	new Template::Magic
		    lookups => \%general_hash ;

	  # in sub 1
	  $tm->nprint( template	=> '/path/to/template1'	,
		       lookups	=> \%special_hash1    )	;
	  # lookup done	in %special_hash1 and then in %general_hash

	  # in sub 2
	  $tm->nprint( template	=> '/path/to/template2'	,
		       lookups	=> \%special_hash2    )	;
	  # lookup done	in %special_hash2 and then in %general_hash

       zone_handlers

       Use this	constructor array to add handlers to manage the	output
       generation before any other process (even before	the
       "lookup_process()"). The	zone handlers are executed just	after the
       creation	of the new zone, so you	can even bypass	or change the way of
       calling the other processes.

       This constructor	array can contain code references and/or standard zone
       handlers	names (resulting in one	or more	code references: see "standard
       zone handlers" for details.

       The default "zone_handler" is undefined,	so you must add	explicitly any
       standard	zone handler or	your own handler in order to use it.

	   $tm = new Template::Magic
		     zone_handlers => [	'_EVAL_'	   ,
					'_EVAL_ATTRIBUTES' ,
					'INCLUDE_TEXT'	   ,
					 \&my_handler	   ] ;

       Note: If	you write your own custom zone_handler,	remember that it must
       return a	true value to end the "zone_process", or a false value to
       continue	the "zone_process". In other words: if your zone_handler has
       taken the control of the	whole process it must return true, so the
       other processes (i.e. "lookup_process" and "value_process") will	be
       skipped,	while if you want to continue the normal process your
       zone_handler must return	false.

       To simplify things you can import and use the constants "NEXT_HANDLER"
       and "LAST_HANDLER" that are more	readable and simpler to	remember (see
       "Constants").

       (see also "zone_process()" in Template::Magic::Zone)

       standard	zone handlers

       _EVAL_
	   This	handler	sets the "value" property to the evalued result	of the
	   zone	content	when the zone identifier is equal to '_EVAL_'

	   WARNING: For	obvious	reasons	you should use this zone handler ONLY
	   if you are the programmer AND the designer.

	   This	handler	is useful if you want a	cheap way to embed perl	code
	   in the template. (see "Embed	perl into a template")

       _EVAL_ATTRIBUTES_
	   This	handler	sets the "param" property to the evalued result	of the
	   zone	attributes

	   WARNING: For	obvious	reasons	you should use this zone handler ONLY
	   if you are the programmer AND the designer.

	   This	handler	is useful if you want to pass some structure to	a sub
	   from	the template without writing a parser: you will	have the
	   structure available in $z->param. (see "Pass	a structure to a
	   subroutine")

       TRACE_DELETIONS
	   This	handler	generates a diagnostic output for each zone that has
	   not generated any output. It	will output a string like <my_zone_id
	   not found> or <my_zone_id found but empty> in place of the zone, so
	   you can better understand what's going on.

       INCLUDE_TEXT
	   This	handler	adds the possibility to	include	in the output a
	   (probably huge) text	file, without having to	keep it	in memory as a
	   template, and without any other parsing.

	   It works with the zone identifier equal to 'INCLUDE_TEXT' and the
	   zone	attributes equal to the	file path to include. It passes	each
	   line	in the file to the "text_process" method and bypass all	the
	   other processs.

	   (see	"Include (huge)	text files without memory charges")

	   Note: Since this handler bypasses every other process, it is	useful
	   only	for text output. If you	need to	include	and parse a real
	   template file see "Include and process a template file".

       value_handlers

       Use this	constructor array to explicitly	define or modify the way the
       object finds the	value in your code.

       This constructor	array can contain code references and/or standard
       value handlers names (resulting in one or more code references: see
       "standard value handlers" for details).

       If you don't pass any "value_handler" constructor array,	the default
       will be used:

	   $tm = new Template::Magic;

	   # means
	   $tm = new Template::Magic
		     value_handler => 'DEFAULT'	;

	   # that expicitly means
	   $tm = new Template::Magic
		 value_handlers	=> [ qw( SCALAR	REF CODE ARRAY
					 HASH OBJECT ) ] ;

       Where 'DEFAULT',	'SCALAR', 'REF', 'CODE', 'ARRAY', 'HASH', 'OBJECT' are
       standard	value handlers names.

       You can add, omit or change the order of	the elements in	the array,
       fine tuning the behaviour of the	object.

	   $tm = new Template::Magic
		     value_handlers => [ 'DEFAULT', \&my_handler ] ;

	   # that explicitly means
	   $tm = new Template::Magic
		     value_handlers => [ 'SCALAR'     ,
					 'REF'	      ,
					 'CODE'	      ,
					 'ARRAY'      ,
					 'HASH'	      ,
					 'OBJECT'
					 \&my_handler ]	;

	   # or	you can	add, omit and change the order of the handlers
	   $tm = new Template::Magic
		     value_handlers => [ 'SCALAR',
					 'REF',
					 \&my_handler,
					 'ARRAY',
					 'HASH',
					 'OBJECT'
				       ] ;

       Note: If	you write your own custom value_handler, remember that it must
       return a	true value to end the "value_process", or a false value	to
       continue	the "value_process".

       To simplify things you can import and use the constants "NEXT_HANDLER"
       and "LAST_HANDLER" that are more	readable and simpler to	remember (see
       "Constants").  (see also	"value_process()" in Template::Magic::Zone)

       standard	value handlers

       DEFAULT
	   This	is the shortcut	for the	default	collection of value handlers
	   that	defines	the following handlers:

	       SCALAR
	       REF
	       CODE
	       ARRAY
	       HASH
	       OBJECT

	   All the default values are based on a condition that	checks the
	   found value.

       SCALAR
	   A SCALAR value sets the "output" property to	the value, and pass it
	   to the "output_process" ending the "value_process" method.

       REF A REFERENCE value (SCALAR or	REF) sets the "value" property to the
	   dereferenced	value and start	again the "value_process()" method

       CODE
	   A CODE value	sets the "value" property to the result	of the
	   execution of	the code and start again the "value_process()" method.
	   The subroutine will receive the zone	object as a parameter.

	   If you want to avoid	the execution of code, triggered by some
	   identifier, just explicitly omit this handler

	       $tm = new Template::Magic
			 value_handlers	=> [ qw( SCALAR	REF ARRAY
						 HASH OBJECT ) ] ;

	   See "Avoid unwanted executions" for details.	See also "Pass
	   parameters to a subroutine"

       ARRAY
	   This	handler	generates a loop, merging each value in	the array with
	   the zone content and	replacing the zone with	the sequence of	the
	   outputs. (see "Build	a loop", "Build	a nested loop" and "Build a
	   simple loop"	for details).

       HASH
	   A HASH value	type will set that HASH	as a temporary lookup for the
	   zone. Template::Magic first uses that hash to look up the
	   identifiers contained in the	block; then, if	unsuccessful, it will
	   search into the other elements of the "lookups" constructor array.
	   This	handler	is usually used	in conjunction with the	ARRAY handler
	   to generate loops. (see "Build a loop" and "Build a nested loop"
	   for details).

       OBJECT
	   An OBJECT value type	causes the object itself to be used as the
	   temporary lookup for	the zone (usually a block ;-). First
	   Template::Magic will	try all	the label contained in the block as a
	   method of the object; if unsuccessful, it will search into the
	   other elements of the "lookups" constructor array.

       output_handlers

       If you need to change the way the output	is processed, you can add your
       own handler.

       This constructor	array can contain code references and/or standard
       output handlers names (resulting	in one or more code references:	see
       "standard output	handlers" for details).

       If you want to use the default output handler, just call	the new()
       method without any "output_handler" constructor array:

	   $tm = new Template::Magic;

	   # this means	(if you	are using print() method)
	   $tm = new Template::Magic
		     output_handler => 'DEFAULT_PRINT_HANDLER';

	   # or	means (if you are using	output() method)
	   $tm = new Template::Magic
		     output_handler => 'DEFAULT_OUTPUT_HANDLER'	;

       Note: If	you write your own custom output_handler, remember that	it
       must return a true value	to end the "output_process", or	a false	value
       to continue the "output_process".

       To simplify things you can import and use the constants "NEXT_HANDLER"
       and "LAST_HANDLER" that are more	readable and simpler to	remember (see
       "Constants").

       (see also "output_process()" in Template::Magic::Zone)

       standard	output handlers

       DEFAULT_PRINT_HANDLER
	   This	handler	is set by default by the "print()" method. It receives
	   and print each chunk	of output that comes from the output
	   generation.

	   This	is the code of the print handler:

	       sub{ print $_[1]	if defined $_[1]; NEXT_HANDLER}

       DEFAULT_OUTPUT_HANDLER
	   Deprecated handler. Use the "DEFAULT_PRINT_HANDLER" instead.

       text_handlers

       Use this	constructor array only if you want to process the text coming
       from the	template in a different	way from the text coming from the
       code.

       This constructor	array can contain code references and/or standard
       output handlers names (resulting	in one or more code references:	see
       "standard output	handlers" for details).

       If you don't set	any text handler, the current output handlers will be
       used.

       Note: If	you write your own custom text_handler,	remember that it must
       return a	true value to end the "text_process", or a false value to
       continue	the "text_process".

       To simplify things you can import and use the constants "NEXT_HANDLER"
       and "LAST_HANDLER" that are more	readable and simpler to	remember (see
       "Constants").

       (see also "text_process()" in Template::Magic::Zone)

       post_handlers

       Use this	constructor array only if you want to clean up or log
       processes just before a zone goes out of	scope. (see also
       "post_process()"	in Template::Magic::Zone)

       Note: This constructor array can	contain	code references.

       Note: If	you write your own custom post_handler,	remember that it must
       return a	true value to end the "post_process", or a false value to
       continue	the "post_process".

       To simplify things you can import and use the constants "NEXT_HANDLER"
       and "LAST_HANDLER" that are more	readable and simpler to	remember (see
       "Constants").

       (see also "post_process()" in Template::Magic::Zone)

       options

       Use this	constructor array to pass some boolean value like 'cache' or
       'no_cache'.

       cache / no_cache
	   Control the caching of the templates	structures. 'cache' is the
	   default, so you don't need to explicitly use	it in order to cache
	   the template. Use 'no_cache'	to avoid the caching.

       container_template

       You can pass a generic template which will be used as a sort of frame
       for all the printed templates. It can be	set to one template parameter
       that can	be a reference to a SCALAR content, a path to a	template file
       or a filehandle.

       (See "Surrounding the output with a container template")

       Constants

       If you write your own handler you can find useful a couple of constants
       that you	can import:

       o   NEXT_HANDLER	(false)

       o   LAST_HANDLER	(true)

	   use Template::Magic qw(NEXT_HANDLER LAST_HANDLER);

	   sub my_handler
	   {
	     my	($zone)	= @_ ;
	     if	(some_condition)
	     {
	       do_something ;
	       LAST_HANDLER ;
	     }
	     else
	     {
	       NEXT_HANDLER ;
	     }
	   }

HOW TO...
       This section is oriented	to suggest you specific	solutions to specific
       needs. If you need some more help, feel free to send me a message.

   Understand the output generation
       By default the output will be generated by the found value type,	that
       means that differents value types will cause different behaviour	in
       generating the output. In details:

       o   A SCALAR value type will replace the	zone with the scalar value.

       o   A REFERENCE value will be dereferenced, and the value returned will
	   be checked again to apply an	appropriate handler

       o   A CODE value	type will be executed, and the value returned will be
	   checked again to apply an appropriate handler

       o   An ARRAY value type will generate a loop, merging each value	in the
	   array with the zone content and replacing the zone with the
	   sequence of the outputs.

       o   A HASH value	type will set that HASH	as a temporary lookup for the
	   zone. Template::Magic first uses that hash to look up the
	   identifiers contained in the	block; then, if	unsuccessful, it will
	   search into the other elements of the "lookups" constructor array.

       o   An OBJECT value type	causes the object itself to be used as the
	   temporary lookup for	the zone (usually a block ;-). First
	   Template::Magic will	try all	the label contained in the block as a
	   method of the object; if unsuccessful, it will search into the
	   other elements of the "lookups" constructor array.

	   = item *

	   Finally, if no value	are found in the code, the zone	will be
	   deleted.

       These are some examples of default value	handlers:

       The same	template: '{block}|before-{label}-after|{/block}'

	   ... with these values...		  ...produce these outputs
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >
	   $block = undef;
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >  NEW CONTENT
	   $block = 'NEW CONTENT';
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >  |before-THE VALUE-after|
	   $block = {};
	   ------------------------------------------------------------------------
	   $label = undef;		    >  |before--after|
	   $block = {};
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >  |before-NEW VALUE-after|
	   %block = (label=>'NEW VALUE');
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >  |before-NEW VALUE-after|
	   $block = {label=>'NEW VALUE'};
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >  NEW CONTENT|before-THE VALUE-after|
	   @block = ('NEW CONTENT',	       |before-NEW VALUE-after|
		     {},
		     {label=>'NEW VALUE'});
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >  NEW CONTENT|before-THE VALUE-after|
	   $block = ['NEW CONTENT',	       |before-NEW VALUE-after|
		     {},
		     {label=>'NEW VALUE'}];
	   ------------------------------------------------------------------------
	   sub label { scalar localtime	}   >  |before-Tue Sep 10 14:52:24 2002-
	   $block = {};			       after|
	   ------------------------------------------------------------------------
	   $label = 'THE VALUE';	    >  |BEFORE-{LABEL}-AFTER|
	   sub block { uc shift	}
	   ------------------------------------------------------------------------
	   package Local::Foo
	   sub new {bless {}, shift}
	   sub label {my $s = shift; 'NEW VALUE	from '.$s}

	   package main
	   $block = Local::Foo->new
			>  |before-NEW VALUE from Local::Foo=HASH(0x1957934)-after|
	   ------------------------------------------------------------------------

       Different combinations of values	and zones can easily produce complex
       outputs:	see the	other topics in	this section.

   Use template	directories
       You can set the $ENV{TEMPLATE_MAGIC_ROOT} or use	the paths constructor
       array to	pass a list of directories to use when searching the template.

       See find_file() method for details about	how the	paths are searched.

   Include and process a template file
       To include a file in a template use the INCLUDE_TEMPLATE	label passing
       the file	path as	the label attribute:

	   {INCLUDE_TEMPLATE /temp/footer.html}

       The  '/temp/footer.html'	file will be included in place of the label
       and it will be processed	(and automatically cached) as usual.

       WARNING:	An icluded template is processed as it was a complete
       template, this means that a block should	be always ended	with an	end
       label in	the same template. In other words blocks cannot	cross the
       boundary	of the file they belong	to, or unpredictable behaviours	could
       occur.

   Conditionally include and process a template	file
       Sometimes it may	be useful to include a template	only if	a condition is
       true. To	do so you can use the $zone->include_template method that
       works exacly as the INCLUDE_TEMPLATE label, but it is triggered from
       inside your code	instead	of the template	itself:

	   sub include_if_some_condition
	   {
	     my	$zone =	shift
	     if	( some_condition )
	     {
	       return $zone->include_template('/path/to/template')
	     }
	     else # may	be you want just return	''
	     {
		return 'template not included'
	     }
	   }

       The template:

	   this	is the template	{include_if_some_condition} end	template

   Surrounding the output with a container template
       Sometime	you may	have headers and footers to add	to a single or all the
       templates you want to print. You	can use	the 'container_template'
       argument, to pass the container template	to the object constructor or
       to the "noutput"	 or "nprint" methods:

	   # will work with all	the outputs
	   $tm = new Template::Magic
		     container_template	=> '/path/to/container_template';

	   $tm->print('/path/to/template');

	   # will work just for	a single output
	   $tm = new Template::Magic

	   $tm->nprint(container_template => '/path/to/container_template',
		      template => '/path/to/template' );

       The container template file is a	regular	template, but MUST include an
       INCLUDE_TEMPLATE	label without any attribute: the original template
       will be used as the included template:

	  An header
	  {INCLUDE_TEMPLATE}
	  a footer

       The template file:

	  The template content

       The output:

	  An header
	  The template content
	  a footer

   Include (huge) text files without memory charges
       To include in the output	a (probably huge) text file, without having to
       keep it in memory as a template,	and without any	other parsing, add the
       INCLUDE_TEXT zone handler and add a label with the zone identifier
       equal to	'INCLUDE_TEXT' and the zone attributes equal to	the file path
       to include.

	   $tm = new Template::Magic
		     zone_handlers => 'INCLUDE_TEXT' ;

       The template label:

	   {INCLUDE_TEXT /path/to/text/file}

       Note: do	not use	quotes!

   Redefine Markers
       by explicitly define the	markers	constructor parameter
	       # redefine the markers as needed
	       $tm = new Template::Magic
			 markers => [ qw( <- / -> ) ] ;

       by using	standard markers
	   The standard	installation comes with	a HTML friendly	"standard
	   markers" that implements a HTML-comment-like	syntax.	If your	output
	   is an HTML text - or	just because you prefer	that particular	look -
	   you can use it instead of using the default markers.

	       $tm = new Template::Magic
			 markers => 'HTML_MARKERS' ;

	       # that means
	       $tm = new Template::Magic
			 markers => [ qw( <!--{	/ }--> ) ] ;

       See "markers" constructor array for details.

   Setup a template
       A quick way to setup a template in 4 simple steps is the	following:

       1 Prepare an output
	   Prepare a complete output as	your code could	print. Place all the
	   static items	of your	output where they should go, place
	   placeholders	(any runtime value that	your code would	supply)	where
	   they	should go and format everything	as you want

       2 Choose	names
	   Choose meaningful names (or variables and subroutines names if you
	   already have	a code)	for labels and blocks

       3 Insert	single labels
	   Find	the dynamic items in the template and replace them with	a
	   label, or if	you want to keep them as visible placeholders,
	   transform each one of them into a block

       4 Define	blocks
	   If you have any area	that will be repeated by a loop	or that	will
	   be printed just under certain conditions transform it into a	block.

   Setup placeholders
       These are a couple of templates that use	a HTML friendly	sintax.	The
       output will be the same for both	templates, with	or without
       placeholders: the difference is the way you can look at the template.

       template	without	placeholders
	       <p><hr>
	       Name: <b	style="color:blue"><!--{name}--></b><br>
	       Surname:	<b style="color:blue"><!--{surname}--></b>
	       <hr></p>

	   This	is what	you would see in a WYSIWYG editor: (you	should be
	   using a browser to see the example below this line)

       template	with placeholders
	   The placeholders "John" and "Smith" are included in blocks and will
	   be replaced by the actual values of 'name' and 'surname' from your
	   code.

	       <p><hr>
	       Name: <b	style="color:blue"><!--{name}-->John<!--{/name}--></b><br>
	       Surname:	<b style="color:blue"><!--{surname}-->Smith<!--{/surname}--></b>
	       <hr></p>

	   This	is what	you would see in a WYSIWYG editor: (you	should be
	   using a browser to see the example below this line)

   Setup simulated areas
       If you want to include in your template some area only for design
       purpose (for example to see, right in the template, how could look a
       large nested loop), just	transform it into a block and give it an
       identifier that will never be defined in	your code.

	   {my_simulated_area} this block simulates a possible output
	   and it will never generate any output {/my_simulated_area}

   Setup labeled areas
       If you want to label some area in your template (for example to extract
       the area	to mix with another template), just transform it into a	block
       and give	it an identifier that will always be defined in	your code. A
       convenient way to do so is to define a reference	to an empty hash. This
       will generate the output	of the block and (since	the hash does not
       contain any keys) the lookup will fallback to the containers zones and
       the lookups locations.

       the code
	       $my_labeled_area	= {}  ;	 # a ref to an empty hash

       the template
	       {my_labeled_area}
	       this block will always generate an output
	       {/my_labeled_area}

   Build a loop
       the template
	   A loop is represented by a block, usually containing	labels:

	       A loop:
	       {my_loop}-------------------
	       Date: {date}
	       Operation: {operation}
	       {/my_loop}-------------------

       the code
	   You should have some	array of hashes	(or a reference	to) defined
	   somewhere:

	       $my_loop	= [
			     {
				 date	   => '8-2-02',
				 operation => 'purchase'
			     },
			     {
				 date	   => '9-3-02',
				 operation => 'payment'
			     }
			   ] ;

       the output
	       A loop:
	       -------------------
	       Date: 8-2-02
	       Operation: purchase
	       -------------------
	       Date: 9-3-02
	       Operation: payment
	       -------------------

   Build a nested loop
       the template
	   A nested loop is represented	by a block nested into another block:

	       A nested	loop:
	       {my_nested_loop}-------------------
	       Date: {date}
	       Operation: {operation}
	       Details:{details}
			  - {quantity} {item}{/details}
	       {/my_nested_loop}-------------------

	   Notice that the block 'details' is nested into the block
	   'my_nested_loop'.

       the code
	   You should have some	array nested into some other array, defined
	   somewhere:

	       # a couple of nested "for" loops	may produce this:
	       $my_nested_loop = [
				    {
				       date	 => '8-2-02',
				       operation => 'purchase',
				       details	 => [
						       {
							  quantity => 5,
							  item	   => 'balls'
							},
							{
							  quantity => 3,
							  item	   => 'cubes'
							},
							{
							  quantity => 6,
							  item	   => 'cones'
							}
						    ]
				    },
				    {
				       date	 => '9-3-02',
				       operation => 'payment',
				       details	 => [
						       {
							  quantity => 2,
							  item	   => 'cones'
							},
							{ quantity => 4,
							  item	   => 'cubes'}
						    ]
				     }
				 ] ;

	   Notice that the value of the	keys 'details' are a reference to an
	   array of hashes.

       the output
	       A nested	loop:
	       -------------------
	       Date: 8-2-02
	       Operation: purchase
	       Details:
			 - 5 balls
			 - 3 cubes
			 - 6 cones
	       -------------------
	       Date: 9-3-02
	       Operation: payment
	       Details:
			 - 2 cones
			 - 4 cubes
	       -------------------

   Build a simple loop
       This is a new feature implemented in Template::Magic 1.32, that allows
       the direct handling of array items in loops (i.e. you can use an	array
       of strings instead of an	array of hashes	containing a named string).

       When the	loop contains just a label, you	can also directly use the
       items of	any array, eventually using also the relative index number:

       the code
	   You should have some	array defined somewhere:

	       $my_loop	= [ qw(	ball cube cone ) ] ;

       the template
	   A loop is represented by a block, usually containing	labels.	This
	   loop	defines	as 'product' the label representing each array item,
	   the progressive count as 'line_number' and the starting count at 1:

	       A loop:
	       {my_loop	OF product line_number 1}-------------------
	       {line_number} - Product:	{product}
	       {/my_loop}-------------------

       the output
	       A loop:
	       -------------------
	       1 - Product: ball
	       -------------------
	       2 - Product: cube
	       -------------------
	       3 - Product: cone
	       -------------------

       Note: any loop that directly uses the values of any array, can be
       written as:

       {my_array}
	   this	is used	only when the array items are reference	to hashes (see
	   "Build a loop" or "Build a nested loop")

       {my_array OF anything index 1}
	   this	defines	as 'anything' the label	representing each array	item,
	   the progressive count as 'index' and	the starting count will	start
	   at 1

       {my_array OF anything index}
	   if you omit the starting count value, it will start at 0

       {my_array OF anything}
	   if you don't	use any	progressive count inside the block you may
	   omit	it

       {my_array anything}
	   you can also	omit the 'OF' (case insensitive) keyword in all	the
	   above cases

   Process (huge) loops	iteration by iteration
       Usually a loop is built just by an array	of hashes value	(see "Build a
       loop"). This means that you have	to fill	an array with all the hashes
       BEFORE the process starts. In normal situations (i.e. the array
       contains	just a few hashes) this	is not a problem, but if the array is
       supposed	to contain a lot of hashes, it could be	more efficient by
       creating	each hash just DURING the process and not BEFORE it (i.e.
       without storing it in any array).

       For example imagine that	in the "Build a	loop" example, the array comes
       from a huge file	like this:

	   8-2-02|purchase
	   9-3-02|payment
	   ... some hundred lines

       You could generate the output line by line with a simple	sub like this:

	   sub my_loop
	   {
	     my	($z) = @_ ;
	     open FILE,	'/path/to/data/file' ;
	     while (<FILE>) # for each line of the file
	     {
	       chomp ;
	       my $line_hash ;
	       @$line_hash{'date', 'operation'}	= split	/\|/ ;	# create line hash
	       $z->value = $line_hash ;				# set the zone value
	       $z->value_process() ;				# process the value
	     }
	   }

       This way	you don't waste	memory to store	the data for all the iteration
       into the	array: you just	use the	memory needed for one iteration	at a
       time.

   Setup an if-else condition
       the template
	   An if-else condition	is represented with 2 blocks

	       {OK_block}This is the OK	block, containig {a_scalar}{/OK_block}
	       {NO_block}This is the NO	block{/NO_block}

       the code
	   Remember that a block will be deleted if the	lookup of the
	   identifier returns the UNDEF	value, so your code will determine
	   what	block will generate output (defined identifier)	and what not
	   (undefined identifier).

	       if ($OK)	{ $OK_block = {a_scalar	=> 'A SCALAR VARIABLE'}	}
	       else	{ $NO_block = {} }

	   Same	thing here:

	       $a_scalar = 'A SCALAR VARIABLE';
	       $OK ? $OK_block={} : $NO_block={};

       the output
	   A true $OK would leave undefined $NO_block, so it would produce
	   this	output:

	       This is the OK block, containig A SCALAR	VARIABLE

	   A false $OK would leave undefined $OK_block,	so it would produce
	   this	output:

	       This is the NO block

	   Notice that $OK_block and $NO_block should not return a SCALAR
	   value, that would replace the whole block with the value of the
	   scalar.

   Use the NOT_* blocks
       This is a new feature implemented in Template::Magic 1.2, that allows
       to simplify the if-else handling	for any	zone. It is intended to	be
       used only in such case (if-else), and in	such order (first the *	block
       and next	the NOT_* block); for any other	use, please refer to "Setup an
       if-else condition".

       For any zone you	can use	a NOT_*	zone (where '*'	stands for the zone
       id) which  will automatically be	printed	if the zone is not printed, or
       wiped out if the	zone is	printed.

       The above example could be written also this way:

       the template
	      {OK_block}This is	the OK block, containig	{a_scalar}{/OK_block}
	      {NOT_OK_block}This is the	NOT_OK_block, containig	{a_scalar},
	      and printed automatically	if the OK_block	will not be printed
	      {/NOT_OK_block}

       the code
	      $a_scalar	= 'A SCALAR VARIABLE';
	      $OK_block	= any_condition() ? {} : ''

       the output
	   A true "any_condition()" whould set the $OK_block to	an empty hash
	   reference, thus printing

	      This is the OK block, containig A	SCALAR VARIABLE

	   While a false "any_condition()" whould wipe out the "OK_block",
	   thus	automatically printing the "NOT_OK_block".

	      This is the NOT_OK_block,	containig A SCALAR VARIABLE,
	      and printed automatically	if the OK_block	will not be printed

   Setup a switch condition
       the template
	   A simple switch (if-elsif-elsif) condition is represented with
	   multiple blocks:

	       {type_A}type A block with {a_scalar_1}{/type_A}
	       {type_B}type B block with {a_scalar_2}{/type_B}
	       {type_C}type C block with {a_scalar_1}{/type_C}
	       {type_D}type D block with {a_scalar_2}{/type_D}

       the code
	   Your	code will determine what block will generate output (defined
	   identifier) and what	not (undefined identifier). In the following
	   example, value of $type  will determine what	block will produce
	   output, then	the next line will define $type_C using	a symbolic
	   reference:

	       $type  =	'type_C';
	       $$type =	{ a_scalar_1 =>	'THE SCALAR 1',
			  a_scalar_2 =>	'THE SCALAR 2' };

	   Same	thing yet but with a different programming style:

	       $a_scalar_1 = 'THE SCALAR 1';
	       $a_scalar_2 = 'THE SCALAR 2';
	       $type	   = 'type_D';
	       $$type	   = {};

	   Same	thing without using any	symbolic reference:

	       $type	       = 'type_D';
	       $my_hash{$type} = { a_scalar_1 => 'THE SCALAR 1',
				   a_scalar_2 => 'THE SCALAR 2'	};
	       $tm = new Template::Magic
			 lookups => \%my_hash ;

       the output
	   A $type set to 'type_C' would produce this output:

	       type C block with THE SCALAR 1

	   A $type set to 'type_D' would produce this output:

	       type D block with THE SCALAR 2

   Pass	parameters to a	subroutine
       Template::Magic can execute subroutines from your code: when you	use a
       zone identifier that matches with a subroutine identifier, the
       subroutine will receive the zone	object as a parameters and will	be
       executed. This is very useful when you want to return a modified	copy
       of the template content itself, or if you want to allow the designer to
       pass parameter to the subroutines.

       This example show you how to allow the designer to pass some parameters
       to a subroutine in your code. The 'matrix' sub, used in the example,
       receives	the parameters written in the template and generates just a
       table filled of 'X'.

       the template
	       {matrix}5,3{/matrix}

	   The content of 'matrix' block ('5,3') is used as parameter

       the code
	       sub matrix
	       {
		   my ($zone) =	@_;
		   my ($column,	$row) =	split ',' , $zone->content; # split the	parameters
		   my $out;
		   for (0..$row-1) {$out .= 'X'	x $column. "\n"};
		   $out;
	       }

	   The sub 'matrix' receive the	reference to the zone object, and
	   return the output for the block

       the output
	       XXXXX
	       XXXXX
	       XXXXX

       The same	example	with named parameters, could be	written	as follow:

       the template
	       {matrix columns => 5, rows => 3}

	   The attributes string of 'matrix' label (' columns => 5, rows =>
	   3') is used as parameter

       the code
	       sub matrix
	       {
		   my ($zone) =	shift;
		   my $attributes = $zone->attributes;
		   $attributes =~ tr/ //d; # no	spaces
		   my %attr = split /=>|,/, $attributes; # split the parameters
		   my $out;
		   for (0..$attr{rows}-1) {$out	.= 'X' x $attr{columns}	. "\n"};
		   $out;
	       }

	   The sub 'matrix' receive the	reference to the zone object, and
	   return the output for the block

       the output
	       XXXXX
	       XXXXX
	       XXXXX

   Pass	a structure to a subroutine
       You can use the '_EVAL_ATTRIBUTES_' zone	handler	to pass	complex	named
       structures to a subroutine.

       A simple	example	that use the '_EVAL_ATTRIBUTES_' zone handler could
       be:

	   $tm = new Template::Magic
		     markers	   => ['<<', '/', '>>']	  , # to avoid conflict
		     zone_handlers => '_EVAL_ATTRIBUTES_' ;

       This is a possible example of template:

	   text	<<my_sub {color	=> 'red', quantity => 2}>> text

       The '_EVAL_ATTRIBUTES_' zone handler set	the "param" property to	the
       evalued attributes string "{color => 'red', quantity => 2}" in the
       template, so you	can use	it directly in your sub:

	   sub my_sub
	   {
	     my	($z) = @_ ;
	     'The color	is '. $z->param->{color}
	     . ' the quantity is '. $z->param->{quantity}
	   }

       WARNING:	You should use '_EVAL_ATTRIBUTES_' handler ONLY	if you are the
       programmer AND the designer.

   Use subroutines to rewrite links
       If you use a block identifier that matches with a subroutine
       identifier, the subroutine will receive the content of the block	as a
       single parameter	and will be executed. This is very useful when you
       want to return a	modified copy of the template content itself.

       A typical application of	this capability	is the template	of a HTML
       table of	content	that point to several template files. You can use the
       capabilities of your favourite WYSIWYG editor to	easily link each menu
       in the template with each template file.	By doing so you	will generate
       a static	and working HTML file, linked with the other static and
       working HTML template files. This will allow you	to easily check	the
       integrity of your links,	and preview how	the links would	work when
       utilized	by your	program.

       Then a simple "modify_link" subroutine -	defined	in your	program	- will
       return a	self-pointing link that	will be	put in the output in place of
       the static link.	See the	example	below:

       the template
	       <p><a href="<!--{modify_link}-->add.html<!--{/modify_link}-->">Add Item
	       </a></p>
	       <p>
	       <a href="<!--{modify_link}-->update.html<!--{/modify_link}-->">Update Item
	       </a></p>
	       <p>
	       <a href="<!--{modify_link}-->delete.html<!--{/modify_link}-->">Delete Item
	       </a></p>

	   Working links pointing to static templates files (useful for
	   testing and preview purpose,	without	passing	through	the program)

       the code
	       sub modify_link
	       {
		   my ($zone) =	shift;
		   my ($content) = $zone->content;
		   $content =~ m|([^/]*).html$|;
		   return '/path/to/myprog.cgi?action='.$content;
	       }

       the output
	       <p><a href="/path/to/myprog.cgi?action=add">Add Item</a></p>
	       <p><a href="/path/to/myprog.cgi?action=update">Update Item</a></p>
	       <p><a href="/path/to/myprog.cgi?action=delete">Delete Item</a></p>

	   Working links pointing to your program, defining different query
	   strings.

	   See also "Pass parameters to	a subroutine".

   Prepare the identifiers description list
       If you have to pass to a	webmaster the description of every identifier
       in your program utilized	by any label or	block, Template::Magic can
       help you	by generating a	pretty formatted list of all the identifiers
       (from labels and	blocks)	present	in any output printed by your program.
       Just follow these steps:

       1 Add the following line	anywhere before	printing the output:
	       $tm->ID_list;

       2 Capture the outputs of	your program
	   Your	program	will run exactly the same way, but instead of print
	   the regular outputs,	it will	print just a pretty formatted list of
	   all the identifiers present in any output.

       3 Add the description
	   Add the description of each label and block to the captured output
	   and give it to the webmaster.

   Allow untrustworthy people to edit the template
       Magic.pm	does not use any eval()	statement and the allowed characters
       for identifiers are only	alphanumeric "(\w+)", so even dealing with
       tainted templates it should not raise any security problem that you
       wouldn't	have in	your program itself.

       Avoid unwanted executions

       This module can execute the subroutines of your code whenever it
       matches a label or block	identifier with	the subroutine identifier.
       Though unlikely,	it is possible in principle that someone (only if
       allowed to edit the template) sneaks the	correct	identifier from	your
       code, therefore,	if you have any	potentially dangerous subroutine in
       your code, you should restrict this capability. To do this, you can
       omit the	"CODE" value handler, or pass only explicit locations to the
       "new()" method.

       potentially unsafe code
	       sub my_potentially_dangerous_sub	{ unlink 'database_file' };
	       $name = 'John';
	       $surname	= 'Smith';

	       # automatic lookup in __PACKAGE__ namespace
	       $tm = new Template::Magic ;

	   With	this code, a malicious person allowed to edit the template
	   could add the label {my_potentially_dangerous_sub} in the template
	   and that label would	trigger	the deletion of	'database_file'.

       code with subs_execution	disabled
	   Just	explicitly omit	the "CODE" value handler when you create the
	   object, so no sub will be executed:

		$tm = new Template::Magic
			  value_handler	=> [ qw( SCALAR	REF ARRAY HASH ) ] ;

       code with restricted lookups
	       sub my_potentially_dangerous_sub	{ unlink 'database_file' };
	       %my_restricted_hash = ( name => 'John', surname => 'Smith' );

	       # lookup	in %my_restricted_hash only
	       $tm = new Template::Magic
			 lookups => \%my_restricted_hash ;

	   With	this code the lookup is	restricted to just the identifiers
	   used	in the template, thus the subroutine
	   "my_potentially_dangerous_sub" is unavailable to the	outside	world.

   Embed perl into a template
       This example represents the maximum degree of inclusion of perl code
       into a template:	in this	situation, virtually any code inside the
       '_EVAL_'	block will be executed from the	template.

       WARNING:	For obvious reasons you	should use this	handler	ONLY if	you
       are the programmer AND the designer.

       the template
	       {_EVAL_}$char x ($num+1){/_EVAL_}

	   The content of '_EVAL_' block could be any perl expression

       the code
	       $tm = new Template::Magic
			 zone_handlers =>  '_EVAL_' ;
	       $char = 'W';
	       $num = 5;

       the output
	   The handler will generate as	the output the evaluated content of
	   the block.

	       WWWWWW

	   Since a block can contain any quantity of text, you could use this
	   type	of configuration as a cheap way	to embed perl into (HTML)
	   files.

	   Notice that the default syntax markers ({/})	could somehow clash
	   with	perl blocks, so	if you want to embed perl into your templates,
	   you should consider to redefine the syntax with some	more
	   appropriate marker (See "Redefine Markers").

   Caching or not the template
       Template::Magic cache the template structure by default if it is	passed
       as a path to a file. You	can avoid the caching either by	passing	a
       filehandler or a	reference to a template	content	(not so	memory
       efficient) or by	using the 'cache/nocache' "options":

	   $tm = new Template::Magic
		     options =>	'no_cache' ;

EFFICIENCY
       The system is very flexible, so you can use it in a variety of ways,
       but you have to know what is the	best option for	your needs.

   Memory optimization
       You can avoid waste of memory by	avoiding the method output() that
       needs to	collect	and store the output in	memory.	Use print() instead
       that prints the output while it is produced, without charging the
       memory.

       Don't pass big templates	contents as a reference, because
       Template::Magic copies the content in an	internal and optimized
       representation of the template, so you would need twice the memory.

       Don't do	this:

	   open	TEMPLATE, '/path/to/big_template' ;
	   $big_template = do{local $/;	<TEMPLATE>} ;
	   $output = $tm->output(\$big_template);
	   print $$output;

       You can save a lot of typing and	a lot of memory	if you do this
       instead:

	   $tm->print('/path/to/big_template') ;

       If you need to use "Template::Magic" with "CGI::Application" (that
       requires	the run	modes method to	collect	the whole output) you may use
       CGI::Application::Magic or Apache::Application::Magic that
       transparently integrates	the template system with the application and
       avoid the "output()" method.

       For memory optimization see also:

       o   "Include and	process	a template file"

       o   "Include (huge) text	files without memory charges"

       o   "Process (huge) loops iteration by iteration"

   Cache
       If you pass the template	as a path, Template::Magic will	cache it (in
       the global %Template::Magic::CACHE hash)	and will open and parse	it
       just the	first time or if it has	been modified, so you can save a lot
       of processing too! This is a big	advantage under	mod_perl, where	the
       persistent environment can speed	up the process,	completely avoiding to
       read and	parse the template file.

       If for any reason you don't want	the template to	be cached, you can use
       the 'no_cache' "options".

       See also:

       o   "Caching or not the template"

       o   load() method

       o   purge_cache() method

   The -compile	pragma
       It has no effect	since version 1.39.

SYNTAX GLOSSARY
       attributes string
	   The attributes string contains every	character between the end of
	   the label identifier	and the	end label marker. This is optionally
	   used	to pass	special	parameters to a	sub.

       block
	   A block is a	template zone delimited	by (and	including) a label and
	   an end label:

	       +-------+-------------------+------------+
	       | LABEL |      CONTENT	   | END_LABEL	|
	       +-------+-------------------+------------+

	   Example: {my_identifier} content of the block {/my_identifier}

	   where '{my_identifier}' is the LABEL, ' content of the block	' is
	   the CONTENT and '{/my_identifier}' is the END_LABEL.

       end label
	   An end label	is a string in the form	of:

	       +--------------+---------------+------------+------------+
	       | START_MARKER |	END_MARKER_ID |	IDENTIFIER | END_MARKER	|
	       +--------------+---------------+------------+------------+

	   Example of end label	: {/my_identifier}

	   where '{' is	the START_MARKER, '/' is the END_MARKER_ID,
	   'my_identifier' is the IDENTIFIER, and '}' is the END_MARKER.

       identifier
	   A label identifier is an alphanumeric name "(\w+)" that represents
	   (and	usually	matches) a variable or a subroutine identifier of your
	   code.

       illegal blocks
	   Each	block in the template can contain arbitrary quantities of
	   nested labels and/or	blocks,	but it cannot contain itself (a	block
	   with	its same identifier), or cannot	be cross-nested.

	   Legal  block: {block1}...{block2}...{/block2}...{/block1}

	   Illegal auto-nested block:
	   {block1}...{block1}...{/block1}...{/block1}

	   Illegal cross-nested	block:
	   {block1}...{block2}...{/block1}...{/block2}

	   If the template contains any	illegal	block, unpredictable
	   behaviours may occur.

       include label
	   An include label is a label used to include a template file.	The
	   identifier must be 'INCLUDE_TEMPLATE' and the attributes string
	   should be a valid path.

	   Example: {INCLUDE_TEMPLATE /templates/temp_file.html}

       label
	   A label is a	string in the form of:

	       +--------------+------------+------------+------------+
	       | START_MARKER |	IDENTIFIER | ATTRIBUTES	| END_MARKER |
	       +--------------+------------+------------+------------+

	   Example: {my_identifier attribute1 attribute2}

	   where '{' is	the START_MARKER, 'my_identifier' is the IDENTIFIER,
	   'attribute1 attribute2' are the ATTRIBUTES and '}' is the
	   END_MARKER.

       lookup
	   The action to match label identifier	with code identifier
	   (variable, subroutine and method identifier and hash	keys).

       main template zone
	   The 'root' zone representing	the whole template content

       markers
	   The markers that defines labels and blocks. These are the default
	   values of the markers that define the label:

	       START_MARKER:   {
	       END_MARKER_ID:  /
	       END_MARKER:     }

	   You can redefine them by using the "markers"	constructor array.
	   (see	"Redefine Markers" and markers).

       matching	identifier
	   The identifier (symbol name or key name) in the code	that is
	   matching with the zone or label identifier

       merger process
	   The process that merges runtime values with a template producing
	   the final output

       nested block
	   A nested block is a block contained in another block:

	       +----------------------+
	       |   CONTAINER_BLOCK    |
	       |  +----------------+  |
	       |  |  NESTED_BLOCK  |  |
	       |  +----------------+  |
	       +----------------------+

	   Example:
	       {my_container_identifier}
	       {my_nested_identifier} content of the block
	   {/my_nested_identifier}
	       {/my_container_identifier}

	   where all the above is the CONTAINER_BLOCK and
	   '{my_nested_identifier} content of the block
	   {/my_nested_identifier}' is the NESTED_BLOCK.

       output
	   The output is the result of the merger of runtimes values with a
	   template

       template
	   A template is a text	content	or a text file (i.e. plain, HTML, XML,
	   etc.) containing some label or block.

       value type
	   The type of the value found by a lookup (i.e. UNDEF,	SCALAR,	HASH,
	   ARRAY, ...),	that is	usually	used in	the value handler condition to
	   trigger the value handler.

       zone
	   A zone is an	area in	the template that must have an identifier, may
	   have	an attributes string and may have a content. A zone without
	   any content is also called label, while a zone with content is also
	   called block.

       zone object
	   A zone object is an internal	object representing a zone.

SEE ALSO
       o   Template::Magic::Zone

       o   Template::Magic::HTML

       o   Template::Magic::Pager

       o   CGI::Builder::Magic

       o   CGI::Application::Magic

       o   Apache::Application::Magic

SUPPORT
       Support for all the modules of the Template Magic System	is via the
       mailing list. The list is used for general support on the use of	the
       Template::Magic,	announcements, bug reports, patches, suggestions for
       improvements or new features. The API to	the Magic Template System is
       stable, but if you use it in a production environment, it's probably a
       good idea to keep a watch on the	list.

       You can join the	Template Magic System mailing list at this url:

       <http://lists.sourceforge.net/lists/listinfo/template-magic-users>

AUTHOR and COPYRIGHT
       A(C) 2004-2005 by Domizio Demichelis (<http://perl.4pro.net>)

       All Rights Reserved. This module	is free	software. It may be used,
       redistributed and/or modified under the same terms as perl itself.

CREDITS
       Thanks to Mark Overmeer <http://search.cpan.org/author/MARKOV/> which
       has submitted a variety of code cleanups/speedups and other useful
       suggestions.

       A special thanks	to Megyaszai Sandor for	his very detailed revision of
       the POD.

POD ERRORS
       Hey! The	above document had some	coding errors, which are explained
       below:

       Around line 2618:
	   Non-ASCII character seen before =encoding in	'A(C)'.	Assuming
	   CP1252

perl v5.24.1			  2006-09-19		    Template::Magic(3)

NAME | VERSION 1.39 | INSTALLATION | SYNOPSIS | DESCRIPTION | METHODS | CUSTOMIZATION | HOW TO... | EFFICIENCY | SYNTAX GLOSSARY | SEE ALSO | SUPPORT | AUTHOR and COPYRIGHT | CREDITS | POD ERRORS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Template::Magic&sektion=3&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help