.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.ie \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.el \{\
. de IX
..
.\}
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "Mojolicious::Lite 3pm"
.TH Mojolicious::Lite 3pm "2012-09-05" "perl v5.14.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Mojolicious::Lite \- Real\-time micro web framework
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 2
\& # Automatically enables "strict", "warnings" and Perl 5.10 features
\& use Mojolicious::Lite;
\&
\& # Route with placeholder
\& get \*(Aq/:foo\*(Aq => sub {
\& my $self = shift;
\& my $foo = $self\->param(\*(Aqfoo\*(Aq);
\& $self\->render(text => "Hello from $foo.");
\& };
\&
\& # Start the Mojolicious command system
\& app\->start;
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Mojolicious::Lite is a micro real-time web framework built around
Mojolicious.
.SH "TUTORIAL"
.IX Header "TUTORIAL"
A quick example driven introduction to the wonders of Mojolicious::Lite.
Most of what you'll learn here also applies to normal Mojolicious
applications.
.SS "Hello World"
.IX Subsection "Hello World"
A simple Hello World application can look like this, strict, warnings
and Perl 5.10 features are automatically enabled and a few functions imported
when you use Mojolicious::Lite, turning your script into a full featured
web application.
.PP
.Vb 2
\& #!/usr/bin/env perl
\& use Mojolicious::Lite;
\&
\& get \*(Aq/\*(Aq => sub {
\& my $self = shift;
\& $self\->render(text => \*(AqHello World!\*(Aq);
\& };
\&
\& app\->start;
.Ve
.SS "Generator"
.IX Subsection "Generator"
There is also a helper command to generate a small example application.
.PP
.Vb 1
\& $ mojo generate lite_app
.Ve
.SS "Commands"
.IX Subsection "Commands"
All the normal Mojolicious::Commands are available from the command line.
Note that \s-1CGI\s0 and \s-1PSGI\s0 environments can usually be auto detected and will
just work without commands.
.PP
.Vb 2
\& $ ./myapp.pl daemon
\& Server available at http://127.0.0.1:3000.
\&
\& $ ./myapp.pl daemon \-l http://*:8080
\& Server available at http://127.0.0.1:8080.
\&
\& $ ./myapp.pl cgi
\& ...CGI output...
\&
\& $ ./myapp.pl
\& ...List of available commands (or automatically detected environment)...
.Ve
.SS "Start"
.IX Subsection "Start"
The app\->start call that starts the Mojolicious command system can be
customized to override normal \f(CW@ARGV\fR use.
.PP
.Vb 1
\& app\->start(\*(Aqcgi\*(Aq);
.Ve
.SS "Reloading"
.IX Subsection "Reloading"
Your application will automatically reload itself if you start it with the
\&\f(CW\*(C`morbo\*(C'\fR development web server, so you don't have to restart the server after
every change.
.PP
.Vb 2
\& $ morbo myapp.pl
\& Server available at http://127.0.0.1:3000.
.Ve
.SS "Routes"
.IX Subsection "Routes"
Routes are basically just fancy paths that can contain different kinds of
placeholders. \f(CW$self\fR is a Mojolicious::Controller object containing both,
the \s-1HTTP\s0 request and response.
.PP
.Vb 5
\& # /foo
\& get \*(Aq/foo\*(Aq => sub {
\& my $self = shift;
\& $self\->render(text => \*(AqHello World!\*(Aq);
\& };
.Ve
.SS "\s-1GET/POST\s0 parameters"
.IX Subsection "GET/POST parameters"
All \f(CW\*(C`GET\*(C'\fR and \f(CW\*(C`POST\*(C'\fR parameters are accessible via
\&\*(L"param\*(R" in Mojolicious::Controller.
.PP
.Vb 6
\& # /foo?user=sri
\& get \*(Aq/foo\*(Aq => sub {
\& my $self = shift;
\& my $user = $self\->param(\*(Aquser\*(Aq);
\& $self\->render(text => "Hello $user.");
\& };
.Ve
.SS "Stash and templates"
.IX Subsection "Stash and templates"
The \*(L"stash\*(R" in Mojolicious::Controller is used to pass data to templates,
which can be inlined in the \f(CW\*(C`DATA\*(C'\fR section.
.PP
.Vb 6
\& # /bar
\& get \*(Aq/bar\*(Aq => sub {
\& my $self = shift;
\& $self\->stash(one => 23);
\& $self\->render(\*(Aqbaz\*(Aq, two => 24);
\& };
\&
\& _\|_DATA_\|_
\&
\& @@ baz.html.ep
\& The magic numbers are <%= $one %> and <%= $two %>.
.Ve
.PP
For more information about templates see also
\&\*(L"Embedded Perl\*(R" in Mojolicious::Guides::Rendering.
.SS "\s-1HTTP\s0"
.IX Subsection "HTTP"
\&\*(L"req\*(R" in Mojolicious::Controller and \*(L"res\*(R" in Mojolicious::Controller give you
full access to all \s-1HTTP\s0 features and information.
.PP
.Vb 6
\& # /agent
\& get \*(Aq/agent\*(Aq => sub {
\& my $self = shift;
\& $self\->res\->headers\->header(\*(AqX\-Bender\*(Aq => \*(AqBite my shiny metal ass!\*(Aq);
\& $self\->render(text => $self\->req\->headers\->user_agent);
\& };
.Ve
.SS "Route names"
.IX Subsection "Route names"
All routes can have a name associated with them, this allows automatic
template detection and back referencing with
\&\*(L"url_for\*(R" in Mojolicious::Controller as well as many helpers like
\&\*(L"link_to\*(R" in Mojolicious::Plugin::TagHelpers. Nameless routes get an
automatically generated one assigned that is simply equal to the route itself
without non-word characters.
.PP
.Vb 5
\& # /
\& get \*(Aq/\*(Aq => sub {
\& my $self = shift;
\& $self\->render;
\& } => \*(Aqindex\*(Aq;
\&
\& # /hello
\& get \*(Aq/hello\*(Aq;
\&
\& _\|_DATA_\|_
\&
\& @@ index.html.ep
\& <%= link_to Hello => \*(Aqhello\*(Aq %>.
\& <%= link_to Reload => \*(Aqindex\*(Aq %>.
\&
\& @@ hello.html.ep
\& Hello World!
.Ve
.SS "Layouts"
.IX Subsection "Layouts"
Templates can have layouts too, you just select one with the helper
\&\*(L"layout\*(R" in Mojolicious::Plugin::DefaultHelpers and place the result of the
current template with the helper
\&\*(L"content\*(R" in Mojolicious::Plugin::DefaultHelpers.
.PP
.Vb 5
\& # /with_layout
\& get \*(Aq/with_layout\*(Aq => sub {
\& my $self = shift;
\& $self\->render(\*(Aqwith_layout\*(Aq);
\& };
\&
\& _\|_DATA_\|_
\&
\& @@ with_layout.html.ep
\& % title \*(AqGreen\*(Aq;
\& % layout \*(Aqgreen\*(Aq;
\& Hello World!
\&
\& @@ layouts/green.html.ep
\&
\&
\&
<%= title %>
\& <%= content %>
\&
.Ve
.SS "Blocks"
.IX Subsection "Blocks"
Template blocks can be used like normal Perl functions and are always
delimited by the \f(CW\*(C`begin\*(C'\fR and \f(CW\*(C`end\*(C'\fR keywords.
.PP
.Vb 2
\& # /with_block
\& get \*(Aq/with_block\*(Aq => \*(Aqblock\*(Aq;
\&
\& _\|_DATA_\|_
\&
\& @@ block.html.ep
\& % my $link = begin
\& % my ($url, $name) = @_;
\& Try <%= link_to $url => begin %><%= $name %><% end %>.
\& % end
\&
\&
\& Sebastians frameworks
\&
\& %= $link\->(\*(Aqhttp://mojolicio.us\*(Aq, \*(AqMojolicious\*(Aq)
\& %= $link\->(\*(Aqhttp://catalystframework.org\*(Aq, \*(AqCatalyst\*(Aq)
\&
\&
.Ve
.SS "Captured content"
.IX Subsection "Captured content"
The helper \*(L"content_for\*(R" in Mojolicious::Plugin::TagHelpers can be used to
pass around blocks of captured content.
.PP
.Vb 5
\& # /captured
\& get \*(Aq/captured\*(Aq => sub {
\& my $self = shift;
\& $self\->render(\*(Aqcaptured\*(Aq);
\& };
\&
\& _\|_DATA_\|_
\&
\& @@ captured.html.ep
\& % layout \*(Aqblue\*(Aq, title => \*(AqGreen\*(Aq;
\& % content_for header => begin
\&
\& % end
\& Hello World!
\& % content_for header => begin
\&
\& % end
\&
\& @@ layouts/blue.html.ep
\&
\&
\&
\& <%= title %>
\& %= content_for \*(Aqheader\*(Aq
\&
\& <%= content %>
\&
.Ve
.SS "Helpers"
.IX Subsection "Helpers"
You can also extend Mojolicious with your own helpers, a list of all
built-in ones can be found in Mojolicious::Plugin::DefaultHelpers and
Mojolicious::Plugin::TagHelpers.
.PP
.Vb 7
\& # "whois" helper
\& helper whois => sub {
\& my $self = shift;
\& my $agent = $self\->req\->headers\->user_agent || \*(AqAnonymous\*(Aq;
\& my $ip = $self\->tx\->remote_address;
\& return "$agent ($ip)";
\& };
\&
\& # /secret
\& get \*(Aq/secret\*(Aq => sub {
\& my $self = shift;
\& my $user = $self\->whois;
\& $self\->app\->log\->debug("Request from $user.");
\& };
\&
\& _\|_DATA_\|_
\&
\& @@ secret.html.ep
\& We know who you are <%= whois %>.
.Ve
.SS "Placeholders"
.IX Subsection "Placeholders"
Route placeholders allow capturing parts of a request path until a \f(CW\*(C`/\*(C'\fR or
\&\f(CW\*(C`.\*(C'\fR separator occurs, results are accessible via
\&\*(L"stash\*(R" in Mojolicious::Controller and \*(L"param\*(R" in Mojolicious::Controller.
.PP
.Vb 7
\& # /foo/test
\& # /foo/test123
\& get \*(Aq/foo/:bar\*(Aq => sub {
\& my $self = shift;
\& my $bar = $self\->stash(\*(Aqbar\*(Aq);
\& $self\->render(text => "Our :bar placeholder matched $bar");
\& };
\&
\& # /testsomething/foo
\& # /test123something/foo
\& get \*(Aq/(:bar)something/foo\*(Aq => sub {
\& my $self = shift;
\& my $bar = $self\->param(\*(Aqbar\*(Aq);
\& $self\->render(text => "Our :bar placeholder matched $bar");
\& };
.Ve
.SS "Relaxed Placeholders"
.IX Subsection "Relaxed Placeholders"
Relaxed placeholders allow matching of everything until a \f(CW\*(C`/\*(C'\fR occurs.
.PP
.Vb 4
\& # /test/hello
\& # /test123/hello
\& # /test.123/hello
\& get \*(Aq/#you/hello\*(Aq => \*(Aqgroovy\*(Aq;
\&
\& _\|_DATA_\|_
\&
\& @@ groovy.html.ep
\& Your name is <%= $you %>.
.Ve
.SS "Wildcard placeholders"
.IX Subsection "Wildcard placeholders"
Wildcard placeholders allow matching absolutely everything, including \f(CW\*(C`/\*(C'\fR and
\&\f(CW\*(C`.\*(C'\fR.
.PP
.Vb 4
\& # /hello/test
\& # /hello/test123
\& # /hello/test.123/test/123
\& get \*(Aq/hello/*you\*(Aq => \*(Aqgroovy\*(Aq;
\&
\& _\|_DATA_\|_
\&
\& @@ groovy.html.ep
\& Your name is <%= $you %>.
.Ve
.SS "\s-1HTTP\s0 methods"
.IX Subsection "HTTP methods"
Routes can be restricted to specific request methods.
.PP
.Vb 5
\& # GET /hello
\& get \*(Aq/hello\*(Aq => sub {
\& my $self = shift;
\& $self\->render(text => \*(AqHello World!\*(Aq);
\& };
\&
\& # PUT /hello
\& put \*(Aq/hello\*(Aq => sub {
\& my $self = shift;
\& my $size = length $self\->req\->body;
\& $self\->render(text => "You uploaded $size bytes to /hello.");
\& };
\&
\& # GET|POST|PATCH /bye
\& any [qw(GET POST PATCH)] => \*(Aq/bye\*(Aq => sub {
\& my $self = shift;
\& $self\->render(text => \*(AqBye World!\*(Aq);
\& };
\&
\& # * /whatever
\& any \*(Aq/whatever\*(Aq => sub {
\& my $self = shift;
\& my $method = $self\->req\->method;
\& $self\->render(text => "You called /whatever with $method.");
\& };
.Ve
.SS "Optional placeholders"
.IX Subsection "Optional placeholders"
Routes allow default values to make placeholders optional.
.PP
.Vb 6
\& # /hello
\& # /hello/Sara
\& get \*(Aq/hello/:name\*(Aq => {name => \*(AqSebastian\*(Aq} => sub {
\& my $self = shift;
\& $self\->render(\*(Aqgroovy\*(Aq, format => \*(Aqtxt\*(Aq);
\& };
\&
\& _\|_DATA_\|_
\&
\& @@ groovy.txt.ep
\& My name is <%= $name %>.
.Ve
.SS "Restrictive placeholders"
.IX Subsection "Restrictive placeholders"
The easiest way to make placeholders more restrictive are alternatives, you
just make a list of possible values.
.PP
.Vb 7
\& # /test
\& # /123
\& any \*(Aq/:foo\*(Aq => [foo => [qw(test 123)]] => sub {
\& my $self = shift;
\& my $foo = $self\->param(\*(Aqfoo\*(Aq);
\& $self\->render(text => "Our :foo placeholder matched $foo");
\& };
.Ve
.PP
All placeholders get compiled to a regex internally, this process can also be
easily customized.
.PP
.Vb 7
\& # /1
\& # /123
\& any \*(Aq/:bar\*(Aq => [bar => qr/\ed+/] => sub {
\& my $self = shift;
\& my $bar = $self\->param(\*(Aqbar\*(Aq);
\& $self\->render(text => "Our :bar placeholder matched $bar");
\& };
.Ve
.PP
Just make sure not to use \f(CW\*(C`^\*(C'\fR and \f(CW\*(C`$\*(C'\fR or capturing groups \f(CW\*(C`(...)\*(C'\fR, because
placeholders become part of a larger regular expression internally, \f(CW\*(C`(?:...)\*(C'\fR
is fine though.
.SS "Under"
.IX Subsection "Under"
Authentication and code shared between multiple routes can be realized easily
with the \f(CW\*(C`under\*(C'\fR statement. All following routes are only evaluated if the
\&\f(CW\*(C`under\*(C'\fR callback returned a true value.
.PP
.Vb 1
\& use Mojolicious::Lite;
\&
\& # Authenticate based on name parameter
\& under sub {
\& my $self = shift;
\&
\& # Authenticated
\& my $name = $self\->param(\*(Aqname\*(Aq) || \*(Aq\*(Aq;
\& return 1 if $name eq \*(AqBender\*(Aq;
\&
\& # Not authenticated
\& $self\->render(\*(Aqdenied\*(Aq);
\& return;
\& };
\&
\& # / (with authentication)
\& get \*(Aq/\*(Aq => \*(Aqindex\*(Aq;
\&
\& app\->start;
\& _\|_DATA_\|_;
\&
\& @@ denied.html.ep
\& You are not Bender, permission denied.
\&
\& @@ index.html.ep
\& Hi Bender.
.Ve
.PP
Prefixing multiple routes is another good use for \f(CW\*(C`under\*(C'\fR.
.PP
.Vb 1
\& use Mojolicious::Lite;
\&
\& # /foo
\& under \*(Aq/foo\*(Aq;
\&
\& # /foo/bar
\& get \*(Aq/bar\*(Aq => {text => \*(Aqfoo bar\*(Aq};
\&
\& # /foo/baz
\& get \*(Aq/baz\*(Aq => {text => \*(Aqfoo baz\*(Aq};
\&
\& # /
\& under \*(Aq/\*(Aq => {message => \*(Aqwhatever\*(Aq};
\&
\& # /bar
\& get \*(Aq/bar\*(Aq => {inline => \*(Aq<%= $message %> works\*(Aq};
\&
\& app\->start;
.Ve
.PP
You can also \f(CW\*(C`group\*(C'\fR related routes, which allows nesting of multiple
\&\f(CW\*(C`under\*(C'\fR statements.
.PP
.Vb 1
\& use Mojolicious::Lite;
\&
\& # Global logic shared by all routes
\& under sub {
\& my $self = shift;
\& return 1 if $self\->req\->headers\->header(\*(AqX\-Bender\*(Aq);
\& $self\->render(text => "You\*(Aqre not Bender.");
\& return;
\& };
\&
\& # Admin section
\& group {
\&
\& # Local logic shared only by routes in this group
\& under \*(Aq/admin\*(Aq => sub {
\& my $self = shift;
\& return 1 if $self\->req\->heaers\->header(\*(AqX\-Awesome\*(Aq);
\& $self\->render(text => "You\*(Aqre not awesome enough.");
\& return;
\& };
\&
\& # GET /admin/dashboard
\& get \*(Aq/dashboard\*(Aq => {text => \*(AqNothing to see here yet.\*(Aq};
\& };
\&
\& # GET /welcome
\& get \*(Aq/welcome\*(Aq => {text => \*(AqHi Bender.\*(Aq};
\&
\& app\->start;
.Ve
.SS "Formats"
.IX Subsection "Formats"
Formats can be automatically detected by looking at file extensions.
.PP
.Vb 6
\& # /detection.html
\& # /detection.txt
\& get \*(Aq/detection\*(Aq => sub {
\& my $self = shift;
\& $self\->render(\*(Aqdetected\*(Aq);
\& };
\&
\& _\|_DATA_\|_
\&
\& @@ detected.html.ep
\&
\&
\& Detected
\& HTML was detected.
\&
\&
\& @@ detected.txt.ep
\& TXT was detected.
.Ve
.PP
Restrictive placeholders can also be used.
.PP
.Vb 8
\& # /hello.json
\& # /hello.txt
\& get \*(Aq/hello\*(Aq => [format => [qw(json txt)]] => sub {
\& my $self = shift;
\& return $self\->render_json({hello => \*(Aqworld\*(Aq})
\& if $self\->stash(\*(Aqformat\*(Aq) eq \*(Aqjson\*(Aq;
\& $self\->render_text(\*(Aqhello world\*(Aq);
\& };
.Ve
.PP
Or you can just disable format detection.
.PP
.Vb 2
\& # /hello
\& get \*(Aq/hello\*(Aq => [format => 0] => {text => \*(AqNo format detection.\*(Aq};
\&
\& # Disable detection and allow the following routes selective re\-enabling
\& under [format => 0];
\&
\& # /foo
\& get \*(Aq/foo\*(Aq => {text => \*(AqNo format detection again.\*(Aq};
\&
\& # /bar.txt
\& get \*(Aq/bar\*(Aq => [format => \*(Aqtxt\*(Aq] => {text => \*(Aq Just one format.\*(Aq};
.Ve
.SS "Content negotiation"
.IX Subsection "Content negotiation"
For resources with different representations and that require truly \f(CW\*(C`RESTful\*(C'\fR
content negotiation you can also use \*(L"respond_to\*(R" in Mojolicious::Controller.
.PP
.Vb 10
\& # /hello (Accept: application/json)
\& # /hello (Accept: text/xml)
\& # /hello.json
\& # /hello.xml
\& # /hello?format=json
\& # /hello?format=xml
\& get \*(Aq/hello\*(Aq => sub {
\& my $self = shift;
\& $self\->respond_to(
\& json => {json => {hello => \*(Aqworld\*(Aq}},
\& xml => {text => \*(Aqworld\*(Aq},
\& any => {data => \*(Aq\*(Aq, status => 204}
\& );
\& };
.Ve
.PP
\&\s-1MIME\s0 type mappings can be extended or changed easily with
\&\*(L"types\*(R" in Mojolicious.
.PP
.Vb 1
\& app\->types\->type(rdf => \*(Aqapplication/rdf+xml\*(Aq);
.Ve
.SS "Conditions"
.IX Subsection "Conditions"
Conditions such as \f(CW\*(C`agent\*(C'\fR and \f(CW\*(C`host\*(C'\fR from
Mojolicious::Plugin::HeaderCondition allow even more powerful route
constructs.
.PP
.Vb 5
\& # /foo (Firefox)
\& get \*(Aq/foo\*(Aq => (agent => qr/Firefox/) => sub {
\& my $self = shift;
\& $self\->render(text => \*(AqCongratulations, you are using a cool browser.\*(Aq);
\& };
\&
\& # /foo (Internet Explorer)
\& get \*(Aq/foo\*(Aq => (agent => qr/Internet Explorer/) => sub {
\& my $self = shift;
\& $self\->render(text => \*(AqDude, you really need to upgrade to Firefox.\*(Aq);
\& };
\&
\& # http://mojolicio.us/bar
\& get \*(Aq/bar\*(Aq => (host => \*(Aqmojolicio.us\*(Aq) => sub {
\& my $self = shift;
\& $self\->render(text => \*(AqHello Mojolicious.\*(Aq);
\& };
.Ve
.SS "Sessions"
.IX Subsection "Sessions"
Signed cookie based sessions just work out of the box as soon as you start
using them through the helper
\&\*(L"session\*(R" in Mojolicious::Plugin::DefaultHelpers.
.PP
.Vb 1
\& use Mojolicious::Lite;
\&
\& get \*(Aq/counter\*(Aq => sub {
\& my $self = shift;
\& $self\->session\->{counter}++;
\& };
\&
\& app\->start;
\& _\|_DATA_\|_
\&
\& @@ counter.html.ep
\& Counter: <%= session \*(Aqcounter\*(Aq %>
.Ve
.SS "Secret"
.IX Subsection "Secret"
Note that you should use a custom \*(L"secret\*(R" in Mojolicious to make signed
cookies really secure.
.PP
.Vb 1
\& app\->secret(\*(AqMy secret passphrase here\*(Aq);
.Ve
.SS "File uploads"
.IX Subsection "File uploads"
All files uploaded via \f(CW\*(C`multipart/form\-data\*(C'\fR request are automatically
available as Mojo::Upload objects. And you don't have to worry about memory
usage, because all files above \f(CW\*(C`250KB\*(C'\fR will be automatically streamed into a
temporary file.
.PP
.Vb 1
\& use Mojolicious::Lite;
\&
\& # Upload form in DATA section
\& get \*(Aq/\*(Aq => \*(Aqform\*(Aq;
\&
\& # Multipart upload handler
\& post \*(Aq/upload\*(Aq => sub {
\& my $self = shift;
\&
\& # Check file size
\& return $self\->render(text => \*(AqFile is too big.\*(Aq, status => 200)
\& if $self\->req\->is_limit_exceeded;
\&
\& # Process uploaded file
\& return $self\->redirect_to(\*(Aqform\*(Aq)
\& unless my $example = $self\->param(\*(Aqexample\*(Aq);
\& my $size = $example\->size;
\& my $name = $example\->filename;
\& $self\->render(text => "Thanks for uploading $size byte file $name.");
\& };
\&
\& app\->start;
\& _\|_DATA_\|_
\&
\& @@ form.html.ep
\&
\&
\& Upload
\&
\& %= form_for upload => (enctype => \*(Aqmultipart/form\-data\*(Aq) => begin
\& %= file_field \*(Aqexample\*(Aq
\& %= submit_button \*(AqUpload\*(Aq
\& % end
\&
\&
.Ve
.PP
To protect you from excessively large files there is also a limit of \f(CW\*(C`5MB\*(C'\fR by
default, which you can tweak with the \f(CW\*(C`MOJO_MAX_MESSAGE_SIZE\*(C'\fR environment
variable.
.PP
.Vb 2
\& # Increase limit to 1GB
\& $ENV{MOJO_MAX_MESSAGE_SIZE} = 1073741824;
.Ve
.SS "User agent"
.IX Subsection "User agent"
With \*(L"ua\*(R" in Mojolicious::Controller there's a full featured \s-1HTTP\s0 1.1 and
WebSocket user agent built right in. Especially in combination with
Mojo::JSON and Mojo::DOM this can be a very powerful tool.
.PP
.Vb 4
\& get \*(Aq/test\*(Aq => sub {
\& my $self = shift;
\& $self\->render(data => $self\->ua\->get(\*(Aqhttp://mojolicio.us\*(Aq)\->res\->body);
\& };
.Ve
.SS "WebSockets"
.IX Subsection "WebSockets"
WebSocket applications have never been this easy before.
.PP
.Vb 7
\& websocket \*(Aq/echo\*(Aq => sub {
\& my $self = shift;
\& $self\->on(message => sub {
\& my ($self, $message) = @_;
\& $self\->send("echo: $message");
\& });
\& };
.Ve
.PP
The event \*(L"message\*(R" in Mojo::Transaction::WebSocket, which you can subscribe
to with \*(L"on\*(R" in Mojolicious::Controller, will be emitted for every new
WebSocket message that is received.
.SS "External templates"
.IX Subsection "External templates"
External templates will be searched by the renderer in a \f(CW\*(C`templates\*(C'\fR
directory.
.PP
.Vb 3
\& # /external
\& any \*(Aq/external\*(Aq => sub {
\& my $self = shift;
\&
\& # templates/foo/bar.html.ep
\& $self\->render(\*(Aqfoo/bar\*(Aq);
\& };
.Ve
.SS "Static files"
.IX Subsection "Static files"
Static files will be automatically served from the \f(CW\*(C`DATA\*(C'\fR section (even
Base64 encoded) or a \f(CW\*(C`public\*(C'\fR directory if it exists.
.PP
.Vb 2
\& @@ something.js
\& alert(\*(Aqhello!\*(Aq);
\&
\& @@ test.txt (base64)
\& dGVzdCAxMjMKbGFsYWxh
\&
\& $ mkdir public
\& $ mv something.js public/something.js
.Ve
.SS "Testing"
.IX Subsection "Testing"
Testing your application is as easy as creating a \f(CW\*(C`t\*(C'\fR directory and filling
it with normal Perl unit tests.
.PP
.Vb 2
\& use Test::More tests => 3;
\& use Test::Mojo;
\&
\& use FindBin;
\& require "$FindBin::Bin/../myapp.pl";
\&
\& my $t = Test::Mojo\->new;
\& $t\->get_ok(\*(Aq/\*(Aq)\->status_is(200)\->content_like(qr/Funky/);
.Ve
.PP
Run all unit tests with the \f(CW\*(C`test\*(C'\fR command.
.PP
.Vb 1
\& $ ./myapp.pl test
.Ve
.PP
To make your tests more noisy and show you all log messages you can also
change the application log level directly in your test files.
.PP
.Vb 1
\& $t\->app\->log\->level(\*(Aqdebug\*(Aq);
.Ve
.SS "Mode"
.IX Subsection "Mode"
To disable debug messages later in a production setup you can change the
Mojolicious mode, default will be \f(CW\*(C`development\*(C'\fR.
.PP
.Vb 1
\& $ ./myapp.pl \-m production
.Ve
.SS "Logging"
.IX Subsection "Logging"
Mojo::Log messages will be automatically written to \f(CW\*(C`STDERR\*(C'\fR or a
\&\f(CW\*(C`log/$mode.log\*(C'\fR file if a \f(CW\*(C`log\*(C'\fR directory exists.
.PP
.Vb 1
\& $ mkdir log
.Ve
.PP
For more control the Mojolicious object can be accessed directly.
.PP
.Vb 6
\& app\->log\->level(\*(Aqerror\*(Aq);
\& app\->routes\->get(\*(Aq/foo/:bar\*(Aq => sub {
\& my $self = shift;
\& $self\->app\->log\->debug(\*(AqGot a request for "Hello Mojo!".\*(Aq);
\& $self\->render(text => \*(AqHello Mojo!\*(Aq);
\& });
.Ve
.SS "More"
.IX Subsection "More"
You can continue with Mojolicious::Guides now, and don't forget to have
fun!
.SH "FUNCTIONS"
.IX Header "FUNCTIONS"
Mojolicious::Lite implements the following functions.
.ie n .SS """any"""
.el .SS "\f(CWany\fP"
.IX Subsection "any"
.Vb 2
\& my $route = any \*(Aq/:foo\*(Aq => sub {...};
\& my $route = any [qw(GET POST)] => \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"any\*(R" in Mojolicious::Routes::Route, matching any of the
listed \s-1HTTP\s0 request methods or all. See also the tutorial above for more
argument variations.
.ie n .SS """app"""
.el .SS "\f(CWapp\fP"
.IX Subsection "app"
.Vb 1
\& my $app = app;
.Ve
.PP
The Mojolicious::Lite application.
.ie n .SS """del"""
.el .SS "\f(CWdel\fP"
.IX Subsection "del"
.Vb 1
\& my $route = del \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"delete\*(R" in Mojolicious::Routes::Route, matching only
\&\f(CW\*(C`DELETE\*(C'\fR requests. See also the tutorial above for more argument variations.
.ie n .SS """get"""
.el .SS "\f(CWget\fP"
.IX Subsection "get"
.Vb 1
\& my $route = get \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"get\*(R" in Mojolicious::Routes::Route, matching only \f(CW\*(C`GET\*(C'\fR
requests. See also the tutorial above for more argument variations.
.ie n .SS """group"""
.el .SS "\f(CWgroup\fP"
.IX Subsection "group"
.Vb 1
\& group {...};
.Ve
.PP
Start a new route group.
.ie n .SS """helper"""
.el .SS "\f(CWhelper\fP"
.IX Subsection "helper"
.Vb 1
\& helper foo => sub {...};
.Ve
.PP
Alias for \*(L"helper\*(R" in Mojolicious.
.ie n .SS """hook"""
.el .SS "\f(CWhook\fP"
.IX Subsection "hook"
.Vb 1
\& hook after_dispatch => sub {...};
.Ve
.PP
Alias for \*(L"hook\*(R" in Mojolicious.
.ie n .SS """options"""
.el .SS "\f(CWoptions\fP"
.IX Subsection "options"
.Vb 1
\& my $route = options \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"options\*(R" in Mojolicious::Routes::Route, matching only
\&\f(CW\*(C`OPTIONS\*(C'\fR requests. See also the tutorial above for more argument
variations.
.ie n .SS """patch"""
.el .SS "\f(CWpatch\fP"
.IX Subsection "patch"
.Vb 1
\& my $route = patch \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"patch\*(R" in Mojolicious::Routes::Route, matching only
\&\f(CW\*(C`PATCH\*(C'\fR requests. See also the tutorial above for more argument variations.
.ie n .SS """plugin"""
.el .SS "\f(CWplugin\fP"
.IX Subsection "plugin"
.Vb 1
\& plugin \*(AqSomeThing\*(Aq;
.Ve
.PP
Alias for \*(L"plugin\*(R" in Mojolicious.
.ie n .SS """post"""
.el .SS "\f(CWpost\fP"
.IX Subsection "post"
.Vb 1
\& my $route = post \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"post\*(R" in Mojolicious::Routes::Route, matching only
\&\f(CW\*(C`POST\*(C'\fR requests. See also the tutorial above for more argument variations.
.ie n .SS """put"""
.el .SS "\f(CWput\fP"
.IX Subsection "put"
.Vb 1
\& my $route = put \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"put\*(R" in Mojolicious::Routes::Route, matching only \f(CW\*(C`PUT\*(C'\fR
requests. See also the tutorial above for more argument variations.
.ie n .SS """under"""
.el .SS "\f(CWunder\fP"
.IX Subsection "under"
.Vb 2
\& my $route = under sub {...};
\& my $route = under \*(Aq/:foo\*(Aq;
.Ve
.PP
Generate bridge with \*(L"under\*(R" in Mojolicious::Routes::Route, to which all
following routes are automatically appended. See also the tutorial above for
more argument variations.
.ie n .SS """websocket"""
.el .SS "\f(CWwebsocket\fP"
.IX Subsection "websocket"
.Vb 1
\& my $route = websocket \*(Aq/:foo\*(Aq => sub {...};
.Ve
.PP
Generate route with \*(L"websocket\*(R" in Mojolicious::Routes::Route, matching only
\&\f(CW\*(C`WebSocket\*(C'\fR handshakes. See also the tutorial above for more argument
variations.
.SH "ATTRIBUTES"
.IX Header "ATTRIBUTES"
Mojolicious::Lite inherits all attributes from Mojolicious.
.SH "METHODS"
.IX Header "METHODS"
Mojolicious::Lite inherits all methods from Mojolicious.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Mojolicious, Mojolicious::Guides, .