Modern Perl web development has evolved over the past 20 years. While Perl was once widely used for web development via CGI scripts, newer technologies emerged that were easier to maintain. The document discusses how Perl is still suitable for web development using modern tools like PSGI, Plack, Dancer2, and others. It demonstrates building a basic TODO application in Perl using these tools, including generating database classes from an existing database, retrieving and displaying data, and adding features with JavaScript and jQuery.
2. Some History
●
20 years ago most web development was done
with Perl & CGI
●
10-15 years ago that changed
●
Competition in the web development space
●
Other (better?) technologies
3. What Changed?
●
Hard to maintain
●
CGI used less
●
No "new version" for twenty years
●
Technologies with less historical baggage
4. What Else Changed?
●
Perl changed a lot
●
Major release every year
●
Powerful extension libraries
●
CPAN - Perl's killer app
5. The Plan
●
Show that Perl is still good for web development
●
Demonstrate some Modern Perl tools
●
Show Perl working with modern web
technology
– Bootstrap
– jQuery
– Mustache
15. Plack
●
Plack is a toolbox for working with PSGI
●
A lot like Ruby's Rack
● Development web server (plackup)
●
Middleware
●
Apps
●
Adapters for various deployment environments
16. Writing a PSGI Application
●
You can write your application in "raw" Plack
– Plack::Request
– Plack::Response
●
But unless it's very simple you should use a
framework
●
Makes your life easier
24. Bootstrap
●
The default Dancer2 index page looks nice
●
But we can do better
●
Bootstrap is a CSS framework
– From Twitter
●
Easy improvements to web pages
●
http://getbootstrap.com
25. Pages and Layouts
● Dancer2 stores page templates in views
– views/index.tt
● And layouts in views/layouts
– views/layouts/main.tt
●
These are Template Toolkit files
26. Changing Template Engine
●
Dancer2's default templating engine is
Template::Simple
●
But we use the Template Toolkit instead
● Change templating engine in config.yml
29. Template Toolkit
●
Perl's de-facto standard templating engine
●
Text templates
● Processing tags marked with <% ... %>
●
Simple programming language
– Variables
– Loops
30. Layouts vs Pages
●
A page is a single page
●
A layout is a wrapper around all of your pages
●
Consistant look and feel
● <% content %> tag where page content is
inserted
31. Bootstrap Changes
● Edit views/layouts/main.tt
●
Steal HTML from Bootstrap examples page
● Insert the <% content %> tag
● Replace views/index.tt
– <p>Page content</p>
34. Plack Middleware
●
Plack Middleware wraps around your PSGI app
●
Can alter the request on the way in
●
Can alter the response on the way out
●
PSGI's simple specification makes this easy
37. Static Files
●
Your app will have static files
– Images
– CSS
– Javascript
●
Serve these from the filesystem
●
No need to go through the app
●
Use Plack::Middleware::Static
38. Your Dancer2 App
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Todo;
Todo->to_app;
39. Adding Middleware
●
Plack::Builder is used to load and configure middleware
● Use the builder and enable keywords
use Plack::Builder;
my $app = ...;
builder {
enable 'Some::Middleware';
$app;
};
51. Dynamic Data
●
That's nice, but we don't have a static Todo list
– Hopefully
●
Need to get the data from a database
52. Define Database Table
CREATE TABLE item (
id integer not null
auto_increment primary key,
title varchar(200) not null,
description text,
due datetime,
done boolean not null default false
) Engine=InnoDB;
53. Database Interfaces with Perl
●
The standard Perl database interface is called
DBI
●
But we can do better than that
●
We will use DBIx::Class
– Based on DBI
●
ORM
54. Object Relational Mapping
●
Maps between OO concepts and DB concepts
●
table : class
●
row : object
●
column : attribute
●
Write less SQL!
55. Database Metadata
●
DBIx::Class needs a set of Perl classes
●
You can write these yourself
●
Or you can automatically generate them
● dbicdump extracts metadata from your
database
●
Generates the classes
61. Todo.pm
use Dancer2::Plugin::DBIC;
get '/' => sub {
# Removed hard-coded data
# Get data from database instead
my @items =
schema->resultset('Item')->all;
template 'index', { items => @items };
};
62. index.tt
●
No changes
●
Which is a bonus
●
Previously we passed hashrefs
●
Now we pass objects
●
TT uses the same syntax for both
66. Flexibility
●
Generating the HTML using TT code in the template
isn't very flexible
●
Write a JSON data structure instead
– JSON
●
Generate the HTML from the JSON
– Mustache
●
Process Mustache template on page load
– jQuery
95. Todo.pm - POST
post '/add' => sub {
my $item;
my @errors;
my %cols = (
title => 'Title',
description => 'Description',
due => 'Due Date',
);
foreach (qw[title description due]) {
unless ($item->{$_} = body_parameters->get($_)) {
push @errors, $cols{$_};
}
}
if (@errors) {
return template 'add', {
errors => @errors, item => $item
};
}
resultset('Item')->create($item);
redirect('/');
};
96. add.tt (Error Display)
<% IF errors.size -%>
<div class="alert alert-danger" role="alert">
The following inputs were missing:
<ul>
<% FOREACH error IN errors -%>
<li><% error %></li>
<% END -%>
</ul>
</div>
<% END -%>
102. Logging In
●
Only valid users should be able to edit the list
●
Other visitors can view the list
●
Use sessions to store login details
103. Add Login Form and Logout Link to
main.tt
<li>
<% IF session.user %>
<a href="/logout">Log out</a>
<% ELSE %>
<form class="navbar-form navbar-right"
method="post" action="/login">
<div class="form-group form-group-sm">
<input type="text" class="form-control"
name="user" placeholder="User">
</div>
<div class="form-group form-group-sm">
<input type="password" class="form-control"
name="password" placeholder="Password">
</div>
<button type="submit"
class="btn btn-default btn-xs">Log in</button>
</form>
<% END %>
</li>
104. Todo.pm - Logging In
post '/login' => sub {
my $user = body_parameters->get('user');
my $pass = body_parameters->get('password');
# TODO: Make this better!
if ($pass eq 'letmein') {
session user => $user;
}
redirect '/';
};
105. Todo.pm - Logging Out
get '/logout' => sub {
session user => undef;
redirect '/';
};
114. Deletion Code
get '/delete/:id' => sub {
my $id = route_parameters->get('id');
my $item = find_item_by_id($id)
or return "Item $id not found";
template 'delete', { item => $item };
};
post '/delete/:id' => sub {
my $id = route_parameters->get('id');
my $item = find_item_by_id($id)
or return "Item $id not found";
$item->delete;
redirect '/';
};
134. Things to Read
●
Dancer documentation
●
Dancer advent calendar
●
PSGI/Plack documentation
●
CPAN
135. Things to Consider
●
Perl has great tools for web development
●
Moose is a state of the art object system
●
DBIC is a state of the art ORM
●
Dancer, Catalyst and Mojolicious are state of the
art web frameworks
●
No language has better tools