SlideShare a Scribd company logo
1 of 44
Download to read offline
Mojolicious
Marcos Rebelo (oleber@gmail.com)
Mojolicious
● An amazing real-time web framework
  supporting a simplified single file mode
  through Mojolicious::Lite.
● Very clean, portable and Object Oriented
  pure Perl API without any hidden magic and
  no requirements besides Perl 5.10.1
  (although 5.12+ is recommended, and
  optional CPAN modules will be used to
  provide advanced functionality if they are
  installed).
Mojolicious
● Full stack HTTP 1.1 and WebSocket
  client/server implementation with IPv6, TLS,
  Bonjour, IDNA, Comet (long polling),
  chunking and multipart support.
● Built-in non-blocking I/O web server
  supporting libev and hot deployment, perfect
  for embedding.
● Automatic CGI and PSGI detection.
● JSON and HTML5/XML parser with CSS3
  selector support.
Marcos Rebelo
● 10 years Perl Developer
● Test-driven development fan
● Mojolicious experience:
  ○ I'm not a Mojolicious developer.
  ○ A group of JSON Back-ends
  ○ Short effort on the Front-end
Any intelligent fool can make things bigger,
more complex, and more violent. It takes a
touch of genius -- and a lot of courage -- to
move in the opposite direction.
Albert Einstein
Installation




$ sudo cpan Mojolicious
Hello World
use Mojolicious::Lite;
get '/' => sub {
    shift->render(text => 'Hello World!')
};
app->start;

● $ 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;

# Documentation browser under "/perldoc"
plugin 'PODRenderer';

get '/welcome' => sub {
   my $self = shift;
   $self->render('index');
};

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 { … };

post '/user' => sub { … };

any '/baz' => sub { … };

any ['get', 'post', 'delete'] =>
  '/bye' => sub { … };
GET/POST parameters
# /foo?user=Peter
get '/foo' => sub {
   my $self = shift;
   my $user = $self->param('user');
   $self->render(
     text => "Hello $user.");
};
Placeholders
# /foo/peter
get '/foo/:user' => sub {
   my $self = shift;
   my $user = $self->param('user');
   $self->render(
     text => "Hello $user.");
};

● Much more can be told about Placeholders,
  see the documentation.
Under
under sub {
   # Global logic shared by all routes
   my $self = shift;
   return 1 if
     $self->req->headers->header('X-Bender');
   $self->render(text=>"You're not Bender.");
   return;
};

# 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' %>

● Signed cookie based sessions just work out
  of the box as soon as you start using them.
Flash
get '/save' => sub {
  my $self = shift;

  $self->flash('success' => 1);
  $c->redirect_to('/show_user');
};

● Data storage persistent only for the next
  request, stored in the session.
Stash
# /bar
get '/bar' => sub {
   my $self = shift;
   $self->stash(one => 23);
   $self->render('baz', two => 24);
};

__DATA__
@@ baz.html.ep
Magic numbers: <%= $one %> and <%= $two %>.

● The stash is used to pass data to templates.
Log
my $log = $self->app->log;

$log->debug("Why isn't this working?");
$log->info("FYI: it happened again");
$log->warn("This might be a problem");
$log->error("Garden variety error");
$log->fatal("Boom!");

● Messages will be automatically written to
  STDERR or a '$mode.log' file if a log
  directory exists.
Render
● Rendering text: Perl characters can be
  rendered with the text stash value, the given
  content will be automatically encoded to
  bytes.

  $self->render(text => 'Hello World!');

● Rendering data: Raw bytes can be rendered,
  no encoding will be performed.

  $self->render(data => $octets);
Render
● Rendering JSON: The json stash value
  allows you to pass Perl structures to the
  renderer which get directly encoded to
  JSON.

$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') %>

● The templates shall in the __DATA__
  session or in the templates directory with the
  file name name.format.handler.
Rendering templates
● The renderer does some magic to find the
  templates.
