Skip to content

Instantly share code, notes, and snippets.

Created December 3, 2012 00:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/4191717 to your computer and use it in GitHub Desktop.
Save anonymous/4191717 to your computer and use it in GitHub Desktop.
Beginnings of a Mojolicious Tutorial
=head1 TUTORIAL
A quick example driven introduction to the wonders of L<Mojolicious>.
=head2 Hello World Generator
A simple Hello World application can be constructed in a few commands.
$ mojo generate app Eg
[mkdir] .../eg/script
[write] .../eg/script/eg
[chmod] eg/script/eg 744
[mkdir] .../eg/lib
[write] .../eg/lib/Eg.pm
[mkdir] .../eg/lib/Eg
[write] .../eg/lib/Eg/Example.pm
[mkdir] .../eg/t
[write] .../eg/t/basic.t
[mkdir] .../eg/log
[mkdir] .../eg/public
[write] .../eg/public/index.html
[mkdir] .../eg/templates/layouts
[write] .../eg/templates/layouts/default.html.ep
[mkdir] .../eg/templates/example
[write] .../eg/templates/example/welcome.html.ep
$ morbo eg/script/eg
Server available at http://127.0.0.1:3000.
=head2 Commands
All the normal L<Mojolicious::Commands> are available from the command line.
Note that CGI and L<PSGI> environments can usually be auto detected and will
just work without commands.
$ ./script/eg daemon
Server available at http://127.0.0.1:3000.
$ ./script/eg daemon -l http://*:8080
Server available at http://127.0.0.1:8080.
$ ./script/eg cgi
...CGI output...
$ ./script/eg
...List of available commands (or automatically detected environment)...
=head2 Reloading
Your application will automatically reload itself if you start it with the
C<morbo> development web server, so you don't have to restart the server after
every change.
$ morbo script/eg
Server available at http://127.0.0.1:3000.
=head2 Routes
Routes are basically just fancy paths that can contain different kinds of
placeholders. C<$self> is a L<Mojolicious::Controller> object containing both,
the HTTP request and response.
package Eg;
use Mojo::Base 'Mojolicious';
# This method will run once at server start
sub startup {
my $self = shift;
$self->secret('Mojolicious rocks');
# Router
my $r = $self->routes;
# Normal route to controller
$r->get('/')->to('example#welcome');
$r->get('/foo')->to('example#foo');
}
1;
package Eg::Example;
use Mojo::Base 'Mojolicious::Controller';
# This action will render a template
sub welcome {
my $self = shift;
# Render template "example/welcome.html.ep" with message
$self->render(
message => 'Welcome to the Mojolicious real-time web framework!');
}
sub foo {
my $self = shift;
# Render template "example/foo.html.ep"
$self->render();
}
GET / invokes Eg::Example::welcome.
GET /foo invokes Eg::Example::foo.
=head2 GET/POST parameters
All C<GET> and C<POST> parameters are accessible via
L<Mojolicious::Controller/"param">.
package Eg::Example;
use Mojo::Base 'Mojolicious::Controller';
# This action will render a template
sub foo {
my $self = shift;
my $user = $self->param("user") || "";
# Render template "example/foo.html.ep" with message
$self->render(user => $user);
}
=head2 Stash and templates
The L<Mojolicious::Controller/"stash"> is used to pass data to templates.
sub foo {
my $self = shift;
my $user = $self->param("user") || "";
$self->stash(one => 23);
# Render template "example/foo.html.ep" with message
$self->render(user => $user);
}
templates/example/foo.html.ep
Hi <%= $user %>: <%= $one %><br>
For more information about templates see also
L<Mojolicious::Guides::Rendering/"Embedded Perl">.
=head2 HTTP
L<Mojolicious::Controller/"req"> and L<Mojolicious::Controller/"res"> give you
full access to all HTTP features and information.
sub foo {
my $self = shift;
my $user = $self->param("user") || "";
$self->stash(one => 23);
$self->res->headers->header('X-Bender' => 'Bite my shiny metal ass!');
# Render template "example/foo.html.ep"
$self->render(user => $user, txt => $self->req->headers->user_agent);
}
=head2 Helpers
You can also extend L<Mojolicious> with your own helpers, a list of all
built-in ones can be found in L<Mojolicious::Plugin::DefaultHelpers> and
L<Mojolicious::Plugin::TagHelpers>.
package Eg;
use Mojo::Base 'Mojolicious';
sub startup {
my $self = shift;
# Documentation browser under "/perldoc"
$self->plugin('PODRenderer');
$self->secret('Mojolicious rocks');
# Router
my $r = $self->routes;
# Normal route to controller
$r->get('/')->to('example#welcome');
$r->get('/foo')->to('example#foo');
# "whois" helper
$self->helper(whois => sub {
my $self = shift;
my $agent = $self->req->headers->user_agent || 'Anonymous';
my $ip = $self->tx->remote_address;
return "$agent ($ip)";
});
}
package Eg::Example;
use Mojo::Base 'Mojolicious::Controller';
sub foo {
my $self = shift;
my $user = $self->param("user") || "";
$self->stash(one => 23);
$self->res->headers->header('X-Bender' => 'Bite my shiny metal ass!');
# Render template "example/foo.html.ep"
$self->render(user => $user, txt => $self->whois());
}
=head2 Placeholders
Route placeholders allow capturing parts of a request path until a C</> or
C<.> separator occurs, results are accessible via
L<Mojolicious::Controller/"stash"> and L<Mojolicious::Controller/"param">.
# /foo/test
# /foo/test123
$r->get('/foo/:bar')->to('example#placeholder');
# /testsomething/foo
# /test123something/foo
$r->get('/(:bar)something/foo')->to('example#placeholder');
sub placeholder {
my $self = shift;
my $user = $self->param("user") || "";
$self->stash(one => 23);
my $bar = $self->stash('bar');
$self->render(template => "example/foo", user => $user, txt => "Our :bar placeholder matched $bar");
};
=head2 Sessions
Signed cookie based sessions just work out of the box as soon as you start
using them through the helper
L<Mojolicious::Plugin::DefaultHelpers/"session">.
$r->get('/counter')->to('example#counter');
sub counter {
my $self = shift;
$self->session->{counter}++;
}
templates/example/counter.html.ep
Counter: <%= session 'counter' %>
Just be aware that all session data gets serialized with L<Mojo::JSON>.
=head2 Secret
Note that you should use a custom L<Mojolicious/"secret"> to make signed
cookies really secure.
$self->secret('My secret passphrase here');
=head2 User agent
With L<Mojolicious::Controller/"ua"> there's a full featured HTTP and
WebSocket user agent built right in. Especially in combination with
L<Mojo::JSON> and L<Mojo::DOM> this can be a very powerful tool.
$r->get('/some')->to('example#mojo');
sub mojo {
my $self = shift;
$self->render(data => $self->ua->get('http://mojolicio.us')->res->body);
};
=head2 Eg::startup
sub startup {
my $self = shift;
# Documentation browser under "/perldoc"
$self->plugin('PODRenderer');
$self->secret('Mojolicious rocks');
# Router
my $r = $self->routes;
# Normal route to controller
$r->get('/')->to('example#welcome');
$r->get('/foo')->to('example#foo');
$r->get('/foo/:bar')->to('example#placeholder');
$r->get('/(:bar)something/foo')->to('example#placeholder');
$r->get('/counter')->to('example#counter');
$r->get('/some')->to('example#mojo');
# "whois" helper
$self->helper(whois => sub {
my $self = shift;
my $agent = $self->req->headers->user_agent || 'Anonymous';
my $ip = $self->tx->remote_address;
return "$agent ($ip)";
});
}
=head2 Eg/Example.pm
package Eg::Example;
use Mojo::Base 'Mojolicious::Controller';
sub foo {
my $self = shift;
my $user = $self->param("user") || "";
$self->stash(one => 23);
$self->res->headers->header('X-Bender' => 'Bite my shiny metal ass!');
# Render template "example/foo.html.ep"
$self->render(user => $user, txt => $self->whois());
}
# This action will render a template
sub welcome {
my $self = shift;
# Render template "example/welcome.html.ep" with message
$self->render(
message => 'Welcome to the Mojolicious real-time web framework!');
}
sub placeholder {
my $self = shift;
my $user = $self->param("user") || "";
$self->stash(one => 23);
my $bar = $self->stash('bar');
$self->render(template => "example/foo", user => $user, txt => "Our :bar placeholder matched $bar");
};
sub counter {
my $self = shift;
$self->session->{counter}++;
}
sub mojo {
my $self = shift;
$self->render(data => $self->ua->get('http://mojolicio.us')->res->body);
};
1;
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment