Web applications with Catalyst

21
6/12/05 6/12/05 1 / 21 / 21 Catalyst Catalyst easy to use MVC framework easy to use MVC framework Svilen Ivanov ([email protected]) Svilen Ivanov ([email protected])

Transcript of Web applications with Catalyst

Page 1: Web applications with Catalyst

6/12/056/12/05 11 / 21 / 21

CatalystCatalysteasy to use MVC frameworkeasy to use MVC framework

Svilen Ivanov ([email protected])Svilen Ivanov ([email protected])

Page 2: Web applications with Catalyst

6/12/056/12/05 22 / 21 / 21

What is MVC?What is MVC?

● MModelodel VViewiew CControllerontroller::■ architecture that separates an application's data model, architecture that separates an application's data model,

user interface, and control logic into 3 distinct componentsuser interface, and control logic into 3 distinct components

■ modifications to one component can be made with minimal modifications to one component can be made with minimal impact to the others.impact to the others.

● ResponsabilityResponsability■ model - domain-specific representation of the information model - domain-specific representation of the information

on which the application operates (database)on which the application operates (database)

■ view - renders the model into a form suitable for view - renders the model into a form suitable for interaction, typically a user interface (html)interaction, typically a user interface (html)

■ controller - responds to events and invokes changes on the controller - responds to events and invokes changes on the model and/or the view model and/or the view

Page 3: Web applications with Catalyst

6/12/056/12/05 33 / 21 / 21

What is Catalyst?What is Catalyst?

● A framework for development of web application A framework for development of web application using Model-View-Controller pattern:using Model-View-Controller pattern:■ Promotes the re-use of existing Perl modules that already Promotes the re-use of existing Perl modules that already

handle common web applicationhandle common web application

■ Catalyst is controllerCatalyst is controller

■ View: Template::Toolkit, Mason, HTML::Temlate, etc.View: Template::Toolkit, Mason, HTML::Temlate, etc.

■ Model: Class::DBI, Tangram, Rose::DB, etc.Model: Class::DBI, Tangram, Rose::DB, etc.

■ platform independent (really!)platform independent (really!)

■ Engines: CGI, FastCGI, mod_perl (1.3 and 2.0), self-Engines: CGI, FastCGI, mod_perl (1.3 and 2.0), self-restartinng developement enginerestartinng developement engine

Page 4: Web applications with Catalyst

6/12/056/12/05 44 / 21 / 21

Why Catalyst?Why Catalyst?

● Doesn't aim to provide end to end solution (RnR)Doesn't aim to provide end to end solution (RnR)● Flexability – use different components as M or VFlexability – use different components as M or V● Reusability – plugins (extends runtime Reusability – plugins (extends runtime

functionality):functionality):■ session, form validation, static files serving, unicodesession, form validation, static files serving, unicode

● Built-in developent tools:Built-in developent tools:■ self-restarting developement web server on dev's machineself-restarting developement web server on dev's machine

● Distribute the application as CPAN moduleDistribute the application as CPAN module● Framwork for auto and unit testsFramwork for auto and unit tests

■ doen't need web server to generate pagesdoen't need web server to generate pages

Page 5: Web applications with Catalyst

6/12/056/12/05 55 / 21 / 21

Catalyst WorkflowCatalyst Workflow

Page 6: Web applications with Catalyst

6/12/056/12/05 66 / 21 / 21

Installing and runningInstalling and running

● Installation from CPANInstallation from CPAN■ $ perl -MCPAN -e 'install Task::Catalyst'$ perl -MCPAN -e 'install Task::Catalyst'

● Creating stub applicationCreating stub application■ $ catalyst.pl MyApp$ catalyst.pl MyApp# output omitted# output omitted$ cd MyApp$ cd MyApp$ script/myapp_create.pl controller Library::Login$ script/myapp_create.pl controller Library::Login

● RunningRunning■ $ script/myapp_server.pl$ script/myapp_server.pl

● Open in browser:Open in browser:■ http://localhost:3000/library/login/http://localhost:3000/library/login/

Page 7: Web applications with Catalyst

6/12/056/12/05 77 / 21 / 21

Building application (1)Building application (1)

