1Text::Xslate::Manual::CUosoekrboCookn(t3r)ibuted Perl DoTceuxmte:n:tXastliaotne::Manual::Cookbook(3)
2
3
4
6 Text::Xslate::Manual::Cookbook - How to cook Xslate templates
7
9 The Xslate cookbook is a set of recipes showing Xslate features.
10
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="<filled value>" />
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="<Xslate>" />
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 techniques
256 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
301 Text::Xslate
302
303 Text::Xslate::Manual
304
305 Text::Xslate::Manual::FAQ
306
307
308
309perl v5.36.0 2023-01-20 Text::Xslate::Manual::Cookbook(3)