● Since we are processing '/bar', all this are
  similar:
  ○   $self->render(template => 'bar');
  ○   $self->render('bar');
  ○   $self->render();
  ○   You don't even need it. If there is no rendering done,
      Mojolicious will do it by default.
Embedded Perl
<% Perl code %>
<%= Perl expression, replaced with XML escaped result %>
<%== Perl expression, replaced with result %>
<%# Comment, useful for debugging %>
<%% Replaced with "<%", useful for generating templates %>
% Perl code line, treated as "<% line =%>"
%= Perl expression line, treated as "<%= line %>"
%== Perl expression line, treated as "<%== line %>"
%# Comment line, treated as "<%# line =%>"
%% Replaced with "%", useful for generating templates
Examples
<% my $count = 10; %>
<ul>
     <% for my $index (1 .. $count) { %>
         <li>
              <%= $index %>
         </li>
     <% } %>
</ul>
Examples
% my $count = 10;
<ul>
     % for my $index (1 .. $count) {
         <li>
              %= $index
         </li>
     % }
</ul>
Examples
<%= 'lalala' %>         <%# XML escaped %>
<%== '<p>test</p>' %>   <%# not escaped %>
Layouts
@@ foo/bar.html.ep
% layout 'mylayout', title => 'Hi there';
Hello World!

@@ layouts/mylayout.html.ep
<!DOCTYPE html>
<html>
  <head><title><%= $title %></title></head>
  <body><%= content %></body>
</html>

● Most of the time you want to wrap your
  generated content in a HTML skeleton.
Helpers
get '/bar' => sub {
   my $self = shift;
   $self->app->log->debug(
     $self->dumper( [1,2,3] ) );
};

__DATA__

@@ bar.html.ep
<%= dumper( { 'a' => 'b' } ) %>

● Helpers are little functions you can use in
  templates and controller code.
Helpers examples
● dumper: Dump a Perl data structure using
  Data::Dumper
● app: Alias for "app" in Mojolicious::Controller
● param: Alias for "param".
● session: Alias for "session".
● stash: Alias for "stash".
● layout: Render this template with a layout.
● content: Insert content into a layout
  template.
Creating a Helper
helper 'prefix' => sub {
   my ( $self, $text, $length ) = @_;
   return length( $text ) > $length - 3
     ? substr($text, 0, $length) . '...'
     : $text;
};

get '/bar' => sub {
   shift->stash('str' => '123456789');
};

__DATA__
@@ bar.html.ep
value: <%= prefix( $str, 5 ) %>
Growing
Generator




$ mojo generate app MyApp
my_app                        #   Application directory
  |- script                   #   Script directory
  | `- my_app                 #   Application script
  |- lib                      #   Library directory
  | |- MyApp.pm               #   Application class
  | `- MyApp                  #   Application namespace
  |      `- Example.pm        #   Controller class
  |- t                        #   Test directory
  | `- basic.t                #   Random test
  |- log                      #   Log directory
  | `- development.log        #   Development mode log file
  |- public                   #   Static file directory
  | `- index.html             #   Static HTML file
  `- templates                #   Template directory
     |- layouts               #   Template directory for layouts
     | `- default.html.ep     #   Layout template
     `- example               #   Tmpl dir for "Example"
controller
         `- welcome.html.ep   # Template for "welcome" action
my_app/lib/MyApp.pm
package MyApp;
use Mojo::Base 'Mojolicious';

# This method will run once at server start
sub startup {
  my $self = shift;

     # Documentation browser under "/perldoc"
     $self->plugin('PODRenderer');

     # Routes
     my $r = $self->routes;

     # Normal route to controller
     $r->route('/welcome')->to('example#welcome');
}

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';

# This action will render a template
sub welcome {
  my $self = shift;

    # Render "example/welcome.html.ep"
    $self->render( message => 'Welcome!');
}

1;
Testing
use Mojo::Base -strict;

