|
||||
|
||||
|
|
AbstractWigwam is a general-purpose Perl template parsing module designed with emphasis on ease of use, reusability, flexibility and extensibility. Its purpose is to provide the basic framework for building custom template scripting environments with varying degrees of functionality ranging from strict variable interpolation, to full blown turing-complete scripting languages.
IntroductionThere are several industrial strength Perl templating systems out there that have stood the test of time and intense scrutiny of widespread use. If this is what you're looking for, look no further than HTML::Template or Template Toolikit. For those looking for an alternative or just a fresh approach to templating, Wigwam awaits. Wigwam has remained more or less our pet project over the past few years, over which time we've tweaked and added features to it to meet our own modest demands. Our hope for Wigwam is that it may someday find a niche, or perhaps some of the ideas put to use in Wigwam will find their way into other applications, or inspire new ideas.
Synopsis
use strict;
use Text::Wigwam;
my $template = Text::Wigwam->new( text => join( '', <DATA> ) )
or die $Text::Wigwam::ERROR;
my ($err, $txt) = $template->execute(
{
greeting => 'Hello',
entity => 'World'
}
);
die $err if $err;
print $txt; # Hello, World.
# Now we re-use the same template with different parameters.
# This time we invoke the execute method using scalar context, which implies
# that we want Wigwam to die if an error is encountered.
$txt = $template->execute(
{
greeting => 'Welcome',
entity => 'Fred'
}
);
print $txt; # Welcome, Fred.
__DATA__
[!! #parameters < greeting entity > !!]
[!! greeting !!], [!! entity !!].
ExtensibilityWigwam's functionality can be extended in a number of ways, the most unique of which is the ease in which user-coded directives can be added without the need to write grammar rules or even understand the inner workings of Wigwam. [!! #join '; ' ( 1 2 3 4 5 ) !!] The supporting Perl code for the #join directive is listed below.
package Text::Wigwam::Directives; # Directive tree base
sub _proto_join { [ STRING, ARRAY ] } # Prototype
sub _join { # Handler
my ($Api) = @_;
join( $Api->get_arg, @{$Api->get_arg} )
}
Any directive or set of directives can be stored in a module and loaded on the fly to make them available in templates. Wigwam's dynamic data casting feature uses the information in the prototype to ensure that the handler receives the expected data type for each of its arguments, thereby minimizing the amount of code required in the handler, drastically reducing runtime errors, and lending to more forgiving and flexible template coding. Wigwam provides all the necessary facilities for writing custom iterators, conditionals, and even directives that affect the parsing process - all with the same ease, simplicity and terseness as demonstrated here.
ReusabilityDirectives are typically saved in Perl library files which exist under the guise of Wigwam plug-ins and modules. This allows them to be easily reused in other templates simply by specifying the required plug-in or module within the template's configuration tag. Wigwam templates are also reusable, as they can be called by other templates and simply executed, or stored in a variable where they can then be executed multiple times with varying parameters.
ConfigurabilityEach template may contain its own configuration tag which is processed prior to template execution. It can be used to specify parsing options, debugging features, template characteristics (such as redefining tag delimiters), or to load plug-ins & modules. It may also be used to define default settings for, or impose restrictions upon, subsequently invoked templates.
Directive treeThe directive tree is a name space hierarchy into which directives can be loaded, defined, or imported. Directives may be organized into various branches of the directive tree (nested name spaces) and accessed from within templates either explicitly, or indirectly by way of an ordered path mechanism. Templates can also be restricted to specific branches, thereby limiting the functions available to them. This allows Wigwam to simultaneously provide template environments with varying degrees of functionality ranging from strict variable interpolation, to turing-complete scripting languages.
Data handlingWigwam employs simple notational conventions which can be used in templates to either explicitly or indirectly reference data elements that are stored within arbitrary complex data structures made up of nested arrays and hashes.
DebuggerWigwam's debugger is an invaluable tool which drastically reduces development time. It displays runtime errors, debug information, and warnings in context within a beautified redraw of the relevant templates.
FlexibilityTemplates can be written freeform style, interchanging text blocks with code blocks, or omitting them altogether - whichever the user feels is more appropriate for the task at hand.
[!!
/* Iterate over a text block, denoted by !!> and <!! */
#foreach num ( 1 2 3 4 5 ) !!>
[!! num !!]
<!!
/* Iterate over a code block, denoted by the braces */
#foreach num ( 1 2 3 4 5 ) { num }
/* Iterate over a single token, the 'num' variable */
#foreach num ( 1 2 3 4 5 ) num
!!]
DirectiveSet plug-inThe DirectiveSet plug-in is loaded by default unless explicitly overridden. It loads the over one hundred directives available in the library, thereby adding their functionality to the template environment and providing the following features:
UsesWigwam can be used virtually anywhere you want to intermingle text with data. The Wigwam package includes the wigwam.launcher.pl script which can be used to parse individual templates from the command line, or as a cgi wrapper for use with the Apache web server to invoke Wigwam via SSI, mod_rewrite, or mod_perl via the Apache::Registry module.
DocumentationThe Wigwam package contains full documentation in Perl's POD format, and is constantly updated as Wigwam develops. We recommend that you start with the basics.
Try itYou can try out Wigwam on-line at http://www.wigwamhq.org/tryit/ (at least for a while). Paste in some examples and watch them execute, or try out some code of your own. It's also a good way to see the debugger in action.
DevelopmentWigwam is still under active development, though many aspects of it have been stable for some time. Most of the recent modifications pertain to its object-oriented front-end interface. Future revisions may not be fully backward compatible, although plug-ins, modules and templates will most likely remain backward compatible as those specifications have remained relatively unchanged for quite some time.
FeedbackWe can be reached at the following address: DJOHNSTON, <djohnston@cpan.org> |