SlideShare a Scribd company logo
Catalyst 
Elegant Perl MVC Framework 
Sheeju Alex 
Exceleron Software
Installing Catalyst 
cpan/cpanm Task::Catalyst 
● DBIx::Class Support 
● Template::Toolkit Support 
● Authentication/Authorization Support 
● HTML::FormFu Support 
OR install from apt-get
Setting up Catalyst App 
catalyst gets rid of repeated work... 
sheeju@sheeju-exceleron:~/projects$ catalyst.pl Library 
created "Library" 
created "Library/script" 
created "Library/lib" 
created "Library/root" 
……... 
created "Library/script/library_cgi.pl" 
created "Library/script/library_fastcgi.pl" 
created "Library/script/library_server.pl" 
created "Library/script/library_test.pl" 
created "Library/script/library_create.pl" 
Change to application directory and Run "perl Makefile.PL" to make sure your install is complete
What is MVC 
● Model (Data) 
○ Get All Users 
○ Get User foo 
○ Delete User 
● View (Display) 
○ Render the page 
○ Render user as JSON/XML 
● Controller (Glue’s - model and view) 
○ Get the Data from Model 
○ Check Permission 
○ Send data over to the view
So what does this mean? 
* Is full CPAN package 
* Contains Standalone and server deployment scripts 
* loads config automatically 
* testing stubs 
* helpers to create more parts of your app
App Layout 
● lib/ - package/class namespaces 
○ Library - lib/Library.pm 
○ Library::Controller::Root - lib/Library/Controller/Root.pm 
○ Model & View - empty for purpose 
● root/ - css,js,tt etc store here exposed via /static URL 
● script/ - application level script goes here including dev server script 
○ library_create.pl 
○ library_server.pl 
● t/ - Tests goes here (Watch for TDD presentation) 
fires up app in own dedicated server http://localhost:3000
Built-In Server - Start 
sheeju@sheeju-exceleron:~/projects/Library$ ./script/library_server.pl 
[debug] Debug messages enabled 
[debug] Loaded Config "/home/sheeju/projects/Library/library.conf" 
[debug] Statistics enabled 
[debug] Loaded plugins: 
.----------------------------------------------------------------------------. 
| Catalyst::Plugin::ConfigLoader 0.32 | 
| Catalyst::Plugin::Unicode::Encoding 2.1 | 
'----------------------------------------------------------------------------' 
[debug] Loaded Request Data Handlers: 
[debug] Loaded dispatcher "Catalyst::Dispatcher" 
[debug] Loaded engine "Catalyst::Engine" 
[debug] Found home "/home/sheeju/projects/Library" 
[debug] Loaded components:
Built-In Server - Start 
[debug] Loaded components: 
.-----------------------------------------------------------------+------------. 
| Class | Type | 
+-------------------------------------------------------------+-------------+ 
| Library::Controller::Root | instance | 
'---------------------------------------------------------------+--------------' 
[debug] Loaded Private actions: 
.------------------------+-----------------------------------------+--------------. 
| Private | Class | Method | 
+----------------------+------------------------------------------+-------------+ 
| /default | Library::Controller::Root | default | 
| /index | Library::Controller::Root | index | 
| /end | Library::Controller::Root | end | 
'------------------------+-----------------------------------------+--------------' 
[debug] Loaded Path actions: 
.-------------------------------------+-------------------------------------. 
| Path | Private | 
+-------------------------------------+----------------------------------+ 
| / | /index | 
| /... | /default | 
'-------------------------------------+-------------------------------------' 
[info] Library powered by Catalyst 5.90053 
HTTP::Server::PSGI: Accepting connections at http://0:3000/
Browse me
Request ⇔ Response 
● All web applications handle request and generate responses. 
● In Catalyst, this happens in special methods called "actions". On every request, Catalyst 
identifies one or more actions and calls them with special arguments, including a reference to 
the "context" object that provides a convenient and practical API through which everything 
else is accomplished. 
○ Actions are contained within classes called "controllers", which live in a special 
path/namespace in the application 
● script/library_create.pl controller Something - creates a new controller 
○ The only reason to have more than one controller is for organization; you can put all 
your actions in the Root controller with no loss of features or ability. Controllers are just 
the containers for actions. 
● In the following sections, I describe how Catalyst decides which actions to call on each request 
("dispatch") and then explain how to use the supplied context object within them.
Dispatch 
● Catalyst provides a particularly flexible and powerful mechanism for configuring dispatch rules. 
● Rather than having a separate configuration to assign URLs to specific actions, Catalyst uses 
the actions themselves to determine URL mappings dynamically. 
● Each action definition (which is just a Perl subroutine) represents not only a block of code, but 
also what URL paths apply to it. This is specified in subroutine attributes—a lesser-known Perl 
feature that provides arbitrary labels that can be used for introspection. 
● Catalyst supports a handful of parameterized attributes (Local,Global,Private,Path, 
LocalRegex,Regex,Chained) to determine the URL path to action mappings in a variety ways 
sub do_stuff :Attribute1 :Attribute2 :Attribute3('with_argument') { ... 
Note The first : for the attributes is compulsory, whereas the 
following are optional.
Dispatch :Path 
:Path Attribute (Absolute Path) 
sub myaction :Path('/some/place') { 
my ( $self, $c, @args ) = @_; 
# do stuff... 
} 
● Regardless of what controller you put it in, the above action would map to all URLs starting 
with /some/place (http://localhost:3000/some/place with the development server). 
● If you omitted the starting slash and used :Path('some/place'), the action would map to a path 
relative to the namespace of the controller. For example, if it were in Library::Controller:: 
Foobar, it would be mapped to URL paths starting with /foobar/some/place.
Dispatch :Local 
sub place :Local { 
my ( $self, $c, @args ) = @_; 
# do stuff... 
} 
● Instead of using :Path to set the path explicitly, you can set :Local to use the name of the 
controller and method. 
● For instance, the following action, if contained in the controller Library::Controller::Some, 
would also map to /some/place: 
● If it were contained in the controller Library::Controller::Some::Other, it would map to 
/some/other/place.
Dispatch :Path/Local/* :Args 
sub myaction :Path('/some/place') { 
my ( $self, $c ) = @_; 
# do stuff... 
} 
● Actions include subpaths by default, so the above also would match /some/place/blah/foo/1. 
● When this happens, the leftover parts of the path are supplied as arguments to the action method 
('blah','foo','1'). 
● You can use the :Args attribute to limit how deep the action will match subpaths, if at all. 
● With an Args value of 0, this action would match only /some/place, but nothing below it: 
sub myaction :Path('/some/place') :Args(0) { 
my ( $self, $c ) = @_; 
# do stuff... 
}
Dispatch :Global & :Private 
● :Global 
○ works like :Local but ignores the controller name 
○ Anywhere - show’s up in the root of your namespace 
● :Private 
○ Internal Functions 
○ No URL 
○ Can be invoked only through a $c->forward or a $c->detach within a 
controller.
Dispatch :Regex/:LocalRegex 
● path pattern matching, discouraged from 
using. 
● Explore yourself 
● You can use Chained instead
Dispatch :Chained 
● You can configure additional/multiple actions to be called with single requests in any order 
you like. 
package MyApp::Controller::Users; 
use parent 'Catalyst::Controller'; 
# private 
sub base :Chained("/") :PathPart("users") :CaptureArgs(0) {} 
# match /users 
sub root :Chained("base") :PathPart("") :Args(0) {} 
# private 
sub base_user : Chained('base') PathPart('') CaptureArgs(1) { ... } 
# match /users/1 
sub root_user : Chained('base_user') PathPart('') Args(0) { ... } 
# match /users/1/edit 
sub user_edit : Chained('base') PathPart('edit') Args(0) { ... } 
# match /users/1/display 
sub user_edit : Chained('base') PathPart('display') Args(0) { ... } 
Users <id> 
Edit 
Display 
URL’s like /users/1/edit, /users/1/display can separate the processing of /users/1 part into its own 
method.
Dispatch Flow 
● When a URL matches more than one action, Catalyst picks the one that matches best. 
● Exceptions: Called at various stages of every request in addition to the matched action 
○ sub default :Private {} - Match everything that doesn’t match 
○ sub index :Private {} 
○ sub begin :Private {} 
○ sub end :Private {} 
○ sub auto :Private {} 
Eg URL: /person/sheeju 
MyApp::C::Person -> sheeju (finds “sheeju” action inside “person” namespace) 
MyApp::C::Person -> auto (When found) 
MyApp::C::Root -> auto (if previous auto returs true continue to the next auto, else kill the request) 
MyApp::C::Person -> begin (if there is controller’s begin or run Root’s begin) 
MyApp::C::Person/Root -> end (Finally end, usually to render view)
Internal Request Flow Control 
$c->forward & $c->detach
Internal Request Flow Control 
$c->visit & $c->go
The Context Object ($c) 
● Controller actions serve as entry points to application code. 
● A special per-request object called the "context" is supplied as an argument to every action 
when it is called by the dispatcher. 
● The context object typically is read into a variable named $c, but it could be called anything. 
Important Objects 
● Request ($c->req) – web paranaters, cookies, headers, uploaded files 
● Response ($c->res) – set document body, HTTP status code 
● Configuration ($c->config) – static project configuration 
● Log ($c->log) – print log messages 
● Stash ($c->stash) – pass data from model to view 
● Session ($c->session) - session store
Controller: GET/POST Params 
$c->req->method - To check the request method (GET/POST) 
● GETs end up in passing parms 
○ my ($self, $c, $get1, $get2, $get3 ) = @_; OR $c->req->params 
● POSTs 
○ my $params = $c->req-params; 
❏ Pass data to models or store in db 
❏ Get Manipulated data and pass it to View (HTML/JSON…) 
https://metacpan.org/pod/Catalyst::Request
Controller Data Stores 
1. Stash: short term, lasts one response cycle. Data are references, same 
form as TT takes for its process() method. 
2. Flash: longer term. Used often with the flash_to_stash config set. Useful 
for storage when handling forms. 
3. Session: lasts some time. Can last longer than visitor's login, 2 hrs by 
default. Don't use same data names as stash, because they interact.
Data – Long Term Storage 
● Usually handled with a database 
○ But check out http://sedition.com/a/2794 
○ The above shows how to read text files. 
● Build your tables, and then use the database to build the ORM schema. 
● script/library_create.pl model DB DBIC::Schema Library::Schema 
create=static components=TimeStamp,EncodedColumn 'dbi:Pg: 
dbname=sheeju sheeju sheeju '{ AutoCommit => 1 }'
View TT 
● Web/HTML 
perl script/library_create.pl view Web TT - creates simple TT view 
perl script/library_create.pl view Web TTSite - creates TT site with layout, header, footer 
● JSON - Catalyst::View::JSON
OK so now how to render? 
● catalyst.pl has already done this for you 
sub end: ActionClass(‘RenderView’) {} 
● RenderView will try to render a template unless body is defined or 
redirect is in place 
● More than one view? $c->config->{default_view} or $c->stash-> 
{current_view} to decide which one to use
ActionClass & ActionRole 
● ActionClass 
○ A type of Controller that uses bottom-level namespace of an class as an argument to ActionClass 
attribute 
○ Catalyst::Action::RenderView - best example available on default project, execute method is called 
○ Use Does instead 
● ActionRole (Does) 
○ Provides the :Does attribute which applies roles to your action class 
○ provides “around execute”, “after execute”, “before execute” method using Moose Methodmodifiers 
sub foo : Local Does('Moo') { ... } # Catalyst::ActionRole:: 
sub bar : Local Does('~Moo') { ... } # MyApp::ActionRole::Moo 
sub baz : Local Does('+MyApp::ActionRole::Moo') { ... } 
http://www.catalystframework.org/calendar/2012/16 
http://metacpan.org/module/Catalyst::Controller::ActionRole
AJAX Dispatching 
● See Demo on AJAX ActionRole 
# Make sure this is an AJAX request 
my $hdr_accept = $c->req->header('Accept') || ''; 
my $hdr_x_req_with = $c->req->header('X-Requested-With') || ''; 
if ( $hdr_accept ne 'application/json' && $hdr_x_req_with ne 'XMLHttpRequest') 
{ 
$c->stash->{ajax} = 0; 
return $self->$orig(@_); 
}
Authentication 
use Catalyst qw/ ... 
Authentication 
Session 
Session::Store::FastMmap 
Session::State::Cookie 
... 
/;
Authentication: Config 
__PACKAGE__->config->{'Plugin::Authentication'} = { 
default => { 
credential => { 
class => ‘Password’, 
password_field => ‘Password’, 
password_type => ‘clear’ 
}, 
store => { 
class => ‘DBIx::Class’, 
user_class => ‘LibraryDB::User’ 
} 
} 
}; 
$c->authenticate 
$c->user 
$c->user_exists() 
$c->logout
References 
http://wiki.catalystframework.org/wiki/gettingstarted/howtos/chainedexamples.view 
http://frioux.github.io/Catalyst-Presentation/ 
http://www.catalystframework.org/calendar/2007/24 
http://sedition.com/a/2794 
http://sedition.com/a/2733

More Related Content

What's hot (20)

PDF
8 Minutes On Rack
danwrong
 
PDF
Redis for your boss
Elena Kolevska
 
PDF
Angular promises and http
Alexe Bogdan
 
PDF
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
PDF
A reviravolta do desenvolvimento web
Wallace Reis
 
PDF
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...
Ville Mattila
 
PPTX
PSGI and Plack from first principles
Perl Careers
 
PDF
Integrating icinga2 and the HashiCorp suite
Bram Vogelaar
 
PPTX
Working with WP_Query in WordPress
topher1kenobe
 
ODP
Http programming in play
Knoldus Inc.
 
KEY
Tatsumaki
Tatsuhiko Miyagawa
 
PDF
Rest api with Python
Santosh Ghimire
 
PDF
Finatra v2
Steve Cosenza
 
PDF
Angular server-side communication
Alexe Bogdan
 
PDF
Selenium&amp;scrapy
Arcangelo Saracino
 
PDF
Blood magic
Alex Denisov
 
PDF
Beyond Phoenix
Gabriele Lana
 
PDF
Symfony2 Components - The Event Dispatcher
Sarah El-Atm
 
KEY
Plack - LPW 2009
Tatsuhiko Miyagawa
 
PDF
Caldera Learn - LoopConf WP API + Angular FTW Workshop
CalderaLearn
 
8 Minutes On Rack
danwrong
 
Redis for your boss
Elena Kolevska
 
Angular promises and http
Alexe Bogdan
 
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
A reviravolta do desenvolvimento web
Wallace Reis
 
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...
Ville Mattila
 
PSGI and Plack from first principles
Perl Careers
 
Integrating icinga2 and the HashiCorp suite
Bram Vogelaar
 
Working with WP_Query in WordPress
topher1kenobe
 
Http programming in play
Knoldus Inc.
 
Rest api with Python
Santosh Ghimire
 
Finatra v2
Steve Cosenza
 
Angular server-side communication
Alexe Bogdan
 
Selenium&amp;scrapy
Arcangelo Saracino
 
Blood magic
Alex Denisov
 
Beyond Phoenix
Gabriele Lana
 
Symfony2 Components - The Event Dispatcher
Sarah El-Atm
 
Plack - LPW 2009
Tatsuhiko Miyagawa
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
CalderaLearn
 

Similar to Catalyst MVC (20)

PDF
Curscatalyst
Kar Juan
 
PDF
Development Setup of B-Translator
Dashamir Hoxha
 
PDF
Oracle API Gateway Installation
Rakesh Gujjarlapudi
 
PDF
Very Brief Intro to Catalyst
Zachary Blair
 
PDF
Capistrano deploy Magento project in an efficient way
Sylvain Rayé
 
PDF
Null Bachaav - May 07 Attack Monitoring workshop.
Prajal Kulkarni
 
PDF
The Naked Bundle - Tryout
Matthias Noback
 
PPTX
Bugzilla Installation Process
Vino Harikrishnan
 
PDF
Web applications with Catalyst
svilen.ivanov
 
PPTX
Service Discovery using etcd, Consul and Kubernetes
Sreenivas Makam
 
PPT
Deploy Rails Application by Capistrano
Tasawr Interactive
 
PDF
What's New In Laravel 5
Darren Craig
 
PDF
Exploring Async PHP (SF Live Berlin 2019)
dantleech
 
PDF
PaaSTA: Autoscaling at Yelp
Nathan Handler
 
PDF
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
Leo Lorieri
 
PDF
TurboGears2 Pluggable Applications
Alessandro Molina
 
PPTX
Orchestration Tool Roundup - Arthur Berezin & Trammell Scruggs
Cloud Native Day Tel Aviv
 
PDF
Improving the Accumulo User Experience
Accumulo Summit
 
PDF
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
DrupalDay
 
ODP
Practical catalyst
dwm042
 
Curscatalyst
Kar Juan
 
Development Setup of B-Translator
Dashamir Hoxha
 
Oracle API Gateway Installation
Rakesh Gujjarlapudi
 
Very Brief Intro to Catalyst
Zachary Blair
 
Capistrano deploy Magento project in an efficient way
Sylvain Rayé
 
Null Bachaav - May 07 Attack Monitoring workshop.
Prajal Kulkarni
 
The Naked Bundle - Tryout
Matthias Noback
 
Bugzilla Installation Process
Vino Harikrishnan
 
Web applications with Catalyst
svilen.ivanov
 
Service Discovery using etcd, Consul and Kubernetes
Sreenivas Makam
 
Deploy Rails Application by Capistrano
Tasawr Interactive
 
What's New In Laravel 5
Darren Craig
 
Exploring Async PHP (SF Live Berlin 2019)
dantleech
 
PaaSTA: Autoscaling at Yelp
Nathan Handler
 
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
Leo Lorieri
 
TurboGears2 Pluggable Applications
Alessandro Molina
 
Orchestration Tool Roundup - Arthur Berezin & Trammell Scruggs
Cloud Native Day Tel Aviv
 
Improving the Accumulo User Experience
Accumulo Summit
 
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
DrupalDay
 
Practical catalyst
dwm042
 
Ad

Recently uploaded (20)

PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Biography of Daniel Podor.pdf
Daniel Podor
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Ad

Catalyst MVC

  • 1. Catalyst Elegant Perl MVC Framework Sheeju Alex Exceleron Software
  • 2. Installing Catalyst cpan/cpanm Task::Catalyst ● DBIx::Class Support ● Template::Toolkit Support ● Authentication/Authorization Support ● HTML::FormFu Support OR install from apt-get
  • 3. Setting up Catalyst App catalyst gets rid of repeated work... sheeju@sheeju-exceleron:~/projects$ catalyst.pl Library created "Library" created "Library/script" created "Library/lib" created "Library/root" ……... created "Library/script/library_cgi.pl" created "Library/script/library_fastcgi.pl" created "Library/script/library_server.pl" created "Library/script/library_test.pl" created "Library/script/library_create.pl" Change to application directory and Run "perl Makefile.PL" to make sure your install is complete
  • 4. What is MVC ● Model (Data) ○ Get All Users ○ Get User foo ○ Delete User ● View (Display) ○ Render the page ○ Render user as JSON/XML ● Controller (Glue’s - model and view) ○ Get the Data from Model ○ Check Permission ○ Send data over to the view
  • 5. So what does this mean? * Is full CPAN package * Contains Standalone and server deployment scripts * loads config automatically * testing stubs * helpers to create more parts of your app
  • 6. App Layout ● lib/ - package/class namespaces ○ Library - lib/Library.pm ○ Library::Controller::Root - lib/Library/Controller/Root.pm ○ Model & View - empty for purpose ● root/ - css,js,tt etc store here exposed via /static URL ● script/ - application level script goes here including dev server script ○ library_create.pl ○ library_server.pl ● t/ - Tests goes here (Watch for TDD presentation) fires up app in own dedicated server http://localhost:3000
  • 7. Built-In Server - Start sheeju@sheeju-exceleron:~/projects/Library$ ./script/library_server.pl [debug] Debug messages enabled [debug] Loaded Config "/home/sheeju/projects/Library/library.conf" [debug] Statistics enabled [debug] Loaded plugins: .----------------------------------------------------------------------------. | Catalyst::Plugin::ConfigLoader 0.32 | | Catalyst::Plugin::Unicode::Encoding 2.1 | '----------------------------------------------------------------------------' [debug] Loaded Request Data Handlers: [debug] Loaded dispatcher "Catalyst::Dispatcher" [debug] Loaded engine "Catalyst::Engine" [debug] Found home "/home/sheeju/projects/Library" [debug] Loaded components:
  • 8. Built-In Server - Start [debug] Loaded components: .-----------------------------------------------------------------+------------. | Class | Type | +-------------------------------------------------------------+-------------+ | Library::Controller::Root | instance | '---------------------------------------------------------------+--------------' [debug] Loaded Private actions: .------------------------+-----------------------------------------+--------------. | Private | Class | Method | +----------------------+------------------------------------------+-------------+ | /default | Library::Controller::Root | default | | /index | Library::Controller::Root | index | | /end | Library::Controller::Root | end | '------------------------+-----------------------------------------+--------------' [debug] Loaded Path actions: .-------------------------------------+-------------------------------------. | Path | Private | +-------------------------------------+----------------------------------+ | / | /index | | /... | /default | '-------------------------------------+-------------------------------------' [info] Library powered by Catalyst 5.90053 HTTP::Server::PSGI: Accepting connections at http://0:3000/
  • 10. Request ⇔ Response ● All web applications handle request and generate responses. ● In Catalyst, this happens in special methods called "actions". On every request, Catalyst identifies one or more actions and calls them with special arguments, including a reference to the "context" object that provides a convenient and practical API through which everything else is accomplished. ○ Actions are contained within classes called "controllers", which live in a special path/namespace in the application ● script/library_create.pl controller Something - creates a new controller ○ The only reason to have more than one controller is for organization; you can put all your actions in the Root controller with no loss of features or ability. Controllers are just the containers for actions. ● In the following sections, I describe how Catalyst decides which actions to call on each request ("dispatch") and then explain how to use the supplied context object within them.
  • 11. Dispatch ● Catalyst provides a particularly flexible and powerful mechanism for configuring dispatch rules. ● Rather than having a separate configuration to assign URLs to specific actions, Catalyst uses the actions themselves to determine URL mappings dynamically. ● Each action definition (which is just a Perl subroutine) represents not only a block of code, but also what URL paths apply to it. This is specified in subroutine attributes—a lesser-known Perl feature that provides arbitrary labels that can be used for introspection. ● Catalyst supports a handful of parameterized attributes (Local,Global,Private,Path, LocalRegex,Regex,Chained) to determine the URL path to action mappings in a variety ways sub do_stuff :Attribute1 :Attribute2 :Attribute3('with_argument') { ... Note The first : for the attributes is compulsory, whereas the following are optional.
  • 12. Dispatch :Path :Path Attribute (Absolute Path) sub myaction :Path('/some/place') { my ( $self, $c, @args ) = @_; # do stuff... } ● Regardless of what controller you put it in, the above action would map to all URLs starting with /some/place (http://localhost:3000/some/place with the development server). ● If you omitted the starting slash and used :Path('some/place'), the action would map to a path relative to the namespace of the controller. For example, if it were in Library::Controller:: Foobar, it would be mapped to URL paths starting with /foobar/some/place.
  • 13. Dispatch :Local sub place :Local { my ( $self, $c, @args ) = @_; # do stuff... } ● Instead of using :Path to set the path explicitly, you can set :Local to use the name of the controller and method. ● For instance, the following action, if contained in the controller Library::Controller::Some, would also map to /some/place: ● If it were contained in the controller Library::Controller::Some::Other, it would map to /some/other/place.
  • 14. Dispatch :Path/Local/* :Args sub myaction :Path('/some/place') { my ( $self, $c ) = @_; # do stuff... } ● Actions include subpaths by default, so the above also would match /some/place/blah/foo/1. ● When this happens, the leftover parts of the path are supplied as arguments to the action method ('blah','foo','1'). ● You can use the :Args attribute to limit how deep the action will match subpaths, if at all. ● With an Args value of 0, this action would match only /some/place, but nothing below it: sub myaction :Path('/some/place') :Args(0) { my ( $self, $c ) = @_; # do stuff... }
  • 15. Dispatch :Global & :Private ● :Global ○ works like :Local but ignores the controller name ○ Anywhere - show’s up in the root of your namespace ● :Private ○ Internal Functions ○ No URL ○ Can be invoked only through a $c->forward or a $c->detach within a controller.
  • 16. Dispatch :Regex/:LocalRegex ● path pattern matching, discouraged from using. ● Explore yourself ● You can use Chained instead
  • 17. Dispatch :Chained ● You can configure additional/multiple actions to be called with single requests in any order you like. package MyApp::Controller::Users; use parent 'Catalyst::Controller'; # private sub base :Chained("/") :PathPart("users") :CaptureArgs(0) {} # match /users sub root :Chained("base") :PathPart("") :Args(0) {} # private sub base_user : Chained('base') PathPart('') CaptureArgs(1) { ... } # match /users/1 sub root_user : Chained('base_user') PathPart('') Args(0) { ... } # match /users/1/edit sub user_edit : Chained('base') PathPart('edit') Args(0) { ... } # match /users/1/display sub user_edit : Chained('base') PathPart('display') Args(0) { ... } Users <id> Edit Display URL’s like /users/1/edit, /users/1/display can separate the processing of /users/1 part into its own method.
  • 18. Dispatch Flow ● When a URL matches more than one action, Catalyst picks the one that matches best. ● Exceptions: Called at various stages of every request in addition to the matched action ○ sub default :Private {} - Match everything that doesn’t match ○ sub index :Private {} ○ sub begin :Private {} ○ sub end :Private {} ○ sub auto :Private {} Eg URL: /person/sheeju MyApp::C::Person -> sheeju (finds “sheeju” action inside “person” namespace) MyApp::C::Person -> auto (When found) MyApp::C::Root -> auto (if previous auto returs true continue to the next auto, else kill the request) MyApp::C::Person -> begin (if there is controller’s begin or run Root’s begin) MyApp::C::Person/Root -> end (Finally end, usually to render view)
  • 19. Internal Request Flow Control $c->forward & $c->detach
  • 20. Internal Request Flow Control $c->visit & $c->go
  • 21. The Context Object ($c) ● Controller actions serve as entry points to application code. ● A special per-request object called the "context" is supplied as an argument to every action when it is called by the dispatcher. ● The context object typically is read into a variable named $c, but it could be called anything. Important Objects ● Request ($c->req) – web paranaters, cookies, headers, uploaded files ● Response ($c->res) – set document body, HTTP status code ● Configuration ($c->config) – static project configuration ● Log ($c->log) – print log messages ● Stash ($c->stash) – pass data from model to view ● Session ($c->session) - session store
  • 22. Controller: GET/POST Params $c->req->method - To check the request method (GET/POST) ● GETs end up in passing parms ○ my ($self, $c, $get1, $get2, $get3 ) = @_; OR $c->req->params ● POSTs ○ my $params = $c->req-params; ❏ Pass data to models or store in db ❏ Get Manipulated data and pass it to View (HTML/JSON…) https://metacpan.org/pod/Catalyst::Request
  • 23. Controller Data Stores 1. Stash: short term, lasts one response cycle. Data are references, same form as TT takes for its process() method. 2. Flash: longer term. Used often with the flash_to_stash config set. Useful for storage when handling forms. 3. Session: lasts some time. Can last longer than visitor's login, 2 hrs by default. Don't use same data names as stash, because they interact.
  • 24. Data – Long Term Storage ● Usually handled with a database ○ But check out http://sedition.com/a/2794 ○ The above shows how to read text files. ● Build your tables, and then use the database to build the ORM schema. ● script/library_create.pl model DB DBIC::Schema Library::Schema create=static components=TimeStamp,EncodedColumn 'dbi:Pg: dbname=sheeju sheeju sheeju '{ AutoCommit => 1 }'
  • 25. View TT ● Web/HTML perl script/library_create.pl view Web TT - creates simple TT view perl script/library_create.pl view Web TTSite - creates TT site with layout, header, footer ● JSON - Catalyst::View::JSON
  • 26. OK so now how to render? ● catalyst.pl has already done this for you sub end: ActionClass(‘RenderView’) {} ● RenderView will try to render a template unless body is defined or redirect is in place ● More than one view? $c->config->{default_view} or $c->stash-> {current_view} to decide which one to use
  • 27. ActionClass & ActionRole ● ActionClass ○ A type of Controller that uses bottom-level namespace of an class as an argument to ActionClass attribute ○ Catalyst::Action::RenderView - best example available on default project, execute method is called ○ Use Does instead ● ActionRole (Does) ○ Provides the :Does attribute which applies roles to your action class ○ provides “around execute”, “after execute”, “before execute” method using Moose Methodmodifiers sub foo : Local Does('Moo') { ... } # Catalyst::ActionRole:: sub bar : Local Does('~Moo') { ... } # MyApp::ActionRole::Moo sub baz : Local Does('+MyApp::ActionRole::Moo') { ... } http://www.catalystframework.org/calendar/2012/16 http://metacpan.org/module/Catalyst::Controller::ActionRole
  • 28. AJAX Dispatching ● See Demo on AJAX ActionRole # Make sure this is an AJAX request my $hdr_accept = $c->req->header('Accept') || ''; my $hdr_x_req_with = $c->req->header('X-Requested-With') || ''; if ( $hdr_accept ne 'application/json' && $hdr_x_req_with ne 'XMLHttpRequest') { $c->stash->{ajax} = 0; return $self->$orig(@_); }
  • 29. Authentication use Catalyst qw/ ... Authentication Session Session::Store::FastMmap Session::State::Cookie ... /;
  • 30. Authentication: Config __PACKAGE__->config->{'Plugin::Authentication'} = { default => { credential => { class => ‘Password’, password_field => ‘Password’, password_type => ‘clear’ }, store => { class => ‘DBIx::Class’, user_class => ‘LibraryDB::User’ } } }; $c->authenticate $c->user $c->user_exists() $c->logout
  • 31. References http://wiki.catalystframework.org/wiki/gettingstarted/howtos/chainedexamples.view http://frioux.github.io/Catalyst-Presentation/ http://www.catalystframework.org/calendar/2007/24 http://sedition.com/a/2794 http://sedition.com/a/2733