Tmojo(tm) In A Nutshell
    by Will Conant

Abstract
    Tmojo is a powerful and flexible content generation engine developed at
    Lab-01. For more information, visit <http://lab-01.com/>.

Tmojo Template Basics
    Tmojo templates are used for generating dynamic text documents. While
    they are particularly suited to generating HTML and XML documents, they
    can be used effectively to produce any text output, including
    dynamically generated source code.

    Tmojo may be used to generate text documents that are stored on disk for
    later use, or it may be used to generate documents on the fly to be
    served through your web server.

    The simplest Tmojo template looks like this:

      Hello, world!

    When called, this template would simply return the string "Hello,
    world!". Obvious as this example may be, it illustrates an important
    fact about Tmojo templates: any plain text document can be a valid Tmojo
    template.

    A slightly more interesting template might look like this:

      Hello, <: $Args{name} :>!

    Here, we see our first Tmojo tag. In a Tmojo template, any valid Perl
    expression enclosed in "<:" and ":>" will be replaced by the result of
    evaluating that expression. Furthermore, Tmojo templates gain access to
    their arguments through the implicitly defined %Args hash.

    When generating text, it is useful to conditionally allow the inclusion
    of certain portions. Tmojo allows you to use any valid Perl structures
    for controlling the creation of the document:

      : if ($Args{show_cat} == 1) {
        <img src='cat.jpg'>
      : } else {
        <img src='dog.jpg'>
      : }
  
      <ol>
        : foreach my $item (@{$Args{list}}) {
          <li><: $item :></li>
        : }
      </ol>

    In Tmojo templates, any line that begins with a colon, optionally
    preceded by any amount of whitespace, will be treated as pure Perl. This
    is useful for conditional and looping logic, as in our example above, as
    well as simple variable assignment:

      : my @list = @{$Args{list}};

    Occasionally, it is useful to perform operations that take more than one
    line. In these cases, rather than preceding every line of the operation
    with a colon, you may use a "<:perl>" block, like this:

      <:perl>
        my $year = (localtime()[5]);
        $year += 1900;
      </:perl>
  
      The year is <: $year :>.

  Methods
    In more complex Tmojo templates, it is sometimes convenient to break the
    template up into multiple reusable sections. This is accomplished with
    methods:

      <:method title>
        Favorite Colors
      </:method>
  
      <html>
        <head><title><: $Self->title :></title></head>
  
        <body>
          <h1><: $Self->title :></h1>
  
          Red<br>
          Blue<br>
          Green<br>
        </body>
      </html>

    This example contains a method called 'title' which is referenced twice:
    once in the header of the HTML and once in the body. Notice that methods
    are accessed through the implicit $Self variable, which always contains
    a reference to the current template object.

    Methods may take arguments in the same way that Perl methods take
    arguments:

      <:method show_number>
        : my ($current_number) = @_;
        Current Number: <: $current_number :><br>
      </:method>
  
      : for (1..5) {
        <: $Self->show_number($_) :>
      : }

    Methods also have access to the implicit %Args hash and $Self variables
    as well as the implicit %Vars hash and $Tmojo variable that we'll be
    discussing later.

    When a Tmojo template is run, all of the content outside of any methods
    acts as the main part of the template. In fact, everything outside of
    the other sections is *implicitly* placed in a method called 'main'.
    Thus, when a template is run, it is initialized, and then its main
    method is executed. The inclusion of any other methods in the output is
    dictated by the main method.

  The Global Section
    It is often useful to include outside Perl modules for use in your Tmojo
    templates. This is best accomplished in the "<:global>" section, like
    this:

      <:global>
        use Time::Local;
      </:global>
  
      : my $time_stamp = timelocal(0, 0, 12, 24, 2, 104);
  
      Unix Time Stamp: <: $time_stamp :>

    Everything in the "<:global>" section is executed outside of any
    methods, *including* the main method. Here, for instance, you could
    declare a global variable that would be available to all of the methods
    in the template, like this:

      <:global>
        my @months = qw(Jan Feb Mar Apr ...);
      </:global>

    Because the "<:global>" section occurs outside of the templates methods,
    it will only be executed when the template is compiled, not every time
    it is run. Thus, code in the "<:global>" section *does not* have access
    to the %Args, %Vars or $Self variables.

  The Init Section and Vars Hash
    Often, every time your template is run, it is useful to prepare some
    data that will be available to all of the methods in the template. This
    can be accomplished with the "<:init>" section and the %Vars hash.

    Unlike the "<:global>" section, the "<:init>" section *is* run every
    time the template is called, and it *does* have access to the %Args,
    %Vars, and $Self variables. A typical "<:init>" section might look like
    this:

      <:init>
        $Vars{user} = sql_lookup_user($Args{user_id});
      </:init>

    This example calls the imaginary function "sql_lookup_user" (which would
    have been included from a library used in the "<:global>" section) and
    puts the results in the %Vars hash. In this way, the template can look
    up the user once, and have that data be available through the %Vars hash
    to all of the methods in the template.

    It is important to note that lexical variables declared in the "<:init>"
    section *are not* available to the rest of the template. Thus the
    nessicity of the %Vars hash.

