view release on metacpan or search on metacpan
README.mkdn view on Meta::CPAN
just so you have a place to match, when you have complex and deeply nested data.
Additionally many UI designers already are familiar with some basic templating systems and
might really prefer to use that so that they can maintain more autonomy and avoid the additional
learning curve that [Template::Pure](https://metacpan.org/pod/Template::Pure) will requires (most people seem to find its a bit more
effort to learn off the top compared to more simple systems like Mustache or even [Template::Toolkit](https://metacpan.org/pod/Template::Toolkit).
Although inspired by pure.js [http://beebole.com/pure/](http://beebole.com/pure/) this module attempts to help mitigate some
of the listed possible downsides with additional features that are a superset of the original
pure.js specification. For example you may include templates inside of templates as includes or even
overlays that provide much of the same benefit that template inheritance offers in many other
popular template frameworks. These additional features are intended to make it more suitable as a general
purpose server side templating system.
# CREATING TEMPLATE OBJECTS
The first step is to create a [Template::Pure](https://metacpan.org/pod/Template::Pure) object:
my $pure = Template::Pure->new(
template=>$html,
directives=> \@directives);
README.mkdn view on Meta::CPAN
Results in:
<div>
<p class="headline">This is a test of the emergency broadcasting
network... This is only a test</p>
</div>
Lastly you can mimic a type of inheritance using data mapping and
node aliasing:
my $overlay_html = q[
<html>
<head>
<title>Example Title</title>
<link rel="stylesheet" href="/css/pure-min.css"/>
<link rel="stylesheet" href="/css/grids-responsive-min.css"/>
<link rel="stylesheet" href="/css/common.css"/>
<script src="/js/3rd-party/angular.min.js"></script>
<script src="/js/3rd-party/angular.resource.min.js"></script>
</head>
<body>
<section id="content">...</section>
<p id="foot">Here's the footer</p>
</body>
</html>
];
my $overlay = Template::Pure->new(
template=>$overlay_html,
directives=> [
'title' => 'title',
'^title+' => 'scripts',
'body section#content' => 'content',
]);
my $page_html = q[
<html>
<head>
<title>The Real Page</title>
README.mkdn view on Meta::CPAN
my $page = Template::Pure->new(
template=>$page_html,
directives=> [
'title' => 'meta.title',
'html' => [
{
title => \'title',
scripts => \'^head script',
content => \'body',
},
'^.' => $overlay,
]
]);
my $data = +{
meta => {
title => 'Inner Stuff',
},
};
Results in:
README.mkdn view on Meta::CPAN
template=>$base_html,
directives=> [
'title+' => 'meta.title',
'#story' => 'story,
'^#story => $story_section_wrapper,
]
);
## Overlay
An overlay replaces the selected node with the results on another template. Typically
you will pass selected nodes of the original template as directives to the new template.
This can be used to minic features like template inheritance, that exist in other templating
systems. One example:
my $overlay_html = q[
<html>
<head>
<title>Example Title</title>
<link rel="stylesheet" href="/css/pure-min.css"/>
<link rel="stylesheet" href="/css/grids-responsive-min.css"/>
<link rel="stylesheet" href="/css/common.css"/>
<script src="/js/3rd-party/angular.min.js"></script>
<script src="/js/3rd-party/angular.resource.min.js"></script>
</head>
<body>
</body>
</html>
];
my $overlay = Template::Pure->new(
template=>$overlay_html,
directives=> [
'title' => 'title',
'head+' => 'scripts',
'body' => 'content',
]);
my $base_html = q[
<?pure-overlay src='layout'
title=\'title'
scripts=\'^head script'
content=\'body'?>
<html>
<head>
<title>Page Title: </title>
<script>
function foo(bar) {
return baz;
}
README.mkdn view on Meta::CPAN
my $base = Template::Pure->new(
template=>$base_html,
directives=> [
'title+' => 'meta.title',
'#story' => 'story,
]
);
print $base->render({
layout => $overlay,
story => 'Once Upon a Time...',
meta => {
title=>'Once',
author=>'jnap',
},
});
Renders As:
<html>
README.mkdn view on Meta::CPAN
}
</script>
</head>
<body>
<div id='story'>Once Upon a Time...</div>
</body>
</html>
The syntax of the processing instruction is:
<?pure-overlay src='' @args ?>
Where 'src' is a data path to the template you want to use as the overlay, and @args is
a list of key values which populate the data context of the overlay when you process it.
Often these values will be references to existing nodes in the base template (as in the
examples \\'title' and \\'body' above) but they can also be used to map values from your
data context in the same way we do so for ["Include"](#include) and ["Wrapper"](#wrapper).
If you were to write this as 'directives only' it would look like:
my $base = Template::Pure->new(
template=>$base_html,
directives=> [
'title+' => 'meta.title',
README.mkdn view on Meta::CPAN
{
title => \'title'
script s=> \'^head script'
content => \'body'
},
'^.' => 'layout',
],
]
);
Please note that although in this example the overlay wrapped over the entire template, it is
not limited to that, rather like the ["Wrapper"](#wrapper) processing instruction it just takes the next
tag node following as its overlay target. So you could have more than one overlap in a document
and can overlay sections for those cases where a ["Wrapper"](#wrapper) is not sufficently complex.
## Filter
A Filter will process the following node on a [Template::Pure](https://metacpan.org/pod/Template::Pure) instance as if that node was the
source for its template. This means that the target source template must be a coderef that builds
a <Template::Pure> object, and not an already instantiated one. For Example:
my $base_html = q[
<html>
<head>
lib/Template/Pure.pm view on Meta::CPAN
);
} else {
push @{$params{directives}}, (
"^*[data-pure-filter-id=filter-$params{cnt}]", sub {
my ($t, $dom, $data) = @_;
$t->data_at_path($data, $src)->($dom);
},
"*[data-pure-filter-id=filter-$params{cnt}]\@data-pure-filter-id", sub { undef },
);
}
} elsif($target eq 'pure-overlay') {
$params{node}->following('*')->first->attr('data-pure-overlay-id'=>"overlay-$params{cnt}");
$params{node}->remove;
push @{$params{directives}}, (
"^*[data-pure-overlay-id=overlay-$params{cnt}]", [ +{%attrs, src=>$src }, '^.' => 'src'],
# "*[data-pure-overlay-id=overlay-$params{cnt}]\@data-pure-overlay-id", sub { undef },
);
} else {
warn "Encountering processing instruction $target that I can't process";
}
$params{cnt}++;
return %params;
}
sub components { shift->{components} }
sub initialized_components { shift->{initialized_components} }
lib/Template/Pure.pm view on Meta::CPAN
just so you have a place to match, when you have complex and deeply nested data.
Additionally many UI designers already are familiar with some basic templating systems and
might really prefer to use that so that they can maintain more autonomy and avoid the additional
learning curve that L<Template::Pure> will requires (most people seem to find its a bit more
effort to learn off the top compared to more simple systems like Mustache or even L<Template::Toolkit>.
Although inspired by pure.js L<http://beebole.com/pure/> this module attempts to help mitigate some
of the listed possible downsides with additional features that are a superset of the original
pure.js specification. For example you may include templates inside of templates as includes or even
overlays that provide much of the same benefit that template inheritance offers in many other
popular template frameworks. These additional features are intended to make it more suitable as a general
purpose server side templating system.
=head1 CREATING TEMPLATE OBJECTS
The first step is to create a L<Template::Pure> object:
my $pure = Template::Pure->new(
template=>$html,
directives=> \@directives);
lib/Template/Pure.pm view on Meta::CPAN
Results in:
<div>
<p class="headline">This is a test of the emergency broadcasting
network... This is only a test</p>
</div>
Lastly you can mimic a type of inheritance using data mapping and
node aliasing:
my $overlay_html = q[
<html>
<head>
<title>Example Title</title>
<link rel="stylesheet" href="/css/pure-min.css"/>
<link rel="stylesheet" href="/css/grids-responsive-min.css"/>
<link rel="stylesheet" href="/css/common.css"/>
<script src="/js/3rd-party/angular.min.js"></script>
<script src="/js/3rd-party/angular.resource.min.js"></script>
</head>
<body>
<section id="content">...</section>
<p id="foot">Here's the footer</p>
</body>
</html>
];
my $overlay = Template::Pure->new(
template=>$overlay_html,
directives=> [
'title' => 'title',
'^title+' => 'scripts',
'body section#content' => 'content',
]);
my $page_html = q[
<html>
<head>
<title>The Real Page</title>
lib/Template/Pure.pm view on Meta::CPAN
my $page = Template::Pure->new(
template=>$page_html,
directives=> [
'title' => 'meta.title',
'html' => [
{
title => \'title',
scripts => \'^head script',
content => \'body',
},
'^.' => $overlay,
]
]);
my $data = +{
meta => {
title => 'Inner Stuff',
},
};
Results in:
lib/Template/Pure.pm view on Meta::CPAN
template=>$base_html,
directives=> [
'title+' => 'meta.title',
'#story' => 'story,
'^#story => $story_section_wrapper,
]
);
=head2 Overlay
An overlay replaces the selected node with the results on another template. Typically
you will pass selected nodes of the original template as directives to the new template.
This can be used to minic features like template inheritance, that exist in other templating
systems. One example:
my $overlay_html = q[
<html>
<head>
<title>Example Title</title>
<link rel="stylesheet" href="/css/pure-min.css"/>
<link rel="stylesheet" href="/css/grids-responsive-min.css"/>
<link rel="stylesheet" href="/css/common.css"/>
<script src="/js/3rd-party/angular.min.js"></script>
<script src="/js/3rd-party/angular.resource.min.js"></script>
</head>
<body>
</body>
</html>
];
my $overlay = Template::Pure->new(
template=>$overlay_html,
directives=> [
'title' => 'title',
'head+' => 'scripts',
'body' => 'content',
]);
my $base_html = q[
<?pure-overlay src='layout'
title=\'title'
scripts=\'^head script'
content=\'body'?>
<html>
<head>
<title>Page Title: </title>
<script>
function foo(bar) {
return baz;
}
lib/Template/Pure.pm view on Meta::CPAN
my $base = Template::Pure->new(
template=>$base_html,
directives=> [
'title+' => 'meta.title',
'#story' => 'story,
]
);
print $base->render({
layout => $overlay,
story => 'Once Upon a Time...',
meta => {
title=>'Once',
author=>'jnap',
},
});
Renders As:
<html>
lib/Template/Pure.pm view on Meta::CPAN
}
</script>
</head>
<body>
<div id='story'>Once Upon a Time...</div>
</body>
</html>
The syntax of the processing instruction is:
<?pure-overlay src='' @args ?>
Where 'src' is a data path to the template you want to use as the overlay, and @args is
a list of key values which populate the data context of the overlay when you process it.
Often these values will be references to existing nodes in the base template (as in the
examples \'title' and \'body' above) but they can also be used to map values from your
data context in the same way we do so for L</Include> and L</Wrapper>.
If you were to write this as 'directives only' it would look like:
my $base = Template::Pure->new(
template=>$base_html,
directives=> [
'title+' => 'meta.title',
lib/Template/Pure.pm view on Meta::CPAN
{
title => \'title'
script s=> \'^head script'
content => \'body'
},
'^.' => 'layout',
],
]
);
Please note that although in this example the overlay wrapped over the entire template, it is
not limited to that, rather like the L</Wrapper> processing instruction it just takes the next
tag node following as its overlay target. So you could have more than one overlap in a document
and can overlay sections for those cases where a L</Wrapper> is not sufficently complex.
=head2 Filter
A Filter will process the following node on a L<Template::Pure> instance as if that node was the
source for its template. This means that the target source template must be a coderef that builds
a <Template::Pure> object, and not an already instantiated one. For Example:
my $base_html = q[
<html>
<head>
t/processing-instructions.t view on Meta::CPAN
use Test::Most;
use Template::Pure;
ok my $overlay_html = q[
<html>
<head>
<title>Example Title</title>
<link rel="stylesheet" href="/css/pure-min.css"/>
<link rel="stylesheet" href="/css/grids-responsive-min.css"/>
<link rel="stylesheet" href="/css/common.css"/>
<script src="/js/3rd-party/angular.min.js"></script>
<script src="/js/3rd-party/angular.resource.min.js"></script>
</head>
<body>
<section id="content">...</section>
<p id="foot">Here's the footer</p>
</body>
</html>
];
ok my $overlay = Template::Pure->new(
template=>$overlay_html,
directives=> [
'title' => 'title',
'head+' => 'scripts',
'body section#content' => 'content',
]);
ok my $story_html = qq[
<section>
<h1>story title</h1>
<p>By </p>
t/processing-instructions.t view on Meta::CPAN
ok my $foot_html = qq[
<span class="time">current time: </span>];
ok my $foot = Template::Pure->new(
template=>$foot_html,
directives=> [
'.time+' => 'time',
]);
ok my $base_html = q[
<?pure-overlay src='lib.overlay'
title=\'title'
scripts=\'^head script'
content=\'body'?>
<html>
<head>
<title>Page Title: </title>
<script>
function foo(bar) {
return baz;
}
t/processing-instructions.t view on Meta::CPAN
meta => {
title=>'My Title',
author=>'jnap',
time => scalar(localtime),
class => 'blue',
},
class => 'red',
lib => {
foot => $foot,
story => $story,
overlay => $overlay,
filter => sub {
my $template = shift;
return Template::Pure->new(
template => $template,
directives => [
'a@class' => 'class',
]
);
},
}