Text-FillIn
view release on metacpan or search on metacpan
sub find_value { $main::TVars{ $_[0] } }
sub run_function {
# Usage: $result = &run_function("some_function(param1,param2,param3)");
my $text = shift;
my ($function_name, $args) = $text =~ /(\w+)\((.*)\)/
or die ("Can't understand function call '$text'");
no strict('refs'); # Allow symbolic name substitution for a little while
return &{"TExport::$function_name"}( split(/,/, $args) );
}
1;
__END__
=head1 NAME
Text::FillIn.pm - a class implementing a fill-in template
=head1 SYNOPSIS
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
=head1 DESCRIPTION
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. B<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".
=head2 Defining the structure of templates
=over 4
=item * delimiters
B<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 B<[[> and B<]]>, but they don't have to be, you can set
them to whatever you want. So you could do this:
Text::FillIn->Ldelim('{');
Text::FillIn->Rdelim('}');
$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 literals:
$template->set_text('some [[$[[$var2]][[$var]]]] and \[[ text \]]');
$template->interpret_and_print();
# Prints "some stuff and [[ text ]]"
You cannot currently have several different kinds of delimiters in a single template.
=item * interpretation hooks
In order to interpret templates, C<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 C<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 B<Text::FillIn> sees
some text like "some [[$vars]] and some [[&funk]]", it will run
C<&Text::FillIn::find_value> to find the value of [[$vars]], and it will
run C<&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 {
'Pi is about [[&add_numbers(3,.1,.04,.001,.0006)]]'
);
$template->interpret_and_print;
In the original version of C<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.
=item * template directories
You can tell C<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
=back
=head1 METHODS
=over 4
=item * new Text::FillIn($text)
This is the constructor, which means it returns a new object of type B<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]]");
=item * $template->get_file( $filename );
This will look for a template called $filename (in the directories given in
B<$template-E<gt>path()>) and slurp it in. If $filename starts with / ,
then B<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 ('.').
=item * $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.
=item * $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 out.
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.
=back
The following methods all get and/or set certain attributes of the template. They can
all be called as instance methods, a la C<$template-E<gt>Ldelim()>, or as static methods,
a la C<Text::FillIn-E<gt>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.
=over 4
=item * $template->Ldelim($new_delimiter)
=item * $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.
=item * $template->text($new_text)
Get or set the contents of the template.
=item * $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.
=item * $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.
=item * $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()
( run in 0.432 second using v1.01-cache-2.11-cpan-e1769b4cff6 )