Calling Tmojo Templates
    In order to call a Tmojo template from your Perl script or module, you
    must have a Tmojo object. You create a Tmojo object like this:

      my $Tmojo = HTML::Tmojo->new(
        template_dir => '/location/of/templates',
        cache_dir    => '/place/to/save/compiled/templates',
      );

    If you don't provide those arguments, Tmojo will look for their values
    in $ENV{TMOJO_TEMPLATE_DIR} and $ENV{TMOJO_CACHE_DIR} respectively.

    Once you have your $Tmojo object, you can call a template like this:

      my $result = $Tmojo->call('/group_1/my_template.tmojo');

    Assuming that we're using the Tmojo object from the previous example,
    this would compile and execute the Tmojo template located in the file
    /location/of/templates/group_1/my_template.tmojo.

  Arguments
    When you call a Tmojo template, you may need to pass arguments. Tmojo
    allows you to pass named arguments into the template like this:

      my $result = $Tmojo->call(
        '/group_1/my_template.tmojo',
  
        arg1 => 'value1',
        arg2 => 'value2',
      );

    In this case, the arguments 'arg1' and 'arg2' would be available to
    /group_1/my_template.tmojo in the %Args hash.

  Templates Calling Templates
    While you must create your own Tmojo object to use Tmojo from your own
    Perl scripts or modules, within Tmojo templates, there is always an
    implicit $Tmojo object that allows Tmojo templates to refer to other
    templates in the same template directory.

    Tmojo templates often refer to other Tmojo templates. For instance,
    /group_1/my_template.tmojo may refer to /group_1/another_template.tmojo.
    It may do so in two possible ways. First, it may use the absolute
    template id, like this:

      <: $Tmojo->call('/group_1/another_template.tmojo') :>

    Sometimes, however, it is more convenient when a template doesn't need
    to know exactly what directory it is in. In these cases,
    /group_1/my_template.tmojo could refer to
    /group_1/another_template.tmojo using a relative template id, like this:

      <: $Tmojo->call('another_template.tmojo') :>

    Or, a template may refer to another template in the directory above it
    like this:

      <: $Tmojo->call('../another_template.tmojo') :>

    This works not only for Tmojo calls inside if templates, but also for
    template ids put in $TMOJO_CONTAINER and @TMOJO_ISA.

    Another important feature of template ids is Upward Traversal. Take a
    look at this example:

      my $result = $Tmojo->call(
            '/some/deep/directory/template.tmojo^'
      );

    Notice the up-carrot ("^") at the end of this template id. When you
    provide an up-carrot, Tmojo will traverse all of the specified
    directories innermost to outermost in search of the template specified.
    So, in this case, Tmojo would search for the template in this fashion:

      /some/deep/directory/template.tmojo
      /some/deep/template.tmojo
      /some/template.tmojo
      /template.tmojo

    This trick also works for relative template ids, so, if a template in
    /some/directory refers to a template simply as 'other_template.tmojo^',
    then Tmojo will search for that template like this:

      /some/directory/other_template.tmojo
      /some/other_template.tmojo
      /other_template.tmojo

