create a web-app with cgi appplication

34
How to create a simple Web application with CGI::Application Template::Toolkit and DBIx::Class Leonard Miller February 7, 2009

Upload: olegmmiller

Post on 19-May-2015

6.402 views

Category:

Technology


1 download

DESCRIPTION

How to create a simple Web application with CGI::Application Template::Toolkit and DBIx::Class

TRANSCRIPT

Page 1: Create a web-app with Cgi Appplication

How to create a simple Web application with CGI::Application

Template::Toolkit and DBIx::Class

Leonard MillerFebruary 7, 2009

Page 2: Create a web-app with Cgi Appplication

Who is this talk for?

• Need to write web applications• Don’t want/cannot have a heavy

framework• Experienced Programmers.• Know about CPAN, how to learn from

CPAN’s documentation.• Newer programmers that could use a

new/better way to organize their code.

Page 3: Create a web-app with Cgi Appplication

Why these three Modules?

• Separate out the code to MVC Pieces

• Each can be used/tested alone

• The modules themselves are easy to use and understand

Page 4: Create a web-app with Cgi Appplication

Why not Catalyst?

• mod_perl/fastcgi: You don’t always have the access on the machine to get Catalyst to work.

• CGI::Application is a ‘lite’ framework, and as such is much smaller.

• Not as big and scary.• Trivial to install in a local ~/lib dir

Page 5: Create a web-app with Cgi Appplication

What is MVC

• MVC stands for Model-View-Controller

Page 6: Create a web-app with Cgi Appplication

What is MVC

MVC breaks the work into three parts• Model - Short for database model.

DBIx::Class does all the database work: inserts/queries.

• View - Template::Toolkit does all the view/html work.

• Controller - CGI::Application holds all the logic to glue the Model and the View together.

Page 7: Create a web-app with Cgi Appplication

What is MVC

