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

FreeBSD Manual Pages

  
 
  

home | help
dTemplate(3)	      User Contributed Perl Documentation	  dTemplate(3)

NAME
       dTemplate - A simple yet	powerful template handling logic with advanced
       features.

	   $Id:	dTemplate.pod 105 2004-07-24 12:08:22Z dlux $

	   $URL: http://svn.dlux.hu/public/dTemplate/trunk/dTemplate.pod $

SYNOPSIS
	   use dTemplate;

	   # definition

	   $mail_template = dTemplate->new( file => "mail_tmpl.txt" );

	   $template = dTemplate->new( text => "<html>$BODY$</html>" ),

	   # parsing
	   $mail = $mail_template->parse(
	       FROM    => {
		   first_name => "Balazs",
		   last_name  => "Szabo",
		   email      => "dlux@dlux.hu"
	       },
	       TO      => "foo@bar.com",
	       SUBJECT => $subject,
	       BODY    =>
		   sub { $email_type==3	? $body_for_type_3 : $body_for_others },
	       SIGNATURE=> $signature_template->parse( KEY => "value" )
	   );

	   print "Please send this mail:\n$mail";

       where mail_tmpl.txt is:

	       From    : "$FROM.first_name$ $FROM.last_name$" <$FROM.email$>
	       To      : $TO$
	       Subject : $SUBJECT$

	       Message body:
	       $BODY$

	       $SIGNATURE$

	   ### Advanced	feature: Styling

	   # Style definition
	   $style= { lang =>'hungarian', color=>'white'	};

	   # Selector definition
	   $html_template = dTemplate->new(choose => $style,
	       'hungarian+white' =>
		   dTemplate->new(file => "hun_white_template.html"),
	       'spanish'	 =>
		   dTemplate->new(file => "spanish.html"),
	       'black+hungarian' =>
		   dTemplate->new(file => "hun_black_template.html"),
	       'english'	 =>
		   dTemplate->new(file => "english_template.html"),
	       'empty'		 =>
		   "<html>This is a text, $BODY$ is NOT	substituted!!!!"</html>",
	       # default:
	       ''		 =>
		   dTemplate->new(text => "<html>$BODY$</html>"),
	   );

	   # Selector definition
	   $body_template = dTemplate->new(choose => $style,
	       'hungarian'	 =>
		   dTemplate->new(file => "sziasztok_emberek.html"),
	       'spanish'	 =>
		   dTemplate->new(file => "adios_amigos.html"),
	       # default:
	       ''		 =>
		   dTemplate->new(file => "bye_bye.html"),
	   );

	   print  $html_template->parse(BODY  =>  $body_template->parse());
	       # will  print  "sziasztok_emberek.html"	in  the
	       # "hun_white_template.html"

	   %$style = ();
	   print $html_template->parse(BODY => $body_template->parse());
	       #  will print "bye_bye.html" surrounded by "<html>" and "</html>" tags.

	   %$style = ( lang => 'english' );
	   print $html_template->parse(BODY => $body_template->parse());
	       # will print the	"bye_bye.html" in of the "english_template.html"

	   ### Advanced	feature: Changing placeholder special characters:

	   $dTemplate::START_DELIMITER	   = '<%\s*'; #	default: \$
	   $dTemplate::END_DELIMITER	   = '\s*%>'; #	default: \$
	   $dTemplate::VAR_PATH_SEP	   = '\/';    #	default: \.
	   $dTemplate::PRINTF_SEP	   = '\$';    #	default: %+
	   $dTemplate::ENCODER_SEP	   = '\@';    #	default: \*+
	   $dTemplate::ENCODER_PARAM_START = '\(';    #	default: \/
	   $dTemplate::ENCODER_PARAM_END   = '\)';    #	default:

	   # dTemplate 2.2 Compatibility:
	   $template1 =	define dTemplate "mail.txt";

	   $template2 =	text dTemplate "This is	the template text...";

	   $template3 =	choose dTemplate \%hash, ...;

