Newer Older
1118 lines | 26.9kb
add files
Yuki Kimoto authored on 2014-03-26
1
package Mojolicious::Lite;
2
use Mojo::Base 'Mojolicious';
3

            
4
# "Bender: Bite my shiny metal ass!"
5
use File::Basename qw(basename dirname);
6
use File::Spec::Functions 'catdir';
7
use Mojo::UserAgent::Server;
8
use Mojo::Util 'monkey_patch';
9

            
10
sub import {
11

            
12
  # Remember executable for later
13
  $ENV{MOJO_EXE} ||= (caller)[1];
14

            
15
  # Reuse home directory if possible
16
  local $ENV{MOJO_HOME} = catdir(split '/', dirname $ENV{MOJO_EXE})
17
    unless $ENV{MOJO_HOME};
18

            
19
  # Initialize application class
20
  my $caller = caller;
21
  no strict 'refs';
22
  push @{"${caller}::ISA"}, 'Mojo';
23

            
24
  # Generate moniker based on filename
25
  my $moniker = basename $ENV{MOJO_EXE};
26
  $moniker =~ s/\.(?:pl|pm|t)$//i;
27
  my $app = shift->new(moniker => $moniker);
28

            
29
  # Initialize routes without namespaces
30
  my $routes = $app->routes->namespaces([]);
31
  $app->static->classes->[0] = $app->renderer->classes->[0] = $caller;
32

            
33
  # The Mojolicious::Lite DSL
34
  my $root = $routes;
35
  for my $name (qw(any get options patch post put websocket)) {
36
    monkey_patch $caller, $name, sub { $routes->$name(@_) };
37
  }
38
  monkey_patch $caller, $_, sub {$app}
39
    for qw(new app);
40
  monkey_patch $caller, del => sub { $routes->delete(@_) };
41
  monkey_patch $caller, group => sub (&) {
42
    (my $old, $root) = ($root, $routes);
43
    shift->();
44
    ($routes, $root) = ($root, $old);
45
  };
46
  monkey_patch $caller,
47
    helper => sub { $app->helper(@_) },
48
    hook   => sub { $app->hook(@_) },
49
    plugin => sub { $app->plugin(@_) },
50
    under  => sub { $routes = $root->under(@_) };
51

            
52
  # Make sure there's a default application for testing
53
  Mojo::UserAgent::Server->app($app) unless Mojo::UserAgent::Server->app;
54

            
55
  # Lite apps are strict!
56
  Mojo::Base->import(-strict);
57
}
58

            
59
1;
60

            
61
=encoding utf8
62

            
63
=head1 NAME
64

            
65
Mojolicious::Lite - Real-time micro web framework
66

            
67
=head1 SYNOPSIS
68

            
69
  # Automatically enables "strict", "warnings", "utf8" and Perl 5.10 features
70
  use Mojolicious::Lite;
71

            
72
  # Route with placeholder
73
  get '/:foo' => sub {
74
    my $self = shift;
75
    my $foo  = $self->param('foo');
76
    $self->render(text => "Hello from $foo.");
77
  };
78

            
79
  # Start the Mojolicious command system
80
  app->start;
81

            
82
=head1 DESCRIPTION
83

            
84
L<Mojolicious::Lite> is a micro real-time web framework built around
85
L<Mojolicious>.
86

            
87
=head1 TUTORIAL
88

            
89
A quick example driven introduction to the wonders of L<Mojolicious::Lite>.
90
Most of what you'll learn here also applies to normal L<Mojolicious>
91
applications.
92

            
93
=head2 Hello World
94

            
95
A simple Hello World application can look like this, L<strict>, L<warnings>,
96
L<utf8> and Perl 5.10 features are automatically enabled and a few functions
97
imported when you use L<Mojolicious::Lite>, turning your script into a full
98
featured web application.
99

            
100
  #!/usr/bin/env perl
101
  use Mojolicious::Lite;
102

            
103
  get '/' => sub {
104
    my $self = shift;
105
    $self->render(text => 'Hello World!');
106
  };
107

            
108
  app->start;
109

            
110
There is also a helper command to generate a small example application.
111

            
112
  $ mojo generate lite_app myapp.pl
113

            
114
=head2 Commands
115

            
116
All the normal L<Mojolicious::Commands> are available from the command line.
117
Note that CGI and L<PSGI> environments can usually be auto detected and will
118
just work without commands.
119

            
120
  $ ./myapp.pl daemon
121
  Server available at http://127.0.0.1:3000.
