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

FreeBSD Manual Pages


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

NAME - a class implementing a	fill-in	template

	use Text::FillIn;

	# Set the functions to do the filling-in:
	Text::FillIn->hook('$',	sub { return ${$_[0]} });  # Hard reference
	Text::FillIn->hook('&',	"main::run_function");	   # Symbolic reference
	sub run_function { return &{$_[0]} }

	$template = new	Text::FillIn('some text	with [[$vars]] and [[&routines]]');
	$filled_in = $template->interpret();  #	Returns	filled-in template
	print $filled_in;
	$template->interpret_and_print();  # Prints template to	currently
					   # selected filehandle

	# Or
	$template = new	Text::FillIn();
	$template->set_text('the text is [[ $[[$var1]][[$var2]]	]]');
	$TVars{'var1'} = 'two_';
	$TVars{'var2'} = 'parter';
	$TVars{'two_parter'} = 'interpreted';
	$template->interpret_and_print();  # Prints "the text is interpreted"

	# Or
	$template = new	Text::FillIn();
	$template->get_file('/etc/template_dir/my_template');  # Fetches a file

	# Or
	$template = new	Text::FillIn();
	$template->path('.', '/etc/template_dir');  # Where to find templates
	$template->get_file('my_template'); # Gets ./my_template or
					    # /etc/template_dir/my_template

       This module provides a class for	doing fill-in templates.  These
       templates may be	used as	web pages with dynamic content,	e-mail
       messages	with fill-in fields, or	whatever other uses you	might think
       of.  Text::FillIn provides handy	methods	for fetching files from	the
       disk, printing a	template while interpreting it (also called
       streaming), and nested fill-in sections (i.e. expressions like [[
       $th[[$thing2]]ing1 ]] are legal).

       Note that the version number here is 0.04 - that	means that the
       interface may change a bit.  In fact, it's already changed some with
       respect to 0.02 (see the	CHANGES	file).	In particular, the
       $LEFT_DELIM, $RIGHT_DELIM, %HOOK, and @TEMPLATE_PATH variables are
       gone, replaced by a default/instance variable system.

       I might also change the default hooks or	something.  Please read	the
       CHANGES file before upgrading to	find out whether I've changed anything
       you use.

       In this documentation, I	generally use "template" to mean "an object of
       class Text::FillIn".

   Defining the	structure of templates
       o   delimiters

	   Text::FillIn	has some special variables that	it uses	to do its
	   work.  You can set those variables and customize the	way templates
	   get filled in.

	   The delimiters that set fill-in sections of your form apart from
	   the rest of the form	are generally [[ and ]], but they don't	have
	   to be, you can set them to whatever you want.  So you could do

	    $template->set_text('this is a {$variable} and a {&function}.');

	   Whatever you	set the	delimiter to, you can put backslashes before
	   them	in your	templates, to force them to be interpreted as

	    $template->set_text('some [[$[[$var2]][[$var]]]] and \[[ text \]]');
	    # Prints "some stuff and [[	text ]]"

	   You cannot currently	have several different kinds of	delimiters in
	   a single template.

       o   interpretation hooks

	   In order to interpret templates, "Text::FillIn" needs to know how
	   to treat different kinds of [[tags]]	it finds.  The way it
	   accomplishes	this is	through	"hook functions."  These are various
	   functions that "Text::FillIn" will run when confronted with various
	   kinds of fill-in fields.  There are two hooks provided by default:

	    Text::FillIn->hook('$') is \&find_value,
	    Text::FillIn->hook('&') is \&run_function.

	   So if you leave these hooks the way they are, when Text::FillIn
	   sees	some text like "some [[$vars]] and some	[[&funk]]", it will
	   run &Text::FillIn::find_value to find the value of [[$vars]], and
	   it will run &Text::FillIn::run_function to find the value of
	   [[&funk]].  This is based on	the first non-whitespace character
	   after the delimiter,	which is required to be	a non-word character
	   (no letters,	numbers, or underscores).  You can define hooks	for
	   any non-word	character you want:

	    $template =	new Text::FillIn("some [[!mushrooms]] were in my shoes!");
	    $template->hook('!', "main::scream_it");  #	or \&scream_it
	    sub	scream_it {
	       my $text	= shift;
	       return uc($text); # Uppercase-it
	    $new_text =	$template->interpret();
	    # Returns "some MUSHROOMS were in my shoes!"

	   Every hook function will be passed all the text between the
	   delimiters, without any surrounding whitespace or the leading
	   identifier (the & or	$, or whatever).  Hooks	can be given as	either
	   hard	references or symbolic references, but if they are symbolic,
	   they	need to	use the	complete package name and everything.

	   Beginning in	version	0.04, you may use some object's	methods	as
	   hook	functions.  For	example, if you	have a template	$template and
	   another object $myObj, you can instruct $template to	call
	   "$myObj->find_value()" and "$myObj->run_function()" to fill in
	   templates.  See the "$template->object()" method below.

       o   the default hook functions

	   The hook functions installed	with the shipping version of this
	   module are &Text::FillIn::find_value	and
	   &Text::FillIn::run_function.	 They are extremely simple.  I suggest
	   you take a look at them to see how they work.  What follows here is
	   a description of how	these functions	will fill in your templates.

	   The &find_value function looks for an entry in a hash called
	   %main::TVars.  So put an entry in this hash if you want it to be
	   available to	templates:

	    my $template = new Text::FillIn( 'hey, [[$you]]!' );
	    $::TVars{'you'} = 'Sam';
	    $template->interpret_and_print();  # Prints	"hey, Sam!"

	   The &run_function function looks for	a function in the "TExport"
	   package and runs it.	 The reason it doesn't look in the main
	   package is that you probably	don't want to make all the functions
	   in your program available to	the templates (not that	putting	all
	   your	program's functions in the main	package	is always the greatest
	   programming style).	Here are a couple of ways to make functions

	    sub	TExport::add_numbers {
	       my $result;
	       foreach (@_) {
		  $result += $_;
	       return $result;

	    #  or, if you like:

	    package TExport;
	    sub	add_numbers {
	       my $result;
	       foreach (@_) {
		  $result += $_;
	       return $result;

	   The &run_function function will split the argument string at
	   commas, and pass the	resultant list to your function:

	    my $template = new Text::FillIn(
	       'Pi is about [[&add_numbers(3,.1,.04,.001,.0006)]]'

	   In the original version of "Text::FillIn", I	didn't provide any
	   hook	functions.  I expected people to write their own, partly
	   because I didn't want to stifle creativity or anything.  I now
	   include hook	functions because the ones I give will probably	work
	   okay	for most people, and providing them means it's easier to use
	   the module right out	of "the	box."  But I hope you won't be afraid
	   to write your own hooks - if	mine don't work	well for you, by all
	   means go ahead and replace them with	your own.  If you think	you've
	   written some	really killer hooks, let me know.  I may include cool
	   ones	with future distributions.

       o   template directories

	   You can tell	"Text::FillIn" where to	look for templates:

	    Text::FillIn->path('.', '/etc/template_dir');
	    $template->get_file('my_template');	# Gets ./my_template or	/etc/template_dir/my_template

       o   new Text::FillIn($text)

	   This	is the constructor, which means	it returns a new object	of
	   type	Text::FillIn.  If you feed it some text, it will set the
	   template's text to be what you give it:

	    $template =	new Text::FillIn("some [[$vars]] and some [[&funk]]");

       o   $template->get_file(	$filename );

	   This	will look for a	template called	$filename (in the directories
	   given in $template->path()) and slurp it in.	 If $filename starts
	   with	/ , then Text::FillIn will treat $filename as an absolute
	   path, and not search	through	the directories	for it:

	    $template->get_file( "my_template" );
	    $template->get_file( "/weird/place/with/template" );

	   The default path is ('.').

       o   $template->interpret()

	   Returns the interpreted contents of the template:

	    $interpreted_text =	$template->interpret();

	   This, along with interpret_and_print, are the main point of this
	   whole module.

       o   $template->interpret_and_print()

	   Interprets the [[ fill-in parts ]]  of a template and prints	the
	   template, streaming its output as much as possible.	This means
	   that	if it encounters an expression like "[[	stuff [[ more stuff]]
	   ]]",	it will	fill in	[[ more	stuff ]], then use the filled-in value
	   to resolve the value	of [[ stuff something ]], and then print it

	   If it encounters an expression like "stuff1 [[thing1]] stuff2
	   [[thing2]]",	it will	print stuff1, then the value of	[[thing1]],
	   then	stuff2,	then the value of [[thing2]].  This is as streamed as
	   possible if you want	nested brackets	to resolve correctly.

       The following methods all get and/or set	certain	attributes of the
       template.  They can all be called as instance methods, a	la
       "$template->Ldelim()", or as static methods, a la
       "Text::FillIn->Ldelim()".  Using	an instance method only	changes	the
       given template, it does not affect the properties of any	other
       template.  Using	a static method	will change the	default	behavior of
       all templates created in	the future.

       I think I need to reserve the right to change what happens when you
       create a	template $t, then change the default behavior of all
       templates, then call $t->interpret() -- should it use the new defaults
       or the old defaults?  Currently it uses the old defaults, but that
       might change.

       o   $template->Ldelim($new_delimiter)

       o   $template->Rdelim($new_delimiter)

	   Get or set the left or right	delimiter.  When called	with no
	   arguments, simply returns the delimiter.  When called with an
	   argument, sets the delimiter.

       o   $template->text($new_text)

	   Get or set the contents of the template.

       o   $template->path($dir1, $dir2, ...)

	   Get or set the list of directories to search	for templates in.  The
	   path	is used	in the get_file() method.

       o   $template->hook($character, $hook_function)

	   Get or set the functions for	filling	in the sections	of the
	   template between delimiters.	 The first argument is the non-word
	   character the hook is installed under.  The second argument,	if
	   present, is the function to install as a hook.  It may either be a
	   hard	reference to a function, a string containing the fully
	   package-qualified name of a function, or if you're using objects to
	   fill	in your	template, a method name.  See also the subsection on
	   interpretation hooks	in the DESCRIPTION section.

       o   $template->object($obj)

	   As of version 0.04, you may use method calls	on an arbitrary	object
	   as template hooks.  This can	be very	powerful.  Your	code might
	   look	like this:

	    $t	 = new Text::FillIn("some [[$animal]]s");
	    $obj = new MyClass(animal=>'chicken');  # Create some object
	    $t->object($obj);  # Tell $t to use	methods	of $obj	as hooks
	    $t->hook('$', 'lookup_var');  # Set	the method name	for '$'
	    $t->interpret_and_print();	# Calls	$obj->lookup_var()

	   The object methods will be passed the same arguments	as regular
	   (static) hook functions.

       o   $template->property(	$name, $value );

	   This	method lets you	get and	set arbitrary properties of the
	   template, like this:

	    $template->property('color', 'blue');  # Set the color
	    # ... some code...
	    $color = $template->property('color'); # Get the color

	   The Text::FillIn class doesn't actually pay any attention
	   whatsoever to the properties	- it's purely for your own
	   convenience,	so that	small changes in functionality can be achieved
	   without having to subclass Text::FillIn.

       If you want to use nested fill-ins on your template, make sure things
       get printed in the order	you think they'll be printed.  If you have
       something like this: "[[$var_number_[[&get_number]]]]", and your
       &get_number prints a number, you	won't get the results you probably
       want.  Text::FillIn will	print your number, then	try to interpret
       "[[$var_number_]]", which probably won't	work.

       The solution is to make &get_number return its number rather than print
       it.  Then Text::FillIn will turn	"[[$var_number_[[&get_number]]]]" into
       "[[$var_number_5]]", and	then print the value of	$var_number_5.	That's
       probably	what you wanted.

       The deprecated methods get_text(), set_text(), get_property(), and
       set_property() will be removed in version 0.06 and greater.  Use	text()
       and property() instead.

       By slick	use of local() variables, it would be possible to have
       Text::FillIn keep track of when it's doing nested tags and when it's
       not, allowing the user to nest tags using arbitrary depth and not have
       to worry	about the above	"common	mistake."  This	would let hook
       functions be oblivious to whether they're supposed to print their
       results or return them, since Text::FillIn would	keep track of it all.
       This will take some doing on my part, but it's not insurmountable.  It
       would probably involve evaluating the tags from the outside in, rather
       than the	inside out.

       The interpreting	engine can be fooled by	certain	backslashing sequences
       like "\\[[$var]]", which	looks to it like the "[[" is backslashed.  I
       think I know how	to fix this, but I need	to think about it a little.

       Ken Williams (

       Copyright (c) 1998 Swarthmore College. All rights reserved.  This
       program is free software; you can redistribute it and/or	modify it
       under the same terms as Perl itself.

perl v5.32.1			  1999-01-06			     FillIn(3)


Want to link to this manual page? Use this URL:

home | help