Schenker - DSL for quickly creating web applications in Perl - Presentation Transcript
Jiro Nishiguchi( 西口次郎 ) id:spiritloose [email_address] 2009/09/09 Yokohama.pm 出張版 in YAPC::Asia 2009 前夜祭 Schenker a DSL for quickly creating web applications in Perl.
$self
PAUSE ID: JIRO
http://search.cpan.org/~jiro/
Image::ObjectDetect
Text::Migemo
etc...
http://d.hatena.ne.jp/spiritloose/
What's Schenker?
A DSL for quickly creating web applications in Perl
Inspired by Ruby's Sinatra
What's Sinatra? # myapp.rb require 'sinatra' get '/' do 'hello, world!' end
Schenker package MyApp; use Schenker; get '/' => sub { 'hello, world!'; }; どう見てもパク(ry
Similar frameworks
Mojolicious::Lite
http://search.cpan.org/dist/Mojo/
Dancer
http://search.cpan.org/dist/Dancer/
Requirements
Schenker
-> HTTP::Engine + HTTP::Engine::Middleware
(feature Plack + Plack::Middleware)
Sinatra
-> Rack + Rack::Middleware
What's HTTP::Engine? Web Server(Apache, Lighttpd and etc) ↓ HTTP::Engine .= Rack(Ruby) .= WSGI(Python) ↓ Web Application Framework(Catalyst, Rails, Django and etc)
SYNOPSIS $ cat > myapp.pl package MyApp; use Schenker; get '/' => sub { 'Hello, world!'; }; $ ./myapp.pl & && firefox http://localhost:4567/
Easy!
No helpers
No configuration
Schenker supports
Configurations
Routing
Controller
Views
No models (use your favorite modules)
Command line options ./myapp.pl --help Usage: ./hoge.pl [OPTIONS] -h, --help display this help -H, --host set the host -p, --port=PORT set the port -e, --environment=ENV set the environment -s, --server=SERVER HTTP::Engine interface === snip ===
Configuration configure development => sub { set port => 8080; set host => '127.0.0.1'; set server => 'AnyEvent'; enable 'sessions'; disable 'run'; };
Routing get '/' => sub {}; post '/' => sub {}; put '/' => sub {}; Delete '/' => sub {}; get '/' => host => 'example.com' => sub {}; get '/' => agent => qr/MobileSafari/ => sub {};
Method override <form action=”/” method=”post”> <input type=”hidden” name=”_method” value=”put” /> post '/' => sub {}; put '/' => sub {};
Paramaters get '/' => sub { params->{foo}; param('foo'); };
Path paramaters get '/user/:user' => sub { my $args = shift; "hello, $args->{user}!"; };
Encoding set encode => { encode => 'utf-8', decode => 'utf-8' }; get '/user/:name' => sub { my $args = shift; ok utf8::is_utf8($args->{name}); ok utf8::is_utf8(params->{foo}); };
View
Template-Toolkit
Text::MicroTemplate
Template-Toolkit tt_options WRAPPER => 'layout.tt'; get '/tt' => sub { tt 'index'; # views/index.tt };
In-file Template get '/' => sub { stash name => 'Michael Schenker'; tt 'index'; }; __END__ @@ index hello, [% name %]!
TT with PadWalker get '/hello/:name' => sub { my $args = shift; tt 'index'; }; __END__ @@ index hello, [% args.name %]!
Text::MicroTemplate get '/mt' => sub { mt 'index' # views/index.mt };
Helpers helper foo => sub { "foo$_[0]"; }; get '/' => sub { foo('bar') }; [% foo('bar') %] <?= foo('bar') ?>
Before filters Before sub { stash now => DateTime->now; }; get '/' =>sub { stash->{now}; }; [% now %]
Functions get '/' => sub { request; # HTTP::Engine::Request response; # HTTP::Engine::Response status 200; body 'hello, world!'; headers 'X-Hoge' => 'hoge'; back; # Referer };
Example: Image File get '/qrcode' => sub { my $text = params->{text}; content_type 'image/png'; GD::Barcode::QRcode->new($text)->plot->png; };
Example: Send file get '/' => sub { send_file 'image.jpg'; }; get '/' => sub { send_file 'image.jpg', filename => 'image.jpg'; };
Halting get '/' => sub { halt; do_something(); # NOTREACHED }; get '/' => sub { redirect 'http://www.yahoo.co.jp/'; do_something(); # NOTREACHED };
Error Handling define_error MyError => sub { status 500; tt 'myerror'; }; get '/' => sub { raise MyError; do_something(); # NOTREACHED };
Sessions enable 'sessions'; get '/' => sub { session; # HTTP::Session session->get('foo'); session->set(foo => 'bar'); };
0 comments
Post a comment