WigwamHQ


Wigwam Community Libraries Modules Plugins Download Development
Wigwam: Introduction | Basics | Details

Abstract

Wigwam 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.


Introduction

There 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 !!].


Extensibility

Wigwam'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.


Reusability

Directives 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.


Configurability

Each 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 tree

The 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 handling

Wigwam 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.


Debugger

Wigwam'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.


Flexibility

Templates 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-in

The 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:

  • external templates w/parameter passing
  • macros/subroutines w/parameter passing
  • local variables
  • if/elsif/else conditionals w/unlimited nesting
  • switch/case/default tree directives w/unlimited nesting
  • given/when/default tree directives w/unlimited nesting
  • iterator directives w/unlimited nesting (while, repeat, foreach, for, ...)
  • process interrupt directives (break, continue, exit, ...)
  • error handling directives (try, throw, catch, ...)


Uses

Wigwam 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.


Documentation

The 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 it

You 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.


Development

Wigwam 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.


Feedback

We can be reached at the following address:

DJOHNSTON, <djohnston@cpan.org>

Validate: CSS, HTML, Spelling