122

            
123
  $ ./myapp.pl daemon -l http://*:8080
124
  Server available at http://127.0.0.1:8080.
125

            
126
  $ ./myapp.pl cgi
127
  ...CGI output...
128

            
129
  $ ./myapp.pl
130
  ...List of available commands (or automatically detected environment)...
131

            
132
The C<app-E<gt>start> call that starts the L<Mojolicious> command system
133
should usually be the last expression in your application and can be
134
customized to override normal C<@ARGV> use.
135

            
136
  app->start('cgi');
137

            
138
=head2 Reloading
139

            
140
Your application will automatically reload itself if you start it with the
141
C<morbo> development web server, so you don't have to restart the server after
142
every change.
143

            
144
  $ morbo myapp.pl
145
  Server available at http://127.0.0.1:3000.
146

            
147
For more information about how to deploy your application see also
148
L<Mojolicious::Guides::Cookbook/"DEPLOYMENT">.
149

            
150
=head2 Routes
151

            
152
Routes are basically just fancy paths that can contain different kinds of
153
placeholders and usually lead to an action. The first argument passed to all
154
actions (the invocant C<$self>) is a L<Mojolicious::Controller> object
155
containing both the HTTP request and response.
156

            
157
  use Mojolicious::Lite;
158

            
159
  # Route leading to an action
160
  get '/foo' => sub {
161
    my $self = shift;
162
    $self->render(text => 'Hello World!');
163
  };
164

            
165
  app->start;
166

            
167
Response content is often generated by actions with
168
L<Mojolicious::Controller/"render">, but more about that later.
169

            
170
=head2 GET/POST parameters
171

            
172
All GET and POST parameters sent with the request are accessible via
173
L<Mojolicious::Controller/"param">.
174

            
175
  use Mojolicious::Lite;
176

            
177
  # /foo?user=sri
178
  get '/foo' => sub {
179
    my $self = shift;
180
    my $user = $self->param('user');
181
    $self->render(text => "Hello $user.");
182
  };
183

            
184
  app->start;
185

            
186
=head2 Stash and templates
187

            
188
The L<Mojolicious::Controller/"stash"> is used to pass data to templates,
189
which can be inlined in the C<DATA> section.
190

            
191
  use Mojolicious::Lite;
192

            
193
  # Route leading to an action that renders a template
194
  get '/bar' => sub {
195
    my $self = shift;
196
    $self->stash(one => 23);
197
    $self->render('baz', two => 24);
198
  };
199

            
200
  app->start;
201
  __DATA__
202

            
203
  @@ baz.html.ep
204
  The magic numbers are <%= $one %> and <%= $two %>.
205

            
206
For more information about templates see also
207
L<Mojolicious::Guides::Rendering/"Embedded Perl">.
208

            
209
=head2 HTTP
210

            
211
L<Mojolicious::Controller/"req"> and L<Mojolicious::Controller/"res"> give you
212
full access to all HTTP features and information.
213

            
214
  use Mojolicious::Lite;
215

            
216
  # Access request information
217
  get '/agent' => sub {
218
    my $self = shift;
219
    my $host = $self->req->url->to_abs->host;
220
    my $ua   = $self->req->headers->user_agent;
221
    $self->render(text => "Request by $ua reached $host.");
222
  };
223

            
224
  # Echo the request body and send custom header with response
225
  get '/echo' => sub {
226
    my $self = shift;
227
    $self->res->headers->header('X-Bender' => 'Bite my shiny metal ass!');
228
    $self->render(data => $self->req->body);
229
  };
230

            
231
  app->start;
232

            
233
=head2 Route names
234

            
235
All routes can have a name associated with them, this allows automatic
236
template detection and back referencing with
237
L<Mojolicious::Controller/"url_for"> as well as many helpers like
238
L<Mojolicious::Plugin::TagHelpers/"link_to">. Nameless routes get an
239
automatically generated one assigned that is simply equal to the route itself
240
without non-word characters.
241

            
242
  use Mojolicious::Lite;
243

            
244
  # Render the template "index.html.ep"
245
  get '/' => sub {
246
    my $self = shift;
247
    $self->render;
248
  } => 'index';
249

            
250
  # Render the template "hello.html.ep"
251
  get '/hello';
252

            
253
  app->start;
254
  __DATA__
255

            
256
  @@ index.html.ep
257
  <%= link_to Hello  => 'hello' %>.
258
  <%= link_to Reload => 'index' %>.
259

            
260
  @@ hello.html.ep
261
  Hello World!