use Test::More tests => 4;
use Test::Mojo;

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

More Related Content

What's hot

Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojobpmedley
 
YAPC::Asia 2010 Twitter解析サービス
YAPC::Asia 2010 Twitter解析サービスYAPC::Asia 2010 Twitter解析サービス
YAPC::Asia 2010 Twitter解析サービスYusuke Wada
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101hendrikvb
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Anatoly Sharifulin
 
エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -
エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -
エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -Yusuke Wada
 
Twib in Yokoahma.pm 2010/3/5
Twib in Yokoahma.pm 2010/3/5Twib in Yokoahma.pm 2010/3/5
Twib in Yokoahma.pm 2010/3/5Yusuke Wada
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Arc & Codementor
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkJeremy Kendall
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutSlim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutVic Metcalfe
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
PerlでWeb API入門
PerlでWeb API入門PerlでWeb API入門
PerlでWeb API入門Yusuke Wada
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design PatternsRobert Casanova
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creationbenalman
 
Asynchronous programming patterns in Perl
Asynchronous programming patterns in PerlAsynchronous programming patterns in Perl
Asynchronous programming patterns in Perldeepfountainconsulting
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST APICaldera Labs
 

What's hot (20)

Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
 
YAPC::Asia 2010 Twitter解析サービス
YAPC::Asia 2010 Twitter解析サービスYAPC::Asia 2010 Twitter解析サービス
YAPC::Asia 2010 Twitter解析サービス
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!
 
エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -
エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -
エロサイト管理者の憂鬱3 - Hokkaiodo.pm#4 -
 
Twib in Yokoahma.pm 2010/3/5
Twib in Yokoahma.pm 2010/3/5Twib in Yokoahma.pm 2010/3/5
Twib in Yokoahma.pm 2010/3/5
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutSlim RedBeanPHP and Knockout
Slim RedBeanPHP and Knockout
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
PerlでWeb API入門
PerlでWeb API入門PerlでWeb API入門
PerlでWeb API入門
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design Patterns
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creation
 
Asynchronous programming patterns in Perl
Asynchronous programming patterns in PerlAsynchronous programming patterns in Perl
Asynchronous programming patterns in Perl
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST API
 

Similar to Mojolicious

Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Michelangelo van Dam
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web frameworktaggg
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Engine Yard
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkDirk Haun
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastMichelangelo van Dam
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
HackU PHP and Node.js
HackU PHP and Node.jsHackU PHP and Node.js
HackU PHP and Node.jssouridatta
 
TurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsTurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsAlessandro Molina
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Balázs Tatár
 
Curscatalyst
CurscatalystCurscatalyst
CurscatalystKar Juan
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)xSawyer
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkChristian Trabold
 
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, GermanyLet's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, GermanyBalázs Tatár
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 

Similar to Mojolicious (20)

PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web framework
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
HackU PHP and Node.js
HackU PHP and Node.jsHackU PHP and Node.js
HackU PHP and Node.js
 
TurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsTurboGears2 Pluggable Applications
TurboGears2 Pluggable Applications
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
 
Curscatalyst
CurscatalystCurscatalyst
Curscatalyst
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
 
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, GermanyLet's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 

Recently uploaded

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney
 

Recently uploaded (20)

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
 

