Mojolicious::Lite - Micro Web Framework
# Using Mojolicious::Lite will enable "strict" and "warnings" use Mojolicious::Lite; # Route with placeholder get '/:foo' => sub { my $self = shift; $self->render_text('Yea baby!'); }; # Start the Mojolicious command system shagadelic;
Mojolicous::Lite is a micro web framework built around Mojolicious.
A minimal application looks like this.
#!/usr/bin/env perl use Mojolicious::Lite; get '/' => sub { my $self = shift; $self->render_text('Yea baby!'); }; shagadelic;
There is also a helper command to generate a small example application.
% mojolicious generate lite_app
All the normal Mojolicious command options are available from the command line.
% ./myapp.pl daemon Server available at http://127.0.0.1:3000. % ./myapp.pl daemon 8080 Server available at http://127.0.0.1:8080. % ./myapp.pl daemon_prefork Server available at http://127.0.0.1:3000. % ./myapp.pl cgi ...CGI output... % ./myapp.pl fastcgi ...Blocking FastCGI main loop...
The shagadelic call that starts the Mojolicious command system can be customized to override normal @ARGV use.
@ARGV
shagadelic('cgi');
Routes are basically just fancy paths that can contain different kinds of placeholders.
# /foo get '/foo' => sub { my $self = shift; $self->render_text('Yea baby!'); };
All routes can have a name associated with them, this allows automatic template detection and back referencing with url_for. Names are always the last argument.
url_for
# / get '/' => 'index'; # /foo get '/foo' => 'foo'; # /bar get '/bar' => sub { my $self = shift; $self->render_text('Hi!') } => 'bar'; __DATA__ @@ index.html.ep <a href="<%= url_for 'foo' %>">Foo</a>. <a href="<%= url_for 'bar' %>">Bar</a>. @@ foo.html.ep <a href="<%= url_for 'index' %>">Home</a>.
Templates can have layouts.
# GET /with_layout get '/with_layout' => sub { my $self = shift; $self->render('with_layout', layout => 'green'); }; __DATA__ @@ with_layout.html.ep We've got content! @@ layouts/green.html.ep <!doctype html><html> <head><title>Green!</title></head> <body><%= content %></body> </html>
Templates can also extend each other.
# GET / get '/' => 'first'; # GET /second get '/second' => 'second'; __DATA__ @@ first.html.ep % extends 'second'; %{ content header => <title>Howdy!</title> %} First! @@ second.html.ep % layout 'third'; %{ content header => <title>Welcome!</title> %} Second! @@ layouts/third.html.ep <!doctype html><html> <head> <%{= content header => %> <title>Lame default title...</title> <%}%> </head> <body><%= content %></body> </html>
Route placeholders allow capturing parts of a request path until a / or . separator occurs, results will be stored by name in the stash.
/
.
stash
# /foo/* get '/foo/:bar' => sub { my $self = shift; my $bar = $self->stash('bar'); $self->render_text("Our :bar placeholder matched $bar"); }; # /*something/foo get '/(:bar)something/foo' => sub { my $self = shift; my $bar = $self->stash('bar'); $self->render_text("Our :bar placeholder matched $bar"); };
Relaxed placeholders allow matching of everything until a / occurs.
# GET /hello/* get '/hello/(.you)' => sub { shift->render('groovy'); }; __DATA__ @@ groovy.html.ep Your name is <%= $you %>.
Wildcard placeholders allow matching absolutely everything, including / and ..
# /hello/* get '/hello/(*you)' => sub { shift->render('groovy'); }; __DATA__ @@ groovy.html.ep Your name is <%= $you %>.
Routes can be restricted to specific request methods.
# GET /bye get '/bye' => sub { shift->render_text('Bye!') }; # POST /bye post '/bye' => sub { shift->render_text('Bye!') }; # GET|POST|DELETE /bye any [qw/get post delete/] => '/bye' => sub { shift->render_text('Bye!'); }; # /baz any '/baz' => sub { my $self = shift; my $method = $self->req->method; $self->render_text("You called /baz with $method"); };
All placeholders get compiled to a regex internally, with regex constraints this process can be easily customized.
# /* any '/:bar' => [bar => qr/\d+/] => sub { my $self = shift; my $bar = $self->stash('bar'); $self->render_text("Our :bar placeholder matched $bar"); };
Routes allow default values to make placeholders optional.
# /hello/* get '/hello/:name' => {name => 'Sebastian'} => sub { my $self = shift; $self->render('groovy', format => 'txt'); }; __DATA__ @@ groovy.txt.ep My name is <%= $name %>.
All those features can be easily used together.
# /everything/*?name=* get '/everything/:stuff' => [stuff => qr/\d+/] => {stuff => 23} => sub { shift->render('welcome'); }; __DATA__ @@ welcome.html.ep Stuff is <%= $stuff %>. Query param name is <%= param 'name' %>.
Here's a fully functional example for a html form handling application using multiple features at once.
#!/usr/bin/env perl use Mojolicious::Lite; get '/' => 'index'; post '/form' => sub { my $self = shift; my $groovy = $self->param('groovy') || 'Austin Powers'; $groovy =~ s/[^\w\s]+//g; $self->render( template => 'welcome', layout => 'funky', groovy => $groovy ); } => 'form'; shagadelic; __DATA__ @@ index.html.ep % layout 'funky'); Who is groovy? <form action="<%= url_for 'form' %>" method="POST"> <input type="text" name="groovy" /> <input type="submit" value="Woosh!"> </form> @@ welcome.html.ep <%= $groovy %> is groovy! <%= include 'menu' %> @@ menu.html.ep <a href="<%= url_for 'index' %>">Try again</a> @@ layouts/funky.html.ep <!doctype html><html> <head><title>Funky!</title></head> <body><%= content %> </body> </html>
Ladders can be used for authentication and to share code between multiple routes. All routes following a ladder are only evaluated if the ladder returns a true value.
use Mojolicious::Lite; # Authenticate based on name parameter ladder sub { my $self = shift; # Authenticated my $name = $self->param('name') || ''; return 1 if $name eq 'Bender'; # Not authenticated $self->render('denied'); return; }; # GET / (with ladder authentication) get '/' => 'index'; shagadelic; __DATA__; @@ denied.html.ep You are not Bender, permission denied! @@ index.html.ep Hi Bender!
Conditions such as agent allow even more powerful route constructs.
agent
# /foo get '/foo' => (agent => qr/Firefox/) => sub { shift->render_text('Congratulations, you are using a cool browser!'); } # /foo get '/foo' => (agent => qr/Internet Explorer/) => sub { shift->render_text('Dude, you really need to upgrade to Firefox!'); }
Formats can be automatically detected by looking at file extensions.
# /detection.html # /detection.txt get '/detection' => sub { my $self = shift; $self->render('detected'); }; __DATA__ @@ detected.html.ep <!doctype html><html> <head><title>Detected!</title></head> <body>HTML was detected.</body> </html> @@ detected.txt.ep TXT was detected.
External templates will be searched by the renderer in a templates directory.
templates
# /external any '/external' => sub { my $self = shift; # templates/foo/bar.html.ep $self->render('foo/bar'); };
Static files will be automatically served from the public directory if it exists.
public
% mkdir public % mv something.js public/something.js
Testing your application is as easy as creating a t directory and filling it with normal Perl unit tests like t/funky.t.
t
t/funky.t
use Test::More tests => 3; use Test::Mojo; use FindBin; require "$FindBin::Bin/../myapp.pl"; my $t = Test::Mojo->new; $t->get_ok('/')->status_is(200)->content_like(qr/Funky!/);
Run all unit tests with the test command.
test
% ./myapp.pl test
To disable debug messages later in a production setup you can change the Mojolicious mode, default will be development.
development
% MOJO_MODE=production ./myapp.pl
Log messages will be automatically written to a log/$mode.log file if a log directory exists.
log/$mode.log
log
% mkdir log
For more control the Mojolicious instance can be accessed directly.
app->log->level('error'); app->routes->route('/foo/:bar')->via('get')->to(callback => sub { my $self = shift; $self->render_text('Hello Mojo!'); });
In case a lite app needs to grow, lite and real Mojolicous applications can be easily mixed to make the transition process very smooth.
package MyApp::Foo; use base 'Mojolicious::Controller'; sub index { shift->render_text('It works!') } package main; use Mojolicious::Lite; get '/bar' => sub { shift->render_text('This too!') }; app->routes->namespace('MyApp'); app->routes->route('/foo/:action')->via('get') ->to(controller => 'foo', action => index); shagadelic;
Mojolicious::Lite inherits all attributes from Mojolicious.
Mojolicious::Lite inherits all methods from Mojolicious and implements the following new ones.
new
my $mojo = Mojolicious::Lite->new;
To install Mojo, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Mojo
CPAN shell
perl -MCPAN -e shell install Mojo
For more information on module installation, please visit the detailed CPAN module installation guide.