262

            
263
=head2 Layouts
264

            
265
Templates can have layouts too, you just select one with the helper
266
L<Mojolicious::Plugin::DefaultHelpers/"layout"> and place the result of the
267
current template with the helper
268
L<Mojolicious::Plugin::DefaultHelpers/"content">.
269

            
270
  use Mojolicious::Lite;
271

            
272
  get '/with_layout';
273

            
274
  app->start;
275
  __DATA__
276

            
277
  @@ with_layout.html.ep
278
  % title 'Green';
279
  % layout 'green';
280
  Hello World!
281

            
282
  @@ layouts/green.html.ep
283
  <!DOCTYPE html>
284
  <html>
285
    <head><title><%= title %></title></head>
286
    <body><%= content %></body>
287
  </html>
288

            
289
The stash or helpers like L<Mojolicious::Plugin::DefaultHelpers/"title"> can
290
be used to pass additional data to the layout.
291

            
292
=head2 Blocks
293

            
294
Template blocks can be used like normal Perl functions and are always
295
delimited by the C<begin> and C<end> keywords.
296

            
297
  use Mojolicious::Lite;
298

            
299
  get '/with_block' => 'block';
300

            
301
  app->start;
302
  __DATA__
303

            
304
  @@ block.html.ep
305
  % my $link = begin
306
    % my ($url, $name) = @_;
307
    Try <%= link_to $url => begin %><%= $name %><% end %>.
308
  % end
309
  <!DOCTYPE html>
310
  <html>
311
    <head><title>Sebastians frameworks</title></head>
312
    <body>
313
      %= $link->('http://mojolicio.us', 'Mojolicious')
314
      %= $link->('http://catalystframework.org', 'Catalyst')
315
    </body>
316
  </html>
317

            
318
=head2 Captured content
319

            
320
The helper L<Mojolicious::Plugin::DefaultHelpers/"content_for"> can be used to
321
pass around blocks of captured content.
322

            
323
  use Mojolicious::Lite;
324

            
325
  get '/captured';
326

            
327
  app->start;
328
  __DATA__
329

            
330
  @@ captured.html.ep
331
  % layout 'blue', title => 'Green';
332
  % content_for header => begin
333
    <meta http-equiv="Pragma" content="no-cache">
334
  % end
335
  Hello World!
336
  % content_for header => begin
337
    <meta http-equiv="Expires" content="-1">
338
  % end
339

            
340
  @@ layouts/blue.html.ep
341
  <!DOCTYPE html>
342
  <html>
343
    <head>
344
      <title><%= title %></title>
345
      %= content_for 'header'
346
    </head>
347
    <body><%= content %></body>
348
  </html>
349

            
350
=head2 Helpers
351

            
352
You can also extend L<Mojolicious> with your own helpers, a list of all
353
built-in ones can be found in L<Mojolicious::Plugin::DefaultHelpers> and
354
L<Mojolicious::Plugin::TagHelpers>.
355

            
356
  use Mojolicious::Lite;
357

            
358
  # A helper to identify visitors
359
  helper whois => sub {
360
    my $self  = shift;
361
    my $agent = $self->req->headers->user_agent || 'Anonymous';
362
    my $ip    = $self->tx->remote_address;
363
    return "$agent ($ip)";
364
  };
365

            
366
  # Use helper in action and template
367
  get '/secret' => sub {
368
    my $self = shift;
369
    my $user = $self->whois;
370
    $self->app->log->debug("Request from $user.");
371
  };
372

            
373
  app->start;
374
  __DATA__
375

            
376
  @@ secret.html.ep
377
  We know who you are <%= whois %>.
378

            
379
=head2 Placeholders
380

            
381
Route placeholders allow capturing parts of a request path until a C</> or
382
C<.> separator occurs, results are accessible via
383
L<Mojolicious::Controller/"stash"> and L<Mojolicious::Controller/"param">.
384

            
385
  use Mojolicious::Lite;
386

            
387
  # /foo/test
388
  # /foo/test123
389
  get '/foo/:bar' => sub {
390
    my $self = shift;
391
    my $bar  = $self->stash('bar');
392
    $self->render(text => "Our :bar placeholder matched $bar");
393
  };
394

            
395
  # /testsomething/foo
396
  # /test123something/foo
397
  get '/(:bar)something/foo' => sub {
398
    my $self = shift;
399
    my $bar  = $self->param('bar');
400
    $self->render(text => "Our :bar placeholder matched $bar");
401
  };
402

            
403
  app->start;
