1Mojolicious::Guides::ReUnsdeerriCnogn(t3r)ibuted Perl DoMcoujmoelnitcaitoiuosn::Guides::Rendering(3)
2
3
4

NAME

6       Mojolicious::Guides::Rendering - Rendering content
7

OVERVIEW

9       This document explains content generation with the Mojolicious
10       renderer.
11

CONCEPTS

13       Essentials every Mojolicious developer should know.
14
15   Renderer
16       The renderer is a tiny black box turning stash data into actual
17       responses utilizing multiple template systems and data encoding
18       modules.
19
20         {text => 'Hello.'}                 -> 200 OK, text/html, 'Hello.'
21         {json => {x => 3}}                 -> 200 OK, application/json, '{"x":3}'
22         {text => 'Oops.', status => '410'} -> 410 Gone, text/html, 'Oops.'
23
24       Templates can be automatically detected if enough information is
25       provided by the developer or routes. Template names are expected to
26       follow the "template.format.handler" scheme, with "template" defaulting
27       to "controller/action" or the route name, "format" defaulting to "html"
28       and "handler" to "ep".
29
30         {controller => 'users', action => 'list'} -> 'users/list.html.ep'
31         {template => 'foo', format => 'txt'}      -> 'foo.txt.ep'
32         {template => 'foo', handler => 'epl'}     -> 'foo.html.epl'
33
34       The "controller" value gets converted from "CamelCase" to "snake_case"
35       using "decamelize" in Mojo::Util and "-" characters replaced with "/".
36
37         {controller => 'My::Users', action => 'add'} -> 'my/users/add.html.ep'
38         {controller => 'my-users', action => 'show'} -> 'my/users/show.html.ep'
39
40       All templates should be in the "templates" directories of the
41       application, which can be customized with "paths" in
42       Mojolicious::Renderer, or one of the the "DATA" sections from "classes"
43       in Mojolicious::Renderer.
44
45         __DATA__
46
47         @@ time.html.ep
48         % use Time::Piece;
49         % my $now = localtime;
50         <!DOCTYPE html>
51         <html>
52           <head><title>Time</title></head>
53           <body>The time is <%= $now->hms %>.</body>
54         </html>
55
56         @@ hello.txt.ep
57         ...
58
59       The renderer can be easily extended to support additional template
60       systems with plugins, but more about that later.
61
62   Embedded Perl
63       Mojolicious includes a minimalistic but very powerful template system
64       out of the box called Embedded Perl or "ep" for short. It is based on
65       Mojo::Template and allows the embedding of Perl code right into actual
66       content using a small set of special tags and line start characters.
67       For all templates strict, warnings, utf8 and Perl 5.10 features are
68       automatically enabled.
69
70         <% Perl code %>
71         <%= Perl expression, replaced with XML escaped result %>
72         <%== Perl expression, replaced with result %>
73         <%# Comment, useful for debugging %>
74         <%% Replaced with "<%", useful for generating templates %>
75         % Perl code line, treated as "<% line =%>" (explained later)
76         %= Perl expression line, treated as "<%= line %>"
77         %== Perl expression line, treated as "<%== line %>"
78         %# Comment line, useful for debugging
79         %% Replaced with "%", useful for generating templates
80
81       Tags and lines work pretty much the same, but depending on context one
82       will usually look a bit better. Semicolons get automatically appended
83       to all expressions.
84
85         <% my $i = 10; %>
86         <ul>
87           <% for my $j (1 .. $i) { %>
88             <li>
89               <%= $j %>
90             </li>
91           <% } %>
92         </ul>
93
94         % my $i = 10;
95         <ul>
96           % for my $j (1 .. $i) {
97             <li>
98               %= $j
99             </li>
100           % }
101         </ul>
102
103       Aside from differences in whitespace handling, both examples generate
104       similar Perl code, a naive translation could look like this.
105
106         my $output = '';
107         my $i = 10;
108         $output .= '<ul>';
109         for my $j (1 .. $i) {
110           $output .= '<li>';
111           $output .= xml_escape scalar + $j;
112           $output .= '</li>';
113         }
114         $output .= '</ul>';
115         return $output;
116
117       An additional equal sign can be used to disable escaping of the
118       characters "<", ">", "&", "'" and """ in results from Perl expressions,
119       which is the default to prevent XSS attacks against your application.
120
121         <%= 'I ♥ Mojolicious!' %>
122         <%== '<p>I ♥ Mojolicious!</p>' %>
123
124       Only Mojo::ByteStream objects are excluded from automatic escaping.
125
126         <%= b('<p>I ♥ Mojolicious!</p>') %>
127
128       Whitespace characters around tags can be trimmed by adding an
129       additional equal sign to the end of a tag.
130
131         <% for (1 .. 3) { %>
132           <%= 'Trim all whitespace characters around this expression' =%>
133         <% } %>
134
135       Newline characters can be escaped with a backslash.
136
137         This is <%= 1 + 1 %> a\
138         single line
139
140       And a backslash in front of a newline character can be escaped with
141       another backslash.
142
143         This will <%= 1 + 1 %> result\\
144         in multiple\\
145         lines
146
147       A newline character gets appended automatically to every template,
148       unless the last character is a backslash. And empty lines at the end of
149       a template are ignored.
150
151         There is <%= 1 + 1 %> no newline at the end here\
152
153       At the beginning of the template, stash values that don't have invalid
154       characters in their name get automatically initialized as normal
155       variables, and the controller object as both $self and $c.
156
157         $c->stash(name => 'tester');
158
159         Hello <%= $name %> from <%= $c->tx->remote_address %>.
160
161       A prefix like "myapp.*" is commonly used for stash values that you
162       don't want to expose in templates.
163
164         $c->stash('myapp.name' => 'tester');
165
166       There are also many helper functions available, but more about that
167       later.
168
169         <%= dumper {foo => 'bar'} %>
170

BASICS

172       Most commonly used features every Mojolicious developer should know
173       about.
174
175   Automatic rendering
176       The renderer can be manually started by calling the method "render" in
177       Mojolicious::Controller, but that's usually not necessary, because it
178       will get automatically called if nothing has been rendered after the
179       router finished its work. This also means you can have routes pointing
180       only to templates without actual actions.
181
182         $c->render;
183
184       There is one big difference though, by calling it manually you can make
185       sure that templates use the current controller object, and not the
186       default controller specified with the attribute "controller_class" in
187       Mojolicious.
188
189         $c->render_later;
190
191       You can also disable automatic rendering with the method "render_later"
192       in Mojolicious::Controller, which can be very useful to delay rendering
193       when a non-blocking operation has to be performed first.
194
195   Rendering templates
196       The renderer will always try to detect the right template, but you can
197       also use the "template" stash value to render a specific one.
198       Everything before the last slash will be interpreted as the
199       subdirectory path in which to find the template.
200
201         # foo/bar/baz.*.*
202         $c->render(template => 'foo/bar/baz');
203
204       Choosing a specific "format" and "handler" is just as easy.
205
206         # foo/bar/baz.txt.epl
207         $c->render(template => 'foo/bar/baz', format => 'txt', handler => 'epl');
208
209       Because rendering a specific template is the most common task it also
210       has a shortcut.
211
212         $c->render('foo/bar/baz');
213
214       If you're not sure in advance if a template actually exists, you can
215       also use the method "render_maybe" in Mojolicious::Controller to try
216       multiple alternatives.
217
218         $c->render_maybe('localized/baz') or $c->render('foo/bar/baz');
219
220   Rendering to strings
221       Sometimes you might want to use the rendered result directly instead of
222       generating a response, for example, to send emails, this can be done
223       with "render_to_string" in Mojolicious::Controller.
224
225         my $html = $c->render_to_string('mail');
226
227       No encoding will be performed, making it easy to reuse the result in
228       other templates or to generate binary data.
229
230         my $pdf = $c->render_to_string('invoice', format => 'pdf');
231         $c->render(data => $pdf, format => 'pdf');
232
233       All arguments passed will get localized automatically and are only
234       available during this render operation.
235
236   Template variants
237       To make your application look great on many different devices you can
238       also use the "variant" stash value to choose between different variants
239       of your templates.
240
241         # foo/bar/baz.html+phone.ep
242         # foo/bar/baz.html.ep
243         $c->render('foo/bar/baz', variant => 'phone');
244
245       This can be done very liberally since it only applies when a template
246       with the correct name actually exists and falls back to the generic one
247       otherwise.
248
249   Rendering inline templates
250       Some renderers such as "ep" allow templates to be passed "inline".
251
252         $c->render(inline => 'The result is <%= 1 + 1 %>.');
253
254       Since auto-detection depends on a path you might have to supply a
255       "handler" too.
256
257         $c->render(inline => "<%= shift->param('foo') %>", handler => 'epl');
258
259   Rendering text
260       Characters can be rendered to bytes with the "text" stash value, the
261       given content will be automatically encoded with "encoding" in
262       Mojolicious::Renderer.
263
264         $c->render(text => 'I ♥ Mojolicious!');
265
266   Rendering data
267       Bytes can be rendered with the "data" stash value, no encoding will be
268       performed.
269
270         $c->render(data => $bytes);
271
272   Rendering JSON
273       The "json" stash value allows you to pass Perl data structures to the
274       renderer which get directly encoded to JSON with Mojo::JSON.
275
276         $c->render(json => {foo => [1, 'test', 3]});
277
278   Status code
279       Response status codes can be changed with the "status" stash value.
280
281         $c->render(text => 'Oops.', status => 500);
282
283   Content type
284       The "Content-Type" header of the response is actually based on the MIME
285       type mapping of the "format" stash value.
286
287         # Content-Type: text/plain
288         $c->render(text => 'Hello.', format => 'txt');
289
290         # Content-Type: image/png
291         $c->render(data => $bytes, format => 'png');
292
293       These mappings can be easily extended or changed with "types" in
294       Mojolicious.
295
296         # Add new MIME type
297         $app->types->type(md => 'text/markdown');
298
299   Stash data
300       Any of the native Perl data types can be passed to templates as
301       references through the "stash" in Mojolicious::Controller.
302
303         $c->stash(description => 'web framework');
304         $c->stash(frameworks  => ['Catalyst', 'Mojolicious']);
305         $c->stash(spinoffs    => {minion => 'job queue'});
306
307         %= $description
308         %= $frameworks->[1]
309         %= $spinoffs->{minion}
310
311       Since everything is just Perl normal control structures just work.
312
313         % for my $framework (@$frameworks) {
314           <%= $framework %> is a <%= $description %>.
315         % }
316
317         % if (my $description = $spinoffs->{minion}) {
318           Minion is a <%= $description %>.
319         % }
320
321       For templates that might get rendered in different ways and where
322       you're not sure if a stash value will actually be set, you can just use
323       the helper "stash" in Mojolicious::Plugin::DefaultHelpers.
324
325         % if (my $spinoffs = stash 'spinoffs') {
326           Minion is a <%= $spinoffs->{minion} %>.
327         % }
328
329   Helpers
330       Helpers are little functions you can use in templates as well as
331       application and controller code.
332
333         # Template
334         %= dumper [1, 2, 3]
335
336         # Application
337         my $serialized = $app->dumper([1, 2, 3]);
338
339         # Controller
340         my $serialized = $c->dumper([1, 2, 3]);
341
342       We differentiate between default helpers, which are more general
343       purpose like "dumper" in Mojolicious::Plugin::DefaultHelpers, and tag
344       helpers like "link_to" in Mojolicious::Plugin::TagHelpers, which are
345       template specific and mostly used to generate HTML tags.
346
347         %= link_to Mojolicious => 'https://mojolicious.org'
348
349       In controllers you can also use the method "helpers" in
350       Mojolicious::Controller to fully qualify helper calls and ensure that
351       they don't conflict with existing methods you may already have.
352
353         my $serialized = $c->helpers->dumper([1, 2, 3]);
354
355       A list of all built-in helpers can be found in
356       Mojolicious::Plugin::DefaultHelpers and
357       Mojolicious::Plugin::TagHelpers.
358
359   Content negotiation
360       For resources with different representations and that require truly
361       RESTful content negotiation you can also use "respond_to" in
362       Mojolicious::Plugin::DefaultHelpers instead of "render" in
363       Mojolicious::Controller.
364
365         # /hello (Accept: application/json) -> "json"
366         # /hello (Accept: application/xml)  -> "xml"
367         # /hello.json                       -> "json"
368         # /hello.xml                        -> "xml"
369         # /hello?format=json                -> "json"
370         # /hello?format=xml                 -> "xml"
371         $c->respond_to(
372           json => {json => {hello => 'world'}},
373           xml  => {text => '<hello>world</hello>'}
374         );
375
376       The best possible representation will be automatically selected from
377       the "format" "GET"/"POST" parameter, "format" stash value or "Accept"
378       request header and stored in the "format" stash value. To change MIME
379       type mappings for the "Accept" request header or the "Content-Type"
380       response header you can use "types" in Mojolicious.
381
382         $c->respond_to(
383           json => {json => {hello => 'world'}},
384           html => sub {
385             $c->content_for(head => '<meta name="author" content="sri">');
386             $c->render(template => 'hello', message => 'world')
387           }
388         );
389
390       Callbacks can be used for representations that are too complex to fit
391       into a single render call.
392
393         # /hello (Accept: application/json) -> "json"
394         # /hello (Accept: text/html)        -> "html"
395         # /hello (Accept: image/png)        -> "any"
396         # /hello.json                       -> "json"
397         # /hello.html                       -> "html"
398         # /hello.png                        -> "any"
399         # /hello?format=json                -> "json"
400         # /hello?format=html                -> "html"
401         # /hello?format=png                 -> "any"
402         $c->respond_to(
403           json => {json => {hello => 'world'}},
404           html => {template => 'hello', message => 'world'},
405           any  => {text => '', status => 204}
406         );
407
408       And if no viable representation could be found, the "any" fallback will
409       be used or an empty 204 response rendered automatically.
410
411         # /hello                      -> "html"
412         # /hello (Accept: text/html)  -> "html"
413         # /hello (Accept: text/xml)   -> "xml"
414         # /hello (Accept: text/plain) -> undef
415         # /hello.html                 -> "html"
416         # /hello.xml                  -> "xml"
417         # /hello.txt                  -> undef
418         # /hello?format=html          -> "html"
419         # /hello?format=xml           -> "xml"
420         # /hello?format=txt           -> undef
421         if (my $format = $c->accepts('html', 'xml')) {
422           ...
423         }
424
425       For even more advanced negotiation logic you can also use the helper
426       "accepts" in Mojolicious::Plugin::DefaultHelpers.
427
428   Rendering "exception" and "not_found" pages
429       By now you've probably already encountered the built-in 404 (Not Found)
430       and 500 (Server Error) pages, that get rendered automatically when you
431       make a mistake. Those are fallbacks for when your own exception
432       handling fails, which can be especially helpful during development. You
433       can also render them manually with the helpers "reply->exception" in
434       Mojolicious::Plugin::DefaultHelpers and "reply->not_found" in
435       Mojolicious::Plugin::DefaultHelpers.
436
437         use Mojolicious::Lite;
438         use Scalar::Util 'looks_like_number';
439
440         get '/divide/:dividend/by/:divisor' => sub {
441           my $c = shift;
442
443           my $dividend = $c->param('dividend');
444           my $divisor  = $c->param('divisor');
445
446           # 404
447           return $c->reply->not_found
448             unless looks_like_number $dividend && looks_like_number $divisor;
449
450           # 500
451           return $c->reply->exception('Division by zero!') if $divisor == 0;
452
453           # 200
454           $c->render(text => $dividend / $divisor);
455         };
456
457         app->start;
458
459       You can also change the templates of those pages, since you most likely
460       want to show your users something more closely related to your
461       application in production. The renderer will always try to find
462       "exception.$mode.$format.*"  or "not_found.$mode.$format.*" before
463       falling back to the built-in default templates.
464
465         use Mojolicious::Lite;
466
467         get '/dies' => sub { die 'Intentional error' };
468
469         app->start;
470         __DATA__
471
472         @@ exception.production.html.ep
473         <!DOCTYPE html>
474         <html>
475           <head><title>Server error</title></head>
476           <body>
477             <h1>Exception</h1>
478             <p><%= $exception->message %></p>
479             <h1>Stash</h1>
480             <pre><%= dumper $snapshot %></pre>
481           </body>
482         </html>
483
484       The hook "before_render" in Mojolicious makes even more advanced
485       customizations possible by allowing you to intercept and modify the
486       arguments passed to the renderer.
487
488         use Mojolicious::Lite;
489
490         hook before_render => sub {
491           my ($c, $args) = @_;
492
493           # Make sure we are rendering the exception template
494           return unless my $template = $args->{template};
495           return unless $template eq 'exception';
496
497           # Switch to JSON rendering if content negotiation allows it
498           return unless $c->accepts('json');
499           $args->{json} = {exception => $c->stash('exception')};
500         };
501
502         get '/' => sub { die "This sho...ALL GLORY TO THE HYPNOTOAD!\n" };
503
504         app->start;
505
506   Layouts
507       Most of the time when using "ep" templates you will want to wrap your
508       generated content in an HTML skeleton, thanks to layouts that's
509       absolutely trivial.
510
511         use Mojolicious::Lite;
512
513         get '/' => {template => 'foo/bar'};
514
515         app->start;
516         __DATA__
517
518         @@ foo/bar.html.ep
519         % layout 'mylayout';
520         Hello World!
521
522         @@ layouts/mylayout.html.ep
523         <!DOCTYPE html>
524         <html>
525           <head><title>MyApp</title></head>
526           <body><%= content %></body>
527         </html>
528
529       You just select the right layout template with the helper "layout" in
530       Mojolicious::Plugin::DefaultHelpers and place the result of the current
531       template with the helper "content" in
532       Mojolicious::Plugin::DefaultHelpers. You can also pass along normal
533       stash values to the "layout" helper.
534
535         use Mojolicious::Lite;
536
537         get '/' => {template => 'foo/bar'};
538
539         app->start;
540         __DATA__
541
542         @@ foo/bar.html.ep
543         % layout 'mylayout', title => 'Hi there';
544         Hello World!
545
546         @@ layouts/mylayout.html.ep
547         <!DOCTYPE html>
548         <html>
549           <head><title><%= $title %></title></head>
550           <body><%= content %></body>
551         </html>
552
553       Instead of the "layout" helper you could also just use the "layout"
554       stash value, or call "render" in Mojolicious::Controller with the
555       "layout" argument.
556
557         $c->render(template => 'mytemplate', layout => 'mylayout');
558
559       To set a "layout" stash value application-wide you can use "defaults"
560       in Mojolicious.
561
562         $app->defaults(layout => 'mylayout');
563
564       Layouts can also be used with "render_to_string" in
565       Mojolicious::Controller, but the "layout" value needs to be passed as a
566       render argument (not a stash value).
567
568         my $html = $c->render_to_string('reminder', layout => 'mail');
569
570   Partial templates
571       You can break up bigger templates into smaller, more manageable chunks.
572       These partial templates can also be shared with other templates. Just
573       use the helper "include" in Mojolicious::Plugin::DefaultHelpers to
574       include one template into another.
575
576         use Mojolicious::Lite;
577
578         get '/' => {template => 'foo/bar'};
579
580         app->start;
581         __DATA__
582
583         @@ foo/bar.html.ep
584         <!DOCTYPE html>
585         <html>
586           %= include '_header', title => 'Howdy'
587           <body>Bar</body>
588         </html>
589
590         @@ _header.html.ep
591         <head><title><%= $title %></title></head>
592
593       You can name partial templates however you like, but a leading
594       underscore is a commonly used naming convention.
595
596   Reusable template blocks
597       It's never fun to repeat yourself, that's why you can build reusable
598       template blocks in "ep" that work very similar to normal Perl
599       functions, with the "begin" and "end" keywords. Just be aware that both
600       keywords are part of the surrounding tag and not actual Perl code, so
601       there can only be whitespace after "begin" and before "end".
602
603         use Mojolicious::Lite;
604
605         get '/' => 'welcome';
606
607         app->start;
608         __DATA__
609
610         @@ welcome.html.ep
611         <% my $block = begin %>
612           % my $name = shift;
613           Hello <%= $name %>.
614         <% end %>
615         <%= $block->('Wolfgang') %>
616         <%= $block->('Baerbel') %>
617
618       A naive translation of the template to Perl code could look like this.
619
620         my $output = '';
621         my $block  = sub {
622           my $name   = shift;
623           my $output = '';
624           $output .= 'Hello ';
625           $output .= xml_escape scalar + $name;
626           $output .= '.';
627           return Mojo::ByteStream->new($output);
628         };
629         $output .= xml_escape scalar + $block->('Wolfgang');
630         $output .= xml_escape scalar + $block->('Baerbel');
631         return $output;
632
633       While template blocks cannot be shared between templates, they are most
634       commonly used to pass parts of a template to helpers.
635
636   Adding helpers
637       You should always try to keep your actions small and reuse as much code
638       as possible. Helpers make this very easy, they get passed the current
639       controller object as first argument, and you can use them to do pretty
640       much anything an action could do.
641
642         use Mojolicious::Lite;
643
644         helper debug => sub {
645           my ($c, $str) = @_;
646           $c->app->log->debug($str);
647         };
648
649         get '/' => sub {
650           my $c = shift;
651           $c->debug('Hello from an action!');
652         } => 'index';
653
654         app->start;
655         __DATA__
656
657         @@ index.html.ep
658         % debug 'Hello from a template!';
659
660       Helpers can also accept template blocks as last argument, this for
661       example, allows very pleasant to use tag helpers and filters. Wrapping
662       the helper result into a Mojo::ByteStream object can prevent accidental
663       double escaping.
664
665         use Mojolicious::Lite;
666         use Mojo::ByteStream;
667
668         helper trim_newline => sub {
669           my ($c, $block) = @_;
670           my $result = $block->();
671           $result =~ s/\n//g;
672           return Mojo::ByteStream->new($result);
673         };
674
675         get '/' => 'index';
676
677         app->start;
678         __DATA__
679
680         @@ index.html.ep
681         %= trim_newline begin
682           Some text.
683           %= 1 + 1
684           More text.
685         % end
686
687       Similar to stash values, you can use a prefix like "myapp.*" to keep
688       helpers from getting exposed in templates as functions, and to organize
689       them into namespaces as your application grows. Every prefix
690       automatically becomes a helper that returns a proxy object containing
691       the current controller object and on which you can call the nested
692       helpers.
693
694         use Mojolicious::Lite;
695
696         helper 'cache_control.no_caching' => sub {
697           my $c = shift;
698           $c->res->headers->cache_control('private, max-age=0, no-cache');
699         };
700
701         helper 'cache_control.five_minutes' => sub {
702           my $c = shift;
703           $c->res->headers->cache_control('public, max-age=300');
704         };
705
706         get '/news' => sub {
707           my $c = shift;
708           $c->cache_control->no_caching;
709           $c->render(text => 'Always up to date.');
710         };
711
712         get '/some_older_story' => sub {
713           my $c = shift;
714           $c->cache_control->five_minutes;
715           $c->render(text => 'This one can be cached for a bit.');
716         };
717
718         app->start;
719
720       While helpers can also be redefined, this should only be done very
721       carefully to avoid conflicts.
722
723   Content blocks
724       The helper "content_for" in Mojolicious::Plugin::DefaultHelpers allows
725       you to pass whole blocks of content from one template to another. This
726       can be very useful when your layout has distinct sections, such as
727       sidebars, where content should be inserted by the template.
728
729         use Mojolicious::Lite;
730
731         get '/' => 'foo';
732
733         app->start;
734         __DATA__
735
736         @@ foo.html.ep
737         % layout 'mylayout';
738         % content_for header => begin
739           <meta http-equiv="Content-Type" content="text/html">
740         % end
741         <div>Hello World!</div>
742         % content_for header => begin
743           <meta http-equiv="Pragma" content="no-cache">
744         % end
745
746         @@ layouts/mylayout.html.ep
747         <!DOCTYPE html>
748         <html>
749           <head><%= content 'header' %></head>
750           <body><%= content %></body>
751         </html>
752
753   Forms
754       To build HTML forms more efficiently you can use tag helpers like
755       "form_for" in Mojolicious::Plugin::TagHelpers, which can automatically
756       select a request method for you if a route name is provided. And since
757       most browsers only allow forms to be submitted with "GET" and "POST",
758       but not request methods like "PUT" or "DELETE", they are spoofed with
759       an "_method" query parameter.
760
761         use Mojolicious::Lite;
762
763         get '/' => 'form';
764
765         # PUT  /nothing
766         # POST /nothing?_method=PUT
767         put '/nothing' => sub {
768           my $c = shift;
769
770           # Prevent double form submission with redirect
771           my $value = $c->param('whatever');
772           $c->flash(confirmation => "We did nothing with your value ($value).");
773           $c->redirect_to('form');
774         };
775
776         app->start;
777         __DATA__
778
779         @@ form.html.ep
780         <!DOCTYPE html>
781         <html>
782           <body>
783             % if (my $confirmation = flash 'confirmation') {
784               <p><%= $confirmation %></p>
785             % }
786             %= form_for nothing => begin
787               %= text_field whatever => 'I ♥ Mojolicious!'
788               %= submit_button
789             % end
790           </body>
791         </html>
792
793       The helpers "flash" in Mojolicious::Plugin::DefaultHelpers and
794       "redirect_to" in Mojolicious::Plugin::DefaultHelpers are often used
795       together to prevent double form submission, allowing users to receive a
796       confirmation message that will vanish if they decide to reload the page
797       they've been redirected to.
798
799   Form validation
800       You can use "validation" in Mojolicious::Plugin::DefaultHelpers to
801       validate "GET" and "POST" parameters submitted to your application. All
802       unknown fields will be ignored by default, so you have to decide which
803       should be required or optional before you can perform checks on their
804       values. Every check is performed right away, so you can use the results
805       immediately to build more advanced validation logic with methods like
806       "is_valid" in Mojolicious::Validator::Validation.
807
808         use Mojolicious::Lite;
809
810         get '/' => sub {
811           my $c = shift;
812
813           # Check if parameters have been submitted
814           my $v = $c->validation;
815           return $c->render('index') unless $v->has_data;
816
817           # Validate parameters ("pass_again" depends on "pass")
818           $v->required('user')->size(1, 20)->like(qr/^[a-z0-9]+$/);
819           $v->required('pass_again')->equal_to('pass')
820             if $v->optional('pass')->size(7, 500)->is_valid;
821
822           # Check if validation failed
823           return $c->render('index') if $v->has_error;
824
825           # Render confirmation
826           $c->render('thanks');
827         };
828
829         app->start;
830         __DATA__
831
832         @@ index.html.ep
833         <!DOCTYPE html>
834         <html>
835           <head>
836             <style>
837               label.field-with-error { color: #dd7e5e }
838               input.field-with-error { background-color: #fd9e7e }
839             </style>
840           </head>
841           <body>
842             %= form_for index => begin
843               %= label_for user => 'Username (required, 1-20 characters, a-z/0-9)'
844               <br>
845               %= text_field 'user', id => 'user'
846               %= submit_button
847               <br>
848               %= label_for pass => 'Password (optional, 7-500 characters)'
849               <br>
850               %= password_field 'pass', id => 'pass'
851               <br>
852               %= label_for pass_again => 'Password again (equal to the value above)'
853               <br>
854               %= password_field 'pass_again', id => 'pass_again'
855             % end
856           </body>
857         </html>
858
859         @@ thanks.html.ep
860         <!DOCTYPE html>
861         <html><body>Thank you <%= validation->param('user') %>.</body></html>
862
863       Form elements generated with tag helpers from
864       Mojolicious::Plugin::TagHelpers will automatically remember their
865       previous values and add the class "field-with-error" for fields that
866       failed validation to make styling with CSS easier.
867
868         <label class="field-with-error" for="user">
869           Username (required, only characters e-t)
870         </label>
871         <input class="field-with-error" type="text" name="user" value="sri">
872
873       For a full list of available checks see also "CHECKS" in
874       Mojolicious::Validator.
875
876   Adding form validation checks
877       Validation checks can be registered with "add_check" in
878       Mojolicious::Validator and return a false value if they were
879       successful. A true value may be used to pass along additional
880       information which can then be retrieved with "error" in
881       Mojolicious::Validator::Validation.
882
883         use Mojolicious::Lite;
884
885         # Add "range" check
886         app->validator->add_check(range => sub {
887           my ($v, $name, $value, $min, $max) = @_;
888           return $value < $min || $value > $max;
889         });
890
891         get '/' => 'form';
892
893         post '/test' => sub {
894           my $c = shift;
895
896           # Validate parameters with custom check
897           my $v = $c->validation;
898           $v->required('number')->range(3, 23);
899
900           # Render form again if validation failed
901           return $c->render('form') if $v->has_error;
902
903           # Prevent double form submission with redirect
904           $c->flash(number => $v->param('number'));
905           $c->redirect_to('form');
906         };
907
908         app->start;
909         __DATA__
910
911         @@ form.html.ep
912         <!DOCTYPE html>
913         <html>
914           <body>
915             % if (my $number = flash 'number') {
916               <p>Thanks, the number <%= $number %> was valid.</p>
917             % }
918             %= form_for test => begin
919               % if (my $err = validation->error('number')) {
920                 <p>
921                   %= 'Value is required.' if $err->[0] eq 'required'
922                   %= 'Value needs to be between 3 and 23.' if $err->[0] eq 'range'
923                 </p>
924               % }
925               %= text_field 'number'
926               %= submit_button
927             % end
928           </body>
929         </html>
930
931   Cross-site request forgery
932       CSRF is a very common attack on web applications that trick your logged
933       in users to submit forms they did not intend to send, with something as
934       mundane as a link. All you have to do, to protect your users from this,
935       is to add an additional hidden field to your forms with "csrf_field" in
936       Mojolicious::Plugin::TagHelpers, and validate it with "csrf_protect" in
937       Mojolicious::Validator::Validation.
938
939         use Mojolicious::Lite;
940
941         get '/' => {template => 'target'};
942
943         post '/' => sub {
944           my $c = shift;
945
946           # Check CSRF token
947           my $v = $c->validation;
948           return $c->render(text => 'Bad CSRF token!', status => 403)
949             if $v->csrf_protect->has_error('csrf_token');
950
951           my $city = $v->required('city')->param('city');
952           $c->render(text => "Low orbit ion cannon pointed at $city!")
953             unless $v->has_error;
954         } => 'target';
955
956         app->start;
957         __DATA__
958
959         @@ target.html.ep
960         <!DOCTYPE html>
961         <html>
962           <body>
963             %= form_for target => begin
964               %= csrf_field
965               %= label_for city => 'Which city to point low orbit ion cannon at?'
966               %= text_field 'city', id => 'city'
967               %= submit_button
968             %= end
969           </body>
970         </html>
971
972       For Ajax requests and the like, you can also generate a token directly
973       with the helper "csrf_token" in Mojolicious::Plugin::DefaultHelpers,
974       and then pass it along with the "X-CSRF-Token" request header.
975

ADVANCED

977       Less commonly used and more powerful features.
978
979   Template inheritance
980       Inheritance takes the layout concept above one step further, the
981       helpers "content" in Mojolicious::Plugin::DefaultHelpers and "extends"
982       in Mojolicious::Plugin::DefaultHelpers allow you to build skeleton
983       templates with named blocks that child templates can override.
984
985         use Mojolicious::Lite;
986
987         # first > mylayout
988         get '/first' => {template => 'first', layout => 'mylayout'};
989
990         # third > second > first > mylayout
991         get '/third' => {template => 'third', layout => 'mylayout'};
992
993         app->start;
994         __DATA__
995
996         @@ layouts/mylayout.html.ep
997         <!DOCTYPE html>
998         <html>
999           <head><title>Hello</title></head>
1000           <body><%= content %></body>
1001         </html>
1002
1003         @@ first.html.ep
1004         %= content header => begin
1005           Default header
1006         % end
1007         <div>Hello World!</div>
1008         %= content footer => begin
1009           Default footer
1010         % end
1011
1012         @@ second.html.ep
1013         % extends 'first';
1014         % content header => begin
1015           New header
1016         % end
1017
1018         @@ third.html.ep
1019         % extends 'second';
1020         % content footer => begin
1021           New footer
1022         % end
1023
1024       This chain could go on and on to allow a very high level of template
1025       reuse.
1026
1027   Serving static files
1028       Static files are automatically served from the "public" directories of
1029       the application, which can be customized with "paths" in
1030       Mojolicious::Static, or one of the "DATA" sections from "classes" in
1031       Mojolicious::Static. And if that's not enough you can also serve them
1032       manually with "reply->static" in Mojolicious::Plugin::DefaultHelpers
1033       and "reply->file" in Mojolicious::Plugin::DefaultHelpers.
1034
1035         use Mojolicious::Lite;
1036
1037         get '/' => sub {
1038           my $c = shift;
1039           $c->reply->static('index.html');
1040         };
1041
1042         get '/some_download' => sub {
1043           my $c = shift;
1044           $c->res->headers->content_disposition('attachment; filename=bar.png;');
1045           $c->reply->static('foo/bar.png');
1046         };
1047
1048         get '/leak' => sub {
1049           my $c = shift;
1050           $c->reply->file('/etc/passwd');
1051         };
1052
1053         app->start;
1054
1055   Custom responses
1056       Most response content, static as well as dynamic, gets served through
1057       Mojo::Asset::File and Mojo::Asset::Memory objects. For somewhat static
1058       content, like cached JSON data or temporary files, you can create your
1059       own and use the helper "reply->asset" in
1060       Mojolicious::Plugin::DefaultHelpers to serve them while allowing
1061       content negotiation to be performed with "Range", "If-Modified-Since"
1062       and "If-None-Match" headers.
1063
1064         use Mojolicious::Lite;
1065         use Mojo::Asset::File;
1066
1067         get '/leak' => sub {
1068           my $c = shift;
1069           $c->res->headers->content_type('text/plain');
1070           $c->reply->asset(Mojo::Asset::File->new(path => '/etc/passwd'));
1071         };
1072
1073         app->start;
1074
1075       For even more control you can also just skip the helper and use
1076       "rendered" in Mojolicious::Controller to tell the renderer when you're
1077       done generating a response.
1078
1079         use Mojolicious::Lite;
1080         use Mojo::Asset::File;
1081
1082         get '/leak' => sub {
1083           my $c = shift;
1084           $c->res->headers->content_type('text/plain');
1085           $c->res->content->asset(Mojo::Asset::File->new(path => '/etc/passwd'));
1086           $c->rendered(200);
1087         };
1088
1089         app->start;
1090
1091   Helper plugins
1092       Some helpers might be useful enough for you to share them between
1093       multiple applications, plugins make that very simple.
1094
1095         package Mojolicious::Plugin::DebugHelper;
1096         use Mojo::Base 'Mojolicious::Plugin';
1097
1098         sub register {
1099           my ($self, $app) = @_;
1100           $app->helper(debug => sub {
1101             my ($c, $str) = @_;
1102             $c->app->log->debug($str);
1103           });
1104         }
1105
1106         1;
1107
1108       The "register" method will be called when you load the plugin. And to
1109       add your helper to the application, you can use "helper" in
1110       Mojolicious.
1111
1112         use Mojolicious::Lite;
1113
1114         plugin 'DebugHelper';
1115
1116         get '/' => sub {
1117           my $c = shift;
1118           $c->debug('It works!');
1119           $c->render(text => 'Hello!');
1120         };
1121
1122         app->start;
1123
1124       A skeleton for a full CPAN compatible plugin distribution can be
1125       automatically generated.
1126
1127         $ mojo generate plugin DebugHelper
1128
1129       And if you have a "PAUSE" account (which can be requested at
1130       <http://pause.perl.org>), you are only a few commands away from
1131       releasing it to CPAN.
1132
1133         $ perl Makefile.PL
1134         $ make test
1135         $ make manifest
1136         $ make dist
1137         $ mojo cpanify -u USER -p PASS Mojolicious-Plugin-DebugHelper-0.01.tar.gz
1138
1139   Bundling assets with plugins
1140       Assets such as templates and static files can be easily bundled with
1141       your plugins, even if you plan to release them to CPAN.
1142
1143         $ mojo generate plugin AlertAssets
1144         $ mkdir Mojolicious-Plugin-AlertAssets/lib/Mojolicious/Plugin/AlertAssets
1145         $ cd Mojolicious-Plugin-AlertAssets/lib/Mojolicious/Plugin/AlertAssets
1146         $ mkdir public
1147         $ echo 'alert("Hello World!");' > public/alertassets.js
1148         $ mkdir templates
1149         $ echo '%= javascript "/alertassets.js"' > templates/alertassets.html.ep
1150
1151       Just give them reasonably unique names, ideally based on the name of
1152       your plugin, and append their respective directories to the list of
1153       search paths when "register" is called.
1154
1155         package Mojolicious::Plugin::AlertAssets;
1156         use Mojo::Base 'Mojolicious::Plugin';
1157
1158         use Mojo::File 'curfile';
1159
1160         sub register {
1161           my ($self, $app) = @_;
1162
1163           # Append "templates" and "public" directories
1164           my $base = curfile->sibling('AlertAssets');
1165           push @{$app->renderer->paths}, $base->child('templates')->to_string;
1166           push @{$app->static->paths},   $base->child('public')->to_string;
1167         }
1168
1169         1;
1170
1171       Both will work just like normal "templates" and "public" directories
1172       once you've installed and loaded the plugin, with slightly lower
1173       precedence.
1174
1175         use Mojolicious::Lite;
1176
1177         plugin 'AlertAssets';
1178
1179         get '/alert_me';
1180
1181         app->start;
1182         __DATA__
1183
1184         @@ alert_me.html.ep
1185         <!DOCTYPE html>
1186         <html>
1187           <head>
1188             <title>Alert me!</title>
1189             %= include 'alertassets'
1190           </head>
1191           <body>You've been alerted.</body>
1192         </html>
1193
1194       And it works just the same for assets bundled in the "DATA" section of
1195       your plugin.
1196
1197         package Mojolicious::Plugin::AlertAssets;
1198         use Mojo::Base 'Mojolicious::Plugin';
1199
1200         sub register {
1201           my ($self, $app) = @_;
1202
1203           # Append class
1204           push @{$app->renderer->classes}, __PACKAGE__;
1205           push @{$app->static->classes},   __PACKAGE__;
1206         }
1207
1208         1;
1209         __DATA__
1210
1211         @@ alertassets.js
1212         alert("Hello World!");
1213
1214         @@ alertassets.html.ep
1215         %= javascript "/alertassets.js"
1216
1217   Post-processing dynamic content
1218       While post-processing tasks are generally very easy with the hook
1219       "after_dispatch" in Mojolicious, for content generated by the renderer
1220       it is a lot more efficient to use "after_render" in Mojolicious.
1221
1222         use Mojolicious::Lite;
1223         use IO::Compress::Gzip 'gzip';
1224
1225         hook after_render => sub {
1226           my ($c, $output, $format) = @_;
1227
1228           # Check if "gzip => 1" has been set in the stash
1229           return unless $c->stash->{gzip};
1230
1231           # Check if user agent accepts gzip compression
1232           return unless ($c->req->headers->accept_encoding // '') =~ /gzip/i;
1233           $c->res->headers->append(Vary => 'Accept-Encoding');
1234
1235           # Compress content with gzip
1236           $c->res->headers->content_encoding('gzip');
1237           gzip $output, \my $compressed;
1238           $$output = $compressed;
1239         };
1240
1241         get '/' => {template => 'hello', title => 'Hello', gzip => 1};
1242
1243         app->start;
1244         __DATA__
1245
1246         @@ hello.html.ep
1247         <!DOCTYPE html>
1248         <html>
1249           <head><title><%= title %></title></head>
1250           <body>Compressed content.</body>
1251         </html>
1252
1253       If you want to compress all dynamically generated content you can also
1254       activate "compress" in Mojolicious::Renderer.
1255
1256   Streaming
1257       You don't have to render all content at once, the method "write" in
1258       Mojolicious::Controller can also be used to stream a series of smaller
1259       chunks.
1260
1261         use Mojolicious::Lite;
1262
1263         get '/' => sub {
1264           my $c = shift;
1265
1266           # Prepare body
1267           my $body = 'Hello World!';
1268           $c->res->headers->content_length(length $body);
1269
1270           # Start writing directly with a drain callback
1271           my $drain;
1272           $drain = sub {
1273             my $c = shift;
1274             my $chunk = substr $body, 0, 1, '';
1275             $drain = undef unless length $body;
1276             $c->write($chunk, $drain);
1277           };
1278           $c->$drain;
1279         };
1280
1281         app->start;
1282
1283       The drain callback will be executed whenever the entire previous chunk
1284       of data has actually been written.
1285
1286         HTTP/1.1 200 OK
1287         Date: Sat, 13 Sep 2014 16:48:29 GMT
1288         Content-Length: 12
1289         Server: Mojolicious (Perl)
1290
1291         Hello World!
1292
1293       Instead of providing a "Content-Length" header you can also call
1294       "finish" in Mojolicious::Controller and close the connection manually
1295       once you are done.
1296
1297         use Mojolicious::Lite;
1298
1299         get '/' => sub {
1300           my $c = shift;
1301
1302           # Prepare body
1303           my $body = 'Hello World!';
1304
1305           # Start writing directly with a drain callback
1306           my $drain;
1307           $drain = sub {
1308             my $c = shift;
1309             my $chunk = substr $body, 0, 1, '';
1310             length $chunk ? $c->write($chunk, $drain) : $c->finish;
1311           };
1312           $c->$drain;
1313         };
1314
1315         app->start;
1316
1317       While this is rather inefficient, as it prevents keep-alive, it is
1318       sometimes necessary for EventSource and similar applications.
1319
1320         HTTP/1.1 200 OK
1321         Date: Sat, 13 Sep 2014 16:48:29 GMT
1322         Connection: close
1323         Server: Mojolicious (Perl)
1324
1325         Hello World!
1326
1327   Chunked transfer encoding
1328       For very dynamic content you might not know the response content length
1329       in advance, that's where the chunked transfer encoding and
1330       "write_chunk" in Mojolicious::Controller come in handy. A common use
1331       would be to send the "head" section of an HTML document to the browser
1332       in advance and speed up preloading of referenced images and
1333       stylesheets.
1334
1335         use Mojolicious::Lite;
1336
1337         get '/' => sub {
1338           my $c = shift;
1339           $c->write_chunk('<html><head><title>Example</title></head>' => sub {
1340             my $c = shift;
1341             $c->finish('<body>Example</body></html>');
1342           });
1343         };
1344
1345         app->start;
1346
1347       The optional drain callback ensures that all previous chunks have been
1348       written before processing continues. To end the stream you can call
1349       "finish" in Mojolicious::Controller or write an empty chunk of data.
1350
1351         HTTP/1.1 200 OK
1352         Date: Sat, 13 Sep 2014 16:48:29 GMT
1353         Transfer-Encoding: chunked
1354         Server: Mojolicious (Perl)
1355
1356         29
1357         <html><head><title>Example</title></head>
1358         1b
1359         <body>Example</body></html>
1360         0
1361
1362       Especially in combination with long inactivity timeouts this can be
1363       very useful for Comet (long polling). Due to limitations in some web
1364       servers this might not work perfectly in all deployment environments.
1365
1366   Encoding
1367       Templates stored in files are expected to be "UTF-8" by default, but
1368       that can be easily changed with "encoding" in Mojolicious::Renderer.
1369
1370         $app->renderer->encoding('koi8-r');
1371
1372       All templates from the "DATA" section are bound to the encoding of the
1373       Perl script.
1374
1375         use Mojolicious::Lite;
1376
1377         get '/heart';
1378
1379         app->start;
1380         __DATA__
1381
1382         @@ heart.html.ep
1383         I ♥ Mojolicious!
1384
1385   Base64 encoded DATA files
1386       Base64 encoded static files such as images can be easily stored in the
1387       "DATA" section of your application, similar to templates.
1388
1389         use Mojolicious::Lite;
1390
1391         get '/' => {text => 'I ♥ Mojolicious!'};
1392
1393         app->start;
1394         __DATA__
1395
1396         @@ favicon.ico (base64)
1397         ...base64 encoded image...
1398
1399   Inflating DATA templates
1400       Templates stored in files get preferred over files from the "DATA"
1401       section, this allows you to include a default set of templates in your
1402       application that the user can later customize. The command
1403       Mojolicious::Command::Author::inflate will write all templates and
1404       static files from the "DATA" section into actual files in the
1405       "templates" and "public" directories.
1406
1407         $ ./myapp.pl inflate
1408
1409   Customizing the template syntax
1410       You can easily change the whole template syntax by loading
1411       Mojolicious::Plugin::EPRenderer with a custom configuration.
1412
1413         use Mojolicious::Lite;
1414
1415         plugin EPRenderer => {
1416           name     => 'mustache',
1417           template => {
1418             tag_start => '{{',
1419             tag_end   => '}}'
1420           }
1421         };
1422
1423         get '/:name' => {name => 'Anonymous'} => 'index';
1424
1425         app->start;
1426         __DATA__
1427
1428         @@ index.html.mustache
1429         Hello {{= $name }}.
1430
1431       Mojo::Template contains the whole list of available options.
1432
1433   Adding your favorite template system
1434       Maybe you would prefer a different template system than "ep", which is
1435       provided by Mojolicious::Plugin::EPRenderer, and there is not already a
1436       plugin on CPAN for your favorite one. All you have to do, is to add a
1437       new "handler" with "add_handler" in Mojolicious::Renderer when
1438       "register" is called.
1439
1440         package Mojolicious::Plugin::MyRenderer;
1441         use Mojo::Base 'Mojolicious::Plugin';
1442
1443         sub register {
1444           my ($self, $app) = @_;
1445
1446           # Add "mine" handler
1447           $app->renderer->add_handler(mine => sub {
1448             my ($renderer, $c, $output, $options) = @_;
1449
1450             # Check for one-time use inline template
1451             my $inline_template = $options->{inline};
1452
1453             # Check for appropriate template in "templates" directories
1454             my $template_path = $renderer->template_path($options);
1455
1456             # Check for appropriate template in DATA sections
1457             my $data_template = $renderer->get_data_template($options);
1458
1459             # This part is up to you and your template system :)
1460             ...
1461
1462             # Pass the rendered result back to the renderer
1463             $$output = 'Hello World!';
1464
1465             # Or just die if an error occurs
1466             die 'Something went wrong with the template';
1467           });
1468         }
1469
1470         1;
1471
1472       An "inline" template, if provided by the user, will be passed along
1473       with the options. You can use "template_path" in Mojolicious::Renderer
1474       to search the "templates" directories of the application, and
1475       "get_data_template" in Mojolicious::Renderer to search the "DATA"
1476       sections.
1477
1478         use Mojolicious::Lite;
1479
1480         plugin 'MyRenderer';
1481
1482         # Render an inline template
1483         get '/inline' => {inline => '...', handler => 'mine'};
1484
1485         # Render a template from the DATA section
1486         get '/data' => {template => 'test'};
1487
1488         app->start;
1489         __DATA__
1490
1491         @@ test.html.mine
1492         ...
1493
1494   Adding a handler to generate binary data
1495       By default the renderer assumes that every "handler" generates
1496       characters that need to be automatically encoded, but this can be
1497       easily disabled if you're generating bytes instead.
1498
1499         use Mojolicious::Lite;
1500         use Storable 'nfreeze';
1501
1502         # Add "storable" handler
1503         app->renderer->add_handler(storable => sub {
1504           my ($renderer, $c, $output, $options) = @_;
1505
1506           # Disable automatic encoding
1507           delete $options->{encoding};
1508
1509           # Encode data from stash value
1510           $$output = nfreeze delete $c->stash->{storable};
1511         });
1512
1513         # Set "handler" value automatically if "storable" value is set already
1514         app->hook(before_render => sub {
1515           my ($c, $args) = @_;
1516           $args->{handler} = 'storable'
1517             if exists $args->{storable} || exists $c->stash->{storable};
1518         });
1519
1520         get '/' => {storable => {i => '♥ mojolicious'}};
1521
1522         app->start;
1523
1524       The hook "before_render" in Mojolicious can be used to make stash
1525       values like "storable" special, so that they no longer require a
1526       "handler" value to be set explicitly.
1527
1528         # Explicit "handler" value
1529         $c->render(storable => {i => '♥ mojolicious'}, handler => 'storable');
1530
1531         # Implicit "handler" value (with "before_render" hook)
1532         $c->render(storable => {i => '♥ mojolicious'});
1533

MORE

1535       You can continue with Mojolicious::Guides now or take a look at the
1536       Mojolicious wiki <http://github.com/mojolicious/mojo/wiki>, which
1537       contains a lot more documentation and examples by many different
1538       authors.
1539

SUPPORT

1541       If you have any questions the documentation might not yet answer, don't
1542       hesitate to ask on the mailing list
1543       <http://groups.google.com/group/mojolicious> or the official IRC
1544       channel "#mojo" on "irc.freenode.net" (chat now!
1545       <https://kiwiirc.com/nextclient/#irc://irc.freenode.net/mojo?nick=guest-?>).
1546
1547
1548
1549perl v5.30.1                      2020-01-30 Mojolicious::Guides::Rendering(3)
Impressum