
=head1 NAME

Text::Xslate::Manual::Cookbook - How to cook Xslate templates

=head1 DESCRIPTION

The Xslate cookbook is a set of recipes showing Xslate features.

=head1 RECIPES

=head2 How to manage HTML forms

Managing HTML forms is an important issue on web applications.
You'd better to use modules that manage HTML forms, rather than do something
with templates by yourself. This section proposes two basic solutions:
using FillInForm and HTML form builders.

In both solutions, one should not use the C<mark_raw filter> in templates,
which easily makes B<security holes>. Instead, application code should be
responsible to call the C<mark_raw function> that C<Text::Xslate> can export.

=head3 Using FillInForm

One solution to manage HTML forms is to use FillInForm modules with
the block filter syntax.

Example code using C<HTML::FillInForm>:

    #!perl -w
    use strict;
    use Text::Xslate qw(mark_raw);
    use HTML::FillInForm;

    sub fillinform {
        my($q) = @_;

        return sub {
            my($html) = @_;
            $html = unmark_raw($html); # NOTE: Not required by H::FIF::Lite
            # do mark_raw() here, not in templates
            return mark_raw(HTML::FillInForm->fill(\$html, $q));
        };
    }

    my $tx = Text::Xslate->new(
        function => {
            fillinform => \&fillinform,
        },
    );

    my %vars = (
        q => { foo => "<filled value>" },
    );
    print $tx->render_string(<<'T', \%vars);
    FillInForm:
    : block form | fillinform($q) -> {
    <form>
    <input type="text" name="foo" />
    </form>
    : }
    T

Output:

    FillInForm:
    <form>
    <input type="text" name="foo" value="&lt;filled value&gt;" />
    </form>

See also L<HTML::FillInForm> or L<HTML::FillInForm::Lite> for details.

=head3 Using HTML form builders

Another solution to manage HTML forms is to use form builders.

Here is a PSGI application that uses C<HTML::Shakan>:

    #!psgi
    use strict;
    use warnings;
    use Text::Xslate qw(mark_raw);
    use HTML::Shakan;
    use Plack::Request;

    my $tx = Text::Xslate->new();

    sub app {
        my($env) = @_;
        my $req  = Plack::Request->new($env);

        my $shakan = HTML::Shakan->new(
            request => $req,
            fields  => [ TextField(name => 'name', label => 'Your name: ') ],
        );

        my $res = $req->new_response(200);

        # do mark_raw here, not in templates
        my $form = mark_raw($shakan->render());
        $res->body( $tx->render_string(<<'T', { form => $form }) );
    <!doctype html>
    <html>
    <head><title>Building form</title></head>
    <body>
    <form>
    <p>
    Form:<br />
    <: $form :>
    </p>
    </body>
    </html>
    T
        return $res->finalize();

    }

    return \&app;

Output:

    <!doctype html>
    <html>
    <head><title>Building form</title></head>
    <body>
    <form>
    <p>
    Form:<br />
    <label for="id_name">Your name</label>
    <input id="id_name" name="name" type="text" value="&lt;Xslate&gt;" />
    </p>
    </body>
    </html>

See also L<HTML::Shakan> for details.

=head2 How to use Template Toolkit's WRAPPER feature in Kolon

Use template cascading, which is a super-set of the C<WRAPPER> directive.

F<wrapper.tx>:

    <div class="wrapper">
    block content -> { }
    </div>

F<content.tx>

    : cascade wrapper

    : override content -> {
        Hello, world!
    : }

Output:

    <div class="wrapper">
        Hello, world!
    </div>

See L<Text::Xslate/"Template cascading"> for details.

=head2 How to map __DATA__ sections to the include path

Use Data::Section::Simple, and the C<path> option of C<new()>, which accepts
HASH references which contain C<< $file_name => $content >> mapping.

    use Text::Xslate;
    use Data::Section::Simple;

    my $vpath = Data::Section::Simple->new()->get_data_section();
    my $tx = Text::Xslate->new(
        path => [$vpath],
    );

    print $tx->render('child.tx');

    __DATA__
    @@ base.tx
    <html>
    <body><: block body -> { :>default body<: } :></body>
    </html>
    @@ child.tx
    : cascade base;
    : override body -> {
    child body
    : } # endblock body

This feature is directly inspired by Text::MicroTemplate::DataSection,
and originated from Mojo.

See also L<Data::Section::Simple>, L<Text::MicroTemplate::DataSection>,
and L<Mojo>.

=head1 SEE ALSO

L<Text::Xslate>

L<Text::Xslate::Manual>

=cut