404

            
405
=head2 Relaxed Placeholders
406

            
407
Relaxed placeholders allow matching of everything until a C</> occurs.
408

            
409
  use Mojolicious::Lite;
410

            
411
  # /test/hello
412
  # /test123/hello
413
  # /test.123/hello
414
  get '/#you/hello' => 'groovy';
415

            
416
  app->start;
417
  __DATA__
418

            
419
  @@ groovy.html.ep
420
  Your name is <%= $you %>.
421

            
422
=head2 Wildcard placeholders
423

            
424
Wildcard placeholders allow matching absolutely everything, including C</> and
425
C<.>.
426

            
427
  use Mojolicious::Lite;
428

            
429
  # /hello/test
430
  # /hello/test123
431
  # /hello/test.123/test/123
432
  get '/hello/*you' => 'groovy';
433

            
434
  app->start;
435
  __DATA__
436

            
437
  @@ groovy.html.ep
438
  Your name is <%= $you %>.
439

            
440
=head2 HTTP methods
441

            
442
Routes can be restricted to specific request methods with different keywords.
443

            
444
  use Mojolicious::Lite;
445

            
446
  # GET /hello
447
  get '/hello' => sub {
448
    my $self = shift;
449
    $self->render(text => 'Hello World!');
450
  };
451

            
452
  # PUT /hello
453
  put '/hello' => sub {
454
    my $self = shift;
455
    my $size = length $self->req->body;
456
    $self->render(text => "You uploaded $size bytes to /hello.");
457
  };
458

            
459
  # GET|POST|PATCH /bye
460
  any [qw(GET POST PATCH)] => '/bye' => sub {
461
    my $self = shift;
462
    $self->render(text => 'Bye World!');
463
  };
464

            
465
  # * /whatever
466
  any '/whatever' => sub {
467
    my $self   = shift;
468
    my $method = $self->req->method;
469
    $self->render(text => "You called /whatever with $method.");
470
  };
471

            
472
  app->start;
473

            
474
=head2 Optional placeholders
475

            
476
All placeholders require a value, but by assigning them default values you can
477
make capturing optional.
478

            
479
  use Mojolicious::Lite;
480

            
481
  # /hello
482
  # /hello/Sara
483
  get '/hello/:name' => {name => 'Sebastian'} => sub {
484
    my $self = shift;
485
    $self->render('groovy', format => 'txt');
486
  };
487

            
488
  app->start;
489
  __DATA__
490

            
491
  @@ groovy.txt.ep
492
  My name is <%= $name %>.
493

            
494
=head2 Restrictive placeholders
495

            
496
The easiest way to make placeholders more restrictive are alternatives, you
497
just make a list of possible values.
498

            
499
  use Mojolicious::Lite;
500

            
501
  # /test
502
  # /123
503
  any '/:foo' => [foo => [qw(test 123)]] => sub {
504
    my $self = shift;
505
    my $foo  = $self->param('foo');
506
    $self->render(text => "Our :foo placeholder matched $foo");
507
  };
508

            
509
  app->start;
510

            
511
All placeholders get compiled to a regular expression internally, this process
512
can also be easily customized.
513

            
514
  use Mojolicious::Lite;
515

            
516
  # /1
517
  # /123
518
  any '/:bar' => [bar => qr/\d+/] => sub {
519
    my $self = shift;
520
    my $bar  = $self->param('bar');
521
    $self->render(text => "Our :bar placeholder matched $bar");
522
  };
523

            
524
  app->start;
525

            
526
Just make sure not to use C<^> and C<$> or capturing groups C<(...)>, because
527
placeholders become part of a larger regular expression internally, C<(?:...)>
528
is fine though.
529

            
530
=head2 Under
531

            
532
Authentication and code shared between multiple routes can be realized easily
533
with bridge routes generated by the L</"under"> statement. All following
534
routes are only evaluated if the callback returned a true value.
535

            
536
  use Mojolicious::Lite;
537

            
538
  # Authenticate based on name parameter
539
  under sub {
540
    my $self = shift;
541

            
542
    # Authenticated
543
    my $name = $self->param('name') || '';
544
    return 1 if $name eq 'Bender';
545

            
546
    # Not authenticated
547
    $self->render('denied');
548
    return undef;
549
  };
550

            
551
  # Only reached when authenticated
552
  get '/' => 'index';
553

            
554
  app->start;
555
  __DATA__
556

            
557
  @@ denied.html.ep
558
  You are not Bender, permission denied.
559

            
560
  @@ index.html.ep
