SlideShare a Scribd company logo
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 frameworks
diego_k
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
Yusuke Wada
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
Marcus Ramberg
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
bpmedley
 
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 101
hendrikvb
 
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/5
Yusuke 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 framework
Jeremy 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 framework
Jeremy Kendall
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutSlim RedBeanPHP and Knockout
Slim RedBeanPHP and Knockout
Vic 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 Framework
Jeremy 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 Patterns
Robert Casanova
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creation
benalman
 
Asynchronous programming patterns in Perl
Asynchronous programming patterns in PerlAsynchronous programming patterns in Perl
Asynchronous programming patterns in Perl
deepfountainconsulting
 
Mojolicious
MojoliciousMojolicious
Mojolicious
Lenz Gschwendtner
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST API
Caldera 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

PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
Fabien Potencier
 
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
Michelangelo van Dam
 
Mojolicious, real-time web framework
Mojolicious, real-time web frameworkMojolicious, real-time web framework
Mojolicious, real-time web framework
taggg
 
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 Framework
Dirk 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 - phpbelfast
Michelangelo van Dam
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-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.js
souridatta
 
TurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsTurboGears2 Pluggable Applications
TurboGears2 Pluggable Applications
Alessandro 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, 2018
Balázs Tatár
 
Curscatalyst
CurscatalystCurscatalyst
Curscatalyst
Kar Juan
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
Yehuda 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 tek12
Michelangelo 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 framework
Christian 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, Germany
Balá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 2012
Michelangelo 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

Pigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending PlantPigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending Plant
LINUS PROJECTS (INDIA)
 
July Patch Tuesday
July Patch TuesdayJuly Patch Tuesday
July Patch Tuesday
Ivanti
 
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Bert Blevins
 
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAIApplying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
ssuserd4e0d2
 
Salesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot WorkshopSalesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot Workshop
CEPTES Software Inc
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
Yevgen Sysoyev
 
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and OllamaTirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Zilliz
 
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyyActive Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
RaminGhanbari2
 
Calgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptxCalgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptx
ishalveerrandhawa1
 
Recent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS InfrastructureRecent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS Infrastructure
KAMAL CHOUDHARY
 
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
Kief Morris
 
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
Priyanka Aash
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
Safe Software
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
Emerging Tech
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
Zilliz
 
How to build a generative AI solution A step-by-step guide (2).pdf
How to build a generative AI solution A step-by-step guide (2).pdfHow to build a generative AI solution A step-by-step guide (2).pdf
How to build a generative AI solution A step-by-step guide (2).pdf
ChristopherTHyatt
 
The Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdfThe Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdf
paysquare consultancy
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
ArgaBisma
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
aakash malhotra
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
Lidia A.
 

Recently uploaded (20)

Pigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending PlantPigging Unit Lubricant Oil Blending Plant
Pigging Unit Lubricant Oil Blending Plant
 
July Patch Tuesday
July Patch TuesdayJuly Patch Tuesday
July Patch Tuesday
 
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
 
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAIApplying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
Applying Retrieval-Augmented Generation (RAG) to Combat Hallucinations in GenAI
 
Salesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot WorkshopSalesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot Workshop
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
 
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and OllamaTirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
 
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyyActive Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
Active Inference is a veryyyyyyyyyyyyyyyyyyyyyyyy
 
Calgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptxCalgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptx
 
Recent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS InfrastructureRecent Advancements in the NIST-JARVIS Infrastructure
Recent Advancements in the NIST-JARVIS Infrastructure
 
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
 
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
 
How to build a generative AI solution A step-by-step guide (2).pdf
How to build a generative AI solution A step-by-step guide (2).pdfHow to build a generative AI solution A step-by-step guide (2).pdf
How to build a generative AI solution A step-by-step guide (2).pdf
 
The Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdfThe Role of Technology in Payroll Statutory Compliance (1).pdf
The Role of Technology in Payroll Statutory Compliance (1).pdf
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
 

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