● Application Class – base class for your applicationApplication Class – base class for your applicationpackage MyApp;package MyApp;use strict;use strict;use Catalyst qw/-Debug/;use Catalyst qw/-Debug/;MyApp->config(MyApp->config( name => 'My Application',name => 'My Application', # You can put anything else you want in here:# You can put anything else you want in here: my_configuration_variable => 'something',my_configuration_variable => 'something',););

sub default : sub default : PrivatePrivate { { my ( $self, $context ) = @_;my ( $self, $context ) = @_; $context->response->body('Catalyst rocks!');$context->response->body('Catalyst rocks!');}}

Page 8: Web applications with Catalyst

6/12/056/12/05 88 / 21 / 21

ActionsActions

● ActionsActions■ action is a subroutine usually executed when requesting action is a subroutine usually executed when requesting

specific URLspecific URL

■ Action-to-URL mapping: Action-to-URL mapping: module:module: MyApp::Controller::Admin::Login MyApp::Controller::Admin::Loginurl: url: http://localhost/admin/login http://localhost/admin/login

● The attribute of the subroutine defines the type of The attribute of the subroutine defines the type of the actionthe actionsubsub namename : : attributesattributes {{

}}example:example:sub bar : Regex('^item(\d+)/order(\d+)$') { }sub bar : Regex('^item(\d+)/order(\d+)$') { }

Page 9: Web applications with Catalyst

6/12/056/12/05 99 / 21 / 21

Types of actions (1)Types of actions (1)

● LiteralLiteralpackage MyApp::Controller::My::Controller;package MyApp::Controller::My::Controller;

sub bar : Path('foo/bar') { }sub bar : Path('foo/bar') { }# http://localhost:3000/my/controller/foo/bar# http://localhost:3000/my/controller/foo/bar

sub bar : Path { }sub bar : Path { }# http://localhost:3000/my/controller# http://localhost:3000/my/controller

sub bar : Path('/foo/bar') { }sub bar : Path('/foo/bar') { }# http://localhost:3000/foo/bar# http://localhost:3000/foo/bar

● LocalRegexLocalRegexpackage MyApp::Controller::My::Controller;package MyApp::Controller::My::Controller;sub bar : LocalRegex('^widget(\d+)$') { }sub bar : LocalRegex('^widget(\d+)$') { }# http://localhost:3000/my/controller/widget23# http://localhost:3000/my/controller/widget23

● RegexRegexsub bar : Regex('^item(\d+)/order(\d+)$') { }sub bar : Regex('^item(\d+)/order(\d+)$') { }# http://localhost:3000/item23/order42# http://localhost:3000/item23/order42

Page 10: Web applications with Catalyst

6/12/056/12/05 1010 / 21 / 21

Types of actions (2)Types of actions (2)

● Top-levelTop-levelpackage MyApp; package MyApp; sub foo : Global { }sub foo : Global { }# http://localhost:3000/foo# http://localhost:3000/foo

● Namespace-PrefixedNamespace-Prefixedpackage MyApp::Controller::My::Controller; package MyApp::Controller::My::Controller; sub foo : Local { }sub foo : Local { }# http://localhost:3000/my/controller/foo# http://localhost:3000/my/controller/foo

● PrivatePrivatesub foo : Private { }sub foo : Private { }

● Default actionsDefault actions■ default, index, begin, enddefault, index, begin, end

Page 11: Web applications with Catalyst

6/12/056/12/05 1111 / 21 / 21

ContextContext

● ContextContext■ object passed to each action in order to interact w/ Catalyst object passed to each action in order to interact w/ Catalyst

(get request parameters, set response body)(get request parameters, set response body)sub hello : Global {sub hello : Global { my ( $self, $c ) = @_; my ( $self, $c ) = @_; $c->res->body('Hello World!'); $c->res->body('Hello World!');}}

■ Important objects:Important objects:▬ Request ($c->req) – web paranaters, cookies, headers, Request ($c->req) – web paranaters, cookies, headers,

uploaded filesuploaded files▬ Response ($c->res) – set document body, HTTP status codeResponse ($c->res) – set document body, HTTP status code▬ Configuration ($c->config) – static project configurationConfiguration ($c->config) – static project configuration▬ Log ($c->log) – print log messagesLog ($c->log) – print log messages▬ Stash ($c->stash) – pass data from model to viewStash ($c->stash) – pass data from model to view

Page 12: Web applications with Catalyst

6/12/056/12/05 1212 / 21 / 21

Views - Template ToolkitViews - Template Toolkit

● Fast, powerful and extensible template processing Fast, powerful and extensible template processing system:system:■ rich presentation languageocumentation including tutorial rich presentation languageocumentation including tutorial

and reference manualsand reference manuals

■ output filtering (for e.g. html escaping), exception handlingoutput filtering (for e.g. html escaping), exception handling

■ use directly hashes, arrays, objects in the templateuse directly hashes, arrays, objects in the template

■ templates are compiled to Perl code for maximum runtime templates are compiled to Perl code for maximum runtime efficiency and performance.efficiency and performance.

■ compiled templates are cached and can be written to disk compiled templates are cached and can be written to disk in "compiled form" to achieve cache persistance.in "compiled form" to achieve cache persistance.

■ documentation including tutorial and reference manualsdocumentation including tutorial and reference manuals

■ open source and free! :)open source and free! :)

