package Maypole::View::TT;
use base 'Maypole::View::Base';
use Maypole::Constants;
use Template;
use File::Spec::Functions qw(catdir tmpdir);

use strict;
our $VERSION = 2.11;

sub template {
    my ( $self, $r ) = @_;

    unless ($self->{tt}) {
        my $view_options = $r->config->view_options || {};
        $self->{provider} = Template::Provider->new($view_options);
        $self->{tt}       = Template->new({
            %$view_options,
            LOAD_TEMPLATES => [ $self->{provider} ],
        });
    }

    $self->{provider}->include_path([ $self->paths($r) ]);

    my $template_file = $r->template;
    my $ext = $r->config->template_extension;
    $template_file .= $ext if defined $ext;

    my $output;
    if ($self->{tt}->process($template_file, { $self->vars($r) }, \$output )) {
        $r->{output} = $output;
        return OK;
    }
    else {
	$r->{error} = "TT error for template '$template_file'\n" . $self->{tt}->error;
        return ERROR;
    }
}

1;

=head1 NAME

Maypole::View::TT - A Template Toolkit view class for Maypole

=head1 SYNOPSIS

    BeerDB->config->view("Maypole::View::TT"); # The default anyway

    # Set some Template Toolkit options
    BeerDB->config->view_options( {
        TRIM        => 1,
        COMPILE_DIR => '/var/tmp/mysite/templates',
    } );

    .....

    [%# Template Toolkit directives and maypole macros go here %]

=head1 DESCRIPTION

This is the default view class for Maypole; it uses the Template Toolkit to
fill in templates with the objects produced by Maypole's model classes.  Please
see the L<Maypole manual|Maypole::Manual>, and in particular, the
L<view|Maypole::Manual::View> chapter for the template variables available and
for a refresher on how template components are resolved.

The underlying Template toolkit object is configured through
C<$r-E<gt>config-E<gt>view_options>. See L<Template|Template> for available
options.

=over 4

=item template

Processes the template and sets the output. See L<Maypole::View::Base>

=back

=head1 TEMPLATE TOOLKIT INTRODUCTION

The Template Toolkit uses it's own mini language described in L<Template::Manual::Directives>.

A simple example would be :

=over 4

re:[% subject %]

Dear [% title %] [% surname %],
Thank you for your letter dated [% your.date %]. This is to
confirm that we have received it and will respond with a more
detailed response as soon as possible. In the mean time, we
enclose more details of ...

=back

TT uses '[%' and '%]' (by default) to delimit directives within a template, and the simple directives
above just display the value of variable named within those delimiters -- [% title %] will be replaced
inline with the value of the 'title' variable passed in the 'stash' to the template when it is processed.

You can access nested data through the dot ('.') operator, which will dereference array or hash elements,
but can also be used to call methods on objects, i.e. '[% name.salutation("Dear %s,") %]'. The other main
operator is underscore ('_'), which will concatonate strings or variables.

The value returned by a directive replaces the directive inline when the template is processes, you can also
SET a value which will not return anything, or CALL a method or operation which will also not return anything.

You can specify expressions using the logical (and, or, not, ?:) and mathematic operators (+ - * / % mod div).

=over 4

[% template.title or default.title %]

[% score * 100 %]

[% order.nitems ? checkout(order.total) : 'no items' %]

=back

TT allows you to include or re-use templates through it's INCLUDE, PROCESS and INSERT directives, which
are fairly self explainatory. You can also re-use parts of template with the BLOCK or MACRO directives.

Conditional and Looping constructs are simple and powerful, and TT provides an inbuilt iterator and helper
functions and classes that make life sweet.

Conditional directives are IF, UNLESS, ELSIF, ELSE and behave as they would in perl :

=over 4

[% IF age < 10 %]
  Hello [% name %], does your mother know you're  using her AOL account?
[% ELSIF age < 18 %]
  Sorry, you're not old enough to enter (and too dumb to lie about your age)
[% ELSE %]
  Welcome [% name %].
[% END %]

[% UNLESS text_mode %] [% INCLUDE biglogo %] [% END %]

=back

Looping directives are FOREACH, LAST and BREAK.

FOREACH loops through a HASH or ARRAY processing the enclosed block for each element.

Looping through an array

 [% FOREACH i = items %]
 [% i %]
 [% END %]

Looping through a hash

 [% FOREACH u IN users %]
 * [% u.key %] : [% u.value %]
 [% END %]

Looping through an array of hashes

 [% FOREACH user IN userlist %]
 * [% user.id %] [% user.name %]
 [% END %]

The LAST and BREAK directive can be used to exit the loop.

The FOREACH directive is implemented using the Template::Iterator module.  A reference
to the iterator object for a FOREACH directive is implicitly available in the 'loop' variable.
The loop iterator object provides a selection of methods including size(), max(), first(), last(),
count(), etc

=over 4

  [% FOREACH item IN [ 'foo', 'bar', 'baz' ] -%]
    [%- "<ul>\n" IF loop.first %]
      <li>[% loop.count %]/[% loop.size %]: [% item %]
    [%- "</ul>\n" IF loop.last %]
  [% END %]

=back

See Template::Iterator for further details on looping and the Iterator.

You might notice the minus ('-') operator in the example above, it is used to remove a newline
before or after a directive so that you can layout the Template logic as above but the resulting
output will look exactly how you require it.

You will also frequently see comments and multi-line directives, # at the start of a directive
marks it as a comment, i.e. '[%# this is a comment %]'. A multiline directive looks like :

 [% do.this;
    do.that;
    do.the_other %]

You can see that lines are terminated with a semi-colon (';') unless the delimter ('%]') closes the directive.

For full details of the Template Toolkit see Template::Manual and Template::Manual::Directives, you can
also check the website, mailing list or the Template Toolkit book published by O Reilly.

=head1 TEMPLATE PLUGINS, FILTERS AND MACROS

The Template Toolkit has a popular and powerful selection of Plugins and Filters.

TT Plugins provide additional functionality within Templates, from accessing CGI and
databases directly, handling paging or simple integration with Class::DBI (for those
rare occasions where you don't actually need Maypole). See L<Template::Manual::Plugins>.

One plugin that is indispensible when using Maypole and the Template View is
C<Template::Plugin::Class> -- This allows you to import and use any class installed
within a template. For example :

=over 4

[% USE foo = Class('Foo') %]
[% foo.bar %]

=back

Would do the equivilent of 'use Foo; Foo->bar;' in perl. See L<Template::Plugin::Class>
for details.

TT Filters process strings or blocks within a template, allowing you to truncate,
format, escape or encode trivially. A useful selection is included with Template Toolkit
and they can also be found on CPAN or can be written easily.
See L<Template::Manual::Filters>.

TT Macros allow you to reuse small blocks of content, directives, etc. The MACRO directive
allows you to define a directive or directive block which is then evaluated each time the
macro is called. Macros can be passed named parameters when called.

Once a MACRO is defined within a template or 'include'd template it can be used as if it
were a native TT directive. Maypole provides a selection of powerful and useful macros
in the templates/ directory of the package and these are used in the beerdb and default
templates. See the MACRO section of the L<Template::Manual::Directives> documentation.

=head1 MAYPOLE MACROS AND FILTERS

Maypole provides a collection of useful and powerful macros...TO DO

=head2 link

=head2 other macros

=head2 finish this documentation

=head1 AUTHOR

Simon Cozens

=cut