DESCRIPTION
       This module is aimed to be a fast, general-purpose, lightweight but
       easily extendible templating system.

       With this module, you can write template-parsing	routines in the	way
       the templates are structured logically: starting	from outside to
       inside. Your code will be clear,	well-structured	and easy to
       understand. This	logic can be attained using by inline subroutines as
       values of template variables.  (Look at the example at the end of the
       document)

USAGE
       A template is a text data (usually taken	from a file), which contains
       special placeholders for	variables.. A template object (a
       dTemplate::Template object) is basically	the representation of this
       text data. The "placeholders" contain informations about:

       o   What	data to	be written into	the placeholder: the name and the
	   "path" of the variable.

       o   How the data	is to be formatted and processed.

   The format of a placeholder
       A placeholder in	a text file has	the following format: (the format can
       be customized, see below)

	 $varname%printf_def*encoder_def$

       , where:

       varname
	   It is the name of the variable, which can be	any string with
	   alphanumeric	characters. The	"." in the varname has a special
	   meaning, see	the "Data Lookup" section below.

       %printf_def
	   This	is an optional part. Used only,	when you want to format	the
	   output by printf before substitution.  You can use as many '%' as
	   you want here, it can be used to pad	the variable, for example when
	   your	output is a table. E.g:

	     $MONEY%%%%%%011d$

	   is a	valid placeholder.

       *encoder_def
	   Encoders are	specifal subroutines, which are	used, to process a
	   data	before substitution. They works	like "pipe" in UNIX. They got
	   the data in the first parameter, and	the return value will be
	   substituted.	They can be chained, so	more than one encoder can be
	   used	for one	value. In this case the	encoders will be executed in
	   the order of	definition.

	   Encoders are	separated with "*", and	can have one parameter,	which
	   is separated	with "/" from the encoder name.

	   There are some built-in encoders in dTemplate:

	       - u	    : url-encoder
	       - h	    : HTML-encoder (converts > to &gt;,	etc)
	       - ha	    : Advanced HTML encoder (\n	=> <BR>, tabs => spaces)
	       - uc	    : convert the string to uppercase
	       - lc	    : convert the string to lowercase
	       - eq/par	    : returns true if the encoded string is "par"
	       - if/par	    : returns "par" if the encoded string is true
	       - printf/par : returns printf formatted data, where "par" is the	format
			      string

	   Chaining of the encoders:

	       $TITLE*uc*h$

	   or

	       $weight*eq/7*if/CHECKED$

	   (the	last example returns CHECKED if	the weight is equal to "7",
	   useful for radio-buttons or drop-down menus in HTML)

	   Read	more on	encoders (and how to make new encoders)	in the
	   Encoders part.

   Template objects
       There are three ways to create template objects

       From a file:

	   $template = dTemplate->new( file => $filename );

       From a scalar variable:

	   $template = dTemplate->new( text => "<html>$BODY$</html>" ),

       Using the template chooser:

	   $template = dTemplate->new( choose => $style_hash_ref,
	       "style1"	=> $dTemplate_object1,
	       "style2"	=> $dTemplate_object2,
	       ...
	   );

       Note, the template chooser is not a "real" template object. It is a
       meta-object (a dTemplate::Choose	object), which selects one of many
       real template objects based on the contents of a	style hash. Read more
       about the chooser later.

   Parsing
       Once you	have the template object, you can use them to create output by
       substituting and	formatting data	into the placeholders.

       The parsing is done by the objects' parse methods. The return value of
       the parse method	is the substituted text.

       The variable substitution is done in following steps:

	   - Look for the data to substitute
	       - Look for the data among the parameters	of the parse method.
	       - Look for the data among the parameters	of the template
		 object's parse	hash ($obj->parsehash->{$varname})
	       - Look for the data among the keys of %dTemplate::parse hash
	   - Process "path" information	in the placeholder
	   - If	we have	not found the variable,	then we	use the	value of the ""
	     key of the	object's parsehash ($obj->parsehash->{""}) if exists, or
	     the $dTemplate::parse{""} if exists.
	   - If	the value is a code reference, then we call it to return the
	     value.
	   - Use the encoders on the returned value
	   - Use the printf-formatter on the returned value

   Looking for the data	to substitute
       Each substitution is started by looking up the substitutable variable
       name.  If the variable name contains path information (contains "."
       characters), then, it is	not used at this step, so only the information
       before the first	"." is used.

       The parse method	looks for the substitutable variable name in three
       places:

	   - Among the parameters of the parse method
	   - Among the keys of local parsehash ($object->parsehash)
	   - Among the keys of dTemplate::parse	hash

   Looking for the data	in the parameters of the parse method
       The parse method	can have parameters in the following format:

	   - List of name => value pairs
	   - Hash-reference.

       For example:

	   my $hashref = {
		   name2 => $value2,
		   name3 => $value3
	   };

	   $template->parse(
	       name => $value,
	       $hashref,
	       name4 =>	$value4,
	       { name5 => $value5 },
	       ...
	   )

       This method call	defines	"name",	"name2", "name3", "name4" and "name5"
       variable	names, so they will be substituted in the $template object
       with $value, $value2, $value3, $value4 and $value5.

   Looking for the data	in the local parsehash
       If we encounter a variable reference in the template placeholders, that
       is not assigned among the parameters of parse method, then we look up
       the variable in keys of the local parsehash of the dTemplate object.
       You can assign values to	the local parsehash with the following
       expression:

	   $obj->parsehash->{key} = $value;

       or you can assign hash-reference	to multiple objects:

	   $obj1->parsehash = $obj2->parsehash = { key1	=> "v1", key2 => "v2" };

       If we found it, then we use its value for further processing.

   Looking for the data	in the dTemplate::parse	hash
       If we did not find the variable even in the local parsehash, then we
       look up the variable in keys of the global dTemplate::parse hash. If we
       found it, then we use its value for further processing.

   Processing "path" information
       After we	have found the variable	in the previous	phase among the
       parameters of the parse method or in the	dTemplate::parse hash, we
       process the "path" information in the placeholder if we have it.

       Path information	is appended to the variable name by "."-s.

       If the variable definition in the placeholder contains "path", then we
       assume that the variable	is a hash-reference, and we tries to access
       the specified hash key in it. For example in $template, you define the
       following placeholder:

	   $name3.key1.key2$

       If you assign $value3 to	name3 (in the parameter-list of	the parse
       method or in the	$dTemplate::parse{name3} hash),	then it	is not simply
       substitute $value3, but it tries	to use the $value3 as a	hash
       reference, and looks up a key in	it with	the name "key1". If it is
       found, then it tries to use the value as	a hash reference, and looks up
       a key in	it with	the name "key2", and its value will be substituted:

	   $value3 = { key1 => { key2 => "This will be substituted" } };

       If the value, which is found is a code reference, then we stop the key-
       lookup and call the sub e.g:

	   $value3 = { key1 => sub { return "This will be substituted";	} }

   Using data in $obj->parsehash->{""} as value
       If we did not find the referenced value by the process described	above,
       then we use the the value of the	"" hash-key of the object's parsehash
       instead of the variable.	If it is a code-reference, then	it is called
       exactly like it was the variable	that has found,	e.g:

	   $obj->parsehash->{""} = sub { "Fallback value for this template"; }

   Using data in $dTemplate::parse{""} as value
       If we did not find the referenced value by the process described	above,
       then we use the the value of $dTemplate::parse{""} hash-key instead of
       the variable. If	it is a	code-reference,	then it	is called exactly like
       it was the variable that	has found.

   Calling code	references
       We can assign code references to	variables, they	will be	called if we
       encounter the variable, which needs substitution.

       The function-call will have the following parameters:

	   - Full matched placeholder as the first argument
	   - An	array reference	to the splitted	variable and path information as a
	     second argument.
	   - The dTemplate::Template object in which you called	the "parse"
	     method.

       For example if a	placeholder is like to this:

	   $HASH1.key1.key2*uc$

       and the parsing code is the following:

	   $t1->parse(
	       # ...
	       HASH1 =>	sub { my ($placeholder,	$pathref, $object) = @_;
		   warn	"Placeholder: $placeholder, Variable path:".@$pathref."\n";
		   # ...
	       }
	   );

       Then it will print the following	message	to the standard	error:

	   Placeholder:	$HASH1.key1.key2*uc$, Variable path: HASH1 key1	key2

   Calling encoders
       If we have the data, which substitutes the placeholder, then we can
       encode them or format them by the dTemplate encoders. The encoders are
       code references,	which are assigned the the values of the
       %dTemplate::ENCODERS hash. Names	of the encoders	are the	keys of	the
       hash.

       Encoders	are called in the order	of declaration in the template,	so

	   $variable*uc*h$

       is not the same as

	   $variable*h*uc$

       An encoder can have one optional	parameter, which can be	provided in
       the placeholder,	e.g:

	   $weight*eq/7*if/CHECKED$

       (the last example returns CHECKED if the	weight variable	is equal to
       "7", useful for radio-buttons or	drop-down menus	in HTML)

       Note, that by default, the encoders are NOT called, if we did not find
       the variable and	we are using the local key of the local	parsehash or
       $dTemplate::parse. This is a feature, not a bug,	because	the "" keys
       are designed to be used only to report errors or	warnings, like this:

	   use Carp qw(cluck);
	   $dTemplate::parse{""} = sub {
	       cluck "$_[0] is not assigned";
	       return "";
	   }

       If you want to use the $dTemplate::parse{""} value (or the local
       parsehash's "" key) as it was a normal value, then set the
       $dTemplate::NOTASSIGNED_MODE variable to	true. In this case, the
       encoders	and the	formatter are called on	the value of
       $dTemplate::parse{""} also.

       For example, if the $dTemplate::parse{""} is assigned to	the subroutine
       above, and if $dTemplate::NOTASSIGNED_MODE is false (by default), the

	   $noassigned_variable%03d$

       will be substituted with	an empty string, but if	it is true, it is
       substituted to "000" (because the formatter is called).

       The parameter-list of an	encoder	if it is called:

	 - The encodable text
	 - The (optional) encoder parameter
	 - The dTemplate::Template object in which the parsing is done

   Changing placeholder	special	characters
       You can change the placeholder parameters by changing (or localizing)
       the following variables.

	   $dTemplate::START_DELIMITER	   = '\$';
	   $dTemplate::END_DELIMITER	   = '\$';
	   $dTemplate::VAR_PATH_SEP	   = '\.';
	   $dTemplate::PRINTF_SEP	   = '%+';
	   $dTemplate::ENCODER_SEP	   = '\*';
	   $dTemplate::ENCODER_PARAM_START = '\/';
	   $dTemplate::ENCODER_PARAM_END   = '';

       If you change these variables, then these are used in the compilation
       of the following	templates. Currently there is no supported way to
       recompile an already compiled template, so you need to create a new
       instance.

       Although	if you want to compile a variable, which is not	compiled, then
       you can call the	$template->compile method on them by hand.

       These variables can be set to any regular expressions, not just one
       single character.

       If you don't want to use	any of the features, then set the
       corresponding variable to any regexp that is too	complex	to be true.

   Styles (Template choosers)
       You can use the "chooser" to dynamically	select one template from many
       based on	styles.

       The current "style" is represented by a hash, for example:

	 my %style = (lang => 'spanish', color => 'white');

       Based on	informations in	the hash, the chooser (which is	a
       dTemplate::Choose object) decides which dTemplate::Template object is
       used in the parse operation.

       dTemplate::Choose object	also has a parse method, and it	is compatible
       with the	parse method of	dTemplate::Template, so	you can	use it
       transparently.

       When you	define a template chooser object in the	following way:

	   $template = dTemplate->new( choose => \%style,
	       "style1"	=> $dTemplate_object1,
	       "style2"	=> $dTemplate_object2,
	       "style3"	=> $dTemplate_object3,
	       "style3+style4" => $dTemplate_object4,
	       ...
	   );

       , then you get a	wrapper	object,	which wraps several
       dTemplate::Template objects, which selects $dTemplate_object1 if
       "style1"	is active, $dTemplate_object2 if "style2" is active,
       $dTemplate_object3 if "style3" and "style4" is active, etc.

       If you call the "parse" method of this template,	then it	selects	one of
       the dTemplate objects ($dTemplate_object1, $dTemplate_object2, etc.)
       and calls the parse method of them.

       The chooser selects the template, which has the most "style" matched.

       For example if the style	hash is:

	   %style = (first_style => "style3", second_stype => "style99");

       Then

	   $template->parse(...)

       calls the parse method of $dTemplate_object3, but if

	   %style = (first_style => "style3", second_stype => "style4");

       then it activates the $dTemplate_object4.

       Note, that the keys in the %style hash has no meaning.

COMPATIBILITY
   Old-style constructors
       Old-style constructors ("define dTemplate", "choose dTemplate", "text
       dTemplate") is obsoleted, but still can be used.	The preferred way to
       call the	"new" method in	new programs.

   Prior 2.3
       dTemplate v2.3 removes the default value	of $dTemplate::parse{""}. In
       the pre 2.3 versions, $dTemplate::parse{""} was a code reference, which
       returned	the first parameter of it.

HINTS
   Template compilation
       In the first parse of every template, the templates will	be compiled.
       It is used to speed up parsing.

   %dTemplate::parse localization
       Don't forget that %dTemplate::parse can be localized. This means	you
       can define local-only variable assignments in a subroutine:

	 local %dTemplate::parse = (
	     %dTemplate::parse,
	     local_name	=> $value
	 );

   References and encoders
       You don't need to use text as the input value of	an encoder, you	can
       use any scalar, even references!	If you want (for example) print	a date
       by a date encoder, which	expects	the date to be an array	ref of [ year,
       month, day ], then you can do this, e.g:

	  $dTemplate::ENCODERS{date} = sub {
	      return ""	if ref($_[0]) ne 'ARRAY';
	      return $_[0]->[0]."-".$_[0]->[1]."-".$_[0]->[2];
	  }

       Then, when you put $START_DATE*date$ to a template, you can parse this
       template:

	 $template->parse(
	   START_DATE => [2000,11,13],
	   ...
	 );

   Magical (tied) hashes
       You can use magical hashes everywhere in	the "parse" method parameter
       list, where you can use normal hashes, but because I redesigned the
       "parse" method with the speed with the first priority, it works quite a
       bit different than the older ( <= 2.0 ) versions.

       At template-compile time, the "compile" method collects the variable
       names, which are	found in that template,	and the	"parse"	method knows
       which variables are required for	processing this	template.

       When the	"parse"	method realizes	that a parameter is a hash reference,
       then it always tries all	the remaining template variables (which	are
       not assigned in the preceding part of the parameter list) in that hash
       reference.

       Imagine the following situation:

	 $template->parse( name	=> "blow", \%hash);

       ... where %hash is a magical hash, and the $template contains the
       "name", "address" and "method.type" variables. When the parse method
       meets with the \%hash, the "name" is already assigned, so it olny tries
       to read the $hash{address} and $hash{method} variables.

       This is not a problem with normal hashes, but if	you use	magical
       hashes, you may have a very expensive FETCH function, and this effect
       can cause problems.

       There are two way to work around	it:

       o   Use qualified variable names. If you	use the	following form of
	   parse:

	     $template->parse( name => "blow", data => \%hash);

	   ... then the	%hash is called	only when the template parser finds
	   the "data.address" and "data.method.type" variable references in
	   the template. Of course, you	have to	change the template variable
	   names also.

       o   Use the hash	instead	of a hash reference:

	     $template->parse( name => "blow", %hash);

	   In this case, the magical hash is iterated through when the
	   parameter list is assembled.	This is	better only if you are afraid
	   of random key retrieval, but	it can be also slow, if	the FIRSTKEY,
	   NEXTKEY and FETCH operations	are slow.

	   But if the random-key retrieval is not a problem for	your magical
	   hash, then use the default form instead of this, because that
	   requires less operation (only one FETCH).

EXAMPLE
       It is an	example, which contains	most of	the features this module has.
       It is not intended to be	a real-world example, but it can show the
       usage of	this module.

       This example consists of	one program, and some template modules.

       The executable version of this program can be found in the example
       directory of the	module distribution.

	 use dTemplate;

	 ### definition	of the standard	templates

	 my @TEMPLATE_LIST=qw(page table_row table_cell);
	 my $templates={};
	 foreach my $template (@TEMPLATE_LIST) {
	   $templates->{$template} =
	     define dTemplate("templates/$template.htm");
	 }

	 ### definition	of the styled templates	(styles	= languages)

	 my @STYLES=qw(eng hun);
	 my @STYLED_TEMPLATE_LIST=qw(table_title);

	 my $style_select={ lang => 'hun' };

	 foreach my $template (@STYLED_TEMPLATE_LIST) {
	   my @array=();
	   foreach my $style (@STYLES) {
	     push @array, $style =>
	       define dTemplate("text/$style/$template.txt");
	   }
	   $templates->{$template} =
	     choose dTemplate $style_select, @array;
	 }

	 ### setting up	input data

	 my $table_to_print=[
	   [ "Buwam",	3, 6, 9	],
	   [ "Greg",	8, 4, 2	],
	   [ "You're",	8, 3, 4	],
	   [ "HTML chars: <>", 3],
	 ];

	 ### setting up	the global parse hash with parse parameters;

	 $dTemplate::parse{PAGENO}=7;

	 ### settings up a hash	with personal data.

	 my $person_hash={
	   name	=> { first_name	=> "Greg" },
	   zip	=> "9971",
	 };

	 ### this hash is simply added to other	parse parameters

	 my $parse_hash={
	   "unknown" =>	{ data => 157 },
	 };

	 ### the main page parse routine

	 print $templates->{page}->parse(
	   TABLE_TITLE =>	      #	name =>	value pair
	     $templates->{table_title}->parse(),
	   TABLE => sub	{	      #	name =>	value pair. value is a sub
	     my	$ret="";
	     foreach my	$row (@$table_to_print)	{
	       $ret .= $templates->{table_row}->parse(
		 BODY => sub {
		   my $ret="";
		   foreach my $cell (@$row) {
		     $ret .= $templates->{table_cell}->parse(
		       TEXT => $cell,
		     )
		   }
		   return $ret;
		 }
	       )
	     }
	     return $ret;
	   },
	   "person" => $person_hash,  #	name =>	value pair. value is a href
	   $parse_hash,		      #	only a hash with parse parameters
	 );

       And the templates:

       templates/page.htm:
	     <html>
	     <body>

	     <h1>$TABLE_TITLE*h$</h1>

	     <table>
	     $TABLE$
	     </table>

	     <br>
	     Person name: $person.name*h$, zip code: $person.zip*h$
	     <br>

	     Unknown data: $unknown.data*h$
	     <br>

	     Page: $PAGENO%02d*h$

	     </body>
	     </html>

       templates/table_row.htm:
	     <tr>$BODY$</tr>

       templates/table_cell.htm:
	     <td>$TEXT*h$</td>

       text/eng/table_title.txt:
	     Table 1

       text/hun/table_title.txt:
	     1.	tA!blA!zat

COPYRIGHT
       Copyrigh	(c) 2000-2001 SzabA^3, BalA!zs (dLux)

       All rights reserved. This program is free software; you can
       redistribute it and/or modify it	under the same terms as	Perl itself.

AUTHOR
       dLux (SzabA^3, BalA!zs) <dlux@kapu.hu>

SEE ALSO
       perl(1),	HTML::Template,	Text::Template,	CGI::FastTemplate, Template.

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

       Around line 763:
	   Non-ASCII character seen before =encoding in	'tA!blA!zat'. Assuming
	   CP1252

perl v5.24.1			  2005-06-25			  dTemplate(3)

NAME | SYNOPSIS | DESCRIPTION | USAGE | COMPATIBILITY | HINTS | EXAMPLE | COPYRIGHT | AUTHOR | SEE ALSO | POD ERRORS

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

home | help