Escaping Tmojo Code
    If you ever need to output text that looks like Tmojo (like I did as I
    was writing this documentation), you'll need to use an "<:escape>"
    block, like this:

      <:escape>
        <:method sample_method>
          This is a sample Tmojo method.
      
          : for (1..4) {
            <: $_ :>
          : }
        </:method
      </:escape>

    In this example, the Tmojo code within the "<:escape>" block will be
    totally ignored and simply including in the result.

    In those bizarre, rare cases where you need to output the text
    "</:escape>" from Tmojo, you can use a terminator in your escape block,
    like this:

      <:escape-sample>
        Sample Escape Block:
    
        <:escape>
          This is a sample escape block
        </:escape>
      </:escape-sample>

    By providing your own terminator on the outer escape block, you can tell
    Tmojo not to end until it sees a matching close block (with the same
    terminator).

    This same trick can be applied to "<:perl>" blocks in those cases where
    you might end up with the text "</:perl>" in your "<:perl>" block, like
    this:

      <:perl-output>
        $Result .= qq{
          I'm creating this with a perl block:
      
          <:perl>
            # SAMPLE PERL CODE
            my $x = 15;
          </:perl>
        };
      </:perl-output>

    If we didn't add '-output' to the outside "<:perl>" block, Tmojo would
    exit the "<:perl>" block after the first close perl tag, not the second.

Filtering
    It can sometimes be useful to filter a portion of Tmojo output before it
    is included in the result. This can be accomplished with a "<:filter>"
    section, like this:

      <:filter uc($Result)>
        All of the text created in this section
        will be made uppercase by the filter.
    
        Filter sections can include any other valid
        Tmojo constructs, like this:
    
        : for ('a'..'z') {
          this will be uppercase too: <: $_ :>
        : }
      </:filter>

    "<:filter>" sections work by temporarily masking the $Result variable
    for the duration of the section. At the end of the section, the Perl
    code provided in the open tag is executed, and the results are added to
    the 'real' $Result. Because the $Result variables are placed on a stack,
    it is possible to have nested "<:filter>" sections.

Capturing
    If you require more thorough filtering of portions of your Tmojo output,
    you may use a "<:capture>" block to capture a portion of Tmojo output
    into a variable of your choosing. For instance:

      <:capture my $stuff>
        The contents of this block will be put into the
        variable $stuff and not included in the $Result.
      </:capture>
  
      <:perl>
        for ($stuff) {
          tr/a-f/A-F/;
          s/\n/ keep going /g;
        }
      </:perl>
  
      <: $stuff :>

    You may use any valid lvalue in the open tag of your "<:capture>" block.

