Mojolicious 120128010851 Phpapp01
Mojolicious 120128010851 Phpapp01
● $ hello.pl daemon
Server available at http://127.0.0.1:
3000.
● $ curl http://127.0.0.1:3000/
Hello World!
Generator
● There is a helper command to generate a
small example application. You may
generate multiple things, but two are very
interesting.
● $ mojo generate app
Generate Mojolicious application directory
structure.
● $ mojo generate lite_app
Generate Mojolicious::Lite application.
Mojolicious::Lite
#!/usr/bin/env perl
use Mojolicious::Lite;
app->start;
Mojolicious::Lite
__DATA__
@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to Mojolicious!
@@ layouts/default.html.ep
<!doctype html><html>
<head><title><%= title %></title></head>
<body><%= content %></body>
</html>
Routes
get '/welcome' => sub { … };
# GET /welcome
get '/welcome' => { text => 'Hi Bender.' };
Under
group {
# shared only by routes in this group
under '/admin' => sub {
my $self = shift;
return 1 if login_ok( $self );
$self->redirect_to('/login_page');
return
};
# GET /admin/dashboard
get '/dashboard' => { text => 'logged' };
};
Sessions
get '/counter' => sub {
my $self = shift;
$self->session->{counter}++;
};
__DATA__
@@ counter.html.ep
Counter: <%= session 'counter' %>
__DATA__
@@ baz.html.ep
Magic numbers: <%= $one %> and <%= $two %>.
$self->render(
json => {foo => [1, 2, 3]});
Rendering templates
get '/bar' => sub {
my $self = shift;
$self->render(template => 'bar');
};
__DATA__
@@ bar.html.ep
Hi <%= param('name') %>
@@ layouts/mylayout.html.ep
<!DOCTYPE html>
<html>
<head><title><%= $title %></title></head>
<body><%= content %></body>
</html>
__DATA__
@@ bar.html.ep
<%= dumper( { 'a' => 'b' } ) %>
__DATA__
@@ bar.html.ep
value: <%= prefix( $str, 5 ) %>
Growing
Generator
# Routes
my $r = $self->routes;
1;
Routing
# GET /user/123
$r->get('/user/:user_id')
->to(cb => sub { ... });
# POST /user/123
$r->post('/user/:user_id')->to(
controller => 'example',
action => 'post_user'
); # Will call: MyApp::Example::post_user
$r->post('/user/:user_id')->to(
'example#post_user');
Route Bridge
# POST /auth/user/123
my $r_auth = $r->bridge('/auth')
->to( cb => sub { ... } );
$r_auth->post('/user/:user_id')
->to('example#hdl_post_user');
Controller: lib/MyApp/Example.pm
package MyApp::Example;
use Mojo::Base 'Mojolicious::Controller';
# Render "example/welcome.html.ep"
$self->render( message => 'Welcome!');
}
1;
Testing
use Mojo::Base -strict;
use_ok 'MyApp';
my $t = Test::Mojo->new('MyApp');
$t->get_ok('/welcome')
->status_is(200)
->content_like(qr/Welcome/i);
Testing
● Request:
$t->delete_ok('/foo');
$t->get_ok('/foo');
$t->head_ok('/foo');
$t->post_ok('/foo');
$t->post_form_ok(
'/foo' => {test => 123});
$t->put_ok('/foo');
● Header
$t->header_is(Expect => 'fun');
$t->header_isnt(Expect => 'fun');
$t->header_like(Expect => qr/fun/);
$t->header_unlike(Expect => qr/fun/);
Testing
● Status
$t->status_is(200);
$t->status_isnt(200);
● Content Type
$t->content_type_is('text/html');
$t->content_type_isnt('text/html');
$t->content_type_like(qr/text/);
$t->content_type_unlike(qr/text/);
Testing
● Response content:
$t->content_is('working!');
$t->content_isnt('working!');
$t->content_like(qr/working!/);
$t->content_unlike(qr/working!/);
● CSS3 selectors
$t->element_exists('div.foo[x=y]');
$t->element_exists_not('div.foo[x=y]');
$t->text_is('div.foo[x=y]' => 'Hello!');
$t->text_isnt('div.foo[x=y]' => 'Hello!');
$t->text_like('div.foo[x=y]' => qr/Hello/);
$t->text_unlike('div.foo[x=y]' =>
qr/Hello/);
Testing
● JSON
$t->json_content_is([1, 2, 3]);
$t->json_is('/foo' => {bar => [1, 3]});
$t->json_has('/minibar');
$t->json_hasnt('/minibar');
Questions
and
Answers