Template-Declare
view release on metacpan or search on metacpan
my $code = shift;
my %params = @_;
html {
head { title { outs "Hello, $params{user}!"} };
body {
$code->();
div { outs 'This is the end, my friend' };
};
}
};
}
template inner => sub {
wrap {
h1 { outs "Hello, Jesse, s'up?" };
} user => 'Jesse';
};
Note how the "wrap" wrapper function is available for calling after it
has been declared in a "BEGIN" block. Also note how you can pass
arguments to the function after the closing brace (you don't need a
comma there!).
The output from the "inner" template will look something like this:
<html>
<head>
<title>Hello, Jesse!</title>
</head>
<body>
<h1>Hello, Jesse, s'up?</h1>
<div>This is the end, my friend</div>
</body>
</html>
Tag Wrappers
Tag wrappers are similar to template wrappers, but mainly function as
syntax sugar for creating subroutines that behave just like tags but are
allowed to contain arbitrary Perl code and to dispatch to other tag. To
create one, simply create a named subroutine with the prototype "(&)" so
that its interface is the same as tags. Within it, use
"smart_tag_wrapper" to do the actual execution, like so:
package My::Template;
use Template::Declare::Tags;
use base 'Template::Declare';
sub myform (&) {
my $code = shift;
smart_tag_wrapper {
my %params = @_; # set using 'with'
form {
attr { %{ $params{attr} } };
$code->();
input { attr { type => 'submit', value => $params{value} } };
};
};
}
template edit_prefs => sub {
with(
attr => { id => 'edit_prefs', action => 'edit.html' },
value => 'Save'
), myform {
label { 'Time Zone' };
input { type is 'text'; name is 'tz' };
};
};
Note in the "edit_prefs" template that we've used "with" to set up
parameters to be passed to the smart wrapper. "smart_tag_wrapper()" is
the device that allows you to receive those parameters, and also handles
the magic of making sure that the tags you execute within it are
properly output. Here we've used "myform" similarly to "form", only
"myform" does something different with the "with()" arguments and
outputs a submit element.
Executing this template:
Template::Declare->init( dispatch_to => ['My::Template'] );
print Template::Declare->show('edit_prefs');
Yields this output:
<form action="edit.html" id="edit_prefs">
<label>Time Zone</label>
<input type="text" name="tz" />
<input type="submit" value="Save" />
</form>
Class Search Dispatching
The classes passed via the "dispatch_to" parameter to "init()" specify
all of the templates that can be executed by subsequent calls to
"show()". Template searches through these classes in order to find those
templates. Thus it can be useful, when you're creating your template
classes and determining which to use for particular class to "show()",
to have templates that override other templates. This is similar to how
an operating system will search all the paths in the $PATH environment
variable for a program to run, and to HTML::Mason component roots or
Template::Toolkit's "INCLUDE_PATH" parameter.
For example, say you have this template class that defines a template
that you'll use for displaying images on your Web site.
package MyApp::UI::Standard;
use Template::Declare::Tags;
use base 'Template::Declare';
template image => sub {
my ($self, $src, $title) = @_;
img {
src is $src;
title is $title;
};
};
As usual, you can use it like so:
my @template_classes = 'MyApp::UI::Standard';
Template::Declare->init( dispatch_to => \@template_classes );
print Template::Declare->show('image', 'foo.png', 'Foo');
We're explicitly using a reference to @template_classes so that we can
manage this list ourselves.
The output of this will be:
<div class="std">
<img src="foo.png" title="Foo" />
<p class="caption"></p>
</div>
But say that in some sections of your site you need to have a more
formal treatment of your photos. Maybe you publish photos from a wire
service and need to provide an appropriate credit. You might write the
template class like so:
package MyApp::UI::Formal;
use Template::Declare::Tags;
use base 'Template::Declare';
template image => sub {
my ($self, $src, $title, $credit, $caption) = @_;
div {
class is 'formal';
( run in 0.544 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )