1Mojolicious::Guides::TuUtsoerriaClo(n3t)ributed Perl DocMuomjeonltiactiioouns::Guides::Tutorial(3)
2
3
4

NAME

6       Mojolicious::Guides::Tutorial - Get started with Mojolicious
7

TUTORIAL

9       A quick example-driven introduction to the wonders of
10       Mojolicious::Lite. Almost everything you'll learn here also applies to
11       full Mojolicious applications.
12
13       This is only the first of the Mojolicious::Guides. Other guides delve
14       deeper into topics like growing a Mojolicious::Lite prototype into a
15       well-structured Mojolicious application, routing, rendering and more.
16       It is highly encouraged that readers continue on to the remaining
17       guides after reading this one.
18
19   Hello World
20       A simple Hello World application can look like this, strict, warnings,
21       utf8 and Perl 5.16 features are automatically enabled and a few
22       functions imported, when you use Mojolicious::Lite, turning your script
23       into a full featured web application.
24
25         #!/usr/bin/env perl
26         use Mojolicious::Lite;
27
28         get '/' => sub {
29           my $c = shift;
30           $c->render(text => 'Hello World!');
31         };
32
33         app->start;
34
35       With Mojolicious::Command::Author::generate::lite_app there is also a
36       helper command to generate a small example application.
37
38         $ mojo generate lite-app myapp.pl
39
40   Commands
41       Many different commands are automatically available from the command
42       line. CGI and PSGI environments can even be detected and will usually
43       just work without commands.
44
45         $ ./myapp.pl daemon
46         Web application available at http://127.0.0.1:3000
47
48         $ ./myapp.pl daemon -l http://*:8080
49         Web application available at http://127.0.0.1:8080
50
51         $ ./myapp.pl cgi
52         ...CGI output...
53
54         $ ./myapp.pl get /
55         Hello World!
56
57         $ ./myapp.pl
58         ...List of available commands (or automatically detected environment)...
59
60       A call to "start" in Mojolicious ("app->start"), which starts the
61       command system, should be the last expression in your application,
62       because its return value can be significant.
63
64         # Use @ARGV to pick a command
65         app->start;
66
67         # Start the "daemon" command
68         app->start('daemon', '-l', 'http://*:8080');
69
70   Reloading
71       Your application will automatically reload itself if you start it with
72       the morbo development web server, so you don't have to restart the
73       server after every change.
74
75         $ morbo ./myapp.pl
76         Web application available at http://127.0.0.1:3000
77
78       For more information about how to deploy your application see also
79       "DEPLOYMENT" in Mojolicious::Guides::Cookbook.
80
81   Routes
82       Routes are basically just fancy paths that can contain different kinds
83       of placeholders and usually lead to an action, if they match the path
84       part of the request URL. The first argument passed to all actions ($c)
85       is a Mojolicious::Controller object, containing both the HTTP request
86       and response.
87
88         use Mojolicious::Lite;
89
90         # Route leading to an action that renders some text
91         get '/foo' => sub {
92           my $c = shift;
93           $c->render(text => 'Hello World!');
94         };
95
96         app->start;
97
98       Response content is often generated by actions with "render" in
99       Mojolicious::Controller, but more about that later.
100
101   GET/POST parameters
102       All "GET" and "POST" parameters sent with the request are accessible
103       via "param" in Mojolicious::Controller.
104
105         use Mojolicious::Lite;
106
107         # /foo?user=sri
108         get '/foo' => sub {
109           my $c    = shift;
110           my $user = $c->param('user');
111           $c->render(text => "Hello $user.");
112         };
113
114         app->start;
115
116   Stash and templates
117       The "stash" in Mojolicious::Controller is used to pass data to
118       templates, which can be inlined in the "DATA" section.  A few stash
119       values like "template", "text" and "data" are reserved and will be used
120       by "render" in Mojolicious::Controller to decide how a response should
121       be generated.
122
123         use Mojolicious::Lite;
124
125         # Route leading to an action that renders a template
126         get '/foo' => sub {
127           my $c = shift;
128           $c->stash(one => 23);
129           $c->render(template => 'magic', two => 24);
130         };
131
132         app->start;
133         __DATA__
134
135         @@ magic.html.ep
136         The magic numbers are <%= $one %> and <%= $two %>.
137
138       For more information about templates see also "Embedded Perl" in
139       Mojolicious::Guides::Rendering.
140
141   HTTP
142       "req" in Mojolicious::Controller and "res" in Mojolicious::Controller
143       give you full access to all HTTP features and information.
144
145         use Mojolicious::Lite;
146
147         # Access request information
148         get '/agent' => sub {
149           my $c    = shift;
150           my $host = $c->req->url->to_abs->host;
151           my $ua   = $c->req->headers->user_agent;
152           $c->render(text => "Request by $ua reached $host.");
153         };
154
155         # Echo the request body and send custom header with response
156         post '/echo' => sub {
157           my $c = shift;
158           $c->res->headers->header('X-Bender' => 'Bite my shiny metal ass!');
159           $c->render(data => $c->req->body);
160         };
161
162         app->start;
163
164       You can test the more advanced examples right from the command line
165       with Mojolicious::Command::get.
166
167         $ ./myapp.pl get -v -M POST -c 'test' /echo
168
169   JSON
170       JSON is the most commonly used data-interchange format for web
171       services. Mojolicious loves JSON and comes with the possibly fastest
172       pure-Perl implementation Mojo::JSON built right in, which is accessible
173       through "json" in Mojo::Message as well as the reserved stash value
174       "json".
175
176         use Mojolicious::Lite;
177
178         # Modify the received JSON document and return it
179         put '/reverse' => sub {
180           my $c    = shift;
181           my $hash = $c->req->json;
182           $hash->{message} = reverse $hash->{message};
183           $c->render(json => $hash);
184         };
185
186         app->start;
187
188       You can send JSON documents from the command line with
189       Mojolicious::Command::get.
190
191         $ ./myapp.pl get -M PUT -c '{"message":"Hello Mojo!"}' /reverse
192
193   Built-in "exception" and "not_found" pages
194       During development you will encounter these pages whenever you make a
195       mistake, they are gorgeous and contain a lot of valuable information
196       that will aid you in debugging your application.
197
198         use Mojolicious::Lite;
199
200         # Not found (404)
201         get '/missing' => sub { shift->render(template => 'does_not_exist') };
202
203         # Exception (500)
204         get '/dies' => sub { die 'Intentional error' };
205
206         app->start;
207
208       You can even use CSS selectors with Mojolicious::Command::get to
209       extract only the information you're actually interested in.
210
211         $ ./myapp.pl get /dies '#error'
212
213       And don't worry about revealing too much information on these pages,
214       they are only available during development, and will be replaced
215       automatically with pages that don't reveal any sensitive information in
216       a production environment.
217
218   Route names
219       All routes can have a name associated with them, this allows automatic
220       template detection and backreferencing with "url_for" in
221       Mojolicious::Controller, on which many methods and helpers like
222       "link_to" in Mojolicious::Plugin::TagHelpers rely.
223
224         use Mojolicious::Lite;
225
226         # Render the template "index.html.ep"
227         get '/' => sub {
228           my $c = shift;
229           $c->render;
230         } => 'index';
231
232         # Render the template "hello.html.ep"
233         get '/hello';
234
235         app->start;
236         __DATA__
237
238         @@ index.html.ep
239         <%= link_to Hello  => 'hello' %>.
240         <%= link_to Reload => 'index' %>.
241
242         @@ hello.html.ep
243         Hello World!
244
245       Nameless routes get an automatically generated one assigned that is
246       simply equal to the route itself without non-word characters.
247
248   Layouts
249       Templates can have layouts too, you just select one with the helper
250       "layout" in Mojolicious::Plugin::DefaultHelpers and place the result of
251       the current template with the helper "content" in
252       Mojolicious::Plugin::DefaultHelpers.
253
254         use Mojolicious::Lite;
255
256         get '/with_layout';
257
258         app->start;
259         __DATA__
260
261         @@ with_layout.html.ep
262         % title 'Green';
263         % layout 'green';
264         Hello World!
265
266         @@ layouts/green.html.ep
267         <!DOCTYPE html>
268         <html>
269           <head><title><%= title %></title></head>
270           <body><%= content %></body>
271         </html>
272
273       The stash or helpers like "title" in
274       Mojolicious::Plugin::DefaultHelpers can be used to pass additional data
275       to the layout.
276
277   Blocks
278       Template blocks can be used like normal Perl functions and are always
279       delimited by the "begin" and "end" keywords, they are the foundation
280       for many helpers.
281
282         use Mojolicious::Lite;
283
284         get '/with_block' => 'block';
285
286         app->start;
287         __DATA__
288
289         @@ block.html.ep
290         % my $link = begin
291           % my ($url, $name) = @_;
292           Try <%= link_to $url => begin %><%= $name %><% end %>.
293         % end
294         <!DOCTYPE html>
295         <html>
296           <head><title>Sebastians frameworks</title></head>
297           <body>
298             %= $link->('http://mojolicious.org', 'Mojolicious')
299             %= $link->('http://catalystframework.org', 'Catalyst')
300           </body>
301         </html>
302
303   Helpers
304       Helpers are little functions you can create with the keyword "helper"
305       in Mojolicious::Lite and reuse throughout your whole application, from
306       actions to templates.
307
308         use Mojolicious::Lite;
309
310         # A helper to identify visitors
311         helper whois => sub {
312           my $c     = shift;
313           my $agent = $c->req->headers->user_agent || 'Anonymous';
314           my $ip    = $c->tx->remote_address;
315           return "$agent ($ip)";
316         };
317
318         # Use helper in action and template
319         get '/secret' => sub {
320           my $c    = shift;
321           my $user = $c->whois;
322           $c->app->log->debug("Request from $user");
323         };
324
325         app->start;
326         __DATA__
327
328         @@ secret.html.ep
329         We know who you are <%= whois %>.
330
331       A list of all built-in ones can be found in
332       Mojolicious::Plugin::DefaultHelpers and
333       Mojolicious::Plugin::TagHelpers.
334
335   Plugins
336       Plugins are application extensions that help with code sharing and
337       organization. You can load a plugin with the keyword "plugin" in
338       Mojolicious::Lite, which can omit the "Mojolicious::Plugin::" part of
339       the name, and optionally provide configuration for the plugin.
340
341         use Mojolicious::Lite;
342
343         plugin Config => {file => '/etc/myapp.conf', default => {foo => 'bar'}};
344
345         # Return configured foo value, or default if no configuration file
346         get '/foo' => sub {
347           my $c   = shift;
348           my $foo = $c->app->config('foo');
349           $c->render(json => {foo => $foo});
350         };
351
352         app->start;
353
354       Mojolicious::Plugin::Config is a built-in plugin which can populate
355       "config" in Mojolicious using a config file.  Plugins can also set up
356       routes, hooks, handlers, or even load other plugins. A list of built-in
357       plugins can be found at "PLUGINS" in Mojolicious::Plugins, and many
358       more are available from CPAN
359       <https://metacpan.org/search?q=Mojolicious+Plugin>.
360
361   Placeholders
362       Route placeholders allow capturing parts of a request path until a "/"
363       or "." separator occurs, similar to the regular expression "([^/.]+)".
364       Results are accessible via "stash" in Mojolicious::Controller and
365       "param" in Mojolicious::Controller.
366
367         use Mojolicious::Lite;
368
369         # /foo/test
370         # /foo/test123
371         get '/foo/:bar' => sub {
372           my $c   = shift;
373           my $bar = $c->stash('bar');
374           $c->render(text => "Our :bar placeholder matched $bar");
375         };
376
377         # /testsomething/foo
378         # /test123something/foo
379         get '/<:bar>something/foo' => sub {
380           my $c   = shift;
381           my $bar = $c->param('bar');
382           $c->render(text => "Our :bar placeholder matched $bar");
383         };
384
385         app->start;
386
387       To separate them from the surrounding text, you can surround your
388       placeholders with "<" and ">", which also makes the colon prefix
389       optional.
390
391   Relaxed Placeholders
392       Relaxed placeholders allow matching of everything until a "/" occurs,
393       similar to the regular expression "([^/]+)".
394
395         use Mojolicious::Lite;
396
397         # /hello/test
398         # /hello/test.html
399         get '/hello/#you' => 'groovy';
400
401         app->start;
402         __DATA__
403
404         @@ groovy.html.ep
405         Your name is <%= $you %>.
406
407   Wildcard placeholders
408       Wildcard placeholders allow matching absolutely everything, including
409       "/" and ".", similar to the regular expression "(.+)".
410
411         use Mojolicious::Lite;
412
413         # /hello/test
414         # /hello/test123
415         # /hello/test.123/test/123
416         get '/hello/*you' => 'groovy';
417
418         app->start;
419         __DATA__
420
421         @@ groovy.html.ep
422         Your name is <%= $you %>.
423
424   HTTP methods
425       Routes can be restricted to specific request methods with different
426       keywords like "get" in Mojolicious::Lite and "any" in
427       Mojolicious::Lite.
428
429         use Mojolicious::Lite;
430
431         # GET /hello
432         get '/hello' => sub {
433           my $c = shift;
434           $c->render(text => 'Hello World!');
435         };
436
437         # PUT /hello
438         put '/hello' => sub {
439           my $c    = shift;
440           my $size = length $c->req->body;
441           $c->render(text => "You uploaded $size bytes to /hello.");
442         };
443
444         # GET|POST|PATCH /bye
445         any ['GET', 'POST', 'PATCH'] => '/bye' => sub {
446           my $c = shift;
447           $c->render(text => 'Bye World!');
448         };
449
450         # * /whatever
451         any '/whatever' => sub {
452           my $c      = shift;
453           my $method = $c->req->method;
454           $c->render(text => "You called /whatever with $method.");
455         };
456
457         app->start;
458
459   Optional placeholders
460       All placeholders require a value, but by assigning them default values
461       you can make capturing optional.
462
463         use Mojolicious::Lite;
464
465         # /hello
466         # /hello/Sara
467         get '/hello/:name' => {name => 'Sebastian', day => 'Monday'} => sub {
468           my $c = shift;
469           $c->render(template => 'groovy', format => 'txt');
470         };
471
472         app->start;
473         __DATA__
474
475         @@ groovy.txt.ep
476         My name is <%= $name %> and it is <%= $day %>.
477
478       Default values that don't belong to a placeholder simply get merged
479       into the stash all the time.
480
481   Restrictive placeholders
482       A very easy way to make placeholders more restrictive are alternatives,
483       you just make a list of possible values.
484
485         use Mojolicious::Lite;
486
487         # /test
488         # /123
489         any '/:foo' => [foo => ['test', '123']] => sub {
490           my $c   = shift;
491           my $foo = $c->param('foo');
492           $c->render(text => "Our :foo placeholder matched $foo");
493         };
494
495         app->start;
496
497       All placeholders get compiled to a regular expression internally, this
498       process can also be customized. Just make sure not to use "^" and "$",
499       or capturing groups "(...)", non-capturing groups "(?:...)" are fine
500       though.
501
502         use Mojolicious::Lite;
503
504         # /1
505         # /123
506         any '/:bar' => [bar => qr/\d+/] => sub {
507           my $c   = shift;
508           my $bar = $c->param('bar');
509           $c->render(text => "Our :bar placeholder matched $bar");
510         };
511
512         app->start;
513
514       You can take a closer look at all the generated regular expressions
515       with the command Mojolicious::Command::routes.
516
517         $ ./myapp.pl routes -v
518
519   Under
520       Authentication and code shared between multiple routes can be realized
521       easily with routes generated by "under" in Mojolicious::Lite. All
522       following routes are only evaluated if the callback returned a true
523       value.
524
525         use Mojolicious::Lite;
526
527         # Authenticate based on name parameter
528         under sub {
529           my $c = shift;
530
531           # Authenticated
532           my $name = $c->param('name') || '';
533           return 1 if $name eq 'Bender';
534
535           # Not authenticated
536           $c->render(template => 'denied');
537           return undef;
538         };
539
540         # Only reached when authenticated
541         get '/' => 'index';
542
543         app->start;
544         __DATA__
545
546         @@ denied.html.ep
547         You are not Bender, permission denied.
548
549         @@ index.html.ep
550         Hi Bender.
551
552       Prefixing multiple routes is another good use for it.
553
554         use Mojolicious::Lite;
555
556         # /foo
557         under '/foo';
558
559         # /foo/bar
560         get '/bar' => {text => 'foo bar'};
561
562         # /foo/baz
563         get '/baz' => {text => 'foo baz'};
564
565         # / (reset)
566         under '/' => {msg => 'whatever'};
567
568         # /bar
569         get '/bar' => {inline => '<%= $msg %> works'};
570
571         app->start;
572
573       You can also group related routes with "group" in Mojolicious::Lite,
574       which allows nesting of routes generated with "under" in
575       Mojolicious::Lite.
576
577         use Mojolicious::Lite;
578
579         # Global logic shared by all routes
580         under sub {
581           my $c = shift;
582           return 1 if $c->req->headers->header('X-Bender');
583           $c->render(text => "You're not Bender.");
584           return undef;
585         };
586
587         # Admin section
588         group {
589
590           # Local logic shared only by routes in this group
591           under '/admin' => sub {
592             my $c = shift;
593             return 1 if $c->req->headers->header('X-Awesome');
594             $c->render(text => "You're not awesome enough.");
595             return undef;
596           };
597
598           # GET /admin/dashboard
599           get '/dashboard' => {text => 'Nothing to see here yet.'};
600         };
601
602         # GET /welcome
603         get '/welcome' => {text => 'Hi Bender.'};
604
605         app->start;
606
607   Formats
608       Formats can be automatically detected from file extensions like
609       ".html", they are used to find the right template and generate the
610       correct "Content-Type" header.
611
612         use Mojolicious::Lite;
613
614         # /detection
615         # /detection.html
616         # /detection.txt
617         get '/detection' => sub {
618           my $c = shift;
619           $c->render(template => 'detected');
620         };
621
622         app->start;
623         __DATA__
624
625         @@ detected.html.ep
626         <!DOCTYPE html>
627         <html>
628           <head><title>Detected</title></head>
629           <body>HTML was detected.</body>
630         </html>
631
632         @@ detected.txt.ep
633         TXT was detected.
634
635       The default format is "html", and restrictive placeholders can be used
636       to limit possible values.
637
638         use Mojolicious::Lite;
639
640         # /hello.json
641         # /hello.txt
642         get '/hello' => [format => ['json', 'txt']] => sub {
643           my $c = shift;
644           return $c->render(json => {hello => 'world'})
645             if $c->stash('format') eq 'json';
646           $c->render(text => 'hello world');
647         };
648
649         app->start;
650
651       Or you can just disable format detection with a special type of
652       restrictive placeholder.
653
654         use Mojolicious::Lite;
655
656         # /hello
657         get '/hello' => [format => 0] => {text => 'No format detection.'};
658
659         # Disable detection and allow the following routes to re-enable it on demand
660         under [format => 0];
661
662         # /foo
663         get '/foo' => {text => 'No format detection again.'};
664
665         # /bar.txt
666         get '/bar' => [format => 'txt'] => {text => ' Just one format.'};
667
668         app->start;
669
670   Content negotiation
671       For resources with different representations and that require truly
672       RESTful content negotiation you can also use "respond_to" in
673       Mojolicious::Plugin::DefaultHelpers.
674
675         use Mojolicious::Lite;
676
677         # /hello (Accept: application/json)
678         # /hello (Accept: application/xml)
679         # /hello.json
680         # /hello.xml
681         # /hello?format=json
682         # /hello?format=xml
683         get '/hello' => sub {
684           my $c = shift;
685           $c->respond_to(
686             json => {json => {hello => 'world'}},
687             xml  => {text => '<hello>world</hello>'},
688             any  => {data => '', status => 204}
689           );
690         };
691
692         app->start;
693
694       MIME type mappings can be extended or changed easily with "types" in
695       Mojolicious.
696
697         app->types->type(rdf => 'application/rdf+xml');
698
699   Static files
700       Similar to templates, but with only a single file extension and
701       optional Base64 encoding, static files can be inlined in the "DATA"
702       section and are served automatically.
703
704         use Mojolicious::Lite;
705
706         app->start;
707         __DATA__
708
709         @@ something.js
710         alert('hello!');
711
712         @@ test.txt (base64)
713         dGVzdCAxMjMKbGFsYWxh
714
715       External static files are not limited to a single file extension and
716       will be served automatically from a "public" directory if it exists.
717
718         $ mkdir public
719         $ mv something.js public/something.js
720         $ mv mojolicious.tar.gz public/mojolicious.tar.gz
721
722       Both have a higher precedence than routes for "GET" and "HEAD"
723       requests. Content negotiation with "Range", "If-None-Match" and
724       "If-Modified-Since" headers is supported as well and can be tested very
725       easily with Mojolicious::Command::get.
726
727         $ ./myapp.pl get /something.js -v -H 'Range: bytes=2-4'
728
729   External templates
730       External templates will be searched by the renderer in a "templates"
731       directory if it exists.
732
733         $ mkdir -p templates/foo
734         $ echo 'Hello World!' > templates/foo/bar.html.ep
735
736       They have a higher precedence than templates in the "DATA" section.
737
738         use Mojolicious::Lite;
739
740         # Render template "templates/foo/bar.html.ep"
741         any '/external' => sub {
742           my $c = shift;
743           $c->render(template => 'foo/bar');
744         };
745
746         app->start;
747
748   Home
749       You can use "home" in Mojolicious to interact with the directory your
750       application considers its home. This is the directory it will search
751       for "public" and "templates" directories, but you can use it to store
752       all sorts of application specific data.
753
754         $ mkdir cache
755         $ echo 'Hello World!' > cache/hello.txt
756
757       There are many useful methods Mojo::Home inherits from Mojo::File, like
758       "child" in Mojo::File and "slurp" in Mojo::File, that will help you
759       keep your application portable across many different operating systems.
760
761         use Mojolicious::Lite;
762
763         # Load message into memory
764         my $hello = app->home->child('cache', 'hello.txt')->slurp;
765
766         # Display message
767         get '/' => sub {
768           my $c = shift;
769           $c->render(text => $hello);
770         };
771
772       You can also introspect your application from the command line with
773       Mojolicious::Command::eval.
774
775         $ ./myapp.pl eval -v 'app->home'
776
777   Conditions
778       Conditions such as "agent" and "host" from
779       Mojolicious::Plugin::HeaderCondition allow even more powerful route
780       constructs.
781
782         use Mojolicious::Lite;
783
784         # Firefox
785         get '/foo' => (agent => qr/Firefox/) => sub {
786           my $c = shift;
787           $c->render(text => 'Congratulations, you are using a cool browser.');
788         };
789
790         # Internet Explorer
791         get '/foo' => (agent => qr/Internet Explorer/) => sub {
792           my $c = shift;
793           $c->render(text => 'Dude, you really need to upgrade to Firefox.');
794         };
795
796         # http://mojolicious.org/bar
797         get '/bar' => (host => 'mojolicious.org') => sub {
798           my $c = shift;
799           $c->render(text => 'Hello Mojolicious.');
800         };
801
802         app->start;
803
804   Sessions
805       Cookie-based sessions just work out of the box, as soon as you start
806       using them through the helper "session" in
807       Mojolicious::Plugin::DefaultHelpers. Just be aware that all session
808       data gets serialized with Mojo::JSON and stored client-side, with a
809       cryptographic signature to prevent tampering.
810
811         use Mojolicious::Lite;
812
813         # Access session data in action and template
814         get '/counter' => sub {
815           my $c = shift;
816           $c->session->{counter}++;
817         };
818
819         app->start;
820         __DATA__
821
822         @@ counter.html.ep
823         Counter: <%= session 'counter' %>
824
825       Note that you should use custom "secrets" in Mojolicious to make signed
826       cookies really tamper resistant.
827
828         app->secrets(['My secret passphrase here']);
829
830   File uploads
831       All files uploaded via "multipart/form-data" request are automatically
832       available as Mojo::Upload objects from "param" in
833       Mojolicious::Controller. And you don't have to worry about memory
834       usage, because all files above 250KiB will be automatically streamed
835       into a temporary file. To build HTML forms more efficiently, you can
836       also use tag helpers like "form_for" in
837       Mojolicious::Plugin::TagHelpers.
838
839         use Mojolicious::Lite;
840
841         # Upload form in DATA section
842         get '/' => 'form';
843
844         # Multipart upload handler
845         post '/upload' => sub {
846           my $c = shift;
847
848           # Check file size
849           return $c->render(text => 'File is too big.', status => 200)
850             if $c->req->is_limit_exceeded;
851
852           # Process uploaded file
853           return $c->redirect_to('form') unless my $example = $c->param('example');
854           my $size = $example->size;
855           my $name = $example->filename;
856           $c->render(text => "Thanks for uploading $size byte file $name.");
857         };
858
859         app->start;
860         __DATA__
861
862         @@ form.html.ep
863         <!DOCTYPE html>
864         <html>
865           <head><title>Upload</title></head>
866           <body>
867             %= form_for upload => (enctype => 'multipart/form-data') => begin
868               %= file_field 'example'
869               %= submit_button 'Upload'
870             % end
871           </body>
872         </html>
873
874       To protect you from excessively large files there is also a limit of
875       16MiB by default, which you can tweak with the attribute
876       "max_request_size" in Mojolicious.
877
878         # Increase limit to 1GiB
879         app->max_request_size(1073741824);
880
881   User agent
882       With Mojo::UserAgent, which is available through the helper "ua" in
883       Mojolicious::Plugin::DefaultHelpers, there's a full featured HTTP and
884       WebSocket user agent built right in. Especially in combination with
885       Mojo::JSON and Mojo::DOM this can be a very powerful tool.
886
887         use Mojolicious::Lite;
888
889         # Blocking
890         get '/headers' => sub {
891           my $c   = shift;
892           my $url = $c->param('url') || 'https://mojolicious.org';
893           my $dom = $c->ua->get($url)->result->dom;
894           $c->render(json => $dom->find('h1, h2, h3')->map('text')->to_array);
895         };
896
897         # Non-blocking
898         get '/title' => sub {
899           my $c = shift;
900           $c->ua->get('mojolicious.org' => sub {
901             my ($ua, $tx) = @_;
902             $c->render(data => $tx->result->dom->at('title')->text);
903           });
904         };
905
906         # Concurrent non-blocking
907         get '/titles' => sub {
908           my $c  = shift;
909           my $mojo = $c->ua->get_p('https://mojolicious.org');
910           my $cpan = $c->ua->get_p('https://metacpan.org');
911           Mojo::Promise->all($mojo, $cpan)->then(sub {
912             my ($mojo, $cpan) = @_;
913             $c->render(json => {
914               mojo => $mojo->[0]->result->dom->at('title')->text,
915               cpan => $cpan->[0]->result->dom->at('title')->text
916             });
917           })->wait;
918         };
919
920         app->start;
921
922       For more information about the user agent see also "USER AGENT" in
923       Mojolicious::Guides::Cookbook.
924
925   WebSockets
926       WebSocket applications have never been this simple before. Just receive
927       messages by subscribing to events such as "json" in
928       Mojo::Transaction::WebSocket with "on" in Mojolicious::Controller and
929       return them with "send" in Mojolicious::Controller.
930
931         use Mojolicious::Lite;
932
933         websocket '/echo' => sub {
934           my $c = shift;
935           $c->on(json => sub {
936             my ($c, $hash) = @_;
937             $hash->{msg} = "echo: $hash->{msg}";
938             $c->send({json => $hash});
939           });
940         };
941
942         get '/' => 'index';
943
944         app->start;
945         __DATA__
946
947         @@ index.html.ep
948         <!DOCTYPE html>
949         <html>
950           <head>
951             <title>Echo</title>
952             <script>
953               var ws = new WebSocket('<%= url_for('echo')->to_abs %>');
954               ws.onmessage = function (event) {
955                 document.body.innerHTML += JSON.parse(event.data).msg;
956               };
957               ws.onopen = function (event) {
958                 ws.send(JSON.stringify({msg: 'I ♥ Mojolicious!'}));
959               };
960             </script>
961           </head>
962         </html>
963
964       For more information about real-time web features see also "REAL-TIME
965       WEB" in Mojolicious::Guides::Cookbook.
966
967   Mode
968       You can use the Mojo::Log object from "log" in Mojolicious to portably
969       collect debug messages and automatically disable them later in a
970       production setup by changing the Mojolicious operating mode, which can
971       also be retrieved from the attribute "mode" in Mojolicious.
972
973         use Mojolicious::Lite;
974
975         # Prepare mode specific message during startup
976         my $msg = app->mode eq 'development' ? 'Development!' : 'Something else!';
977
978         get '/' => sub {
979           my $c = shift;
980           $c->app->log->debug('Rendering mode specific message');
981           $c->render(text => $msg);
982         };
983
984         app->log->debug('Starting application');
985         app->start;
986
987       The default operating mode will usually be "development" and can be
988       changed with command line options or the "MOJO_MODE" and "PLACK_ENV"
989       environment variables. A mode other than "development" will raise the
990       log level from "debug" to "info".
991
992         $ ./myapp.pl daemon -m production
993
994       All messages will be written to "STDERR" or a "log/$mode.log" file if a
995       "log" directory exists.
996
997         $ mkdir log
998
999       Mode changes also affect a few other aspects of the framework, such as
1000       the built-in "exception" and "not_found" pages. Once you switch modes
1001       from "development" to "production", no sensitive information will be
1002       revealed on those pages anymore.
1003
1004   Testing
1005       Testing your application is as easy as creating a "t" directory and
1006       filling it with normal Perl tests like "t/basic.t", which can be a lot
1007       of fun thanks to Test::Mojo.
1008
1009         use Test::More;
1010         use Mojo::File qw(curfile);
1011         use Test::Mojo;
1012
1013         # Portably point to "../myapp.pl"
1014         my $script = curfile->dirname->sibling('myapp.pl');
1015
1016         my $t = Test::Mojo->new($script);
1017         $t->get_ok('/')->status_is(200)->content_like(qr/Funky/);
1018
1019         done_testing();
1020
1021       Just run your tests with prove.
1022
1023         $ prove -l -v
1024         $ prove -l -v t/basic.t
1025

MORE

1027       You can continue with Mojolicious::Guides now or take a look at the
1028       Mojolicious wiki <http://github.com/mojolicious/mojo/wiki>, which
1029       contains a lot more documentation and examples by many different
1030       authors.
1031

SUPPORT

1033       If you have any questions the documentation might not yet answer, don't
1034       hesitate to ask on the mailing list
1035       <http://groups.google.com/group/mojolicious> or the official IRC
1036       channel "#mojo" on "irc.freenode.net" (chat now!
1037       <https://webchat.freenode.net/#mojo>).
1038
1039
1040
1041perl v5.32.0                      2020-07-28  Mojolicious::Guides::Tutorial(3)
Impressum