.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "Text::Xslate::Manual::Cookbook 3pm" .TH Text::Xslate::Manual::Cookbook 3pm "2017-01-21" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Text::Xslate::Manual::Cookbook \- How to cook Xslate templates .SH "DESCRIPTION" .IX Header "DESCRIPTION" The Xslate cookbook is a set of recipes showing Xslate features. .SH "RECIPES" .IX Header "RECIPES" .SS "How to manage \s-1HTML\s0 forms" .IX Subsection "How to manage HTML forms" Managing \s-1HTML\s0 forms is an important issue for web applications. You're better off using modules that manage \s-1HTML\s0 forms rather than managing this yourself in your templates. This section proposes two basic solutions: using FillInForm and \s-1HTML\s0 form builders. .PP In both solutions, you should not use the \f(CW\*(C`mark_raw\*(C'\fR filter in templates, which easily creates \fBsecurity holes\fR. Instead, application code should be responsible for calling the \f(CW\*(C`mark_raw\*(C'\fR function that \f(CW\*(C`Text::Xslate\*(C'\fR can export. .PP \fIUsing FillInForm\fR .IX Subsection "Using FillInForm" .PP One solution to manage \s-1HTML\s0 forms is to use FillInForm modules with the block filter syntax. .PP Example code using \f(CW\*(C`HTML::FillInForm\*(C'\fR: .PP .Vb 3 \& #!perl \-w \& use strict; \& use Text::Xslate qw(html_builder); \& \& use HTML::FillInForm; # HTML::FillInForm::Lite is okay \& \& sub fillinform { \& my($q) = @_; \& my $fif = HTML::FillInForm\->new(); \& return html_builder { \& my($html) = @_; \& return $fif\->fill(\e$html, $q); \& }; \& } \& \& my $tx = Text::Xslate\->new( \& function => { \& fillinform => \e&fillinform, \& }, \& ); \& \& my %vars = ( \& q => { foo => "" }, \& ); \& print $tx\->render_string(<<\*(AqT\*(Aq, \e%vars); \& FillInForm: \& : block form | fillinform($q) \-> { \&
\& \&
\& : } \& T .Ve .PP Output: .PP .Vb 4 \& FillInForm: \&
\& \&
.Ve .PP Because HTML::FillInForm::Lite provides a \f(CW\*(C`fillinform\*(C'\fR function, it becomes even simpler: .PP .Vb 1 \& use HTML::FillInForm::Lite qw(fillinform); \& \& my $tx = Text::Xslate\->new( \& function => { fillinform => html_builder(\e&fillinform) }, \& ); .Ve .PP From 1.5018 on, \f(CW\*(C`html_builder_module\*(C'\fR is supported for \s-1HTML\s0 builder modules like \f(CW\*(C`HTML::FillInForm\*(C'\fR. Just import \s-1HTML\s0 builder functions with \f(CW\*(C`html_builder_module\*(C'\fR option. .PP .Vb 3 \& my $tx = Text::Xslate\->new( \& html_builder_module => [ \*(AqHTML::FillInForm::Lite\*(Aq => [qw(fillinform)] ], \& ); .Ve .PP See also HTML::FillInForm or HTML::FillInForm::Lite for details. .PP \fIUsing \s-1HTML\s0 form builders\fR .IX Subsection "Using HTML form builders" .PP Another solution to manage \s-1HTML\s0 forms is to use form builders. In such cases, all you have to do is to apply \f(CW\*(C`mark_raw()\*(C'\fR to \s-1HTML\s0 parts. .PP Here is a \s-1PSGI\s0 application that uses \f(CW\*(C`HTML::Shakan\*(C'\fR: .PP .Vb 6 \& #!psgi \& use strict; \& use warnings; \& use Text::Xslate qw(mark_raw); \& use HTML::Shakan; \& use Plack::Request; \& \& my $tx = Text::Xslate\->new(); \& \& sub app { \& my($env) = @_; \& my $req = Plack::Request\->new($env); \& \& my $shakan = HTML::Shakan\->new( \& request => $req, \& fields => [ TextField(name => \*(Aqname\*(Aq, label => \*(AqYour name: \*(Aq) ], \& ); \& \& my $res = $req\->new_response(200); \& \& # do mark_raw here, not in templates \& my $form = mark_raw($shakan\->render()); \& $res\->body( $tx\->render_string(<<\*(AqT\*(Aq, { form => $form }) ); \& \& \& Building form \& \&
\&

\& Form:
\& <: $form :> \&

\& \& \& T \& return $res\->finalize(); \& \& } \& \& return \e&app; .Ve .PP Output: .PP .Vb 12 \& \& \& Building form \& \& \&

\& Form:
\& \& \&

\& \& .Ve .PP See also HTML::Shakan for details. .SS "How to use Template Toolkit's \s-1WRAPPER\s0 feature in Kolon" .IX Subsection "How to use Template Toolkit's WRAPPER feature in Kolon" Use template cascading, which is a super-set of the \f(CW\*(C`WRAPPER\*(C'\fR directive. .PP \&\fIwrapper.tx\fR: .PP .Vb 3 \&
\& block content \-> { } \&
.Ve .PP \&\fIcontent.tx\fR .PP .Vb 1 \& : cascade wrapper \& \& : override content \-> { \& Hello, world! \& : } .Ve .PP Output: .PP .Vb 3 \&
\& Hello, world! \&
.Ve .PP \fITemplate cascading\fR .IX Subsection "Template cascading" .PP Xslate supports \fBtemplate cascading\fR, which allows you to extend templates with block modifiers. It is like traditional template inclusion, but is more powerful. .PP This mechanism is also called as template inheritance. .PP See also \*(L"Template cascading\*(R" in Text::Xslate. .SS "How to map _\|_DATA_\|_ sections to the include path" .IX Subsection "How to map __DATA__ sections to the include path" Use \f(CW\*(C`Data::Section::Simple\*(C'\fR, and the \f(CW\*(C`path\*(C'\fR option of \f(CW\*(C`new()\*(C'\fR, which accepts \&\s-1HASH\s0 references which contain \f(CW\*(C`$file_name => $content\*(C'\fR mapping. .PP .Vb 2 \& use Text::Xslate; \& use Data::Section::Simple; \& \& my $vpath = Data::Section::Simple\->new()\->get_data_section(); \& my $tx = Text::Xslate\->new( \& path => [$vpath], \& ); \& \& print $tx\->render(\*(Aqchild.tx\*(Aq); \& \& _\|_DATA_\|_ \& @@ base.tx \& \& <: block body \-> { :>default body<: } :> \& \& @@ child.tx \& : cascade base; \& : override body \-> { \& child body \& : } # endblock body .Ve .PP This feature is directly inspired by Text::MicroTemplate::DataSection, and originated from Mojolicious. .PP See also Data::Section::Simple, Text::MicroTemplate::DataSection, and Mojolicious. .SS "How to interpolate data into JavaScript sections without \s-1XSS\s0" .IX Subsection "How to interpolate data into JavaScript sections without XSS" Because Xslate escapes only \s-1HTML\s0 meta characters, you must escape JavaScript meta characters by yourself when you put data into \&\f(CW\*(C`\*(C'\fR sections. .PP The \f(CW\*(C`JSON\*(C'\fR module is not suitable because it doesn't escape some meta characters such as \f(CW""\fR. .PP It is better to use utilities proven to be secure for JavaScript escaping to avoid \s-1XSS. \&\s0JavaScript::Value::Escape helps you in this regard. .PP .Vb 3 \& my $tx = Text::Xslate\->new( \& module => [\*(AqJavaScript::Value::Escape\*(Aq => [qw(js)]], \& ); \& \& my %params = ( \& user_input => \*(Aq\*(Aq, \& ); \& \& print $tx\->render_string(<<\*(AqT\*(Aq, \e%params); \& \& T .Ve .PP You'd better to consult the security experts on more complex cases. .SS "How to interpolate structured texts into \s-1HTML\s0 without \s-1XSS\s0" .IX Subsection "How to interpolate structured texts into HTML without XSS" There's no silver bullet to parse structured texts in secure ways. You'd better to consult the security experts to do so. .PP Some \s-1CPAN\s0 module might help you. See String::Filter for example. .SS "How to manage localization in templates" .IX Subsection "How to manage localization in templates" You can register any functions including \f(CW\*(C`_()\*(C'\fR, so no specific techniques are required. .PP For example: .PP .Vb 4 \& use I18N::Handle; \& # I18N::Handle installs the locale function "_" to the global namespace. \& # (remember the symbol *_ is global) \& I18N::Handle\->new( ... )\->speak(\*(Aqzh_tw\*(Aq); \& \& my $tx = Text::Xslate\->new( \& function => { \& _ => \e&_, \& }, \& ); .Ve .PP Then in your templates: .PP .Vb 1 \& <: _(\*(AqHello %1\*(Aq, $john ) :> .Ve .PP See also: I18N::Handle, App::I18N. .ie n .SS "How to load templates before ""fork()""ing?" .el .SS "How to load templates before \f(CWfork()\fPing?" .IX Subsection "How to load templates before fork()ing?" It is a good idea to load templates in preforking-model applications. Here is an example to load all the templates which is in a given path: .PP .Vb 1 \& use File::Find; \& \& my $path = ...; \& my $tx = Text::Xslate\->new( \& path => [$path], \& cache_dir => $path, \& ); \& \& # pre\-load files \& find sub { \& if(/\e.tx$/) { \& my $file = $File::Find::name; \& $file =~ s/\eQ$path\eE .//xsm; # fix path names \& $tx\->load_file($file); \& } \& }, $path; \& \& # fork and render ... .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Text::Xslate .PP Text::Xslate::Manual .PP Text::Xslate::Manual::FAQ