SlideShare uma empresa Scribd 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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a 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
 

Semelhante a 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
 

Último

Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
fredae14
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
shyamraj55
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
saastr
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdfNunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
flufftailshop
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Wask
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
LucaBarbaro3
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 

Último (20)

Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdfNunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 

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