1Mojolicious(3) User Contributed Perl Documentation Mojolicious(3)
2
3
4
6 Mojolicious - Real-time web framework
7
9 # Application
10 package MyApp;
11 use Mojo::Base 'Mojolicious';
12
13 # Route
14 sub startup {
15 my $self = shift;
16 $self->routes->get('/hello')->to('foo#hello');
17 }
18
19 # Controller
20 package MyApp::Controller::Foo;
21 use Mojo::Base 'Mojolicious::Controller';
22
23 # Action
24 sub hello {
25 my $self = shift;
26 $self->render(text => 'Hello World!');
27 }
28
30 An amazing real-time web framework built on top of the powerful Mojo
31 web development toolkit. With support for RESTful routes, plugins,
32 commands, Perl-ish templates, content negotiation, session management,
33 form validation, testing framework, static file server, "CGI"/"PSGI"
34 detection, first class Unicode support and much more for you to
35 discover.
36
37 Take a look at our excellent documentation in Mojolicious::Guides!
38
40 Mojolicious will emit the following hooks in the listed order.
41
42 before_server_start
43 Emitted right before the application server is started, for web servers
44 that support it, which includes all the built-in ones (except for
45 Mojo::Server::CGI).
46
47 $app->hook(before_server_start => sub {
48 my ($server, $app) = @_;
49 ...
50 });
51
52 Useful for reconfiguring application servers dynamically or collecting
53 server diagnostics information. (Passed the server and application
54 objects)
55
56 after_build_tx
57 Emitted right after the transaction is built and before the HTTP
58 request gets parsed.
59
60 $app->hook(after_build_tx => sub {
61 my ($tx, $app) = @_;
62 ...
63 });
64
65 This is a very powerful hook and should not be used lightly, it makes
66 some rather advanced features such as upload progress bars possible.
67 Note that this hook will not work for embedded applications, because
68 only the host application gets to build transactions. (Passed the
69 transaction and application objects)
70
71 around_dispatch
72 Emitted right after a new request has been received and wraps around
73 the whole dispatch process, so you have to manually forward to the next
74 hook if you want to continue the chain. Default exception handling with
75 "reply->exception" in Mojolicious::Plugin::DefaultHelpers is the first
76 hook in the chain and a call to "dispatch" the last, yours will be in
77 between.
78
79 $app->hook(around_dispatch => sub {
80 my ($next, $c) = @_;
81 ...
82 $next->();
83 ...
84 });
85
86 This is a very powerful hook and should not be used lightly, it allows
87 you to, for example, customize application-wide exception handling,
88 consider it the sledgehammer in your toolbox. (Passed a callback
89 leading to the next hook and the default controller object)
90
91 before_dispatch
92 Emitted right before the static file server and router start their
93 work.
94
95 $app->hook(before_dispatch => sub {
96 my $c = shift;
97 ...
98 });
99
100 Very useful for rewriting incoming requests and other preprocessing
101 tasks. (Passed the default controller object)
102
103 after_static
104 Emitted after a static file response has been generated by the static
105 file server.
106
107 $app->hook(after_static => sub {
108 my $c = shift;
109 ...
110 });
111
112 Mostly used for post-processing static file responses. (Passed the
113 default controller object)
114
115 before_routes
116 Emitted after the static file server determined if a static file should
117 be served and before the router starts its work.
118
119 $app->hook(before_routes => sub {
120 my $c = shift;
121 ...
122 });
123
124 Mostly used for custom dispatchers and collecting metrics. (Passed the
125 default controller object)
126
127 around_action
128 Emitted right before an action gets executed and wraps around it, so
129 you have to manually forward to the next hook if you want to continue
130 the chain. Default action dispatching is the last hook in the chain,
131 yours will run before it.
132
133 $app->hook(around_action => sub {
134 my ($next, $c, $action, $last) = @_;
135 ...
136 return $next->();
137 });
138
139 This is a very powerful hook and should not be used lightly, it allows
140 you for example to pass additional arguments to actions or handle
141 return values differently. Note that this hook can trigger more than
142 once for the same request if there are nested routes. (Passed a
143 callback leading to the next hook, the current controller object, the
144 action callback and a flag indicating if this action is an endpoint)
145
146 before_render
147 Emitted before content is generated by the renderer. Note that this
148 hook can trigger out of order due to its dynamic nature, and with
149 embedded applications will only work for the application that is
150 rendering.
151
152 $app->hook(before_render => sub {
153 my ($c, $args) = @_;
154 ...
155 });
156
157 Mostly used for pre-processing arguments passed to the renderer.
158 (Passed the current controller object and the render arguments)
159
160 after_render
161 Emitted after content has been generated by the renderer that will be
162 assigned to the response. Note that this hook can trigger out of order
163 due to its dynamic nature, and with embedded applications will only
164 work for the application that is rendering.
165
166 $app->hook(after_render => sub {
167 my ($c, $output, $format) = @_;
168 ...
169 });
170
171 Mostly used for post-processing dynamically generated content. (Passed
172 the current controller object, a reference to the content and the
173 format)
174
175 after_dispatch
176 Emitted in reverse order after a response has been generated. Note that
177 this hook can trigger out of order due to its dynamic nature, and with
178 embedded applications will only work for the application that is
179 generating the response.
180
181 $app->hook(after_dispatch => sub {
182 my $c = shift;
183 ...
184 });
185
186 Useful for rewriting outgoing responses and other post-processing
187 tasks. (Passed the current controller object)
188
190 Mojolicious implements the following attributes.
191
192 commands
193 my $commands = $app->commands;
194 $app = $app->commands(Mojolicious::Commands->new);
195
196 Command line interface for your application, defaults to a
197 Mojolicious::Commands object.
198
199 # Add another namespace to load commands from
200 push @{$app->commands->namespaces}, 'MyApp::Command';
201
202 controller_class
203 my $class = $app->controller_class;
204 $app = $app->controller_class('Mojolicious::Controller');
205
206 Class to be used for the default controller, defaults to
207 Mojolicious::Controller. Note that this class needs to have already
208 been loaded before the first request arrives.
209
210 home
211 my $home = $app->home;
212 $app = $app->home(Mojo::Home->new);
213
214 The home directory of your application, defaults to a Mojo::Home object
215 which stringifies to the actual path.
216
217 # Portably generate path relative to home directory
218 my $path = $app->home->child('data', 'important.txt');
219
220 log
221 my $log = $app->log;
222 $app = $app->log(Mojo::Log->new);
223
224 The logging layer of your application, defaults to a Mojo::Log object.
225 The level will default to either the "MOJO_LOG_LEVEL" environment
226 variable, "debug" if the "mode" is "development", or "info" otherwise.
227 All messages will be written to "STDERR", or a "log/$mode.log" file if
228 a "log" directory exists.
229
230 # Log debug message
231 $app->log->debug('It works');
232
233 max_request_size
234 my $max = $app->max_request_size;
235 $app = $app->max_request_size(16777216);
236
237 Maximum request size in bytes, defaults to the value of
238 "max_message_size" in Mojo::Message. Setting the value to 0 will allow
239 requests of indefinite size. Note that increasing this value can also
240 drastically increase memory usage, should you for example attempt to
241 parse an excessively large request body with the methods "dom" in
242 Mojo::Message or "json" in Mojo::Message.
243
244 mode
245 my $mode = $app->mode;
246 $app = $app->mode('production');
247
248 The operating mode for your application, defaults to a value from the
249 "MOJO_MODE" and "PLACK_ENV" environment variables or "development".
250
251 moniker
252 my $moniker = $app->moniker;
253 $app = $app->moniker('foo_bar');
254
255 Moniker of this application, often used as default filename for
256 configuration files and the like, defaults to decamelizing the
257 application class with "decamelize" in Mojo::Util.
258
259 plugins
260 my $plugins = $app->plugins;
261 $app = $app->plugins(Mojolicious::Plugins->new);
262
263 The plugin manager, defaults to a Mojolicious::Plugins object. See the
264 "plugin" method below if you want to load a plugin.
265
266 # Add another namespace to load plugins from
267 push @{$app->plugins->namespaces}, 'MyApp::Plugin';
268
269 renderer
270 my $renderer = $app->renderer;
271 $app = $app->renderer(Mojolicious::Renderer->new);
272
273 Used to render content, defaults to a Mojolicious::Renderer object. For
274 more information about how to generate content see
275 Mojolicious::Guides::Rendering.
276
277 # Enable compression
278 $app->renderer->compress(1);
279
280 # Add another "templates" directory
281 push @{$app->renderer->paths}, '/home/sri/templates';
282
283 # Add another "templates" directory with higher precedence
284 unshift @{$app->renderer->paths}, '/home/sri/themes/blue/templates';
285
286 # Add another class with templates in DATA section
287 push @{$app->renderer->classes}, 'Mojolicious::Plugin::Fun';
288
289 routes
290 my $routes = $app->routes;
291 $app = $app->routes(Mojolicious::Routes->new);
292
293 The router, defaults to a Mojolicious::Routes object. You use this in
294 your startup method to define the url endpoints for your application.
295
296 # Add routes
297 my $r = $app->routes;
298 $r->get('/foo/bar')->to('test#foo', title => 'Hello Mojo!');
299 $r->post('/baz')->to('test#baz');
300
301 # Add another namespace to load controllers from
302 push @{$app->routes->namespaces}, 'MyApp::MyController';
303
304 secrets
305 my $secrets = $app->secrets;
306 $app = $app->secrets([$bytes]);
307
308 Secret passphrases used for signed cookies and the like, defaults to
309 the "moniker" of this application, which is not very secure, so you
310 should change it!!! As long as you are using the insecure default there
311 will be debug messages in the log file reminding you to change your
312 passphrase. Only the first passphrase is used to create new signatures,
313 but all of them for verification. So you can increase security without
314 invalidating all your existing signed cookies by rotating passphrases,
315 just add new ones to the front and remove old ones from the back.
316
317 # Rotate passphrases
318 $app->secrets(['new_passw0rd', 'old_passw0rd', 'very_old_passw0rd']);
319
320 sessions
321 my $sessions = $app->sessions;
322 $app = $app->sessions(Mojolicious::Sessions->new);
323
324 Signed cookie based session manager, defaults to a
325 Mojolicious::Sessions object. You can usually leave this alone, see
326 "session" in Mojolicious::Controller for more information about working
327 with session data.
328
329 # Change name of cookie used for all sessions
330 $app->sessions->cookie_name('mysession');
331
332 # Disable SameSite feature
333 $app->sessions->samesite(undef);
334
335 static
336 my $static = $app->static;
337 $app = $app->static(Mojolicious::Static->new);
338
339 For serving static files from your "public" directories, defaults to a
340 Mojolicious::Static object.
341
342 # Add another "public" directory
343 push @{$app->static->paths}, '/home/sri/public';
344
345 # Add another "public" directory with higher precedence
346 unshift @{$app->static->paths}, '/home/sri/themes/blue/public';
347
348 # Add another class with static files in DATA section
349 push @{$app->static->classes}, 'Mojolicious::Plugin::Fun';
350
351 # Remove built-in favicon
352 delete $app->static->extra->{'favicon.ico'};
353
354 types
355 my $types = $app->types;
356 $app = $app->types(Mojolicious::Types->new);
357
358 Responsible for connecting file extensions with MIME types, defaults to
359 a Mojolicious::Types object.
360
361 # Add custom MIME type
362 $app->types->type(twt => 'text/tweet');
363
364 ua
365 my $ua = $app->ua;
366 $app = $app->ua(Mojo::UserAgent->new);
367
368 A full featured HTTP user agent for use in your applications, defaults
369 to a Mojo::UserAgent object.
370
371 # Perform blocking request
372 say $app->ua->get('example.com')->result->body;
373
374 validator
375 my $validator = $app->validator;
376 $app = $app->validator(Mojolicious::Validator->new);
377
378 Validate values, defaults to a Mojolicious::Validator object.
379
380 # Add validation check
381 $app->validator->add_check(foo => sub {
382 my ($v, $name, $value) = @_;
383 return $value ne 'foo';
384 });
385
386 # Add validation filter
387 $app->validator->add_filter(quotemeta => sub {
388 my ($v, $name, $value) = @_;
389 return quotemeta $value;
390 });
391
393 Mojolicious inherits all methods from Mojo::Base and implements the
394 following new ones.
395
396 build_controller
397 my $c = $app->build_controller;
398 my $c = $app->build_controller(Mojo::Transaction::HTTP->new);
399 my $c = $app->build_controller(Mojolicious::Controller->new);
400
401 Build default controller object with "controller_class".
402
403 # Render template from application
404 my $foo = $app->build_controller->render_to_string(template => 'foo');
405
406 build_tx
407 my $tx = $app->build_tx;
408
409 Build Mojo::Transaction::HTTP object and emit "after_build_tx" hook.
410
411 config
412 my $hash = $app->config;
413 my $foo = $app->config('foo');
414 $app = $app->config({foo => 'bar', baz => 23});
415 $app = $app->config(foo => 'bar', baz => 23);
416
417 Application configuration.
418
419 # Remove value
420 my $foo = delete $app->config->{foo};
421
422 # Assign multiple values at once
423 $app->config(foo => 'test', bar => 23);
424
425 defaults
426 my $hash = $app->defaults;
427 my $foo = $app->defaults('foo');
428 $app = $app->defaults({foo => 'bar', baz => 23});
429 $app = $app->defaults(foo => 'bar', baz => 23);
430
431 Default values for "stash" in Mojolicious::Controller, assigned for
432 every new request.
433
434 # Remove value
435 my $foo = delete $app->defaults->{foo};
436
437 # Assign multiple values at once
438 $app->defaults(foo => 'test', bar => 23);
439
440 dispatch
441 $app->dispatch(Mojolicious::Controller->new);
442
443 The heart of every Mojolicious application, calls the "static" and
444 "routes" dispatchers for every request and passes them a
445 Mojolicious::Controller object.
446
447 handler
448 $app->handler(Mojo::Transaction::HTTP->new);
449 $app->handler(Mojolicious::Controller->new);
450
451 Sets up the default controller and emits the "around_dispatch" hook for
452 every request.
453
454 helper
455 $app->helper(foo => sub {...});
456
457 Add or replace a helper that will be available as a method of the
458 controller object and the application object, as well as a function in
459 "ep" templates. For a full list of helpers that are available by
460 default see Mojolicious::Plugin::DefaultHelpers and
461 Mojolicious::Plugin::TagHelpers.
462
463 # Helper
464 $app->helper(cache => sub { state $cache = {} });
465
466 # Application
467 $app->cache->{foo} = 'bar';
468 my $result = $app->cache->{foo};
469
470 # Controller
471 $c->cache->{foo} = 'bar';
472 my $result = $c->cache->{foo};
473
474 # Template
475 % cache->{foo} = 'bar';
476 %= cache->{foo}
477
478 hook
479 $app->hook(after_dispatch => sub {...});
480
481 Extend Mojolicious with hooks, which allow code to be shared with all
482 requests indiscriminately, for a full list of available hooks see
483 "HOOKS".
484
485 # Dispatchers will not run if there's already a response code defined
486 $app->hook(before_dispatch => sub {
487 my $c = shift;
488 $c->render(text => 'Skipped static file server and router!')
489 if $c->req->url->path->to_route =~ /do_not_dispatch/;
490 });
491
492 new
493 my $app = Mojolicious->new;
494 my $app = Mojolicious->new(moniker => 'foo_bar');
495 my $app = Mojolicious->new({moniker => 'foo_bar'});
496
497 Construct a new Mojolicious application and call "startup". Will
498 automatically detect your home directory. Also sets up the renderer,
499 static file server, a default set of plugins and an "around_dispatch"
500 hook with the default exception handling.
501
502 plugin
503 $app->plugin('some_thing');
504 $app->plugin('some_thing', foo => 23);
505 $app->plugin('some_thing', {foo => 23});
506 $app->plugin('SomeThing');
507 $app->plugin('SomeThing', foo => 23);
508 $app->plugin('SomeThing', {foo => 23});
509 $app->plugin('MyApp::Plugin::SomeThing');
510 $app->plugin('MyApp::Plugin::SomeThing', foo => 23);
511 $app->plugin('MyApp::Plugin::SomeThing', {foo => 23});
512
513 Load a plugin, for a full list of example plugins included in the
514 Mojolicious distribution see "PLUGINS" in Mojolicious::Plugins.
515
516 server
517 $app->server(Mojo::Server->new);
518
519 Emits the "before_server_start" hook.
520
521 start
522 $app->start;
523 $app->start(@ARGV);
524
525 Start the command line interface for your application. For a full list
526 of commands that are available by default see "COMMANDS" in
527 Mojolicious::Commands. Note that the options "-h"/"--help", "--home"
528 and "-m"/"--mode", which are shared by all commands, will be parsed
529 from @ARGV during compile time.
530
531 # Always start daemon
532 $app->start('daemon', '-l', 'http://*:8080');
533
534 startup
535 $app->startup;
536
537 This is your main hook into the application, it will be called at
538 application startup. Meant to be overloaded in a subclass.
539
540 sub startup {
541 my $self = shift;
542 ...
543 }
544
546 In addition to the "ATTRIBUTES" and "METHODS" above you can also call
547 helpers on Mojolicious objects. This includes all helpers from
548 Mojolicious::Plugin::DefaultHelpers and
549 Mojolicious::Plugin::TagHelpers. Note that application helpers are
550 always called with a new default controller object, so they can't
551 depend on or change controller state, which includes request, response
552 and stash.
553
554 # Call helper
555 say $app->dumper({foo => 'bar'});
556
557 # Longer version
558 say $app->build_controller->helpers->dumper({foo => 'bar'});
559
561 The Mojolicious distribution includes a few files with different
562 licenses that have been bundled for internal use.
563
564 Mojolicious Artwork
565 Copyright (C) 2010-2019, Sebastian Riedel.
566
567 Licensed under the CC-SA License, Version 4.0
568 <http://creativecommons.org/licenses/by-sa/4.0>.
569
570 jQuery
571 Copyright (C) jQuery Foundation.
572
573 Licensed under the MIT License,
574 <http://creativecommons.org/licenses/MIT>.
575
576 prettify.js
577 Copyright (C) 2006, 2013 Google Inc..
578
579 Licensed under the Apache License, Version 2.0
580 <http://www.apache.org/licenses/LICENSE-2.0>.
581
583 Every major release of Mojolicious has a code name, these are the ones
584 that have been used in the past.
585
586 8.0, "Supervillain" (U+1F9B9)
587
588 7.0, "Doughnut" (U+1F369)
589
590 6.0, "Clinking Beer Mugs" (U+1F37B)
591
592 5.0, "Tiger Face" (U+1F42F)
593
594 4.0, "Top Hat" (U+1F3A9)
595
596 3.0, "Rainbow" (U+1F308)
597
598 2.0, "Leaf Fluttering In Wind" (U+1F343)
599
600 1.0, "Snowflake" (U+2744)
601
603 · Stix <https://stix.no> sponsored the creation of the Mojolicious logo
604 (designed by Nicolai Graesdal) and transferred its copyright to
605 Sebastian Riedel.
606
607 · Some of the work on this distribution has been sponsored by The Perl
608 Foundation <http://www.perlfoundation.org>.
609
611 Sebastian Riedel, "kraih@mojolicious.org"
612
614 Current members of the core team in alphabetical order:
615
616 CandyAngel, "candyangel@mojolicious.org"
617
618 Christopher Rasch-Olsen Raa, "christopher@mojolicious.org"
619
620 Dan Book, "grinnz@mojolicious.org"
621
622 Jan Henning Thorsen, "batman@mojolicious.org"
623
624 Joel Berger, "jberger@mojolicious.org"
625
626 Marcus Ramberg, "marcus@mojolicious.org"
627
628 The following members of the core team are currently on hiatus:
629
630 Abhijit Menon-Sen, "ams@cpan.org"
631
632 Glen Hinkle, "tempire@cpan.org"
633
635 In alphabetical order:
636
637 Adam Kennedy
638
639 Adriano Ferreira
640
641 Al Newkirk
642
643 Alex Efros
644
645 Alex Salimon
646
647 Alexander Karelas
648
649 Alexey Likhatskiy
650
651 Anatoly Sharifulin
652
653 Andre Parker
654
655 Andre Vieth
656
657 Andreas Guldstrand
658
659 Andreas Jaekel
660
661 Andreas Koenig
662
663 Andrew Fresh
664
665 Andrew Nugged
666
667 Andrey Khozov
668
669 Andrey Kuzmin
670
671 Andy Grundman
672
673 Aristotle Pagaltzis
674
675 Ashley Dev
676
677 Ask Bjoern Hansen
678
679 Audrey Tang
680
681 Ben Tyler
682
683 Ben van Staveren
684
685 Benjamin Erhart
686
687 Bernhard Graf
688
689 Breno G. de Oliveira
690
691 Brian Duggan
692
693 Brian Medley
694
695 Burak Gursoy
696
697 Ch Lamprecht
698
699 Charlie Brady
700
701 Chas. J. Owens IV
702
703 Chase Whitener
704
705 Christian Hansen
706
707 chromatic
708
709 Curt Tilmes
710
711 Daniel Kimsey
712
713 Daniel Mantovani
714
715 Danijel Tasov
716
717 Dagfinn Ilmari Mannsåker
718
719 Danny Thomas
720
721 David Davis
722
723 David Webb
724
725 Diego Kuperman
726
727 Dmitriy Shalashov
728
729 Dmitry Konstantinov
730
731 Dominik Jarmulowicz
732
733 Dominique Dumont
734
735 Dotan Dimet
736
737 Douglas Christopher Wilson
738
739 Ettore Di Giacinto
740
741 Eugen Konkov
742
743 Eugene Toropov
744
745 Flavio Poletti
746
747 Gisle Aas
748
749 Graham Barr
750
751 Graham Knop
752
753 Henry Tang
754
755 Hideki Yamamura
756
757 Hiroki Toyokawa
758
759 Ian Goodacre
760
761 Ilya Chesnokov
762
763 Ilya Rassadin
764
765 James Duncan
766
767 Jan Jona Javorsek
768
769 Jan Schmidt
770
771 Jaroslav Muhin
772
773 Jesse Vincent
774
775 Johannes Plunien
776
777 John Kingsley
778
779 Jonathan Yu
780
781 Josh Leder
782
783 Kazuhiro Shibuya
784
785 Kevin Old
786
787 Kitamura Akatsuki
788
789 Klaus S. Madsen
790
791 Knut Arne Bjorndal
792
793 Lars Balker Rasmussen
794
795 Lee Johnson
796
797 Leon Brocard
798
799 Magnus Holm
800
801 Maik Fischer
802
803 Mark Fowler
804
805 Mark Grimes
806
807 Mark Stosberg
808
809 Marty Tennison
810
811 Matt S Trout
812
813 Matthew Lineen
814
815 Maksym Komar
816
817 Maxim Vuets
818
819 Michael Gregorowicz
820
821 Michael Harris
822
823 Michael Jemmeson
824
825 Mike Magowan
826
827 Mirko Westermeier
828
829 Mons Anderson
830
831 Moritz Lenz
832
833 Neil Watkiss
834
835 Nic Sandfield
836
837 Nils Diewald
838
839 Oleg Zhelo
840
841 Olivier Mengue
842
843 Pascal Gaudette
844
845 Paul Evans
846
847 Paul Robins
848
849 Paul Tomlin
850
851 Pavel Shaydo
852
853 Pedro Melo
854
855 Peter Edwards
856
857 Pierre-Yves Ritschard
858
859 Piotr Roszatycki
860
861 Quentin Carbonneaux
862
863 Rafal Pocztarski
864
865 Randal Schwartz
866
867 Richard Elberger
868
869 Rick Delaney
870
871 Robert Hicks
872
873 Robin Lee
874
875 Roland Lammel
876
877 Roy Storey
878
879 Ryan Jendoubi
880
881 Salvador Fandino
882
883 Santiago Zarate
884
885 Sascha Kiefer
886
887 Scott Wiersdorf
888
889 Sergey Zasenko
890
891 Simon Bertrang
892
893 Simone Tampieri
894
895 Shoichi Kaji
896
897 Shu Cho
898
899 Skye Shaw
900
901 Stanis Trendelenburg
902
903 Stefan Adams
904
905 Steffen Ullrich
906
907 Stephan Kulow
908
909 Stephane Este-Gracias
910
911 Stevan Little
912
913 Steve Atkins
914
915 Tatsuhiko Miyagawa
916
917 Terrence Brannon
918
919 Tianon Gravi
920
921 Tomas Znamenacek
922
923 Tudor Constantin
924
925 Ulrich Habel
926
927 Ulrich Kautz
928
929 Uwe Voelker
930
931 Viacheslav Tykhanovskyi
932
933 Victor Engmark
934
935 Viliam Pucik
936
937 Wes Cravens
938
939 William Lindley
940
941 Yaroslav Korshak
942
943 Yuki Kimoto
944
945 Zak B. Elep
946
947 Zoffix Znet
948
950 Copyright (C) 2008-2019, Sebastian Riedel and others.
951
952 This program is free software, you can redistribute it and/or modify it
953 under the terms of the Artistic License version 2.0.
954
956 <https://github.com/mojolicious/mojo>, Mojolicious::Guides,
957 <https://mojolicious.org>.
958
959
960
961perl v5.30.0 2019-07-26 Mojolicious(3)