1Mojolicious::Lite(3)  User Contributed Perl Documentation Mojolicious::Lite(3)
2
3
4

NAME

6       Mojolicious::Lite - Micro Web Framework
7

SYNOPSIS

9           # Using Mojolicious::Lite will enable "strict" and "warnings"
10           use Mojolicious::Lite;
11
12           # Route with placeholder
13           get '/:foo' => sub {
14               my $self = shift;
15               my $foo  = $self->param('foo');
16               $self->render(text => "Hello from $foo!");
17           };
18
19           # Start the Mojolicious command system
20           app->start;
21

DESCRIPTION

23       Mojolicous::Lite is a micro web framework built around Mojolicious.
24
25       A minimal Hello World application looks like this, strict and warnings
26       are automatically enabled and a few functions imported when you use
27       Mojolicious::Lite, turning your script into a full featured web
28       application.
29
30           #!/usr/bin/env perl
31
32           use Mojolicious::Lite;
33
34           get '/' => sub { shift->render(text => 'Hello World!') };
35
36           app->start;
37
38       There is also a helper command to generate a small example application.
39
40           % mojolicious generate lite_app
41
42       All the normal Mojolicious command options are available from the
43       command line.  Note that CGI, FastCGI and PSGI environments can usually
44       be auto detected and will just work without commands.
45
46           % ./myapp.pl daemon
47           Server available at http://127.0.0.1:3000.
48
49           % ./myapp.pl daemon --listen http://*:8080
50           Server available at http://127.0.0.1:8080.
51
52           % ./myapp.pl daemon_prefork
53           Server available at http://127.0.0.1:3000.
54
55           % ./myapp.pl cgi
56           ...CGI output...
57
58           % ./myapp.pl fastcgi
59           ...Blocking FastCGI main loop...
60
61           % ./myapp.pl
62           ...List of available commands (or automatically detected environment)...
63
64       The app->start call that starts the Mojolicious command system can be
65       customized to override normal @ARGV use.
66
67           app->start('cgi');
68
69       Your application will automatically reload itself if you set the
70       "--reload" option, so you don't have to restart the server after every
71       change.
72
73           % ./myapp.pl daemon --reload
74           Server available at http://127.0.0.1:3000.
75
76       Routes are basically just fancy paths that can contain different kinds
77       of placeholders.
78
79           # /foo
80           get '/foo' => sub {
81               my $self = shift;
82               $self->render(text => 'Hello World!');
83           };
84
85       All routes can have a name associated with them, this allows automatic
86       template detection and back referencing with "url_for", "link_to" and
87       "form_for".  Names are always the last argument, the value "*" means
88       that the name is simply equal to the route without non-word characters.
89
90           # /
91           get '/' => 'index';
92
93           # /foo
94           get '/foo' => '*';
95
96           # /bar
97           get '/bar' => sub {
98               my $self = shift;
99               $self->render(text => 'Hi!')
100           } => 'bar';
101
102           __DATA__
103
104           @@ index.html.ep
105           <%= link_to foo => {%>
106               Foo
107           <%}%>.
108           <%= link_to bar => {%>
109               Bar
110           <%}%>.
111
112           @@ foo.html.ep
113           <a href="<%= url_for 'index' %>">Home</a>.
114
115       Templates can have layouts.
116
117           # GET /with_layout
118           get '/with_layout' => sub {
119               my $self = shift;
120               $self->render('with_layout', layout => 'green');
121           };
122
123           __DATA__
124
125           @@ with_layout.html.ep
126           We've got content!
127
128           @@ layouts/green.html.ep
129           <!doctype html><html>
130               <head><title>Green!</title></head>
131               <body><%= content %></body>
132           </html>
133
134       Template blocks can be reused like functions in Perl scripts.
135
136           # GET /with_block
137           get '/with_block' => 'block';
138
139           __DATA__
140
141           @@ block.html.ep
142           <% my $link = {%>
143               <% my ($url, $name) = @_; %>
144               Try <%= link_to $url => {%><%= $name %><%}%>!
145           <%}%>
146           <!doctype html><html>
147               <head><title>Sebastians Frameworks!</title></head>
148               <body>
149                   <%== $link->('http://mojolicious.org', 'Mojolicious') %>
150                   <%== $link->('http://catalystframework.org', 'Catalyst') %>
151               </body>
152           </html>
153
154       Templates can also pass around blocks of captured content and extend
155       each other.
156
157           # GET /
158           get '/' => 'first';
159
160           # GET /second
161           get '/second' => 'second';
162
163           __DATA__
164
165           @@ first.html.ep
166           <!doctype html><html>
167               <head><%= content header => {%><title>Hi!</title><%}%></head>
168               <body><%= content body => {%>First page!<%}%></body>
169           </html>
170
171           @@ second.html.ep
172           % extends 'first';
173           <% content header => {%>
174               <title>Howdy!</title>
175           <%}%>
176           <% content body => {%>
177               Second page!
178           <%}%>
179
180       Route placeholders allow capturing parts of a request path until a "/"
181       or "." separator occurs, results will be stored by name in the "stash"
182       and "param".
183
184           # /foo/* (everything except "/" and ".")
185           # /foo/test
186           # /foo/test123
187           get '/foo/:bar' => sub {
188               my $self = shift;
189               my $bar  = $self->stash('bar');
190               $self->render(text => "Our :bar placeholder matched $bar");
191           };
192
193           # /*something/foo (everything except "/" and ".")
194           # /test/foo
195           # /test123/foo
196           get '/(:bar)something/foo' => sub {
197               my $self = shift;
198               my $bar  = $self->param('bar');
199               $self->render(text => "Our :bar placeholder matched $bar");
200           };
201
202       Relaxed placeholders allow matching of everything until a "/" occurs.
203
204           # /*/hello (everything except "/")
205           # /test/hello
206           # /test123/hello
207           # /test.123/hello
208           get '/(.you)/hello' => sub {
209               shift->render('groovy');
210           };
211
212           __DATA__
213
214           @@ groovy.html.ep
215           Your name is <%= $you %>.
216
217       Wildcard placeholders allow matching absolutely everything, including
218       "/" and ".".
219
220           # /hello/* (everything)
221           # /hello/test
222           # /hello/test123
223           # /hello/test.123/test/123
224           get '/hello/(*you)' => sub {
225               shift->render('groovy');
226           };
227
228           __DATA__
229
230           @@ groovy.html.ep
231           Your name is <%= $you %>.
232
233       Routes can be restricted to specific request methods.
234
235           # GET /bye
236           get '/bye' => sub { shift->render(text => 'Bye!') };
237
238           # POST /bye
239           post '/bye' => sub { shift->render(text => 'Bye!') };
240
241           # GET|POST|DELETE /bye
242           any [qw/get post delete/] => '/bye' => sub {
243               shift->render(text => 'Bye!');
244           };
245
246           # /baz
247           any '/baz' => sub {
248               my $self   = shift;
249               my $method = $self->req->method;
250               $self->render(text => "You called /baz with $method");
251           };
252
253       All placeholders get compiled to a regex internally, with regex
254       constraints this process can be easily customized.
255
256           # /*
257           any '/:bar' => [bar => qr/\d+/] => sub {
258               my $self = shift;
259               my $bar  = $self->param('bar');
260               $self->render(text => "Our :bar placeholder matched $bar");
261           };
262
263       Routes allow default values to make placeholders optional.
264
265           # /hello/*
266           get '/hello/:name' => {name => 'Sebastian'} => sub {
267               my $self = shift;
268               $self->render('groovy', format => 'txt');
269           };
270
271           __DATA__
272
273           @@ groovy.txt.ep
274           My name is <%= $name %>.
275
276       All those features can be easily used together.
277
278           # /everything/*?name=*
279           get '/everything/:stuff' => [stuff => qr/\d+/] => {stuff => 23} => sub {
280               shift->render('welcome');
281           };
282
283           __DATA__
284
285           @@ welcome.html.ep
286           Stuff is <%= $stuff %>.
287           Query param name is <%= param 'name' %>.
288
289       Here's a fully functional example for a html form handling application
290       using multiple features at once.
291
292           #!/usr/bin/env perl
293
294           use Mojolicious::Lite;
295
296           get '/' => 'index';
297
298           post '/test' => sub {
299               my $self = shift;
300
301               my $groovy = $self->param('groovy') || 'Austin Powers';
302               $groovy =~ s/[^\w\s]+//g;
303
304               $self->render(
305                   template => 'welcome',
306                   layout   => 'funky',
307                   groovy   => $groovy
308               );
309           } => 'test';
310
311           app->start;
312           __DATA__
313
314           @@ index.html.ep
315           % layout 'funky';
316           Who is groovy?
317           <%= form_for test => (method => 'post') => {%>
318               <%= input 'groovy', type => 'text' %>
319               <input type="submit" value="Woosh!" />
320           <%}%>
321
322           @@ welcome.html.ep
323           <%= $groovy %> is groovy!
324           <%= include 'menu' %>
325
326           @@ menu.html.ep
327           <%= link_to index => {%>
328               Try again
329           <%}%>
330
331           @@ layouts/funky.html.ep
332           <!doctype html><html>
333               <head><title>Funky!</title></head>
334               <body><%= content %>
335               </body>
336           </html>
337
338       Authentication and code shared between multiple routes can be realized
339       easily with the "under" statement.  All following routes are only
340       evaluated if the "under" callback returned a true value.
341
342           use Mojolicious::Lite;
343
344           # Authenticate based on name parameter
345           under sub {
346               my $self = shift;
347
348               # Authenticated
349               my $name = $self->param('name') || '';
350               return 1 if $name eq 'Bender';
351
352               # Not authenticated
353               $self->render('denied');
354               return;
355           };
356
357           # GET / (with authentication)
358           get '/' => 'index';
359
360           app->start;
361           __DATA__;
362
363           @@ denied.html.ep
364           You are not Bender, permission denied!
365
366           @@ index.html.ep
367           Hi Bender!
368
369       Conditions such as "agent" allow even more powerful route constructs.
370
371           # /foo
372           get '/foo' => (agent => qr/Firefox/) => sub {
373               shift->render(
374                   text => 'Congratulations, you are using a cool browser!');
375           }
376
377           # /foo
378           get '/foo' => (agent => qr/Internet Explorer/) => sub {
379               shift->render(
380                   text => 'Dude, you really need to upgrade to Firefox!');
381           }
382
383       Formats can be automatically detected by looking at file extensions.
384
385           # /detection.html
386           # /detection.txt
387           get '/detection' => sub {
388               my $self = shift;
389               $self->render('detected');
390           };
391
392           __DATA__
393
394           @@ detected.html.ep
395           <!doctype html><html>
396               <head><title>Detected!</title></head>
397               <body>HTML was detected.</body>
398           </html>
399
400           @@ detected.txt.ep
401           TXT was detected.
402
403       Signed cookie based sessions just work out of the box as soon as you
404       start using them.  The "flash" can be used to store values that will
405       only be available for one request, this is very useful in combination
406       with "redirect_to".
407
408           use Mojolicious::Lite;
409
410           get '/login' => sub {
411               my $self = shift;
412               my $name = $self->param('name') || '';
413               my $pass = $self->param('pass') || '';
414               return $self->render unless $name eq 'sebastian' && $pass eq '1234';
415               $self->session(name => $name);
416               $self->flash(message => 'Thanks for logging in!');
417               $self->redirect_to('index');
418           } => 'login';
419
420           get '/' => sub {
421               my $self = shift;
422               return $self->redirect_to('login') unless $self->session('name');
423               $self->render;
424           } => 'index';
425
426           get '/logout' => sub {
427               my $self = shift;
428               $self->session(expires => 1);
429               $self->redirect_to('index');
430           } => 'logout';
431
432           app->start;
433           __DATA__
434
435           @@ layouts/default.html.ep
436           <!doctype html><html>
437               <head><title>Mojolicious rocks!</title></head>
438               <body><%= content %></body>
439           </html>
440
441           @@ login.html.ep
442           % layout 'default';
443           <%= form_for login => {%>
444               <% if (param 'name') { %>
445                   <b>Wrong name or password, please try again.</b><br />
446               <% } %>
447               Name:<br />
448               <%= input name => (type => 'text') %><br />
449               Password:<br />
450               <%= input pass => (type => 'text') %><br />
451               <input type="submit" value="Login" />
452           <%}%>
453
454           @@ index.html.ep
455           % layout 'default';
456           <% if (my $message = flash 'message' ) { %>
457               <b><%= $message %></b><br />
458           <% } %>
459           Welcome <%= session 'name' %>!<br />
460           <%= link_to logout => {%>
461               Logout
462           <%}%>
463
464       Note that you should use a custom "secret" to make signed cookies
465       really secure.
466
467           app->secret('My secret passphrase here!');
468
469       A full featured HTTP 1.1 and WebSocket client is built right in.
470       Especially in combination with Mojo::JSON and Mojo::DOM this can be a
471       very powerful tool.
472
473           get '/test' => sub {
474               my $self = shift;
475               $self->render(
476                   data => $self->client->get('http://mojolicious.org')->res->body);
477           };
478
479       WebSocket applications have never been this easy before.
480
481           websocket '/echo' => sub {
482               my $self = shift;
483               $self->receive_message(sub {
484                   my ($self, $message) = @_;
485                   $self->send_message("echo: $message");
486               });
487           };
488
489       External templates will be searched by the renderer in a "templates"
490       directory.
491
492           # /external
493           any '/external' => sub {
494               my $self = shift;
495
496               # templates/foo/bar.html.ep
497               $self->render('foo/bar');
498           };
499
500       Static files will be automatically served from the "DATA" section (even
501       Base 64 encoded) or a "public" directory if it exists.
502
503           @@ something.js
504           alert('hello!');
505
506           @@ test.txt (base64)
507           dGVzdCAxMjMKbGFsYWxh
508
509           % mkdir public
510           % mv something.js public/something.js
511
512       Testing your application is as easy as creating a "t" directory and
513       filling it with normal Perl unit tests like "t/funky.t".
514
515           use Test::More tests => 3;
516           use Test::Mojo;
517
518           use FindBin;
519           $ENV{MOJO_HOME} = "$FindBin::Bin/../";
520           require "$ENV{MOJO_HOME}/myapp.pl";
521
522           my $t = Test::Mojo->new;
523           $t->get_ok('/')->status_is(200)->content_like(qr/Funky!/);
524
525       Run all unit tests with the "test" command.
526
527           % ./myapp.pl test
528
529       To make your tests less noisy you can also change the application log
530       level directly in your test files.
531
532           $t->app->log->level('error');
533
534       To disable debug messages later in a production setup you can change
535       the Mojolicious mode, default will be "development".
536
537           % MOJO_MODE=production ./myapp.pl
538
539       Log messages will be automatically written to a "log/$mode.log" file if
540       a "log" directory exists.
541
542           % mkdir log
543
544       For more control the Mojolicious instance can be accessed directly.
545
546           app->log->level('error');
547           app->routes->route('/foo/:bar')->via('get')->to(cb => sub {
548               my $self = shift;
549               $self->render(text => 'Hello Mojo!');
550           });
551
552       In case a lite app needs to grow, lite and real Mojolicous applications
553       can be easily mixed to make the transition process very smooth.
554
555           package MyApp::Foo;
556           use base 'Mojolicious::Controller';
557
558           sub index { shift->render(text => 'It works!') }
559
560           package main;
561           use Mojolicious::Lite;
562
563           get '/bar' => sub { shift->render(text => 'This too!') };
564
565           app->routes->namespace('MyApp');
566           app->routes->route('/foo/:action')->via('get')->to('foo#index');
567
568           app->start;
569
570       There is also a helper command to generate a full Mojolicious example
571       that will let you explore the astonishing similarities between
572       Mojolicious::Lite and Mojolicious applications.  Both share about 99%
573       of the same code, so almost everything you learned in this tutorial
574       applies there too. :)
575
576           % mojolicious generate app
577
578       Have fun!
579

ATTRIBUTES

581       Mojolicious::Lite inherits all attributes from Mojolicious.
582

METHODS

584       Mojolicious::Lite inherits all methods from Mojolicious.
585

SEE ALSO

587       Mojolicious, Mojolicious::Guides, <http://mojolicious.org>.
588
589
590
591perl v5.12.3                      2010-08-14              Mojolicious::Lite(3)
Impressum