Page 13: Web applications with Catalyst

6/12/056/12/05 1313 / 21 / 21

TT - ExampleTT - Example

t.plt.plmy %vars = ( webpages => [my %vars = ( webpages => [ { url => 'http://foo.org', title => 'The Foo Organisation' }{ url => 'http://foo.org', title => 'The Foo Organisation' } { url => 'http://bar.org', title => 'The Bar Organisation' }{ url => 'http://bar.org', title => 'The Bar Organisation' } ]);]);$template->process(\%vars);$template->process(\%vars);

template.tttemplate.tt::

[% INCLUDE header[% INCLUDE header title = 'This is an HTML example'title = 'This is an HTML example'%]%]

<h1>Some Interesting Links</h1><h1>Some Interesting Links</h1>

Links:Links:<ul><ul>[% FOREACH link = webpages %][% FOREACH link = webpages %] <li><a href="<li><a href="[% link.url %][% link.url %]">">[% link.title %][% link.title %]</a></a>[% END %][% END %]</ul></ul>

header.tt:header.tt:

<html><head><title><html><head><title>[% title %][% title %]</title></head></title></head><body bgcolor="#ffffff"><body bgcolor="#ffffff">

Page 14: Web applications with Catalyst

6/12/056/12/05 1414 / 21 / 21

Model - Rose::DB::ObjectModel - Rose::DB::Object

● Base class for objects that encapsulate a single Base class for objects that encapsulate a single row in a database tablerow in a database table■ supports creating, loading, saving, deleting an objectsupports creating, loading, saving, deleting an object

■ fetching reffered by foreign-key objectsfetching reffered by foreign-key objects● Rose::DB::Object::Manager Rose::DB::Object::Manager

■ Fetch multiple objects from the database using arbitrary Fetch multiple objects from the database using arbitrary query conditions, limits, and offsets.query conditions, limits, and offsets.

■ Iterate over a list of objectIterate over a list of object

■ Update/Delete objects that match a complex query.Update/Delete objects that match a complex query.

■ Fetch objects along with "foreign objects" (related through Fetch objects along with "foreign objects" (related through any of the supported relationship types) in a single query by any of the supported relationship types) in a single query by automatically generating the appropriate SQL join(s).automatically generating the appropriate SQL join(s).

Page 15: Web applications with Catalyst

6/12/056/12/05 1515 / 21 / 21

Rose – example (1)Rose – example (1)

