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

ADVANCED

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

MORE

1493       You can continue with Mojolicious::Guides now or take a look at the
1494       Mojolicious wiki <https://github.com/mojolicious/mojo/wiki>, which
1495       contains a lot more documentation and examples by many different
1496       authors.
1497

SUPPORT

1499       If you have any questions the documentation might not yet answer, don't
1500       hesitate to ask in the Forum <https://forum.mojolicious.org> or the
1501       official IRC channel "#mojo" on "chat.freenode.net" (chat now!
1502       <https://webchat.freenode.net/#mojo>).
1503
1504
1505
1506perl v5.32.1                      2021-02-07 Mojolicious::Guides::Rendering(3)
Impressum