PerlDancer for Perlers (FOSDEM 2011)
Modern Perl for web applications
More Reasons for "No act on ACT"
Perl Dancer Conference Website
http://act.perl.dance/eic2014/
Managed software
Listed in other conferences (Marketing)
User database
PSGI / Plack
Web application framework (Dancer2)
Web framework (Bootstrap, Jquery)
DBIx::Class
Moo and friends
Testing
Apache / mod_perl
slow
memory footprint
deployment related code
PSGI
runs on any webserver supporting PSGI
fast (Nginx)
simple configuration (Nginx)
no deployment related code
Apache/1.3.42 (Unix) mod_perl/1.31
more than 6 years old
Clean OO interface
Routes
Hooks
Engines
Multiple Applications
Web application
REST API
Admin interface
Manual SQL
error prone
compatibility problems
less secure
DBIx::Class
Business logic
works on dozens of RDBMS
usually faster
more secure
Single Point of Failure
Development
Responsiveness
No https://
Baltimore Perl Workshop
Eventbrite
Last commit on ACT: July 2015 https://github.com/book/Act
Last commit on ACT in the box: September 2015
Picture by Guillaume Brocker, CC BY-SA 3.0
https://github.com/interchange/Perl-Dancer-Conference
Maps with Leaflet
Cropping Photos
Administration
SEO / Modern Design
Dancer2::Debugger
Venue on Frontpage
Leaflet library
Leaflet code
User map
var map = L.map('map').setView([48.20078,16.36826], 13); L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>', maxZoom: 18, id: 'petermottram.mp1dpak2', accessToken: 'pk.eyJ1IjoicGV0ZXJtb3R0cmFtIiwiYSI6IjE1NWI5NjRjN2IxNjNkYTM1MzI3YzY5M2E0YjZjMDc0In0.T0bpnZGXCQBSW_SOv_nWHA' }).addTo(map); var marker2 = L.marker([48.18246, 16.38075]).addTo(map); marker2.bindPopup("<b>Hotel Schani Wien</b><br>Karl-Popper-Straße 22<br>Conference Venue<br>21/22 Oct"); $("#marker2").click(function(){ marker2.openPopup(); return false; });
You can drag and drop or uplad your photo and crop it in our website.
Jcrop - jQuery Image Cropping Plugin
Secure site with HTTPS
Speaking links
More secure and gives users more confidence
Small ranking boost with Google
Free certificates with Let's Encrypt
Users
Talks
Tickets
Events
News
Dancer2::Debugger Presentation
Set Based DBIx::Class http://www.perladvent.org/2012/2012-12-21.html
Truth of ResultSet
Chaining
Relationship traversal
Predefined searches
Hashref Inflation
This doesn't execute SQL:
my $talks = $schema->resultset('Talk')->search(...);
This does:
my $first_talk = $schema->resultset('Talk') ->search(...)->first;
my $talks = $schema->resultset('Talk') ->search({-bool => 'accepted'}) ->search({conferences_id => 1}) ->search({room => { '!=' => '' }), ->search({start_time => { '>=' => '2015-10-22 00:00:00' '<=' => '2015-10-23 00:00:00' }}), );
# countries dropdown $tokens->{countries} = [ $users->search_related( 'addresses', { type => 'primary', }, )->search_related( 'country', undef, { columns => [ 'country_iso_code', 'name' ], distinct => 1, order_by => 'country.name', } )->hri->all ];
# countries dropdown $tokens->{countries} = [ rset('Country')->search( undef, { columns => [ 'country_iso_code', 'name' ], order_by => 'name' } ) ->hri->all ]; unshift @{ $tokens->{countries} }, { country_iso_code => undef, name => "Select Country" };
User class:
sub last_conference_attended { my $self = shift; my $conference = $self->conferences->search({}, { order_by => { -desc => 'start_date' }, })->first; }
Web application:
my $conference = $user->last_conference_attended;
Code structure
Hooks
Plugins
Plack::Middleware
Main module
Multiple modules for routes
use Dancer2; use PerlDance::Routes::Account; use PerlDance::Routes::Admin; use PerlDance::Routes::Data; use PerlDance::Routes::PayPal; use PerlDance::Routes::Profile; use PerlDance::Routes::Survey; use PerlDance::Routes::Talk; use PerlDance::Routes::User; use PerlDance::Routes::Wiki;
use Dancer2 appname => 'PerlDance'; use Dancer2::Plugin::Auth::Extensible; use Dancer2::Plugin::DataTransposeValidator; use Dancer2::Plugin::DBIC; use Dancer2::Plugin::Email; use Dancer2::Plugin::Deferred; use Dancer2::Plugin::Interchange6; use Dancer2::Plugin::TemplateFlute; prefix '/profile';
get '/talk/create' => sub { my $tokens = { title => "New Talk", }; $tokens->{form} = form('create-update-talk'); $tokens->{form}->reset; $tokens->{form}->fill( duration => 40 ); add_durations_token($tokens); template 'profile/create_update_talk', $tokens; };
hook 'before_template_render' => sub { my $tokens = shift; if ( my $user = logged_in_user ) { $tokens->{logged_in_user} = schema->current_user; } $tokens->{conference_name} = setting('conference_name'); };
User Authentication
Form validation
DBIx::Class Wrapper
Flash messages after redirect
Sending emails
Cart and other business functions
Form handling
# bin/app.psgi use Plack::Builder; use PerlDance; my $app = PerlDance->to_app; builder { enable 'Session'; enable 'XSRFBlock', cookie_name => 'PerlDance-XSRF-Token', meta_tag => 'xsrf-meta', cookie_options => { httponly => 1, }; enable 'XForwardedFor', trust => [qw( 127.0.0.1 10.0.0.0/8 172.16.0.0/20 192.168.0.0/16 )]; $app; }
Modern Perl
Missing features
Perl Dancer Conference 2016
Call for developers
Ask questions
https://github.com/interchange/Perl-Dancer-Conference
Questions?