__END__

=head1 INTRODUCTION

This is a step-by-step tutorial on how to use Plift. We will start using 100%
pure HTML templates, so you can learn how to render data using render directives.

Then you'll learn how to use the builtin processing instructions in your
template files. There are just three: C<< <x-include/> >>, C<< <x-wrap/> >> and
C<< <x-render/> >>.

Finnaly, I'll show how to create your own custom processing instructions
(triggered by custom tags/attributes) and how to bundle them in the form of
reusable components/plugins.

=head1 HELLO WORLD

Lets start by the classic "Hello World" example.

First our template file, C< index.html >:

    <section>
        <h1>Message placeholder</h1>
    </section>

Now our script, C< hello_world.pl >:

    ### hello_world.pl ###

    use Plift;

    my $plift = Plift->new;

    my %data = (
        hello_message => 'Hello World!'
    );

    my @directives = (
        'h1' => 'hello_message'
    );

    my $html = $plift->render('index', \%data, \@directives );

That will render (not surprisingly) the following text into C< $html >:

    <section>
        <h1>Hello World!</h1>
    </section>

Ok, now lets explain what C< $plift->render > does. As you can see, we passed three
arguments: the template name, some data, and a list of render directives. The first
is the name of the template file, without the C<.html> extension. The second
argument C<\%data> is a reference to a hash of data to make available for
templates. Finally, the third argument C<\@directives> is a reference to a list of
render directives, which are simple rules mapping a CCS selector to a data key.

Our example uses only one render directive, C< 'h1' => 'hello_message' >, that
tells Plift to render the value of the 'hello_message' data key into the C<< <h1> >>
element. If there were multiple C<<<h1>>> elements in the template, all of them
would get rendered. Under the hood, Plift uses L<XML::LibXML::jQuery> to
manipulate the HTML templates. The render directive in the example is equivalent
to the following code:

    my $data_value = $context->get('hello_message');
    $document->find('h1')->text($data_value);

=head1 THE PATH

In the above example Plift used the default config for the 'path' option, which
is the current working dir. In a real world application you usualy pass some pre
defined template path.

If you pass an arrayref with multiple paths, Plift will search all of them in
order. You can use that funcionality to create a simple way to "extend" the
website "theme" or "skin":

    my $plift = Plift->new(
        path => [
            '/myapp/website-foo/skin/templates/',
            '/myapp/share/skin/base/templates/'
        ]
    );

Any file with the same name (and relative path) on the first paths will read
instead of the equivalent file of the second path. If you ask for the template
C<'error_pages/404'> (remember, no .html extension), Plift first looks for
C</myapp/website-foo/skin/templates/error_pages/404.html> then
C</myapp/share/skin/base/templates/error_pages/404.html>.

=head1 THE CONTEXT

Before proceding, we must learn about the Plift::Context object. Is is responsible
for holding all data and render directives for the given rendering... context.

In fact, the methods L<Plift/render> and  L<Plift/process> methods are just
wrappers around the methods  L<Plift::Context/set>, L<Plift::Context/at> and
L<Plift::Context/render>. The follwing code:

    my $html = $plift->render('index', \%data, \@directives );

is equivalent to:

    my $tpl = $plift->template('index');    # returns a Plift::Context inst
    $tpl->set(\%data);
    $tpl->at();



=head1 RENDER DIRECTIVES

Render directives are pairs of C<<MATCH => ACTION>> values. The match part is a CSS
selector that target the element the action applies to. You can use any selector
supported by L<HTML::Selector::XPath>. The action part takes a few variations,
as described next.

All render directives and template data are stored in the L<Plift::Context>
object. Directives are added using the method L<Plift::Context/at>. And data
is added using the  using the method L<Plift::Context/set>. ance



=head2 Scalar - Interpolate data value

    $tpl->set
    $tpl->at( '.first-name' => 'user.first_name' );

This is the most common directive, where the selector points to a data point,
like C< '.first-name' => 'user.first_name' >. By default the data value is
rendered as the element content. You can add a special suffix to you MATCH
in the form of '<selector>@<attribute>' to render the value as an element's
HTML attribute. A final variation exists to allow the data value to be rendered
as HTML in the element's content, set the special sufixx '@HTML' (yes, uppercase.)

=over

=item HTML vs TEXT

The distinction between text and HTML is very important, is the cause of the
L<XSS vulnerability|https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)>.
This vulnerability got so common on web because almost all template engines are
designed to process text. These engines can be used to render a config file,
a christmas letter, and also HTML. Sure, all of those templating engines also
provides a way to properly HTML-escape a value, usualy in the form of filters.
But being a text templating engine, they can't just HTML-escape values by default.
The reality when using that kind of engine is that developers can (and will)
forget to add the proper filters, or just don't know about this security
vulnerability at all.

Plift is a template engine just for HTML, and it's implemented on top of
libxml. It means that for rendering text, we call L<XML::LibXML::Document/createTextNode>,
for attributes, L<XML::LibXML::Document/setAttribute> and for rendering the
final document we call L<XML::LibXML::Document/toStringHTML>. Libxml takes care
of the proper escaping.

Does it mean I'm immune to XSS vulnerability? No, you can still tell Plift to
render unescaped HTML, but its not the default.

=back

=head2 Arrayref - Run directives under a new DOM root

=head2 Hashref - Move the root of the Data Context

=head2 HashRef - Create a loop

=head2 CodeRef - Programmatically render the element

=head2 More on the selector

=head2 THE DOT NOTATION

=head1 PROCESSING INSTRUCTIONS

=head2 ELEMENT REMOVAL

=head1 CUSTOM HANDLERS

=head1 CREATING REUSABLE COMPONENTS

=head1 AUTHOR

Carlos Fernando Avila Gratz E<lt>cafe@kreato.com.brE<gt>

=cut
