cro-webapp-template
Cro::WebApp::Template
Templates are typically used to render some data into HTML. The template engine is designed with HTML in mind, and takes care to escape data as it should be escaped in HTML. Templates are compiled, typically on first use, for efficient rendering. The template language includes conditionals, iteration, subroutines, modules, and a number of other features.
Templates are typically stored either as files and referenced by path, or as
resources (the latter being useful if the web application should be possible
to install as a Raku distribution, for example using zef
).
This document covers how to produce HTTP responses by rendering templates and how templates are located; further documents cover:
Template modules (enabling for re-use of template subs and macros)
Template parts (a mechanism for providing data for common page elements, such as a shopping basket content indicator, instead of passing them into every template rendering)
Basic usage from a Cro route block
First, add the following use
statement to the module containing the route
block that you wish to use templates in:
use Cro::WebApp::Template;
Then, to produce a rendered template as the HTTP response, call template
,
passing the path to the template and, optionally, the data that the template
should render:
get -> 'product', Int $id {
my $product = $repository.lookup-product($id);
template 'templates/product.crotmp', $product;
}
This is short for:
get -> 'product', Int $id {
my $product = $repository.lookup-product($id);
content 'text/html', render-template 'templates/product.crotmp', $product;
}
Where render-template
renders the template and returns the result of doing
so, and content
is from Cro::HTTP::Router
and sets the content type of the
response along with the body.
While by default template
sets a content type of text/html
; this can be
changed by passing the content-type
named argument:
get -> 'product', Int $id {
my $product = $repository.lookup-product($id);
template 'templates/product.crotmp', $product,
content-type => 'text/plain';
}
Template locations
Templates may be served from files on disk or from distribution resources (the
%?RESOURCES
hash). Search locations for templates may be configured either
at a route
block level or globally (resources only at route
-block level).
The global search location list starts out containing the current working
directory. To add further template search locations using files, call the
template-location
function.
my $app = route {
template-location 'templates/';
get -> {
# Will look for templates/index.crotmp first
template 'index.crotmp';
}
}
When template-location
is called in a route
block, it is scoped to the
route handlers within that block and will also be considered by any route
blocks that we include
into this one (but not those we delegate
to).
When template-location
is called outside of a route
block, it adds to
the global search paths. The search order is:
Any
tempalate-location
s in the currentroute
block, tried in the order they were addedAny
template-location
s inroute
blocks thatinclude
us, transitively, innermost firstAny global
template-location
s
To serve templates from resources, first the resources should be associated
with the enclosing route
block using resources-from %?RESOURCES
(this is
not part of the template system, but rather a general mechanism of route
blocks). Then, templates-from-resources
should be called to indicate that
the resources should be considered when searching for templates.
my $app = route {
resources-from %?RESOURCES;
templates-from-resources;
get -> {
template 'templates/index.crotmp'
}
}
Applications using resources will often have many kinds of resource, and are
likely to put templates in a directory within the resources. One can avoid having
to write the templates/
prefix repeatedly by specifying it when calling the
templates-from-resources
function:
my $app = route {
resources-from %?RESOURCES;
templates-from-resources prefix => 'templates';
get -> {
template 'index.crotmp'
}
}
Template auto-reload
Templates are compiled on first use and cached for the rest of the process
lifetime. To have them recompiled automatically on changes, set CRO_DEV=1
in the environment. This is useful in development for avoiding application
restarts.
Template compilation
Sometimes it may be desirable to compile all templates in advance. Passing
:compile-all
to the template-location
function will immediately compile
all of the templates and die if there are any errors. This could be put into
a test case:
use Cro::WebApp::Template;
use Test;
lives-ok { template-location 'templates/', :compile-all },
'All templates have valid syntax';
done-testing;