Mojolicious

  • 2. Mojolicious ● An amazing real-time web framework supporting a simplified single file mode through Mojolicious::Lite. ● Very clean, portable and Object Oriented pure Perl API without any hidden magic and no requirements besides Perl 5.10.1 (although 5.12+ is recommended, and optional CPAN modules will be used to provide advanced functionality if they are installed).
  • 3. Mojolicious ● Full stack HTTP 1.1 and WebSocket client/server implementation with IPv6, TLS, Bonjour, IDNA, Comet (long polling), chunking and multipart support. ● Built-in non-blocking I/O web server supporting libev and hot deployment, perfect for embedding. ● Automatic CGI and PSGI detection. ● JSON and HTML5/XML parser with CSS3 selector support.
  • 4. Marcos Rebelo ● 10 years Perl Developer ● Test-driven development fan ● Mojolicious experience: ○ I'm not a Mojolicious developer. ○ A group of JSON Back-ends ○ Short effort on the Front-end
  • 5. Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction. Albert Einstein
  • 7. Hello World use Mojolicious::Lite; get '/' => sub { shift->render(text => 'Hello World!') }; app->start; ● $ hello.pl daemon Server available at http://127.0.0.1: 3000. ● $ curl http://127.0.0.1:3000/ Hello World!
  • 8. 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.
  • 9. Mojolicious::Lite #!/usr/bin/env perl use Mojolicious::Lite; # Documentation browser under "/perldoc" plugin 'PODRenderer'; get '/welcome' => sub { my $self = shift; $self->render('index'); }; app->start;
  • 10. 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>
  • 11. Routes get '/welcome' => sub { … }; post '/user' => sub { … }; any '/baz' => sub { … }; any ['get', 'post', 'delete'] => '/bye' => sub { … };
  • 12. GET/POST parameters # /foo?user=Peter get '/foo' => sub { my $self = shift; my $user = $self->param('user'); $self->render( text => "Hello $user."); };
  • 13. Placeholders # /foo/peter get '/foo/:user' => sub { my $self = shift; my $user = $self->param('user'); $self->render( text => "Hello $user."); }; ● Much more can be told about Placeholders, see the documentation.
  • 14. Under under sub { # Global logic shared by all routes my $self = shift; return 1 if $self->req->headers->header('X-Bender'); $self->render(text=>"You're not Bender."); return; }; # GET /welcome get '/welcome' => { text => 'Hi Bender.' };
  • 15. 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' }; };
  • 16. Sessions get '/counter' => sub { my $self = shift; $self->session->{counter}++; }; __DATA__ @@ counter.html.ep Counter: <%= session 'counter' %> ● Signed cookie based sessions just work out of the box as soon as you start using them.
  • 17. Flash get '/save' => sub { my $self = shift; $self->flash('success' => 1); $c->redirect_to('/show_user'); }; ● Data storage persistent only for the next request, stored in the session.
  • 18. Stash # /bar get '/bar' => sub { my $self = shift; $self->stash(one => 23); $self->render('baz', two => 24); }; __DATA__ @@ baz.html.ep Magic numbers: <%= $one %> and <%= $two %>. ● The stash is used to pass data to templates.
  • 19. Log my $log = $self->app->log; $log->debug("Why isn't this working?"); $log->info("FYI: it happened again"); $log->warn("This might be a problem"); $log->error("Garden variety error"); $log->fatal("Boom!"); ● Messages will be automatically written to STDERR or a '$mode.log' file if a log directory exists.
  • 20. Render ● Rendering text: Perl characters can be rendered with the text stash value, the given content will be automatically encoded to bytes. $self->render(text => 'Hello World!'); ● Rendering data: Raw bytes can be rendered, no encoding will be performed. $self->render(data => $octets);
  • 21. Render ● Rendering JSON: The json stash value allows you to pass Perl structures to the renderer which get directly encoded to JSON. $self->render( json => {foo => [1, 2, 3]});
  • 22. Rendering templates get '/bar' => sub { my $self = shift; $self->render(template => 'bar'); }; __DATA__ @@ bar.html.ep Hi <%= param('name') %> ● The templates shall in the __DATA__ session or in the templates directory with the file name name.format.handler.
  • 23. Rendering templates ● The renderer does some magic to find the templates. ● Since we are processing '/bar', all this are similar: ○ $self->render(template => 'bar'); ○ $self->render('bar'); ○ $self->render(); ○ You don't even need it. If there is no rendering done, Mojolicious will do it by default.
  • 24. Embedded Perl <% Perl code %> <%= Perl expression, replaced with XML escaped result %> <%== Perl expression, replaced with result %> <%# Comment, useful for debugging %> <%% Replaced with "<%", useful for generating templates %> % Perl code line, treated as "<% line =%>" %= Perl expression line, treated as "<%= line %>" %== Perl expression line, treated as "<%== line %>" %# Comment line, treated as "<%# line =%>" %% Replaced with "%", useful for generating templates
  • 25. Examples <% my $count = 10; %> <ul> <% for my $index (1 .. $count) { %> <li> <%= $index %> </li> <% } %> </ul>
  • 26. Examples % my $count = 10; <ul> % for my $index (1 .. $count) { <li> %= $index </li> % } </ul>
  • 27. Examples <%= 'lalala' %> <%# XML escaped %> <%== '<p>test</p>' %> <%# not escaped %>
  • 28. Layouts @@ foo/bar.html.ep % layout 'mylayout', title => 'Hi there'; Hello World! @@ layouts/mylayout.html.ep <!DOCTYPE html> <html> <head><title><%= $title %></title></head> <body><%= content %></body> </html> ● Most of the time you want to wrap your generated content in a HTML skeleton.
  • 29. Helpers get '/bar' => sub { my $self = shift; $self->app->log->debug( $self->dumper( [1,2,3] ) ); }; __DATA__ @@ bar.html.ep <%= dumper( { 'a' => 'b' } ) %> ● Helpers are little functions you can use in templates and controller code.
  • 30. Helpers examples ● dumper: Dump a Perl data structure using Data::Dumper ● app: Alias for "app" in Mojolicious::Controller ● param: Alias for "param". ● session: Alias for "session". ● stash: Alias for "stash". ● layout: Render this template with a layout. ● content: Insert content into a layout template.
  • 31. Creating a Helper helper 'prefix' => sub { my ( $self, $text, $length ) = @_; return length( $text ) > $length - 3 ? substr($text, 0, $length) . '...' : $text; }; get '/bar' => sub { shift->stash('str' => '123456789'); }; __DATA__ @@ bar.html.ep value: <%= prefix( $str, 5 ) %>
  • 34. my_app # Application directory |- script # Script directory | `- my_app # Application script |- lib # Library directory | |- MyApp.pm # Application class | `- MyApp # Application namespace | `- Example.pm # Controller class |- t # Test directory | `- basic.t # Random test |- log # Log directory | `- development.log # Development mode log file |- public # Static file directory | `- index.html # Static HTML file `- templates # Template directory |- layouts # Template directory for layouts | `- default.html.ep # Layout template `- example # Tmpl dir for "Example" controller `- welcome.html.ep # Template for "welcome" action
  • 35. my_app/lib/MyApp.pm package MyApp; use Mojo::Base 'Mojolicious'; # This method will run once at server start sub startup { my $self = shift; # Documentation browser under "/perldoc" $self->plugin('PODRenderer'); # Routes my $r = $self->routes; # Normal route to controller $r->route('/welcome')->to('example#welcome'); } 1;
  • 36. 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');
  • 37. 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');
  • 38. Controller: lib/MyApp/Example.pm package MyApp::Example; use Mojo::Base 'Mojolicious::Controller'; # This action will render a template sub welcome { my $self = shift; # Render "example/welcome.html.ep" $self->render( message => 'Welcome!'); } 1;
  • 39. Testing use Mojo::Base -strict; use Test::More tests => 4; use Test::Mojo; use_ok 'MyApp'; my $t = Test::Mojo->new('MyApp'); $t->get_ok('/welcome') ->status_is(200) ->content_like(qr/Welcome/i);
  • 40. 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/);
  • 41. 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/);
  • 42. 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/);
  • 43. Testing ● JSON $t->json_content_is([1, 2, 3]); $t->json_is('/foo' => {bar => [1, 3]}); $t->json_has('/minibar'); $t->json_hasnt('/minibar');