• Who has seen code like this:use DBI;my $sql = "select * from users";my $dbh = DBI->connect( $ds, $un, $pw );my $sth = $dbh->prepare($sql);$sth->execute();print "Content-type: text/html\r\n\r\n";while (my $h = $sth->fetchrow_hashref()){ print ”Name is:".$h->{'first_name'}."<br>\n";}

Page 8: Create a web-app with Cgi Appplication

What is MVC

• Who has seen code like this:use DBI;my $sql = "select * from users";my $dbh = DBI->connect( $ds, $un, $pw );my $sth = $dbh->prepare($sql);$sth->execute();print "Content-type: text/html\r\n\r\n";while (my $h = $sth->fetchrow_hashref()){ print ”Name is:".$h->{'first_name'}."<br>\n";}

Page 9: Create a web-app with Cgi Appplication

What is MVC

• Who has seen code like this:my $q = new CGI;

if ($q-> param('first_name' eq ''){ print input_form();}else{ my $sql = "insert into users ..."; my $sth = $dbh->prepare($sql); $sth->execute(); print submission_form();}

Page 10: Create a web-app with Cgi Appplication

What is MVC

• Who has seen code like this:my $q = new CGI;

if ($q-> param('first_name' eq ''){ print input_form();}else{ my $sql = "insert into users ..."; my $sth = $dbh->prepare($sql); $sth->execute(); print submission_form();}

Page 11: Create a web-app with Cgi Appplication

What is MVC

• Any questions regarding what MVC is?

Page 12: Create a web-app with Cgi Appplication

CGI::ApplicationA sample program:• Helloworld.cgi <- config info• HelloWorldCgiApp.pm <- controller• Html files: <- View

– header.html– body.html– footer.html

• DB/Main.pm <- Model– DB/Main/Users.pm– DB/Main/Artists.pm– DB/Main/CDs.pm

Page 13: Create a web-app with Cgi Appplication

CGI::Applicationhelloworld.cgi:

use HelloWorldCgiApp;

my $helloworld = HelloWorldCgiApp->new();

$helloworld->run();

Page 14: Create a web-app with Cgi Appplication

CGI::Applicationhelloworld.cgi (with config info):

use HelloWorldCgiApp;my $helloworld = HelloWorldCgiApp->new ( PARAMS => { tt_config => { INCLUDE_PATH => ".", PRE_PROCESS => 'header.html', POST_PROCESS => 'footer.html', }, hw_string => "Hello world!", }, );$helloworld->run();

Page 15: Create a web-app with Cgi Appplication

CGI::Applicationhelloworld.cgi (with config info):

use lib “~/testdir”;use HelloWorldCgiApp;my $helloworld = HelloWorldCgiApp->new ( PARAMS => { tt_config => { INCLUDE_PATH => ".", PRE_PROCESS =>

‘test/header.html', POST_PROCESS =>

‘test/footer.html', }, hw_string => "Hello test world!", }, );$helloworld->run();

Page 16: Create a web-app with Cgi Appplication

CGI::ApplicationHelloWorldCgiApp (continued):

package HelloWorldCgiApp;

use base 'CGI::Application';

use Template;

sub setup {

my $self = shift;

$self->run_modes( 'mode1' => 'start’,

'mode2' => 'sec_page'

);

$self->start_mode('mode1');

}

Page 17: Create a web-app with Cgi Appplication

CGI::ApplicationHelloWorldCgiApp (continued):

package HelloWorldCgiApp;

use base 'CGI::Application';

use Template;

sub setup {

my $self = shift;

$self->run_modes( 'mode1' => 'start’,

'mode2' => 'sec_page'

);

$self->start_mode('mode1');

}

$q -> param (‘rm’);

Page 18: Create a web-app with Cgi Appplication

CGI::ApplicationHelloWorldCgiApp (continued):

sub start {

my $self = shift;

my $tt_config = $self->param(‘tt_config’)

my $tt = Template->new( $tt_config );

$tt->process('body.html',

{

hwstr => 'hi world!!!',

},

\$html);

return $html;

}

Page 19: Create a web-app with Cgi Appplication

CGI::ApplicationHelloWorldCgiApp (continued):

sub cgiapp_prerun

{

my ($self, $runmode) = @_;

my $q = $self->query;

#things you need to run every time

#input validation etc.

#logging

}

Page 20: Create a web-app with Cgi Appplication

DBIx::Class• The mysql table:

CREATE TABLE users ( user_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, first_name varchar(75) NOT NULL, last_name varchar(75) NOT NULL, country_code CHAR(2) NULL);

+---------+------------+-----------+--------------+| user_id | first_name | last_name | country_code |+---------+------------+-----------+--------------+| 1 | joe | user | US | | 2 | Steve | Jobs | US | | 3 | Bill | Gates | US | | 4 | Larry | Wall | US | +---------+------------+-----------+--------------+

Page 21: Create a web-app with Cgi Appplication

DBIx::Class

DB/Main.pm

package DB::Main;

use base qw/DBIx::Class::Schema/;

__PACKAGE__->load_classes();1;

Page 22: Create a web-app with Cgi Appplication

DBIx::Class

DB/Main/User.pm

package DB::Main::User;

use base qw/DBIx::Class/;

__PACKAGE__-> load_components(qw/PK::Auto Core/);

__PACKAGE__->table('users');

__PACKAGE__->add_columns(qw/ user_id first_name last_name country_code /);

__PACKAGE__-> set_primary_key('user_id');

Page 23: Create a web-app with Cgi Appplication

DBIx::Class• Using the DBIx::Class ModuleHelloWorldCgiApp.pm:

use DB::Main;

my $schema = DB::Main-> connect('dbi:mysql:db','user', 'password');

my @users = $schema->resultset('User')->all;my $users_rs = $schema->resultset('User');my $user = $users_rs ->next;$tt->process('body.html', { users => [ @users ], user => $user, }, \$html);

Page 24: Create a web-app with Cgi Appplication

DBIx::Class

• Using the Module – inserts:

my $new_user = $schema-> resultset('User')->new({

last_name => $last_name,

first_name => $first_name,

});

$new_user->insert;

Page 25: Create a web-app with Cgi Appplication

DBIx::Class

Things that you still need to do:• Verify your data -- this is good practice under

any circumstances• Open your database connection• Error handling -- did the DB connection open?

Did the sql succeed? Unlike some larger frameworks, CGI::Application will not do the error checking for you.

• It’s a lite framework, so you still need to do some work

Page 26: Create a web-app with Cgi Appplication

Template::Toolkit

• Why use Template::Toolkit?– Common ‘look and feel’ templates.

• Easy to change for those people who are better at design than we are.

– What type of data is It good for?• arrays• hashes• scalars

Page 27: Create a web-app with Cgi Appplication

Template::Toolkit

• Any html file is a TT file!

• Simplest usage for a scalar:<html>

<body>

[% var_name %]

</body>

</html>

Page 28: Create a web-app with Cgi Appplication

Template::Toolkit

• Usage for an Array where users is an array:

<body>

[% FOREACH item IN users %]

[% item %]<br />

[% END %]

</body>

Page 29: Create a web-app with Cgi Appplication

Template::Toolkit

• Usage where item is a hash:<body>

[% item.user_id %] [% item.first_name %]

[% item.last_name %] [% item.country %] <br />

</body>

Page 30: Create a web-app with Cgi Appplication

Template::Toolkit

• Usage for an Array where users is an array of hashes (like an array of rows from a database):

<body>

[% FOREACH item IN users %]

[% item.user_id %] [% item.first_name %]

[% item.last_name %] [% item.country %]<br />

[% END %]

</body>

Page 31: Create a web-app with Cgi Appplication

Template::Toolkit

• Usage for an Array where users is an array of hashes (like an array of rows from a database):

<body>

<form>

<input type=“hidden” name=“rm” value=“page_2”

[% FOREACH item IN users %]

...

[% END %]

<input type=“submit”>

</form>

</body>

Page 32: Create a web-app with Cgi Appplication

There’s more available

CGI::Application::Plugin::AbstractCallbackCGI::Application::Plugin::ActionDispatchCGI::Application::Plugin::ActionDispatch::AttributesCGI::Application::Plugin::AnyCGICGI::Application::Plugin::AnyTemplateCGI::Application::Plugin::AnyTemplate::BaseCGI::Application::Plugin::AnyTemplate::ComponentHandlerCGI::Application::Plugin::AnyTemplate::Driver::HTMLTemplateCGI::Application::Plugin::AnyTemplate::Driver::HTMLTemplateExprCGI::Application::Plugin::AnyTemplate::Driver::HTMLTemplatePluggableCGI::Application::Plugin::AnyTemplate::Driver::PetalCGI::Application::Plugin::AnyTemplate::Driver::TemplateToolkitCGI::Application::Plugin::ApacheCGI::Application::Plugin::Apache2::RequestCGI::Application::Plugin::Apache::RequestCGI::Application::Plugin::AuthenticationCGI::Application::Plugin::Authentication::DriverCGI::Application::Plugin::Authentication::Driver::Authen::SimpleCGI::Application::Plugin::Authentication::Driver::CDBICGI::Application::Plugin::Authentication::Driver::DBICGI::Application::Plugin::Authentication::Driver::DBICCGI::Application::Plugin::Authentication::Driver::DummyCGI::Application::Plugin::Authentication::Driver::Filter::cryptCGI::Application::Plugin::Authentication::Driver::Filter::lcCGI::Application::Plugin::Authentication::Driver::Filter::md5CGI::Application::Plugin::Authentication::Driver::Filter::sha1CGI::Application::Plugin::Authentication::Driver::Filter::stripCGI::Application::Plugin::Authentication::Driver::Filter::ucCGI::Application::Plugin::Authentication::Driver::GenericCGI::Application::Plugin::Authentication::Driver::HTPasswdCGI::Application::Plugin::Authentication::StoreCGI::Application::Plugin::Authentication::Store::CookieCGI::Application::Plugin::Authentication::Store::SessionCGI::Application::Plugin::AuthorizationCGI::Application::Plugin::Authorization::DriverCGI::Application::Plugin::Authorization::Driver::DBICGI::Application::Plugin::Authorization::Driver::DummyCGI::Application::Plugin::Authorization::Driver::GenericCGI::Application::Plugin::Authorization::Driver::HTGroupCGI::Application::Plugin::Authorization::Driver::SimpleGroupCGI::Application::Plugin::AutoRunmodeCGI::Application::Plugin::AutoRunmode::FileDelegateCGI::Application::Plugin::BREADCGI::Application::Plugin::BrowserDetectCGI::Application::Plugin::CAPTCHACGI::Application::Plugin::CHICGI::Application::Plugin::Cache::AdaptiveCGI::Application::Plugin::CaptureIOCGI::Application::Plugin::CompressGzipCGI::Application::Plugin::Config::AnyCGI::Application::Plugin::Config::ContextCGI::Application::Plugin::Config::GeneralCGI::Application::Plugin::Config::IniFilesCGI::Application::Plugin::Config::SimpleCGI::Application::Plugin::Config::YAMLCGI::Application::Plugin::ConfigAutoCGI::Application::Plugin::DBH

CGI::Application::Plugin::DBIProfileCGI::Application::Plugin::DBIProfile::DataCGI::Application::Plugin::DBIProfile::Graph::GDGraphInlineCGI::Application::Plugin::DBIProfile::Graph::HTMLCGI::Application::Plugin::DBIProfile::Graph::HTML::HorizontalCGI::Application::Plugin::DBIProfile::Graph::HTMLBarGraphCGI::Application::Plugin::DBIProfile::Graph::SVGTTCGI::Application::Plugin::DebugMessageCGI::Application::Plugin::DebugScreenCGI::Application::Plugin::DevPopupCGI::Application::Plugin::DevPopup::HTTPHeadersCGI::Application::Plugin::DevPopup::LogCGI::Application::Plugin::DevPopup::TimingCGI::Application::Plugin::EmailCGI::Application::Plugin::EparamCGI::Application::Plugin::ErrorPageCGI::Application::Plugin::FeedbackCGI::Application::Plugin::FillInFormCGI::Application::Plugin::FlashCGI::Application::Plugin::FormStateCGI::Application::Plugin::FormValidator::SimpleCGI::Application::Plugin::ForwardCGI::Application::Plugin::HTCompiledCGI::Application::Plugin::HTDotCGI::Application::Plugin::HTMLPrototypeCGI::Application::Plugin::HelpManCGI::Application::Plugin::HtmlTidyCGI::Application::Plugin::I18NCGI::Application::Plugin::JSONCGI::Application::Plugin::LinkIntegrityCGI::Application::Plugin::LogDispatchCGI::Application::Plugin::MasonCGI::Application::Plugin::MenuCGI::Application::Plugin::MessageStackCGI::Application::Plugin::MetadataDBCGI::Application::Plugin::Output::XSVCGI::Application::Plugin::PageBuilderCGI::Application::Plugin::ParsePathCGI::Application::Plugin::PhrasebookCGI::Application::Plugin::ProtectCSRFCGI::Application::Plugin::RateLimitCGI::Application::Plugin::RedirectCGI::Application::Plugin::RequireSSLCGI::Application::Plugin::RoutesCGI::Application::Plugin::RunmodeDeclareCGI::Application::Plugin::SessionCGI::Application::Plugin::StashCGI::Application::Plugin::StreamCGI::Application::Plugin::TTCGI::Application::Plugin::TT::LastModifiedCGI::Application::Plugin::TemplateRunnerCGI::Application::Plugin::ThumbnailCGI::Application::Plugin::TmplInnerOuterCGI::Application::Plugin::ValidateRMCGI::Application::Plugin::View::HTML::TemplateCGI::Application::Plugin::ViewCodeCGI::Application::Plugin::YAML

Page 33: Create a web-app with Cgi Appplication

Questions?

Page 34: Create a web-app with Cgi Appplication

Thank you

Leonard MillerFebruary 7th

Frozen Perl 2009