561
  Hi Bender.
562

            
563
Prefixing multiple routes is another good use for L</"under">.
564

            
565
  use Mojolicious::Lite;
566

            
567
  # /foo
568
  under '/foo';
569

            
570
  # /foo/bar
571
  get '/bar' => {text => 'foo bar'};
572

            
573
  # /foo/baz
574
  get '/baz' => {text => 'foo baz'};
575

            
576
  # / (reset)
577
  under '/' => {msg => 'whatever'};
578

            
579
  # /bar
580
  get '/bar' => {inline => '<%= $msg %> works'};
581

            
582
  app->start;
583

            
584
You can also L</"group"> related routes, which allows nesting of multiple
585
L</"under"> statements.
586

            
587
  use Mojolicious::Lite;
588

            
589
  # Global logic shared by all routes
590
  under sub {
591
    my $self = shift;
592
    return 1 if $self->req->headers->header('X-Bender');
593
    $self->render(text => "You're not Bender.");
594
    return undef;
595
  };
596

            
597
  # Admin section
598
  group {
599

            
600
    # Local logic shared only by routes in this group
601
    under '/admin' => sub {
602
      my $self = shift;
603
      return 1 if $self->req->headers->header('X-Awesome');
604
      $self->render(text => "You're not awesome enough.");
605
      return undef;
606
    };
607

            
608
    # GET /admin/dashboard
609
    get '/dashboard' => {text => 'Nothing to see here yet.'};
610
  };
611

            
612
  # GET /welcome
613
  get '/welcome' => {text => 'Hi Bender.'};
614

            
615
  app->start;
616

            
617
=head2 Formats
618

            
619
Formats can be automatically detected by looking at file extensions.
620

            
621
  use Mojolicious::Lite;
622

            
623
  # /detection.html
624
  # /detection.txt
625
  get '/detection' => sub {
626
    my $self = shift;
627
    $self->render('detected');
628
  };
629

            
630
  app->start;
631
  __DATA__
632

            
633
  @@ detected.html.ep
634
  <!DOCTYPE html>
635
  <html>
636
    <head><title>Detected</title></head>
637
    <body>HTML was detected.</body>
638
  </html>
639

            
640
  @@ detected.txt.ep
641
  TXT was detected.
642

            
643
Restrictive placeholders can also be used.
644

            
645
  use Mojolicious::Lite;
646

            
647
  # /hello.json
648
  # /hello.txt
649
  get '/hello' => [format => [qw(json txt)]] => sub {
650
    my $self = shift;
651
    return $self->render(json => {hello => 'world'})
652
      if $self->stash('format') eq 'json';
653
    $self->render(text => 'hello world');
654
  };
655

            
656
  app->start;
657

            
658
Or you can just disable format detection.
659

            
660
  use Mojolicious::Lite;
661

            
662
  # /hello
663
  get '/hello' => [format => 0] => {text => 'No format detection.'};
664

            
665
  # Disable detection and allow the following routes selective re-enabling
666
  under [format => 0];
667

            
668
  # /foo
669
  get '/foo' => {text => 'No format detection again.'};
670

            
671
  # /bar.txt
672
  get '/bar' => [format => 'txt'] => {text => ' Just one format.'};
673

            
674
  app->start;
675

            
676
=head2 Content negotiation
677

            
678
For resources with different representations and that require truly C<RESTful>
679
content negotiation you can also use L<Mojolicious::Controller/"respond_to">.
680

            
681
  use Mojolicious::Lite;
682

            
683
  # /hello (Accept: application/json)
684
  # /hello (Accept: application/xml)
685
  # /hello.json
686
  # /hello.xml
687
  # /hello?format=json
688
  # /hello?format=xml
689
  get '/hello' => sub {
690
    my $self = shift;
691
    $self->respond_to(
692
      json => {json => {hello => 'world'}},
693
      xml  => {text => '<hello>world</hello>'},
694
      any  => {data => '', status => 204}
695
    );
696
  };
697

            
698
  app->start;
699

            
700
MIME type mappings can be extended or changed easily with
701
L<Mojolicious/"types">.
702

            
703
  app->types->type(rdf => 'application/rdf+xml');
704

            
705
=head2 Static files
706

            
707
Similar to templates, but with only a single file extension and optional
708
Base64 encoding, static files can be inlined in the C<DATA> section and are
709
served automatically.
710

            
711
  use Mojolicious::Lite;
712

            
713
  app->start;
714
  __DATA__
715

            
716
  @@ something.js