Containers
    When designing web sites, it is common to have a complicated bunch of
    HTML that defines the overall look and feel for your web application.
    Generally, this HTML is the same for every single page. Back when I was
    using JSP, I would accomplish this by having a JSP template called
    'header.jsp' and one called 'footer.jsp'. Then, each of my application
    pages would include these at the top and at the bottom of the page.

    While this approach worked OK, it had a few drawbacks. First, because my
    header and footer were stretched across two files, it was easy to have
    mismatched HTML tags and otherwise broken stuff in the header and footer
    files. Second, it forced the header and the footer to rely on the
    application page for all of their information. Thus, it was possible for
    my controller to pass data intended for the header into my application
    page, only to have the application page forget to forward the data to
    the header. Of course, even if you remembered to pass that data on every
    time, that still meant a potentially large chunk of parameter passing
    code repeated on every application page.

    Tmojo resolves the problem with a much more elegant system. Each Tmojo
    template may declare a container. You do this at the top of your
    template in the "<:global>" section, like this:

      <:global>
        our $TMOJO_CONTAINER = '/my/container.tmojo';
      </:global>

    When a template declares a container in this way, it changes the way
    that it is handled. Now, all calls to this template are first handled by
    its container. This process is best illustrated by an example:

    TEMPLATE: /example.tmojo

      <:global>
        our $TMOJO_CONTAINER = '/container.tmojo';
      </:global>
  
      this is the body of my html page

    TEMPLATE: /container.tmojo

      <html>
        <head><title>Lab-01 Example Page</title></head>
    
        <body>
          <: $Next->main :>
        </body>
      </html>

    CONTROLLER

      print $Tmojo->call('/example.tmojo');

    OUTPUT

      <html>
        <head><title>Lab-01 Example Page</title></head>
    
        <body>
          this is the body of my html page
        </body>
      </html>

    In this example, the call to /example.tmojo is interrupted by
    /container.tmojo which provides the outside structure of the page, and
    then includes the originally called page with "<: $Next->main :>".

    Inside container templates, the contained template object is accessible
    through the implicitly defined $Next variable.

    It is possible for a container to communicate with its contained
    template in some very useful ways. Look at this example:

    TEMPLATE: /example.tmojo

      <:global>
        our $TMOJO_CONTAINER = '/container.tmojo';
      </:global>
  
      <:method title>
        Example Page
      </:method>
  
      <:method css>
        p.foo {
          font-size: 16px;
          color: red;
        }
      </:method>
  
      <p class='foo'>
        this is the body of my html page
      </p>

    TEMPLATE: /container.tmojo

      <html>
        <head>
          <title><: $Next->title :></title>
      
          <style type='text/css'>
            h1 {
              font-family: arial;
            }
        
            <: $Next->css :>
          </style>
        </head>
    
        <body>
          <h1><: $Next->title :></h1>
      
          <: $Next->main :>
        </body>
      </html>

    CONTROLLER

      print $Tmojo->call('/example.tmojo');

    OUTPUT

      <html>
        <head>
          <title>Example Page</title>
      
          <style type='text/css'>
            h1 {
              font-family: arial;
            }
        
            p.foo {
              font-size: 16px;
              color: red;
            }
          </style>
        </head>
    
        <body>
          <h1>Example Page</h1>
      
          <p class='foo'>
            this is the body of my html page
          </p>
        </body>
      </html>

    In this example, the container gives the contained template several
    opportunities to effect the final page. First, it allows the contained
    template to choose a title for the page. Second, it allows the contained
    template to add some CSS to the page, and, third, it allows the
    contained template to provide the body of the page. This mechanism
    allows for clear and elegant application design.

    One thing to note in our example, however, is that if '/example.tmojo'
    failed to define a function called 'css', there would be a runtime
    error. This issue is easily resolved by using parent templates, which
    will be described in upcoming sections.

  Containers and Init Sections
    Tmojo templates often contain "<:init>" sections. When a template that
    doesn't declare a container is called, it is processed in the following
    order:

    1   If the template is not yet compiled, do so and run the "<:global>"
        section.

    2   Call the "<:init>" section of the template.

    3   Call the main method of the template.

    When a template declares a container, the process looks like this:

    1   If the contained template is not yet compiled, do so and run its
        "<:global>" section.

    2   Call the "<:init>" section of the contained template.

    3   If the container is not yet compiled, do so and run its "<:global>"
        section.

    4   Provide the container with a reference to the contained template in
        the $Next variable.

    5   Call the "<:init>" section of the container.

    6   Call the main method of the container.

    There are three important things to note about this process:

    First, the contained template always gets to run its "<:init>" section
    first, which gives it an opportunity to perform calculations on the
    %Args and place results in %Vars *before* the container ever calls one
    if its methods.

    Second, while the main() method of the container is guaranteed to run,
    the container itself chooses how to interact with the contained
    template. It may call "$Next->main", but it may choose to call a
    different method entirely, or even several methods as in our last
    example. It may even choose not to call the contained template at all.

    Third, the %Args passed to the contained template when it is called are
    also passed to the container. In fact, the same %Args hash is passed to
    both templates, so it is possible for the contained template to alter
    the %Args in its "<:init>" section before the container ever has a
    chance to see them. This is different from the %Vars hash, which is not
    shared between the container and the contained template.

  Specifying the Container From Your Perl Script
    Generally, if a template whishes to have a container, it must explicitly
    reference that container from its "<:global>" section. However,
    sometimes it makes more sense to choose the container from your Perl
    script and not from within each Tmojo template.

    It is possible to do this by using the call_with_container() method on
    the Tmojo object, like this:

      my $result = $Tmojo->call_with_container(
        '/some/template.tmojo',
        '/some/container.tmojo',
    
        arg1 => 1,
        arg2 => 'foo',
      );

    When called this way, the second argument provided will override
    whatever container was specified by the called template (even if there
    was no container specified).

    One important feature is that the container template id specified in
    this way is relative to the called template. This allows you to specify
    a generic container rule in all of your Tmojo calls, like this:

      my $result = $Tmojo->call_with_container(
        '/some/template.tmojo',
        'container.tmojo^',
    
        arg1 => 'foo',
      );

    In this case, no matter what template you call, it will always be
    contained by the closest template named 'container.tmojo'. This
    technique is especially useful for content oriented web sites where most
    of your Tmojo templates will contain nothing but HTML that should be
    built with containers located in the same directory. By using
    call_with_container(), your content providers can write HTML and never
    have to be bothered with providing a "<:global>" section in their Tmojo
    templates.

