NAME
Template::Caribou::Role - Caribou core engine
VERSION
version 1.2.2
SYNOPSIS
package MyTemplate;
use Template::Caribou;
has name => ( is => 'ro' );
template greetings => sub {
my $self = shift;
print "hello there, ", $self->name;
};
# later on...
my $template = MyTemplate->new( name => 'Yanick' );
print $template->greetings;
DESCRIPTION
This role implements the rendering core of Caribou, which mostly deals with defining the templates of a class and calling them.
The templates
The templates are subs expected to print or return the content they are generating. Under the hood, they are snugly wrapped within a render
call and turned into methods of the template class.
package MyTemplate;
use Template::Caribou;
has name => ( is => 'ro' );
template greetings => sub {
my( $self, %args ) = @_;
'hi there ' . $self->name . '!' x $args{excited};
};
my $bou = MyTemplate->new( name => 'Yanick' );
print $bou->greetings;
# prints 'hi there Yanick'
print $bou->greetings(excited => 1);
# print 'hi there Yanick!
In addition of those arguments, the file descriptions ::STDOUT
and ::RAW
are locally defined. Anything printed to ::RAW
is added verbatim to the content of the template, whereas something printed to STDOUT
will be HTML-escaped.
If nothing has been printed at all by the template, it'll take its return value as its generated content.
# prints '<hey>'
print MyTemplate->render(sub{
print "<hey>";
});
# prints '<hey>'
print MyTemplate->render(sub{
print ::RAW "<hey>";
});
# prints 'onetwo'
print MyTemplate->render(sub{
print "one";
print "two";
});
# prints 'one'
print MyTemplate->render(sub{
print "one";
return "ignored";
});
# prints 'no print, not ignored'
print MyTemplate->render(sub{
return "no print, not ignored";
});
Template methods can, of course, be called within other template methods. When invoked from within a template, their content is implicitly printed to ::RAW
.
template outer => sub {
my $self = shift;
say 'alpha';
$self->inner;
say 'gamma';
};
template inner => sub {
say 'beta';
};
...;
print $bou->outer; # prints 'alpha beta gamma'
Definiting templates via template instances
Templates are usually defined for the class via the template
keyword. template
can also be used as a method. By default, though, it'll die as adding a template that way will not only add it to the instance, but for to class itself, which is probably more than you bargained for.
$bou->template( foo => sub { ... } );
# dies with 'can only add templates from instances created
# via 'anon_instance' or with the attribute 'can_add_templates'
If you want to add a template to a single instance, use the class method anon_instance
, which will create a singleton class inheriting from the main template class.
my $bou = MyTemplate->anon_instance( name => 'Yanick' );
$bou->template( foo => sub { ... } ); # will work
Or if you really want to augment the whole class with new templates, you can set the can_add_templates
attribute of the object to true
.
$bou->can_add_templates(1);
$bou->template( foo => sub { ... } ); # will work too
METHODS
new
my $bou = MyTemplate->new(
indent => 1,
can_add_templates => 0,
);
- indent => $boolean
-
If set to a
true
value, the nested tags rendered inside the templates will be indented. Defaults totrue
. - can_add_templates
-
If templates can be added to the class via the method invocation of
template
.
indent
$bou->indent($bool);
Accessor to the indent attribute. Indicates if the tags rendered within the templates should be pretty-printed with indentation or not.
can_add_templates
$bou->can_add_templates($bool);
Accessor. If set to true
, allows new templates to be defined for the class via the template
method.
template( $name => sub { ... } )
Defines the template $name
. Will trigger an exception unless can_add_templates
was set to true
or the object was created via anon_instance
.
Warnings will be issued if the template redefines an already-existing function/method in the namespace.
anon_instance(@args_for_new)
Creates an anonymous class inheriting from the current one and builds an object instance with the given arguments. Useful when wanting to define templates for one specific instance.
render
$bou->render( $coderef, @template_args );
$bou->render( $template_name, @template_args );
Renders the given $coderef
as a template, passing it the @template_args
, and returns its generated output.
print $bou->render( sub {
my( $self, $name ) = @_;
'hi ' . $name . "\n";
}, $_ ) for @friends;
The template can also be given by name.
template foo => sub { ... };
# later on
$bou->render( 'foo', @args );
# which is equivalent to
$bou->foo(@args);
get_render
Like render
, but always return the generated template content, even when called inside a template.
template foo => sub { 'foo' };
template bar => sub { 'bar' };
print $bou->render(sub{
my $self = shift;
$self->foo;
my $bar = $self->get_render(sub{ $self->bar });
$bar =~ y/r/z/;
say $bar;
});
# prints 'foobaz'
SEE ALSO
http://babyl.dyndns.org/techblog/entry/caribou - The original blog entry introducing Template::Caribou.
AUTHOR
Yanick Champoux <yanick@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2023 by Yanick Champoux.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.