717
  alert('hello!');
718

            
719
  @@ test.txt (base64)
720
  dGVzdCAxMjMKbGFsYWxh
721

            
722
External static files are not limited to a single file extension and will be
723
served automatically from a C<public> directory if it exists.
724

            
725
  $ mkdir public
726
  $ mv something.js public/something.js
727
  $ mv mojolicious.tar.gz public/mojolicious.tar.gz
728

            
729
Both have a higher precedence than routes.
730

            
731
=head2 External templates
732

            
733
External templates will be searched by the renderer in a C<templates>
734
directory if it exists.
735

            
736
  use Mojolicious::Lite;
737

            
738
  # Render template "templates/foo/bar.html.ep"
739
  any '/external' => sub {
740
    my $self = shift;
741
    $self->render('foo/bar');
742
  };
743

            
744
  app->start;
745

            
746
=head2 Conditions
747

            
748
Conditions such as C<agent> and C<host> from
749
L<Mojolicious::Plugin::HeaderCondition> allow even more powerful route
750
constructs.
751

            
752
  use Mojolicious::Lite;
753

            
754
  # Firefox
755
  get '/foo' => (agent => qr/Firefox/) => sub {
756
    my $self = shift;
757
    $self->render(text => 'Congratulations, you are using a cool browser.');
758
  };
759

            
760
  # Internet Explorer
761
  get '/foo' => (agent => qr/Internet Explorer/) => sub {
762
    my $self = shift;
763
    $self->render(text => 'Dude, you really need to upgrade to Firefox.');
764
  };
765

            
766
  # http://mojolicio.us/bar
767
  get '/bar' => (host => 'mojolicio.us') => sub {
768
    my $self = shift;
769
    $self->render(text => 'Hello Mojolicious.');
770
  };
771

            
772
  app->start;
773

            
774
=head2 Sessions
775

            
776
Signed cookie based sessions just work out of the box as soon as you start
777
using them through the helper
778
L<Mojolicious::Plugin::DefaultHelpers/"session">, just be aware that all
779
session data gets serialized with L<Mojo::JSON>.
780

            
781
  use Mojolicious::Lite;
782

            
783
  # Access session data in action and template
784
  get '/counter' => sub {
785
    my $self = shift;
786
    $self->session->{counter}++;
787
  };
788

            
789
  app->start;
790
  __DATA__
791

            
792
  @@ counter.html.ep
793
  Counter: <%= session 'counter' %>
794

            
795
Note that you should use a custom L<Mojolicious/"secret"> to make signed
796
cookies really secure.
797

            
798
  app->secret('My secret passphrase here');
799

            
800
=head2 File uploads
801

            
802
All files uploaded via C<multipart/form-data> request are automatically
803
available as L<Mojo::Upload> objects. And you don't have to worry about memory
804
usage, because all files above C<250KB> will be automatically streamed into a
805
temporary file.
806

            
807
  use Mojolicious::Lite;
808

            
809
  # Upload form in DATA section
810
  get '/' => 'form';
811

            
812
  # Multipart upload handler
813
  post '/upload' => sub {
814
    my $self = shift;
815

            
816
    # Check file size
817
    return $self->render(text => 'File is too big.', status => 200)
818
      if $self->req->is_limit_exceeded;
819

            
820
    # Process uploaded file
821
    return $self->redirect_to('form')
822
      unless my $example = $self->param('example');
823
    my $size = $example->size;
824
    my $name = $example->filename;
825
    $self->render(text => "Thanks for uploading $size byte file $name.");
826
  };
827

            
828
  app->start;
829
  __DATA__
830

            
831
  @@ form.html.ep
832
  <!DOCTYPE html>
833
  <html>
834
    <head><title>Upload</title></head>
835
    <body>
836
      %= form_for upload => (enctype => 'multipart/form-data') => begin
837
        %= file_field 'example'
838
        %= submit_button 'Upload'
839
      % end
840
    </body>
841
  </html>
842

            
843
To protect you from excessively large files there is also a limit of C<10MB>
844
by default, which you can tweak with the MOJO_MAX_MESSAGE_SIZE environment
845
variable.
846

            
847
  # Increase limit to 1GB
848
  $ENV{MOJO_MAX_MESSAGE_SIZE} = 1073741824;
849

            
850
=head2 User agent
851

            
852
With L<Mojo::UserAgent>, which is available through the helper
853
L<Mojolicious::Plugin::DefaultHelpers/"ua">, there's a full featured HTTP and
854
WebSocket user agent built right in. Especially in combination with
855
L<Mojo::JSON> and L<Mojo::DOM> this can be a very powerful tool.
856

            
857
  use Mojolicious::Lite;