Under the Hood
    Before we discuss the mechanism of parent templates, it is useful to
    understand the inner workings of Tmojo templates.

    In actuality, every Tmojo template, when it is first run, is compiled
    into a Perl object class (which is simply a Perl package). Every Tmojo
    method in the template is simply converted into a Perl method of the
    same name. This is also true for the implicit main method. The
    "<:global>" section of the template is placed near the top of the Perl
    package (exactly where you'd expect to see Perl "use" statements and
    constant definitions). The "<:init>" section is placed inside of the
    object constructor, which is a method called 'new'.

    Take a look at this example template:

      <:global>
        use POSIX qw(strftime);
      </:global>
  
      <:init>
        my $year  = $Args{year};
        my $month = $Args{month};
        my $day   = $Args{day};
    
        $Vars{readable_time} = strftime(
          '%b %d, %Y', 0, 0, 12, $day, $month - 1, $year - 1900
        );
      </:init>
  
      <:method title>
        Report For <: $Vars{readable_time} :>
      </:method>
  
      <html>
        <head>
          <title><: $Self->title :></title>
        </head>
    
        <body>
          <h1><: $Self->title :></h1>
      
          <p>
            Well, there is nothing to report!
          </p>
        </body>
      </html>

    This is the resulting Perl package:

      package HTML::Tmojo::Templates::...;
  
      use strict;
  
      our $Tmojo;
  
      use POSIX qw(strftime);
  
      sub new {
        my $Self = {
          args    => $_[1],
          next    => $_[2],
          vars    => {},
        };

        bless $Self, $_[0];

        # DEFINE THE IMPLICIT VARIABLES
        my $Next  = $Self->{next};
        our %Args; local *Args = $Self->{args};
        our %Vars; local *Vars = $Self->{vars};

        # --- BEGIN USER CODE ---
        my $year  = $Args{year};
        my $month = $Args{month};
        my $day   = $Args{day};

        $Vars{readable_time} = strftime(
          '%b %d, %Y', 0, 0, 12, $day, $month - 1, $year - 1900
        );

        # --- END USER CODE ---

        # RETURN THE VALUE
        return $Self;
      }
  
      sub main {
        my $Self = shift @_;

        # DEFINE THE IMPLICIT VARIABLES
        my $Next  = $Self->{next};
        our %Args; local *Args = $Self->{args};
        our %Vars; local *Vars = $Self->{vars};

        my $Result = '';

        # --- BEGIN USER CODE ---
        $Result .= "<html>\n";
        $Result .= "\t<head>\n";
        $Result .= "\t\t<title>";
        $Result .= ( $Self->title );
        $Result .= "</title>\n";
        $Result .= "\t</head>\n";
        $Result .= "\t\n";
        $Result .= "\t<body>\n";
        $Result .= "\t\t<h1>";
        $Result .= ( $Self->title );
        $Result .= "</h1>\n";
        $Result .= "\t\t\n";
        $Result .= "\t\t<p>\n";
        $Result .= "\t\t\tWell, there is nothing to report!\n";
        $Result .= "\t\t</p>\n";
        $Result .= "\t</body>\n";
        $Result .= "</html>";

        # --- END USER CODE ---

        return $Result;
      }
  
      sub title {
        my $Self = shift @_;

        # DEFINE THE IMPLICIT VARIABLES
        my $Next  = $Self->{next};
        our %Args; local *Args = $Self->{args};
        our %Vars; local *Vars = $Self->{vars};

        my $Result = '';

        # --- BEGIN USER CODE ---
        $Result .= "Report For ";
        $Result .= ( $Vars{readable_time} );

        # --- END USER CODE ---

        return $Result;
      }
  
      1;

    When you call a Tmojo template like this one from your Perl script, the
    Tmojo object calls the new method to construct an object based on your
    Tmojo template. It then calls the main method of the new object and
    returns the results. In order to understand Tmojo parent templates, it
    is important to see the distinct similarities between Tmojo templates
    and a pure Perl classes.

