1 | package Mojolicious::Lite;
|
---|
2 | use Mojo::Base 'Mojolicious';
|
---|
3 |
|
---|
4 | # "Bender: Bite my shiny metal ass!"
|
---|
5 | use Mojo::File 'path';
|
---|
6 | use Mojo::UserAgent::Server;
|
---|
7 | use Mojo::Util 'monkey_patch';
|
---|
8 |
|
---|
9 | sub import {
|
---|
10 |
|
---|
11 | # Remember executable for later
|
---|
12 | $ENV{MOJO_EXE} ||= (caller)[1];
|
---|
13 |
|
---|
14 | # Reuse home directory if possible
|
---|
15 | local $ENV{MOJO_HOME} = path($ENV{MOJO_EXE})->dirname->to_string
|
---|
16 | unless $ENV{MOJO_HOME};
|
---|
17 |
|
---|
18 | # Initialize application class
|
---|
19 | my $caller = caller;
|
---|
20 | no strict 'refs';
|
---|
21 | push @{"${caller}::ISA"}, 'Mojolicious';
|
---|
22 |
|
---|
23 | # Generate moniker based on filename
|
---|
24 | my $moniker = path($ENV{MOJO_EXE})->basename('.pl', '.pm', '.t');
|
---|
25 | my $app = shift->new(moniker => $moniker);
|
---|
26 |
|
---|
27 | # Initialize routes without namespaces
|
---|
28 | my $routes = $app->routes->namespaces([]);
|
---|
29 | $app->static->classes->[0] = $app->renderer->classes->[0] = $caller;
|
---|
30 |
|
---|
31 | # The Mojolicious::Lite DSL
|
---|
32 | my $root = $routes;
|
---|
33 | for my $name (qw(any get options patch post put websocket)) {
|
---|
34 | monkey_patch $caller, $name, sub { $routes->$name(@_) };
|
---|
35 | }
|
---|
36 | monkey_patch($caller, $_, sub {$app}) for qw(new app);
|
---|
37 | monkey_patch $caller, del => sub { $routes->delete(@_) };
|
---|
38 | monkey_patch $caller, group => sub (&) {
|
---|
39 | (my $old, $root) = ($root, $routes);
|
---|
40 | shift->();
|
---|
41 | ($routes, $root) = ($root, $old);
|
---|
42 | };
|
---|
43 | monkey_patch $caller,
|
---|
44 | helper => sub { $app->helper(@_) },
|
---|
45 | hook => sub { $app->hook(@_) },
|
---|
46 | plugin => sub { $app->plugin(@_) },
|
---|
47 | under => sub { $routes = $root->under(@_) };
|
---|
48 |
|
---|
49 | # Make sure there's a default application for testing
|
---|
50 | Mojo::UserAgent::Server->app($app) unless Mojo::UserAgent::Server->app;
|
---|
51 |
|
---|
52 | # Lite apps are strict!
|
---|
53 | unshift @_, 'Mojo::Base', -strict;
|
---|
54 | goto &Mojo::Base::import;
|
---|
55 | }
|
---|
56 |
|
---|
57 | 1;
|
---|
58 |
|
---|
59 | =encoding utf8
|
---|
60 |
|
---|
61 | =head1 NAME
|
---|
62 |
|
---|
63 | Mojolicious::Lite - Micro real-time web framework
|
---|
64 |
|
---|
65 | =head1 SYNOPSIS
|
---|
66 |
|
---|
67 | # Automatically enables "strict", "warnings", "utf8" and Perl 5.10 features
|
---|
68 | use Mojolicious::Lite;
|
---|
69 |
|
---|
70 | # Route with placeholder
|
---|
71 | get '/:foo' => sub {
|
---|
72 | my $c = shift;
|
---|
73 | my $foo = $c->param('foo');
|
---|
74 | $c->render(text => "Hello from $foo.");
|
---|
75 | };
|
---|
76 |
|
---|
77 | # Start the Mojolicious command system
|
---|
78 | app->start;
|
---|
79 |
|
---|
80 | =head1 DESCRIPTION
|
---|
81 |
|
---|
82 | L<Mojolicious::Lite> is a tiny domain specific language built around
|
---|
83 | L<Mojolicious>, made up of only about a dozen Perl functions.
|
---|
84 |
|
---|
85 | On Perl 5.20+ you can also use a C<-signatures> flag to enable support for
|
---|
86 | L<subroutine signatures|perlsub/"Signatures">.
|
---|
87 |
|
---|
88 | use Mojolicious::Lite -signatures;
|
---|
89 |
|
---|
90 | get '/:foo' => sub ($c) {
|
---|
91 | my $foo = $c->param('foo');
|
---|
92 | $c->render(text => "Hello from $foo.");
|
---|
93 | };
|
---|
94 |
|
---|
95 | app->start;
|
---|
96 |
|
---|
97 | See L<Mojolicious::Guides::Tutorial> for more!
|
---|
98 |
|
---|
99 | =head1 GROWING
|
---|
100 |
|
---|
101 | While L<Mojolicious::Guides::Growing> will give you a detailed introduction to
|
---|
102 | growing a L<Mojolicious::Lite> prototype into a well-structured L<Mojolicious>
|
---|
103 | application, here we have collected a few snippets that illustrate very well
|
---|
104 | just how similar both of them are.
|
---|
105 |
|
---|
106 | =head2 Routes
|
---|
107 |
|
---|
108 | The functions L</"get">, L</"post"> and friends all have equivalent methods.
|
---|
109 |
|
---|
110 | # Mojolicious::Lite
|
---|
111 | get '/foo' => sub {
|
---|
112 | my $c = shift;
|
---|
113 | $c->render(text => 'Hello World!');
|
---|
114 | };
|
---|
115 |
|
---|
116 | # Mojolicious
|
---|
117 | sub startup {
|
---|
118 | my $self = shift;
|
---|
119 |
|
---|
120 | my $routes = $self->routes;
|
---|
121 | $routes->get('/foo' => sub {
|
---|
122 | my $c = shift;
|
---|
123 | $c->render(text => 'Hello World!');
|
---|
124 | });
|
---|
125 | }
|
---|
126 |
|
---|
127 | =head2 Application
|
---|
128 |
|
---|
129 | The application object you can access with the function L</"app"> is the first
|
---|
130 | argument passed to the C<startup> method.
|
---|
131 |
|
---|
132 | # Mojolicious::Lite
|
---|
133 | app->max_request_size(16777216);
|
---|
134 |
|
---|
135 | # Mojolicious
|
---|
136 | sub startup {
|
---|
137 | my $self = shift;
|
---|
138 | $self->max_request_size(16777216);
|
---|
139 | }
|
---|
140 |
|
---|
141 | =head2 Plugins
|
---|
142 |
|
---|
143 | Instead of the L</"plugin"> function you just use the method
|
---|
144 | L<Mojolicious/"plugin">.
|
---|
145 |
|
---|
146 | # Mojolicious::Lite
|
---|
147 | plugin 'Config';
|
---|
148 |
|
---|
149 | # Mojolicious
|
---|
150 | sub startup {
|
---|
151 | my $self = shift;
|
---|
152 | $self->plugin('Config');
|
---|
153 | }
|
---|
154 |
|
---|
155 | =head2 Helpers
|
---|
156 |
|
---|
157 | Similar to plugins, instead of the L</"helper"> function you just use the method
|
---|
158 | L<Mojolicious/"helper">.
|
---|
159 |
|
---|
160 | # Mojolicious::Lite
|
---|
161 | helper two => sub {
|
---|
162 | my $c = shift;
|
---|
163 | return 1 + 1;
|
---|
164 | };
|
---|
165 |
|
---|
166 | # Mojolicious
|
---|
167 | sub startup {
|
---|
168 | my $self = shift;
|
---|
169 | $self->helper(two => sub {
|
---|
170 | my $c = shift;
|
---|
171 | return 1 + 1;
|
---|
172 | });
|
---|
173 | }
|
---|
174 |
|
---|
175 | =head2 Under
|
---|
176 |
|
---|
177 | Instead of sequential function calls, we can use methods to build a tree with
|
---|
178 | nested routes, that much better illustrates how routes work internally.
|
---|
179 |
|
---|
180 | # Mojolicious::Lite
|
---|
181 | under '/foo';
|
---|
182 | get '/bar' => sub {...};
|
---|
183 |
|
---|
184 | # Mojolicious
|
---|
185 | sub startup {
|
---|
186 | my $self = shift;
|
---|
187 |
|
---|
188 | my $routes = $self->routes;
|
---|
189 | my $foo = $routes->under('/foo');
|
---|
190 | $foo->get('/bar' => sub {...});
|
---|
191 | }
|
---|
192 |
|
---|
193 | =head1 FUNCTIONS
|
---|
194 |
|
---|
195 | L<Mojolicious::Lite> implements the following functions, which are
|
---|
196 | automatically exported.
|
---|
197 |
|
---|
198 | =head2 any
|
---|
199 |
|
---|
200 | my $route = any '/:foo' => sub {...};
|
---|
201 | my $route = any '/:foo' => sub {...} => 'name';
|
---|
202 | my $route = any '/:foo' => {foo => 'bar'} => sub {...};
|
---|
203 | my $route = any '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
204 | my $route = any ['GET', 'POST'] => '/:foo' => sub {...};
|
---|
205 | my $route = any ['GET', 'POST'] => '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
206 | my $route = any
|
---|
207 | ['GET', 'POST'] => '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
208 |
|
---|
209 | Generate route with L<Mojolicious::Routes::Route/"any">, matching any of the
|
---|
210 | listed HTTP request methods or all. See L<Mojolicious::Guides::Tutorial> and
|
---|
211 | L<Mojolicious::Guides::Routing> for more information.
|
---|
212 |
|
---|
213 | =head2 app
|
---|
214 |
|
---|
215 | my $app = app;
|
---|
216 |
|
---|
217 | Returns the L<Mojolicious::Lite> application object, which is a subclass of
|
---|
218 | L<Mojolicious>.
|
---|
219 |
|
---|
220 | # Use all the available attributes and methods
|
---|
221 | app->log->level('error');
|
---|
222 | app->defaults(foo => 'bar');
|
---|
223 |
|
---|
224 | =head2 del
|
---|
225 |
|
---|
226 | my $route = del '/:foo' => sub {...};
|
---|
227 | my $route = del '/:foo' => sub {...} => 'name';
|
---|
228 | my $route = del '/:foo' => {foo => 'bar'} => sub {...};
|
---|
229 | my $route = del '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
230 | my $route = del '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
231 |
|
---|
232 | Generate route with L<Mojolicious::Routes::Route/"delete">, matching only
|
---|
233 | C<DELETE> requests. See L<Mojolicious::Guides::Tutorial> and
|
---|
234 | L<Mojolicious::Guides::Routing> for more information.
|
---|
235 |
|
---|
236 | =head2 get
|
---|
237 |
|
---|
238 | my $route = get '/:foo' => sub {...};
|
---|
239 | my $route = get '/:foo' => sub {...} => 'name';
|
---|
240 | my $route = get '/:foo' => {foo => 'bar'} => sub {...};
|
---|
241 | my $route = get '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
242 | my $route = get '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
243 |
|
---|
244 | Generate route with L<Mojolicious::Routes::Route/"get">, matching only C<GET>
|
---|
245 | requests. See L<Mojolicious::Guides::Tutorial> and
|
---|
246 | L<Mojolicious::Guides::Routing> for more information.
|
---|
247 |
|
---|
248 | =head2 group
|
---|
249 |
|
---|
250 | group {...};
|
---|
251 |
|
---|
252 | Start a new route group.
|
---|
253 |
|
---|
254 | =head2 helper
|
---|
255 |
|
---|
256 | helper foo => sub {...};
|
---|
257 |
|
---|
258 | Add a new helper with L<Mojolicious/"helper">.
|
---|
259 |
|
---|
260 | =head2 hook
|
---|
261 |
|
---|
262 | hook after_dispatch => sub {...};
|
---|
263 |
|
---|
264 | Share code with L<Mojolicious/"hook">.
|
---|
265 |
|
---|
266 | =head2 options
|
---|
267 |
|
---|
268 | my $route = options '/:foo' => sub {...};
|
---|
269 | my $route = options '/:foo' => sub {...} => 'name';
|
---|
270 | my $route = options '/:foo' => {foo => 'bar'} => sub {...};
|
---|
271 | my $route = options '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
272 | my $route = options '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
273 |
|
---|
274 | Generate route with L<Mojolicious::Routes::Route/"options">, matching only
|
---|
275 | C<OPTIONS> requests. See L<Mojolicious::Guides::Tutorial> and
|
---|
276 | L<Mojolicious::Guides::Routing> for more information.
|
---|
277 |
|
---|
278 | =head2 patch
|
---|
279 |
|
---|
280 | my $route = patch '/:foo' => sub {...};
|
---|
281 | my $route = patch '/:foo' => sub {...} => 'name';
|
---|
282 | my $route = patch '/:foo' => {foo => 'bar'} => sub {...};
|
---|
283 | my $route = patch '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
284 | my $route = patch '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
285 |
|
---|
286 | Generate route with L<Mojolicious::Routes::Route/"patch">, matching only
|
---|
287 | C<PATCH> requests. See L<Mojolicious::Guides::Tutorial> and
|
---|
288 | L<Mojolicious::Guides::Routing> for more information.
|
---|
289 |
|
---|
290 | =head2 plugin
|
---|
291 |
|
---|
292 | plugin SomePlugin => {foo => 23};
|
---|
293 |
|
---|
294 | Load a plugin with L<Mojolicious/"plugin">.
|
---|
295 |
|
---|
296 | =head2 post
|
---|
297 |
|
---|
298 | my $route = post '/:foo' => sub {...};
|
---|
299 | my $route = post '/:foo' => sub {...} => 'name';
|
---|
300 | my $route = post '/:foo' => {foo => 'bar'} => sub {...};
|
---|
301 | my $route = post '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
302 | my $route = post '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
303 |
|
---|
304 | Generate route with L<Mojolicious::Routes::Route/"post">, matching only C<POST>
|
---|
305 | requests. See L<Mojolicious::Guides::Tutorial> and
|
---|
306 | L<Mojolicious::Guides::Routing> for more information.
|
---|
307 |
|
---|
308 | =head2 put
|
---|
309 |
|
---|
310 | my $route = put '/:foo' => sub {...};
|
---|
311 | my $route = put '/:foo' => sub {...} => 'name';
|
---|
312 | my $route = put '/:foo' => {foo => 'bar'} => sub {...};
|
---|
313 | my $route = put '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
314 | my $route = put '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
315 |
|
---|
316 | Generate route with L<Mojolicious::Routes::Route/"put">, matching only C<PUT>
|
---|
317 | requests. See L<Mojolicious::Guides::Tutorial> and
|
---|
318 | L<Mojolicious::Guides::Routing> for more information.
|
---|
319 |
|
---|
320 | =head2 under
|
---|
321 |
|
---|
322 | my $route = under sub {...};
|
---|
323 | my $route = under '/:foo' => sub {...};
|
---|
324 | my $route = under '/:foo' => {foo => 'bar'};
|
---|
325 | my $route = under '/:foo' => [foo => qr/\w+/];
|
---|
326 | my $route = under '/:foo' => (agent => qr/Firefox/);
|
---|
327 | my $route = under [format => 0];
|
---|
328 |
|
---|
329 | Generate nested route with L<Mojolicious::Routes::Route/"under">, to which all
|
---|
330 | following routes are automatically appended. See
|
---|
331 | L<Mojolicious::Guides::Tutorial> and L<Mojolicious::Guides::Routing> for more
|
---|
332 | information.
|
---|
333 |
|
---|
334 | =head2 websocket
|
---|
335 |
|
---|
336 | my $route = websocket '/:foo' => sub {...};
|
---|
337 | my $route = websocket '/:foo' => sub {...} => 'name';
|
---|
338 | my $route = websocket '/:foo' => {foo => 'bar'} => sub {...};
|
---|
339 | my $route = websocket '/:foo' => [foo => qr/\w+/] => sub {...};
|
---|
340 | my $route = websocket '/:foo' => (agent => qr/Firefox/) => sub {...};
|
---|
341 |
|
---|
342 | Generate route with L<Mojolicious::Routes::Route/"websocket">, matching only
|
---|
343 | WebSocket handshakes. See L<Mojolicious::Guides::Tutorial> and
|
---|
344 | L<Mojolicious::Guides::Routing> for more information.
|
---|
345 |
|
---|
346 | =head1 ATTRIBUTES
|
---|
347 |
|
---|
348 | L<Mojolicious::Lite> inherits all attributes from L<Mojolicious>.
|
---|
349 |
|
---|
350 | =head1 METHODS
|
---|
351 |
|
---|
352 | L<Mojolicious::Lite> inherits all methods from L<Mojolicious>.
|
---|
353 |
|
---|
354 | =head1 SEE ALSO
|
---|
355 |
|
---|
356 | L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
---|
357 |
|
---|
358 | =cut
|
---|