Created
December 3, 2012 00:16
-
-
Save anonymous/4191717 to your computer and use it in GitHub Desktop.
Beginnings of a Mojolicious Tutorial
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=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