Parent Templates
    Because Tmojo templates are simply Perl object classes, it is possible
    for them to take advantage of class inheritance and polymorphism. If
    those two terms make you wince, you should probably take a look at the
    O'Reilly Programming Perl book before reading this section. In fact, it
    is possible to use Tmojo to solve most web application design problems
    *without* ever using parent templates.

    If, however, you're itching to use Object-Oriented Tmojo, read on!

    In a typical Perl class, you set the super-class by putting the
    super-class package name in the package variable, @ISA. Tmojo has an
    almost identical mechanism for specifying the parent template of a
    template. In the global section of your templates, you may set the
    package variable @TMOJO_ISA, like this:

      <:global>
        our @TMOJO_ISA = ('/some/parent/template.tmojo');
      </:global>

    As with Perl, you can actually set multiple parent templates by putting
    multiple template ids in the @TMOJO_ISA variable. (But I wouldn't
    recommend using multiple inheritance unless you're *really* experienced
    with object oriented programming.)

    Templates referred to in this way are, as with all other things,
    relative to the child template. So, if you say:

      <:global>
        our @TMOJO_ISA = ('parent.tmojo');
      </:global>

    Tmojo will look in the same directory as the child template for the
    parent template. Also, if you say:

      <:global>
        our @TMOJO_ISA = ('parent.tmojo^');
      </:global>

    Tmojo will use Upward Traversal to look up the directory paths in search
    of the nearest 'parent.tmojo'.

    Using parent templates in this way solves the problem discussed earlier,
    in which a container may expect contained templates to provide a certain
    set of functions, even if the content of those functions is optional.
    Take a look at this example:

    TEMPLATE: /example.tmojo

      <:global>
        our $TMOJO_CONTAINER = '/container.tmojo';
        our @TMOJO_ISA       = '/parent.tmojo';
      </:global>
  
      <:method css>
        p.foo {
          font-size: 16px;
          color: red;
        }
      </:method>
  
      <p class='foo'>
        this is the body of my html page
      </p>

    TEMPLATE: /container.tmojo

      <html>
        <head>
          <title><: $Next->title :></title>
      
          <style type='text/css'>
            h1 {
              font-family: arial;
            }
        
            <: $Next->css :>
          </style>
        </head>
    
        <body>
          <h1><: $Next->title :></h1>
      
          <: $Next->main :>
        </body>
      </html>

    TEMPLATE: /parent.tmojo

      <:method title>
        Generic Title
      </:method>
  
      <:method css>
        // no template css
      </:method>

    CONTROLLER

      print $Tmojo->call('/example.tmojo');

    OUTPUT

      <html>
        <head>
          <title>Generic Title</title>
      
          <style type='text/css'>
            h1 {
              font-family: arial;
            }
        
            p.foo {
              font-size: 16px;
              color: red;
            }
          </style>
        </head>
    
        <body>
          <h1>Generic Title</h1>
      
          <p class='foo'>
            this is the body of my html page
          </p>
        </body>
      </html>

    In this example, the container calls the method title() on the contained
    template, example.tmojo. example.tmojo, however, *does not* define the
    method called title(), it does, however, inherit a method called title()
    from parent.tmojo. In this way, you can establish an interface between a
    container and its contained templates in which some or all of the
    methods called are optional.

    With Tmojo, it is possible to solve problems with containers or with
    parent templates or both. Obviously there is some overlap in what
    solutions these two mechanisms provide. Tmojo supports both so that it
    can grow to accomodate very complex applications. In my experience, it
    is better to use containers in your solution first, and then use parent
    templates if they become nessisary.

