1Text::Xslate::Manual::CUosoekrboCookn(t3r)ibuted Perl DoTceuxmte:n:tXastliaotne::Manual::Cookbook(3)
2
3
4

NAME

6       Text::Xslate::Manual::Cookbook - How to cook Xslate templates
7

DESCRIPTION

9       The Xslate cookbook is a set of recipes showing Xslate features.
10

RECIPES

12   How to manage HTML forms
13       Managing HTML forms is an important issue for web applications.  You're
14       better off using modules that manage HTML forms rather than managing
15       this yourself in your templates.  This section proposes two basic
16       solutions: using FillInForm and HTML form builders.
17
18       In both solutions, you should not use the "mark_raw" filter in
19       templates, which easily creates security holes. Instead, application
20       code should be responsible for calling the "mark_raw" function that
21       "Text::Xslate" can export.
22
23       Using FillInForm
24
25       One solution to manage HTML forms is to use FillInForm modules with the
26       block filter syntax.
27
28       Example code using "HTML::FillInForm":
29
30           #!perl -w
31           use strict;
32           use Text::Xslate qw(html_builder);
33
34           use HTML::FillInForm; # HTML::FillInForm::Lite is okay
35
36           sub fillinform {
37               my($q) = @_;
38               my $fif = HTML::FillInForm->new();
39               return html_builder {
40                   my($html) = @_;
41                   return $fif->fill(\$html, $q);
42               };
43           }
44
45           my $tx = Text::Xslate->new(
46               function => {
47                   fillinform => \&fillinform,
48               },
49           );
50
51           my %vars = (
52               q => { foo => "<filled value>" },
53           );
54           print $tx->render_string(<<'T', \%vars);
55           FillInForm:
56           : block form | fillinform($q) -> {
57           <form>
58           <input type="text" name="foo" />
59           </form>
60           : }
61           T
62
63       Output:
64
65           FillInForm:
66           <form>
67           <input type="text" name="foo" value="&lt;filled value&gt;" />
68           </form>
69
70       Because HTML::FillInForm::Lite provides a "fillinform" function, it
71       becomes even simpler:
72
73           use HTML::FillInForm::Lite qw(fillinform);
74
75           my $tx = Text::Xslate->new(
76               function => { fillinform => html_builder(\&fillinform) },
77           );
78
79       From 1.5018 on, "html_builder_module" is supported for HTML builder
80       modules like "HTML::FillInForm". Just import HTML builder functions
81       with "html_builder_module" option.
82
83           my $tx = Text::Xslate->new(
84               html_builder_module => [ 'HTML::FillInForm::Lite' => [qw(fillinform)] ],
85           );
86
87       See also HTML::FillInForm or HTML::FillInForm::Lite for details.
88
89       Using HTML form builders
90
91       Another solution to manage HTML forms is to use form builders.  In such
92       cases, all you have to do is to apply "mark_raw()" to HTML parts.
93
94       Here is a PSGI application that uses "HTML::Shakan":
95
96           #!psgi
97           use strict;
98           use warnings;
99           use Text::Xslate qw(mark_raw);
100           use HTML::Shakan;
101           use Plack::Request;
102
103           my $tx = Text::Xslate->new();
104
105           sub app {
106               my($env) = @_;
107               my $req  = Plack::Request->new($env);
108
109               my $shakan = HTML::Shakan->new(
110                   request => $req,
111                   fields  => [ TextField(name => 'name', label => 'Your name: ') ],
112               );
113
114               my $res = $req->new_response(200);
115
116               # do mark_raw here, not in templates
117               my $form = mark_raw($shakan->render());
118               $res->body( $tx->render_string(<<'T', { form => $form }) );
119           <!doctype html>
120           <html>
121           <head><title>Building form</title></head>
122           <body>
123           <form>
124           <p>
125           Form:<br />
126           <: $form :>
127           </p>
128           </body>
129           </html>
130           T
131               return $res->finalize();
132
133           }
134
135           return \&app;
136
137       Output:
138
139           <!doctype html>
140           <html>
141           <head><title>Building form</title></head>
142           <body>
143           <form>
144           <p>
145           Form:<br />
146           <label for="id_name">Your name</label>
147           <input id="id_name" name="name" type="text" value="&lt;Xslate&gt;" />
148           </p>
149           </body>
150           </html>
151
152       See also HTML::Shakan for details.
153
154   How to use Template Toolkit's WRAPPER feature in Kolon
155       Use template cascading, which is a super-set of the "WRAPPER"
156       directive.
157
158       wrapper.tx:
159
160           <div class="wrapper">
161           block content -> { }
162           </div>
163
164       content.tx
165
166           : cascade wrapper
167
168           : override content -> {
169               Hello, world!
170           : }
171
172       Output:
173
174           <div class="wrapper">
175               Hello, world!
176           </div>
177
178       Template cascading
179
180       Xslate supports template cascading, which allows you to extend
181       templates with block modifiers. It is like traditional template
182       inclusion, but is more powerful.
183
184       This mechanism is also called as template inheritance.
185
186       See also "Template cascading" in Text::Xslate.
187
188   How to map __DATA__ sections to the include path
189       Use "Data::Section::Simple", and the "path" option of "new()", which
190       accepts HASH references which contain "$file_name => $content" mapping.
191
192           use Text::Xslate;
193           use Data::Section::Simple;
194
195           my $vpath = Data::Section::Simple->new()->get_data_section();
196           my $tx = Text::Xslate->new(
197               path => [$vpath],
198           );
199
200           print $tx->render('child.tx');
201
202           __DATA__
203           @@ base.tx
204           <html>
205           <body><: block body -> { :>default body<: } :></body>
206           </html>
207           @@ child.tx
208           : cascade base;
209           : override body -> {
210           child body
211           : } # endblock body
212
213       This feature is directly inspired by Text::MicroTemplate::DataSection,
214       and originated from Mojolicious.
215
216       See also Data::Section::Simple, Text::MicroTemplate::DataSection, and
217       Mojolicious.
218
219   How to interpolate data into JavaScript sections without XSS
220       Because Xslate escapes only HTML meta characters, you must escape
221       JavaScript meta characters by yourself when you put data into "<script>
222       ... </script>" sections.
223
224       The "JSON" module is not suitable because it doesn't escape some meta
225       characters such as "</script>".
226
227       It is better to use utilities proven to be secure for JavaScript
228       escaping to avoid XSS.  JavaScript::Value::Escape helps you in this
229       regard.
230
231           my $tx = Text::Xslate->new(
232               module => ['JavaScript::Value::Escape' => [qw(js)]],
233               );
234
235           my %params = (
236               user_input => '</script><script>alert("XSS")</script>',
237               );
238
239           print $tx->render_string(<<'T', \%params);
240           <script>
241           document.write('<: $user_input | html | js :>');
242           var user_input = '<: $user_input | js :>';
243           </script>
244           T
245
246       You'd better to consult the security experts on more complex cases.
247
248   How to interpolate structured texts into HTML without XSS
249       There's no silver bullet to parse structured texts in secure ways.
250       You'd better to consult the security experts to do so.
251
252       Some CPAN module might help you. See String::Filter for example.
253
254   How to manage localization in templates
255       You can register any functions including "_()", so no specific
256       techniques are required.
257
258       For example:
259
260           use I18N::Handle;
261           # I18N::Handle installs the locale function "_" to the global namespace.
262           # (remember the symbol *_ is global)
263           I18N::Handle->new( ... )->speak('zh_tw');
264
265           my $tx = Text::Xslate->new(
266               function => {
267                   _ => \&_,
268               },
269           );
270
271       Then in your templates:
272
273           <: _('Hello %1', $john ) :>
274
275       See also: I18N::Handle, App::I18N.
276
277   How to load templates before "fork()"ing?
278       It is a good idea to load templates in preforking-model applications.
279       Here is an example to load all the templates which is in a given path:
280
281           use File::Find;
282
283           my $path = ...;
284           my $tx = Text::Xslate->new(
285               path      => [$path],
286               cache_dir =>  $path,
287           );
288
289           # pre-load files
290           find sub {
291               if(/\.tx$/) {
292                   my $file = $File::Find::name;
293                   $file =~ s/\Q$path\E .//xsm; # fix path names
294                   $tx->load_file($file);
295               }
296           }, $path;
297
298           # fork and render ...
299

SEE ALSO

301       Text::Xslate
302
303       Text::Xslate::Manual
304
305       Text::Xslate::Manual::FAQ
306
307
308
309perl v5.34.0                      2021-07-23 Text::Xslate::Manual::Cookbook(3)
Impressum