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

ADVANCED

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

MORE

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

SUPPORT

1497       If you have any questions the documentation might not yet answer, don't
1498       hesitate to ask in the Forum <https://forum.mojolicious.org>, on Matrix
1499       <https://matrix.to/#/#mojo:matrix.org>, or IRC
1500       <https://web.libera.chat/#mojo>.
1501
1502
1503
1504perl v5.36.0                      2022-07-22 Mojolicious::Guides::Rendering(3)
Impressum