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           $args->{json} = {exception => $args->{exception}} if $c->accepts('json');
499         };
500
501         get '/' => sub { die "This sho...ALL GLORY TO THE HYPNOTOAD!\n" };
502
503         app->start;
504
505   Layouts
506       Most of the time when using "ep" templates you will want to wrap your
507       generated content in an HTML skeleton, thanks to layouts that's
508       absolutely trivial.
509
510         use Mojolicious::Lite;
511
512         get '/' => {template => 'foo/bar'};
513
514         app->start;
515         __DATA__
516
517         @@ foo/bar.html.ep
518         % layout 'mylayout';
519         Hello World!
520
521         @@ layouts/mylayout.html.ep
522         <!DOCTYPE html>
523         <html>
524           <head><title>MyApp</title></head>
525           <body><%= content %></body>
526         </html>
527
528       You just select the right layout template with the helper "layout" in
529       Mojolicious::Plugin::DefaultHelpers and place the result of the current
530       template with the helper "content" in
531       Mojolicious::Plugin::DefaultHelpers. You can also pass along normal
532       stash values to the "layout" helper.
533
534         use Mojolicious::Lite;
535
536         get '/' => {template => 'foo/bar'};
537
538         app->start;
539         __DATA__
540
541         @@ foo/bar.html.ep
542         % layout 'mylayout', title => 'Hi there';
543         Hello World!
544
545         @@ layouts/mylayout.html.ep
546         <!DOCTYPE html>
547         <html>
548           <head><title><%= $title %></title></head>
549           <body><%= content %></body>
550         </html>
551
552       Instead of the "layout" helper you could also just use the "layout"
553       stash value, or call "render" in Mojolicious::Controller with the
554       "layout" argument.
555
556         $c->render(template => 'mytemplate', layout => 'mylayout');
557
558       To set a "layout" stash value application-wide you can use "defaults"
559       in Mojolicious.
560
561         $app->defaults(layout => 'mylayout');
562
563       Layouts can also be used with "render_to_string" in
564       Mojolicious::Controller, but the "layout" value needs to be passed as a
565       render argument (not a stash value).
566
567         my $html = $c->render_to_string('reminder', layout => 'mail');
568
569   Partial templates
570       You can break up bigger templates into smaller, more manageable chunks.
571       These partial templates can also be shared with other templates. Just
572       use the helper "include" in Mojolicious::Plugin::DefaultHelpers to
573       include one template into another.
574
575         use Mojolicious::Lite;
576
577         get '/' => {template => 'foo/bar'};
578
579         app->start;
580         __DATA__
581
582         @@ foo/bar.html.ep
583         <!DOCTYPE html>
584         <html>
585           %= include '_header', title => 'Howdy'
586           <body>Bar</body>
587         </html>
588
589         @@ _header.html.ep
590         <head><title><%= $title %></title></head>
591
592       You can name partial templates however you like, but a leading
593       underscore is a commonly used naming convention.
594
595   Reusable template blocks
596       It's never fun to repeat yourself, that's why you can build reusable
597       template blocks in "ep" that work very similar to normal Perl
598       functions, with the "begin" and "end" keywords. Just be aware that both
599       keywords are part of the surrounding tag and not actual Perl code, so
600       there can only be whitespace after "begin" and before "end".
601
602         use Mojolicious::Lite;
603
604         get '/' => 'welcome';
605
606         app->start;
607         __DATA__
608
609         @@ welcome.html.ep
610         <% my $block = begin %>
611           % my $name = shift;
612           Hello <%= $name %>.
613         <% end %>
614         <%= $block->('Wolfgang') %>
615         <%= $block->('Baerbel') %>
616
617       A naive translation of the template to Perl code could look like this.
618
619         my $output = '';
620         my $block  = sub {
621           my $name   = shift;
622           my $output = '';
623           $output .= 'Hello ';
624           $output .= xml_escape scalar + $name;
625           $output .= '.';
626           return Mojo::ByteStream->new($output);
627         };
628         $output .= xml_escape scalar + $block->('Wolfgang');
629         $output .= xml_escape scalar + $block->('Baerbel');
630         return $output;
631
632       While template blocks cannot be shared between templates, they are most
633       commonly used to pass parts of a template to helpers.
634
635   Adding helpers
636       You should always try to keep your actions small and reuse as much code
637       as possible. Helpers make this very easy, they get passed the current
638       controller object as first argument, and you can use them to do pretty
639       much anything an action could do.
640
641         use Mojolicious::Lite;
642
643         helper debug => sub {
644           my ($c, $str) = @_;
645           $c->app->log->debug($str);
646         };
647
648         get '/' => sub {
649           my $c = shift;
650           $c->debug('Hello from an action!');
651         } => 'index';
652
653         app->start;
654         __DATA__
655
656         @@ index.html.ep
657         % debug 'Hello from a template!';
658
659       Helpers can also accept template blocks as last argument, this for
660       example, allows very pleasant to use tag helpers and filters. Wrapping
661       the helper result into a Mojo::ByteStream object can prevent accidental
662       double escaping.
663
664         use Mojolicious::Lite;
665         use Mojo::ByteStream;
666
667         helper trim_newline => sub {
668           my ($c, $block) = @_;
669           my $result = $block->();
670           $result =~ s/\n//g;
671           return Mojo::ByteStream->new($result);
672         };
673
674         get '/' => 'index';
675
676         app->start;
677         __DATA__
678
679         @@ index.html.ep
680         %= trim_newline begin
681           Some text.
682           %= 1 + 1
683           More text.
684         % end
685
686       Similar to stash values, you can use a prefix like "myapp.*" to keep
687       helpers from getting exposed in templates as functions, and to organize
688       them into namespaces as your application grows. Every prefix
689       automatically becomes a helper that returns a proxy object containing
690       the current controller object and on which you can call the nested
691       helpers.
692
693         use Mojolicious::Lite;
694
695         helper 'cache_control.no_caching' => sub {
696           my $c = shift;
697           $c->res->headers->cache_control('private, max-age=0, no-cache');
698         };
699
700         helper 'cache_control.five_minutes' => sub {
701           my $c = shift;
702           $c->res->headers->cache_control('public, max-age=300');
703         };
704
705         get '/news' => sub {
706           my $c = shift;
707           $c->cache_control->no_caching;
708           $c->render(text => 'Always up to date.');
709         };
710
711         get '/some_older_story' => sub {
712           my $c = shift;
713           $c->cache_control->five_minutes;
714           $c->render(text => 'This one can be cached for a bit.');
715         };
716
717         app->start;
718
719       While helpers can also be redefined, this should only be done very
720       carefully to avoid conflicts.
721
722   Content blocks
723       The helper "content_for" in Mojolicious::Plugin::DefaultHelpers allows
724       you to pass whole blocks of content from one template to another. This
725       can be very useful when your layout has distinct sections, such as
726       sidebars, where content should be inserted by the template.
727
728         use Mojolicious::Lite;
729
730         get '/' => 'foo';
731
732         app->start;
733         __DATA__
734
735         @@ foo.html.ep
736         % layout 'mylayout';
737         % content_for header => begin
738           <meta http-equiv="Content-Type" content="text/html">
739         % end
740         <div>Hello World!</div>
741         % content_for header => begin
742           <meta http-equiv="Pragma" content="no-cache">
743         % end
744
745         @@ layouts/mylayout.html.ep
746         <!DOCTYPE html>
747         <html>
748           <head><%= content 'header' %></head>
749           <body><%= content %></body>
750         </html>
751
752   Forms
753       To build HTML forms more efficiently you can use tag helpers like
754       "form_for" in Mojolicious::Plugin::TagHelpers, which can automatically
755       select a request method for you if a route name is provided. And since
756       most browsers only allow forms to be submitted with "GET" and "POST",
757       but not request methods like "PUT" or "DELETE", they are spoofed with
758       an "_method" query parameter.
759
760         use Mojolicious::Lite;
761
762         get '/' => 'form';
763
764         # PUT  /nothing
765         # POST /nothing?_method=PUT
766         put '/nothing' => sub {
767           my $c = shift;
768
769           # Prevent double form submission with redirect
770           my $value = $c->param('whatever');
771           $c->flash(confirmation => "We did nothing with your value ($value).");
772           $c->redirect_to('form');
773         };
774
775         app->start;
776         __DATA__
777
778         @@ form.html.ep
779         <!DOCTYPE html>
780         <html>
781           <body>
782             % if (my $confirmation = flash 'confirmation') {
783               <p><%= $confirmation %></p>
784             % }
785             %= form_for nothing => begin
786               %= text_field whatever => 'I ♥ Mojolicious!'
787               %= submit_button
788             % end
789           </body>
790         </html>
791
792       The helpers "flash" in Mojolicious::Plugin::DefaultHelpers and
793       "redirect_to" in Mojolicious::Plugin::DefaultHelpers are often used
794       together to prevent double form submission, allowing users to receive a
795       confirmation message that will vanish if they decide to reload the page
796       they've been redirected to.
797
798   Form validation
799       You can use "validation" in Mojolicious::Plugin::DefaultHelpers to
800       validate "GET" and "POST" parameters submitted to your application. All
801       unknown fields will be ignored by default, so you have to decide which
802       should be required or optional before you can perform checks on their
803       values. Every check is performed right away, so you can use the results
804       immediately to build more advanced validation logic with methods like
805       "is_valid" in Mojolicious::Validator::Validation.
806
807         use Mojolicious::Lite;
808
809         get '/' => sub {
810           my $c = shift;
811
812           # Check if parameters have been submitted
813           my $v = $c->validation;
814           return $c->render('index') unless $v->has_data;
815
816           # Validate parameters ("pass_again" depends on "pass")
817           $v->required('user')->size(1, 20)->like(qr/^[a-z0-9]+$/);
818           $v->required('pass_again')->equal_to('pass')
819             if $v->optional('pass')->size(7, 500)->is_valid;
820
821           # Check if validation failed
822           return $c->render('index') if $v->has_error;
823
824           # Render confirmation
825           $c->render('thanks');
826         };
827
828         app->start;
829         __DATA__
830
831         @@ index.html.ep
832         <!DOCTYPE html>
833         <html>
834           <head>
835             <style>
836               label.field-with-error { color: #dd7e5e }
837               input.field-with-error { background-color: #fd9e7e }
838             </style>
839           </head>
840           <body>
841             %= form_for index => begin
842               %= label_for user => 'Username (required, 1-20 characters, a-z/0-9)'
843               <br>
844               %= text_field 'user', id => 'user'
845               %= submit_button
846               <br>
847               %= label_for pass => 'Password (optional, 7-500 characters)'
848               <br>
849               %= password_field 'pass', id => 'pass'
850               <br>
851               %= label_for pass_again => 'Password again (equal to the value above)'
852               <br>
853               %= password_field 'pass_again', id => 'pass_again'
854             % end
855           </body>
856         </html>
857
858         @@ thanks.html.ep
859         <!DOCTYPE html>
860         <html><body>Thank you <%= validation->param('user') %>.</body></html>
861
862       Form elements generated with tag helpers from
863       Mojolicious::Plugin::TagHelpers will automatically remember their
864       previous values and add the class "field-with-error" for fields that
865       failed validation to make styling with CSS easier.
866
867         <label class="field-with-error" for="user">
868           Username (required, only characters e-t)
869         </label>
870         <input class="field-with-error" type="text" name="user" value="sri">
871
872       For a full list of available checks see also "CHECKS" in
873       Mojolicious::Validator.
874
875   Adding form validation checks
876       Validation checks can be registered with "add_check" in
877       Mojolicious::Validator and return a false value if they were
878       successful. A true value may be used to pass along additional
879       information which can then be retrieved with "error" in
880       Mojolicious::Validator::Validation.
881
882         use Mojolicious::Lite;
883
884         # Add "range" check
885         app->validator->add_check(range => sub {
886           my ($v, $name, $value, $min, $max) = @_;
887           return $value < $min || $value > $max;
888         });
889
890         get '/' => 'form';
891
892         post '/test' => sub {
893           my $c = shift;
894
895           # Validate parameters with custom check
896           my $v = $c->validation;
897           $v->required('number')->range(3, 23);
898
899           # Render form again if validation failed
900           return $c->render('form') if $v->has_error;
901
902           # Prevent double form submission with redirect
903           $c->flash(number => $v->param('number'));
904           $c->redirect_to('form');
905         };
906
907         app->start;
908         __DATA__
909
910         @@ form.html.ep
911         <!DOCTYPE html>
912         <html>
913           <body>
914             % if (my $number = flash 'number') {
915               <p>Thanks, the number <%= $number %> was valid.</p>
916             % }
917             %= form_for test => begin
918               % if (my $err = validation->error('number')) {
919                 <p>
920                   %= 'Value is required.' if $err->[0] eq 'required'
921                   %= 'Value needs to be between 3 and 23.' if $err->[0] eq 'range'
922                 </p>
923               % }
924               %= text_field 'number'
925               %= submit_button
926             % end
927           </body>
928         </html>
929
930   Cross-site request forgery
931       CSRF is a very common attack on web applications that trick your logged
932       in users to submit forms they did not intend to send, with something as
933       mundane as a link. All you have to do, to protect your users from this,
934       is to add an additional hidden field to your forms with "csrf_field" in
935       Mojolicious::Plugin::TagHelpers, and validate it with "csrf_protect" in
936       Mojolicious::Validator::Validation.
937
938         use Mojolicious::Lite;
939
940         get '/' => {template => 'target'};
941
942         post '/' => sub {
943           my $c = shift;
944
945           # Check CSRF token
946           my $v = $c->validation;
947           return $c->render(text => 'Bad CSRF token!', status => 403)
948             if $v->csrf_protect->has_error('csrf_token');
949
950           my $city = $v->required('city')->param('city');
951           $c->render(text => "Low orbit ion cannon pointed at $city!")
952             unless $v->has_error;
953         } => 'target';
954
955         app->start;
956         __DATA__
957
958         @@ target.html.ep
959         <!DOCTYPE html>
960         <html>
961           <body>
962             %= form_for target => begin
963               %= csrf_field
964               %= label_for city => 'Which city to point low orbit ion cannon at?'
965               %= text_field 'city', id => 'city'
966               %= submit_button
967             %= end
968           </body>
969         </html>
970
971       For Ajax requests and the like, you can also generate a token directly
972       with the helper "csrf_token" in Mojolicious::Plugin::DefaultHelpers,
973       and then pass it along with the "X-CSRF-Token" request header.
974

ADVANCED

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

MORE

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

SUPPORT

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