858

            
859
  # Blocking
860
  get '/headers' => sub {
861
    my $self = shift;
862
    my $url  = $self->param('url') || 'http://mojolicio.us';
863
    my $dom  = $self->ua->get($url)->res->dom;
864
    $self->render(json => [$dom->find('h1, h2, h3')->text->each]);
865
  };
866

            
867
  # Non-blocking
868
  get '/title' => sub {
869
    my $self = shift;
870
    $self->ua->get('mojolicio.us' => sub {
871
      my ($ua, $tx) = @_;
872
      $self->render(data => $tx->res->dom->at('title')->text);
873
    });
874
  };
875

            
876
  # Parallel non-blocking
877
  get '/titles' => sub {
878
    my $self = shift;
879
    my $delay = Mojo::IOLoop->delay(sub {
880
      my ($delay, @titles) = @_;
881
      $self->render(json => \@titles);
882
    });
883
    for my $url ('http://mojolicio.us', 'https://metacpan.org') {
884
      my $end = $delay->begin(0);
885
      $self->ua->get($url => sub {
886
        my ($ua, $tx) = @_;
887
        $end->($tx->res->dom->html->head->title->text);
888
      });
889
    }
890
  };
891

            
892
  app->start;
893

            
894
For more information about the user agent see also
895
L<Mojolicious::Guides::Cookbook/"USER AGENT">.
896

            
897
=head2 WebSockets
898

            
899
WebSocket applications have never been this simple before. Just receive
900
messages by subscribing to events such as
901
L<Mojo::Transaction::WebSocket/"json"> with L<Mojolicious::Controller/"on">
902
and return them with L<Mojolicious::Controller/"send">.
903

            
904
  use Mojolicious::Lite;
905

            
906
  websocket '/echo' => sub {
907
    my $self = shift;
908
    $self->on(json => sub {
909
      my ($self, $hash) = @_;
910
      $hash->{msg} = "echo: $hash->{msg}";
911
      $self->send({json => $hash});
912
    });
913
  };
914

            
915
  get '/' => 'index';
916

            
917
  app->start;
918
  __DATA__
919

            
920
  @@ index.html.ep
921
  <!DOCTYPE html>
922
  <html>
923
    <head>
924
      <title>Echo</title>
925
      %= javascript begin
926
        var ws = new WebSocket('<%= url_for('echo')->to_abs %>');
927
        ws.onmessage = function (event) {
928
          document.body.innerHTML += JSON.parse(event.data).msg;
929
        };
930
        ws.onopen = function (event) {
931
          ws.send(JSON.stringify({msg: 'I ♥ Mojolicious!'}));
932
        };
933
      % end
934
    </head>
935
  </html>
936

            
937
For more information about real-time web features see also
938
L<Mojolicious::Guides::Cookbook/"REAL-TIME WEB">.
939

            
940
=head2 Mode
941

            
942
You can use the L<Mojo::Log> object from L<Mojo/"log"> to portably collect
943
debug messages and automatically disable them later in a production setup by
944
changing the L<Mojolicious> operating mode, which can also be retrieved from
945
the attribute L<Mojolicious/"mode">.
946

            
947
  use Mojolicious::Lite;
948

            
949
  # Prepare mode specific message during startup
950
  my $msg = app->mode eq 'development' ? 'Development!' : 'Something else!';
951

            
952
  get '/' => sub {
953
    my $self = shift;
954
    $self->app->log->debug('Rendering mode specific message.');
955
    $self->render(text => $msg);
956
  };
957

            
958
  app->log->debug('Starting application.');
959
  app->start;
960

            
961
The default operating mode will usually be C<development> and can be changed
962
with command line options or the MOJO_MODE and PLACK_ENV environment
963
variables. A mode other than C<development> will raise the log level from
964
C<debug> to C<info>.
965

            
966
  $ ./myapp.pl daemon -m production
967

            
968
All messages will be written to C<STDERR> or a C<log/$mode.log> file if a
969
C<log> directory exists.
970

            
971
  $ mkdir log
972

            
973
Mode changes also affect a few other aspects of the framework, such as mode
974
specific C<exception> and C<not_found> templates.
975

            
976
=head2 Testing
977

            
978
Testing your application is as easy as creating a C<t> directory and filling
979
it with normal Perl unit tests, which can be a lot of fun thanks to
980
L<Test::Mojo>.
981

            
982
  use Test::More;
