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-locations in the currentrouteblock, tried in the order they were addedAny
template-locations inrouteblocks thatincludeus, transitively, innermost firstAny global
template-locations
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;