Prepare
    Normally, when you call a Tmojo template, you expect it to be
    initialized, and then you expect the result of it's main() method to be
    returned. When Templates have containers, you expect the output of their
    container's main() method to be returned.

    Sometimes, however, it would be convenient to have a Tmojo template
    initialized, and then be given access to it's functions individually
    (much as a container has access to a contained template through the
    $Next variable).

    This can be accomplished with the prepare() function. prepare() takes
    the same arguments as call(). However, rather than calling the main()
    method of the specified template and returning the output, it simply
    initializes the Tmojo template object and returns a reference to that.

    One caveat of prepare() is that it completely ignores containers. You
    receive a reference to an object based on the specified template, not an
    object based on the container.

    Prepare is a critical feature for creating multi-lingual web-sites. This
    is discussed further in... some other document I haven't written yet ;)

But I Don't Want To Write a mod_perl Handler!
    In my experience, most web applications quickly reach the level of
    complexity that justifies the use of a model-view-controller solution,
    with Tmojo stepping in nicely to handle the view side of things.
    However, in some simple projects, especially those that are simply
    content oriented, it's preferable to simply have a directory of Tmojo
    templates served up by Apache for you. If this is all you need, you may
    want to use the "SimpleHandler" as your mod_perl handler.

    In your Apache config (after you've suffered the horror of installing
    mod_perl), you'll do something like this:

      <Location /my_tmojo_site>
        SetHandler perl-script
        PerlHandler HTML::Tmojo::SimpleHandler
        PerlSetEnv TMOJO_TEMPLATE_DIR /location/of/templates
        PerlSetEnv TMOJO_CACHE_DIR /place/to/compile/templates
      </Location>

    This will cause Apache to directly serve any tmojo templates located in
    the "TMOJO_TEMPLATE_DIR" specified. Remember that your "TMOJO_CACHE_DIR"
    *must* be writable by apache processes.

    If you would like to establish a default container for your templates,
    you may optionally set the "TMOJO_DEFAULT_CONTAINER" environment
    variable, like this:

      PerlSetEnv TMOJO_DEFAULT_CONTAINER /container.tmojo

    Remember that you may want to use Upward Traversal for a more flexible
    container hierarchy, like this:

      PerlSetEnv TMOJO_DEFAULT_CONTAINER container.tmojo^

    Tmojo templates served in this way will have access to all POST and GET
    variables through the %Args hash.

Copyright
    Copyright 2004 Lab-01 LLC <http://lab-01.com/>

    Licensed under the Apache License, Version 2.0 (the "License"); you may
    not use this file except in compliance with the License. You may obtain
    a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Tmojo(tm) is a trademark of Lab-01 LLC.

