1Mojolicious::Guides::ReUnsdeerriCnogn(t3r)ibuted Perl DoMcoujmoelnitcaitoiuosn::Guides::Rendering(3)
2
3
4
6 Mojolicious::Guides::Rendering - Rendering
7
9 Generating content with the Mojolicious renderer.
10
12 Essentials every Mojolicious developer should know.
13
14 Renderer
15 The renderer is a tiny black box turning stash data into actual
16 responses utilizing multiple template systems and data encoding
17 modules.
18
19 {text => 'Hello!'} -> 200 OK, text/plain, 'Hello!'
20 {json => {x => 3}} -> 200 OK, application/json, '{"x":3}'
21 {text => 'Oops!', status => '410'} -> 410 Gone, text/plain, 'Oops!'
22
23 Templates can be automatically detected if enough information is
24 provided by the developer or routes. Template names are expected to
25 follow the "name.format.handler" scheme, with "name" defaulting to
26 "controller/action" or the route name, "format" defaulting to "html"
27 and "handler" to "ep".
28
29 {controller => 'users', action => 'list'} -> 'users/list.html.ep'
30 {route => 'foo', format => 'txt'} -> 'foo.txt.ep'
31 {route => 'foo', handler => 'epl'} -> 'foo.html.epl'
32
33 All templates should be in the "templates" directory of the application
34 or the "DATA" section of the class "main".
35
36 __DATA__
37 @@ time.html.ep
38 <!doctype html><html>
39 <head><title>Time</title></head>
40 <body><%= localtime time %></body>
41 </html>
42
43 @@ hello.txt.ep
44 ...
45
46 The renderer can be easily extended to support additional template
47 systems with plugins, but more about that later.
48
49 Embedded Perl
50 Mojolicious includes a minimalistic but very powerful template system
51 out of the box called Embedded Perl or "ep" for short. It allows the
52 embedding of Perl code right into actual content using a small set of
53 special tags and line start characters.
54
55 <% Inline Perl %>
56 <%= Perl expression, replaced with XML escaped result %>
57 <%== Perl expression, replaced with raw result %>
58 <%# Comment, useful for debugging %>
59 % Perl line
60 %= Perl expression line, replaced with XML escaped result
61 %== Perl expression line, replaced with raw result
62 %# Comment line, useful for debugging
63
64 The simplest form is used to insert raw Perl code. Tags and lines work
65 pretty much the same, but depending on context one will usually look a
66 bit better.
67
68 <% my $i = 10; %>
69 Text before.
70 <% for (1 .. $i) { %>
71 Insert this text 10 times!
72 <% } %>
73 Text after.
74
75 % my $i = 10;
76 Text before.
77 % for (1 .. $i) {
78 Insert this text 10 times!
79 % }
80 Text after.
81
82 You can also insert results from actual Perl code using expressions, by
83 default the characters "<", ">", "&", "'" and """ will be escaped to
84 prevent XSS attacks against your application. Semicolons get
85 automatically appended to all expressions.
86
87 <%= 'lalala' %>
88 <%== '<p>test</p>' %>
89
90 Only Mojo::ByteStream objects are excluded from automatic escaping.
91
92 <%= Mojo::ByteStream->new('<p>test</p>') %>
93
94 You can also add an additional equal sign to the end of a tag to have
95 it automatically remove all surrounding whitespaces, this allows free
96 indenting without ruining the result.
97
98 <% for (1 .. 3) { %>
99 <%= $foo =%>
100 <% } %>
101
102 Comment tags and lines are very useful to deactivate code for debugging
103 purposes.
104
105 % my $foo = 'lalala';
106 <%# if ($foo) { %>
107 <%= $foo =%>
108 <%# } %>
109
110 Stash values that don't have invalid characters in their name get
111 automatically initialized as normal variables in the template and the
112 controller instance as $self.
113
114 $r->route('/foo/:name')
115 ->to(controller => 'foo', action => 'bar', name => 'tester');
116
117 Hello <%= $name %>.
118
119 There are also many built in helper functions such as "url_for", which
120 allows you to generate the URL of a specific route just from its name.
121
122 $r->route('/foo/:name')->to('foo#bar')->name('some_route');
123
124 <%= url_for 'some_route' %>
125
127 Most commonly used features every Mojolicious developer should know
128 about.
129
130 Automatic Rendering
131 The renderer can be manually started by calling the "render" controller
132 method, but thats usually not necessary, because it will get
133 automatically called if nothing has been rendered after the routes
134 dispatcher finished its work. This also means you can have routes
135 pointing only to templates without actual actions.
136
137 $self->render;
138
139 There is one big difference though, by calling "render" manually you
140 can make sure that templates use the current controller instance and
141 not the default controller specified in the "controller_class"
142 attribute of the application class.
143
144 Rendering Templates ("template")
145 The renderer will always try to detect the right template but you can
146 also use the "template" stash value to render a specific one.
147
148 $self->render(template => 'foo');
149
150 Choosing a specific "format" and "handler" is just as easy.
151
152 $self->render(template => 'foo', format => 'txt', handler => 'epl');
153
154 Because rendering a specific template is the most common task it also
155 has a shortcut.
156
157 $self->render('foo');
158
159 All values passed to the "render" call are only temporarily assigned to
160 the stash and get reset again once rendering is finished.
161
162 Rendering Text ("text")
163 Plain text can be rendered with the "text" stash value, characters get
164 automatically encoded to bytes.
165
166 $self->render(text => 'Hello Woerld!');
167
168 Rendering Data ("data")
169 Raw bytes can be rendered with the "data" stash value, no encoding will
170 be performed.
171
172 $self->render(data => $octets);
173
174 Rendering JSON ("json")
175 The "json" stash value allows you to pass Perl structures to the
176 renderer which get directly encoded to JSON.
177
178 $self->render(json => {foo => [1, 'test', 3]});
179
180 Partial Rendering ("partial")
181 Sometimes you might want to access the rendered result, for example to
182 generate emails, this can be done using the "partial" stash value.
183
184 my $html = $self->render('mail', partial => 1);
185
186 Status Code ("status")
187 Response status codes can be changed with the "status" stash value.
188
189 $self->render(text => 'Oops!', status => 500);
190
191 Content Type ("format")
192 The "Content-Type" header of the response is actually based on the MIME
193 type mapping of the "format" stash value.
194
195 $self->render(text => 'Hello!', format => 'txt');
196
197 These mappings can be easily extended or changed.
198
199 # Application
200 package MyApp;
201 use base 'Mojolicious';
202
203 sub startup {
204 my $self = shift;
205
206 # Add new MIME type
207 $self->types->type(txt => 'text/plain; charset=utf-8');
208 }
209
210 1;
211
212 Helpers
213 Helpers are little functions that are stored in the renderer, not all
214 of them are strictly template specific, thats why you can also use the
215 "helper" controller method to call them.
216
217 <%= dumper [1, 2, 3] %>
218
219 my $serialized = $self->helper(dumper => [1, 2, 3]);
220
221 The "dumper" helper will use Data::Dumper to serialize whatever data
222 structure you pass it, this can be very useful for debugging. We
223 differentiate between "default helpers" which are more general purpose
224 like "dumper" and "tag helpers", which are template specific and mostly
225 used to generate "HTML" tags.
226
227 <%= script '/script.js' %>
228
229 <%= script {%>
230 var a = 'b';
231 <%}%>
232
233 The plugins Mojolicious::Plugin::DefaultHelpers and
234 Mojolicious::Plugin::TagHelpers contain all of them.
235
236 Layouts
237 Most of the time when using "ep" templates you will want to wrap your
238 generated content in a HTML skeleton, thanks to layouts thats
239 absolutely trivial.
240
241 @@ foo/bar.html.ep
242 % layout 'mylayout';
243 Hello World!
244
245 @@ layouts/mylayout.html.ep
246 <!doctype html><html>
247 <head><title>MyApp!</title></head>
248 <body><%= content %></body>
249 </html>
250
251 You just select the right layout template with the "layout" helper and
252 place the result of the current template with the "content" helper.
253 You can also pass along normal stash values to the "layout" helper.
254
255 @@ foo/bar.html.ep
256 % layout 'mylayout', title => 'Hi there!';
257 Hello World!
258
259 @@ layouts/mylayout.html.ep
260 <!doctype html><html>
261 <head><title><%= $title %></title></head>
262 <body><%= content %></body>
263 </html>
264
265 Including Partial Templates
266 Like most helpers the "include" helper is just a shortcut to make your
267 life a little easier.
268
269 @@ foo/bar.html.ep
270 <!doctype html><html>
271 <%= include 'header' %>
272 <body>Bar!</body>
273 </html>
274
275 @@ header.html.ep
276 <head><title>Howdy!</title></head>
277
278 Instead of "include" you could also just call "render" with the
279 "partial" argument.
280
281 @@ foo/bar.html.ep
282 <!doctype html><html>
283 <%= $self->render('header', partial => 1) %>
284 <body>Bar!</body>
285 </html>
286
287 @@ header.html.ep
288 <head><title>Howdy!</title></head>
289
290 Of course you can also pass stash values.
291
292 @@ foo/bar.html.ep
293 <!doctype html><html>
294 <%= include 'header', title => 'Hello!' %>
295 <body>Bar!</body>
296 </html>
297
298 @@ header.html.ep
299 <head><title><%= $title %></title></head>
300
301 Reusable Template Blocks
302 It's never fun to repeat yourself, thats why you can build reusable
303 template blocks in "ep" that work very similar normal Perl functions.
304
305 <% my $block = {%>
306 <% my $name = shift; %>
307 Hello <%= $name %>.
308 <%}%>
309 <%= $block->('Sebastian') %>
310 <%= $block->('Sara') %>
311
312 Blocks start with an opening bracket in the first tag and end with a
313 mini tag containing only the closing bracket. Whitespace characters
314 between bracket and tag are not allowed, to differentiate between
315 template blocks and normal Perl code.
316
317 <% my $block = {%>
318 <% my $name = shift; %>
319 Hello <%= $name %>.
320 <%}%>
321 <% for (1 .. 10) { %>
322 <%= $block->('Sebastian') %>
323 <% } %>
324
325 A naive translation to equivalent Perl code could look like this.
326
327 my $output = '';
328 my $block = sub {
329 my $name = shift;
330 my $output = '';
331 $output .= "Hello $name.";
332 return $output;
333 }
334 for (1 .. 10) {
335 $output .= $block->('Sebastian');
336 }
337 print $output;
338
339 Content Blocks
340 Blocks and the "content" helper can also be used to pass whole sections
341 of the template to the layout.
342
343 @@ foo/bar.html.ep
344 % layout 'mylayout';
345 <% content header => {%>
346 <title>MyApp!</title>
347 <%}%>
348 Hello World!
349
350 @@ layouts/mylayout.html.ep
351 <!doctype html><html>
352 <head><%= content 'header' %></head>
353 <body><%= content %></body>
354 </html>
355
356 Template Inheritance
357 Inheritance takes the layout concept above one step further, allowing
358 you to use the "content" helper to overload whole template sections of
359 normal templates. The difference between the "layout" and the
360 "extends" helper is that extended templates don't get prefixed with
361 "layout/".
362
363 @@ first.html.ep
364 %# "<div>First header!First footer!</div>"
365 <div>
366 <%= content header => {%>
367 First header!
368 <%}%>
369 <%= content footer => {%>
370 First footer!
371 <%}%>
372 </div>
373
374 @@ second.html.ep
375 %# "<div>Second header!First footer!</div>"
376 % extends 'first';
377 <% content header => {%>
378 Second header!
379 <%}%>
380
381 @@ third.html.ep
382 %# "<div>Second header!Third footer!</div>"
383 % extends 'second';
384 <% content footer => {%>
385 Third footer!
386 <%}%>
387
388 This chain could go on and on to allow a very high level of template
389 reuse.
390
392 Less commonly used and more powerful features.
393
394 Encoding
395 Templates stored in files are expected to be "UTF-8" by default, but
396 that can be easily changed.
397
398 # Application
399 package MyApp;
400 use base 'Mojolicious';
401
402 sub startup {
403 my $self = shift;
404
405 # Different encoding
406 $self->renderer->encoding('koi8-r');
407 }
408
409 1;
410
411 All templates from the DATA section are bound to the encoding of the
412 Perl script, so don't forget to use the utf8 pragma if necessary.
413
414 Inflating DATA Templates
415 Templates stored in files get preferred over files from the "DATA"
416 section, this allows you to include a default set of templates in your
417 application that the user can later customize. The "inflate" command
418 will write all templates from the "DATA" section into actual files in
419 the "templates" directory.
420
421 % ./myapp.pl inflate
422 ...
423
424 Customizing The Template Syntax
425 You can easily change the whole template syntax by loading the
426 "ep_renderer" plugin with a custom configuration.
427
428 use Mojolicious::Lite;
429
430 plugin ep_renderer => {
431 name => 'mustache',
432 template => {
433 tag_start => '{{',
434 tag_end => '}}'
435 }
436 };
437
438 get '/' => 'index';
439
440 app->start;
441 __DATA__
442
443 @@ index.html.mustache
444 Hello {{= $name }}.
445
446 Mojo::Template contains the whole list of available options.
447
448 Adding Helpers
449 Adding and redefining helpers is very easy, you can use them to do
450 pretty much everything.
451
452 use Mojolicious::Lite;
453
454 app->renderer->add_helper(
455 echo => sub {
456 my ($self, $string) = @_;
457 return "ECHO: $string";
458 }
459 );
460
461 get '/' => 'index';
462
463 app->start;
464 __DATA__
465
466 @@ index.html.ep
467 <%= echo 'lalala' %>
468
469 Adding Your Favorite Template System
470 Maybe you would prefer a different template system than "ep", all you
471 have to do is add a new "handler".
472
473 use Mojolicious::Lite;
474
475 app->renderer->add_handler(
476 mine => sub {
477 my ($r, $c, $output, $options) = @_;
478
479 # Generate relative template path
480 my $name = $r->template_name($options);
481
482 # Try to find approprite template in DATA section
483 my $content = $r->get_inline_template($options, $name);
484
485 # Generate absolute template path
486 my $path = $r->template_path($options);
487
488 # This part is up to you and your template system :)
489 ...
490
491 # Pass the rendered result back to the renderer
492 $$output = 'The rendered result!';
493 }
494 );
495
496 get '/' => 'index';
497
498 app->start;
499 __DATA__
500
501 @@ index.html.mine
502 ...
503
504 Since most template systems don't support temlates in the "DATA"
505 section the renderer provides methods to help you with that.
506
507
508
509perl v5.12.3 2010-08-12 Mojolicious::Guides::Rendering(3)