● Defining objectDefining objectCREATE TABLE `products` (CREATE TABLE `products` ( `id` bigint(20) unsigned NOT NULL auto_increment,`id` bigint(20) unsigned NOT NULL auto_increment, `name` varchar(255) NOT NULL default '',`name` varchar(255) NOT NULL default '', `price` decimal(10,2) NOT NULL default '0.00',`price` decimal(10,2) NOT NULL default '0.00', PRIMARY KEY (`id`),PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`),UNIQUE KEY `id` (`id`), UNIQUE KEY `name` (`name`)UNIQUE KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;) ENGINE=MyISAM DEFAULT CHARSET=latin1;

package Product;package Product;use Rose::DB::Object;use Rose::DB::Object;our @ISA = qw(Rose::DB::Object);our @ISA = qw(Rose::DB::Object);__PACKAGE__->meta->table('products');__PACKAGE__->meta->table('products');__PACKAGE__->meta->columns(qw(id name price));__PACKAGE__->meta->columns(qw(id name price));__PACKAGE__->meta->primary_key_columns('id');__PACKAGE__->meta->primary_key_columns('id');__PACKAGE__->meta->add_unique_key('name');__PACKAGE__->meta->add_unique_key('name');__PACKAGE__->meta->initialize;__PACKAGE__->meta->initialize;

Page 16: Web applications with Catalyst

6/12/056/12/05 1616 / 21 / 21

Rose – example (2)Rose – example (2)

● Operations using this objectOperations using this object# add new product# add new product$p1 = Product->new(name => 'Bike');$p1 = Product->new(name => 'Bike');$p1->save;$p1->save;

# get product by its primary key# get product by its primary key$p2 = Product->new(id => '1');$p2 = Product->new(id => '1');$p2->load();$p2->load();

# access/modify fields# access/modify fieldsprint $p2->name; # prints 'Bike'print $p2->name; # prints 'Bike'$p2->name('ski'); # changes the name to 'ski'$p2->name('ski'); # changes the name to 'ski'$p2->save(); # updates database;$p2->save(); # updates database;

# deletes the object by unique key# deletes the object by unique key$p3 = Product->new(name => 'ski');$p3 = Product->new(name => 'ski');$p3->delete(); # the row is gone$p3->delete(); # the row is gone

Page 17: Web applications with Catalyst

6/12/056/12/05 1717 / 21 / 21

Rose – example (3)Rose – example (3)

● Work over set of objects using manager:Work over set of objects using manager:package Product::Manager;package Product::Manager;use Rose::DB::Object::Manager;use Rose::DB::Object::Manager;our @ISA = qw(Rose::DB::Object::Manager);our @ISA = qw(Rose::DB::Object::Manager);sub object_class { 'Product' }sub object_class { 'Product' }__PACKAGE__->make_manager_methods('products');__PACKAGE__->make_manager_methods('products');

● Using the managerUsing the manager$products = Product::Manager->get_products();$products = Product::Manager->get_products();foreach my $product (@$products) { print $product->name, "\n"; }foreach my $product (@$products) { print $product->name, "\n"; }

$iterator = Product::Manager->get_products_iterator();$iterator = Product::Manager->get_products_iterator();while($product = $iterator->next) {while($product = $iterator->next) { print $product->id, ' ', $product->name, "\n";print $product->id, ' ', $product->name, "\n"; $iterator->finish if(...); # exit early?$iterator->finish if(...); # exit early?}}print $iterator->total; # total iterated overprint $iterator->total; # total iterated over

Page 18: Web applications with Catalyst

6/12/056/12/05 1818 / 21 / 21

Rose – example (4)Rose – example (4)

● Complex queryComplex query $products = Product::Manager->get_products(query =>$products = Product::Manager->get_products(query => [[ name => { like => '%Hat' },name => { like => '%Hat' }, id => { ge => 7 },id => { ge => 7 }, or => or => [[ price => 5.00,price => 5.00, price => { lt => 10.00 },price => { lt => 10.00 }, ],], ],], sort_by => 'name',sort_by => 'name', limit => 10,limit => 10, offset => 50);offset => 50);

SELECT id, name, price FROM products WHERESELECT id, name, price FROM products WHERE name LIKE '%Hat' AND id >= 7 ANDname LIKE '%Hat' AND id >= 7 AND (price = 5.00 OR price < 10.00)(price = 5.00 OR price < 10.00) ORDER BY name LIMIT 10 OFFSET 50ORDER BY name LIMIT 10 OFFSET 50

Page 19: Web applications with Catalyst

6/12/056/12/05 1919 / 21 / 21

DemonstrationDemonstration

● Starting development serverStarting development server● Demonstrate basic actionsDemonstrate basic actions

■ protection from refreshprotection from refresh

■ error handlingerror handling

■ HTML escapingHTML escaping

■ Performance of the TTPerformance of the TT● ReviewReview

■ modelmodel

■ viewview

■ controllercontroller

Page 20: Web applications with Catalyst

6/12/056/12/05 2020 / 21 / 21

ConclusionsConclusions

● Catalyst is rich web development platformCatalyst is rich web development platform■ it is AJAX-ready it is AJAX-ready (a little marketing blurp :)(a little marketing blurp :)

● Using open source tools we can boost productivity Using open source tools we can boost productivity ■ let HTML developers work spearately on Template and let HTML developers work spearately on Template and

easily test the resulteasily test the result

■ let backend developers work on model classes, write let backend developers work on model classes, write autotestsautotests

● Create better workflowCreate better workflow■ the front- and back-end integration must be defined prior the front- and back-end integration must be defined prior

start of developmentstart of development● Avoid most common errorsAvoid most common errors● Building web applications Building web applications can be fun!can be fun! :) :)

Page 21: Web applications with Catalyst

6/12/056/12/05 2121 / 21 / 21

Thank you!Thank you!

● Questions?Questions?