983
  use Test::Mojo;
984

            
985
  use FindBin;
986
  require "$FindBin::Bin/../myapp.pl";
987

            
988
  my $t = Test::Mojo->new;
989
  $t->get_ok('/')->status_is(200)->content_like(qr/Funky/);
990

            
991
  done_testing();
992

            
993
Run all unit tests with the C<test> command.
994

            
995
  $ ./myapp.pl test
996
  $ ./myapp.pl test -v
997

            
998
=head2 More
999

            
1000
You can continue with L<Mojolicious::Guides> now, and don't forget to have
1001
fun!
1002

            
1003
=head1 FUNCTIONS
1004

            
1005
L<Mojolicious::Lite> implements the following functions.
1006

            
1007
=head2 any
1008

            
1009
  my $route = any '/:foo' => sub {...};
1010
  my $route = any [qw(GET POST)] => '/:foo' => sub {...};
1011

            
1012
Generate route with L<Mojolicious::Routes::Route/"any">, matching any of the
1013
listed HTTP request methods or all. See also the tutorial above for more
1014
argument variations.
1015

            
1016
=head2 app
1017

            
1018
  my $app = app;
1019

            
1020
The L<Mojolicious::Lite> application.
1021

            
1022
=head2 del
1023

            
1024
  my $route = del '/:foo' => sub {...};
1025

            
1026
Generate route with L<Mojolicious::Routes::Route/"delete">, matching only
1027
DELETE requests. See also the tutorial above for more argument variations.
1028

            
1029
=head2 get
1030

            
1031
  my $route = get '/:foo' => sub {...};
1032

            
1033
Generate route with L<Mojolicious::Routes::Route/"get">, matching only GET
1034
requests. See also the tutorial above for more argument variations.
1035

            
1036
=head2 group
1037

            
1038
  group {...};
1039

            
1040
Start a new route group.
1041

            
1042
=head2 helper
1043

            
1044
  helper foo => sub {...};
1045

            
1046
Add a new helper with L<Mojolicious/"helper">.
1047

            
1048
=head2 hook
1049

            
1050
  hook after_dispatch => sub {...};
1051

            
1052
Share code with L<Mojolicious/"hook">.
1053

            
1054
=head2 options
1055

            
1056
  my $route = options '/:foo' => sub {...};
1057

            
1058
Generate route with L<Mojolicious::Routes::Route/"options">, matching only
1059
OPTIONS requests. See also the tutorial above for more argument
1060
variations.
1061

            
1062
=head2 patch
1063

            
1064
  my $route = patch '/:foo' => sub {...};
1065

            
1066
Generate route with L<Mojolicious::Routes::Route/"patch">, matching only
1067
PATCH requests. See also the tutorial above for more argument variations.
1068

            
1069
=head2 plugin
1070

            
1071
  plugin SomePlugin => {foo => 23};
1072

            
1073
Load a plugin with L<Mojolicious/"plugin">.
1074

            
1075
=head2 post
1076

            
1077
  my $route = post '/:foo' => sub {...};
1078

            
1079
Generate route with L<Mojolicious::Routes::Route/"post">, matching only
1080
POST requests. See also the tutorial above for more argument variations.
1081

            
1082
=head2 put
1083

            
1084
  my $route = put '/:foo' => sub {...};
1085

            
1086
Generate route with L<Mojolicious::Routes::Route/"put">, matching only PUT
1087
requests. See also the tutorial above for more argument variations.
1088

            
1089
=head2 under
1090

            
1091
  my $bridge = under sub {...};
1092
  my $bridge = under '/:foo';
1093

            
1094
Generate bridge route with L<Mojolicious::Routes::Route/"under">, to which all
1095
following routes are automatically appended. See also the tutorial above for
1096
more argument variations.
1097

            
1098
=head2 websocket
1099

            
1100
  my $route = websocket '/:foo' => sub {...};
1101

            
1102
Generate route with L<Mojolicious::Routes::Route/"websocket">, matching only
1103
WebSocket handshakes. See also the tutorial above for more argument
1104
variations.
1105

            
1106
=head1 ATTRIBUTES
1107

            
1108
L<Mojolicious::Lite> inherits all attributes from L<Mojolicious>.
1109

            
1110
=head1 METHODS
1111

            
1112
L<Mojolicious::Lite> inherits all methods from L<Mojolicious>.
1113

            
1114
=head1 SEE ALSO
1115

            
1116
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
1117

            
1118
=cut