Dancer Pittsburgh Perl Workshop 2011

2,010 views

Published on

Dancer is a easy to learn modern Perl minimalist web framework inspired by Sinatra. It uses a series of route handlers to process input from users and generate responses. This presentation discusses the basics of Dancer using a straightforward tutorial application.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,010
On SlideShare
0
From Embeds
0
Number of Embeds
17
Actions
Shares
0
Downloads
11
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Dancer Pittsburgh Perl Workshop 2011

  1. 1. Introduction to Dancer<br />A Sinatra-inspired web framework for Perl<br />Mark Allen<br />mrallen1@yahoo.com<br />http://byte-me.org<br />https://github.com/mrallen1<br />https://bitbucket.org/mrallen1<br />https://metacpan.org/author/MALLEN<br />
  2. 2. The Old Days<br />
  3. 3. The Old Days<br />cgi-lib.pl (1994-1998)<br />
  4. 4. The Old Days<br />CGI.pm (1995-2011)<br />
  5. 5. The Old Days<br />mod_perl (1996-2011)<br />
  6. 6. The Old Days<br />Matt’s Script Archive (1995-2011)<br />Use instead:<br />http://nms-cgi.sourceforge.net/<br />(Thanks London.pm)<br />
  7. 7. The Old Days<br />use CGI.pm;<br />my $q = CGI->new();<br />my ($a, $b, $c) = $q->param();<br />if ($a !~ /d+/) {<br />print $q->header(-status => ‘400 Bad request’);<br />print “<h1>Value of ‘a’ ($a) is not an integer</h1>”;<br />exit 0;<br />}<br /># yada, yada<br />
  8. 8. The Old Days<br />.htaccess Hack<br />RewriteEngine On<br />RewriteBase /abc<br />RewriteRule ^(.*)/(.*)/(.*)$ abc.pl?a=$1;b=$2;c=$3<br />
  9. 9. The Old Days<br />.htaccess Hack<br /># Use Web 2.0 style URLs, but keep CGI interface<br />RewriteEngine On<br />RewriteBase /abc<br />RewriteRule ^(.*)/(.*)/(.*)$ abc.pl?a=$1;b=$2;c=$3<br />
  10. 10. The Old Days<br />.htaccess Hack<br /># Use Web 2.0 style URLs, but keep CGI interface<br />RewriteEngine On<br />RewriteBase /abc<br />RewriteRule ^(.*)/(.*)/(.*)$ abc.pl?a=$1;b=$2;c=$3<br />
  11. 11. The Old Days<br />.htaccess Hack<br /># Use Web 2.0 style URLs, but keep CGI interface<br />RewriteEngine On<br />RewriteBase /abc<br />RewriteRule ^(.*)/(.*)/(.*)$ abc.pl?a=$1;b=$2;c=$3<br />
  12. 12. The Old Days<br />http://flic.kr/p/5TWTR4<br />
  13. 13. The Old Days<br />http://flic.kr/p/5TWTR4<br />
  14. 14. Move over bacon, now there’s something leaner.<br />
  15. 15. Move over bacon<br />Perl 5 Renaissance:<br /><ul><li>Moose
  16. 16. DBIx::Class
  17. 17. Plack
  18. 18. Tons of great new stuff in core perl 5.10+</li></li></ul><li>Move over bacon<br />Do you find Catalyst too <br />heavyweight or intimidating?<br />
  19. 19. Move over bacon<br />Me too!<br />
  20. 20. Move over bacon<br />Enter Dancer<br />
  21. 21. Move over bacon<br />Other Sinatra-inspired frameworks:<br /><ul><li>Mojo (Perl – TMTOWTDI)
  22. 22. Flask (Python)
  23. 23. Fitzgerald (PHP)
  24. 24. Express (Node.js)</li></li></ul><li>Move over bacon<br />Dancer is:<br /><ul><li>Easy to learn
  25. 25. Expressive
  26. 26. Efficient</li></li></ul><li>Dancer is ...<br />Easy to learn<br />
  27. 27. Easy to learn<br />Basic Dancer concepts:<br /><ul><li>One (or more) HTTP verb(s)
  28. 28. A route
  29. 29. A handler</li></li></ul><li>Easy to learn<br />use Dancer;<br />get '/' => sub {<br /> return 'Hello World!n’;<br />};<br />start;<br />
  30. 30. Easy to learn<br />use Dancer;<br />get'/' => sub {<br /> return 'Hello World!n’;<br />};<br />start;<br />
  31. 31. Easy to learn<br />use Dancer;<br />get '/' => sub {<br /> return 'Hello World!n’;<br />};<br />start;<br />
  32. 32. Easy to learn<br />use Dancer;<br />get '/' => sub {<br /> return 'Hello World!n’;<br />};<br />start;<br />
  33. 33. Easy to learn<br />use Dancer;<br />get '/' => sub {<br /> return 'Hello World!n’;<br />};<br />start;<br />
  34. 34. Easy to learn<br />
  35. 35. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  36. 36. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  37. 37. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  38. 38. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  39. 39. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  40. 40. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  41. 41. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  42. 42. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  43. 43. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  44. 44. Easy to learn<br />show_entries.tt<br /><ul class=entries><br /> <% IF entries.size %><br /> <% FOREACH id IN entries.keys.nsort %><br /> <li><h2><% entries.$id.title %></h2><br /> <% entries.$id.text %><br /> <% END %><br /><% ELSE %><br /><li><em>Unbelievable. No entries here so far</em><br /><% END %><br /></ul><br />
  45. 45. Easy to learn<br />show_entries.tt<br /><ul class=entries><br /><% IF entries.size%><br /> <% FOREACH id IN entries.keys.nsort %><br /> <li><h2><% entries.$id.title %></h2><br /> <% entries.$id.text %><br /> <% END %><br /><% ELSE %><br /><li><em>Unbelievable. No entries here so far</em><br /><% END %><br /></ul><br />
  46. 46. Easy to learn<br />show_entries.tt<br /><ul class=entries><br /> <% IFentries.size %><br /> <% FOREACH id IN entries.keys.nsort %><br /> <li><h2><% entries.$id.title %></h2><br /> <% entries.$id.text %><br /> <% END %><br /><% ELSE %><br /><li><em>Unbelievable. No entries here so far</em><br /><% END %><br /></ul><br />
  47. 47. Easy to learn<br />show_entries.tt<br /><ul class=entries><br /> <% IF entries.size %><br /> <% FOREACH id IN entries.keys.nsort %><br /> <li><h2><% entries.$id.title%></h2><br /> <% entries.$id.text%><br /> <% END %><br /><% ELSE %><br /><li><em>Unbelievable. No entries here so far</em><br /><% END %><br /></ul><br />
  48. 48. Easy to learn<br />get '/' => sub {<br /> my $db = connect_db();<br /> my $sql = 'select id, title, text from entries order by id desc’;<br /> my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute or die $sth->errstr;<br />template 'show_entries.tt', {<br /> 'msg' => get_flash(),<br />'add_entry_url' => uri_for('/add'),<br />'entries' => $sth->fetchall_hashref('id'),<br /> };<br />};<br />
  49. 49. Easy to learn<br />show_entries.tt<br /><ul class=entries><br /> <% IF entries.size %><br /> <% FOREACH id IN entries.keys.nsort %><br /> <li><h2><% entries.$id.title %></h2><br /> <% entries.$id.text %><br /> <% END %><br /><% ELSE %><br /><li><em>Unbelievable. No entries here so far</em><br /><% END %><br /></ul><br />
  50. 50. Easy to learn<br />show_entries.tt<br /><ul class=entries> <!– CSS class --><br /> <% IF entries.size %><br /> <% FOREACH id IN entries.keys.nsort %><br /> <li><h2><% entries.$id.title %></h2><br /> <% entries.$id.text %><br /> <% END %><br /><% ELSE %><br /><li><em>Unbelievable. No entries here so far</em><br /><% END %><br /></ul><br />
  51. 51. Easy to learn<br />Directory structure<br />dancr/<br />├── dancr.pl<br />├── public<br />│   └── css<br />│   └── style.css<br />└── views<br /> ├── layouts<br /> │   └── main.tt<br /> ├── login.tt<br /> └── show_entries.tt<br />
  52. 52. Easy to learn<br />Directory structure<br />dancr/<br />├── dancr.pl<br />├── public<br />│   └── css<br />│   └── style.css<br />└── views<br /> ├── layouts<br /> │   └── main.tt<br /> ├── login.tt<br /> └── show_entries.tt<br />
  53. 53. Easy to learn<br />Directory structure<br />dancr/<br />├── dancr.pl<br />├── public<br />│   └── css<br />│   └── style.css<br />└── views<br /> ├── layouts<br /> │   └── main.tt<br /> ├── login.tt<br /> └── show_entries.tt<br />
  54. 54. Easy to learn<br />Directory structure<br />dancr/<br />├── dancr.pl<br />├── public<br />│   └── css<br />│   └── style.css<br />└── views<br /> ├── layouts<br /> │   └── main.tt<br /> ├── login.tt<br /> └── show_entries.tt<br />
  55. 55. Dancer is...<br />Expressive<br />
  56. 56. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br />my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect '/’;<br />};<br />
  57. 57. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br />my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect '/’;<br />};<br />
  58. 58. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br />my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect '/’;<br />};<br />
  59. 59. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br />my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect '/’;<br />};<br />
  60. 60. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br />my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect'/’;<br />};<br />
  61. 61. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br />my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect '/’;<br />};<br />
  62. 62. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br />my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect '/’;<br />};<br />
  63. 63. Expressive<br />Little Bobby Tables<br />http://xkcd.com/327/<br />
  64. 64. Expressive<br />post '/add' => sub {<br /> if ( not session('logged_in') ) {<br /> return send_error("Not logged in", 401);<br />}<br /> # http://bobby-tables.com<br /> my $db = connect_db();<br />my $sql = 'insert into entries (title, text) values (?, ?)’;<br />my $sth = $db->prepare($sql) or die $db->errstr;<br />$sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr;<br />set_flash('New entry posted!');<br />redirect '/’;<br />};<br />
  65. 65. Expressive<br />
  66. 66. Expressive<br />Configuration<br /><ul><li>Session Engine
  67. 67. Template Engine
  68. 68. Logging
  69. 69. Plugins</li></li></ul><li>Expressive<br />Configuration Examples<br />set 'session' => 'Simple';set 'template' =>'template_toolkit';set 'logger' => 'console';set 'log' => 'debug';set 'show_errors' => 1;<br />
  70. 70. Expressive<br />Configuration Examples<br />set 'session' => 'Simple';set 'template' =>'template_toolkit';set 'logger' => 'console';set 'log' => 'debug';set 'show_errors' => 1;<br />
  71. 71. Expressive<br />ConfigurationUse any non-reserved key/value pair.set 'username' => 'admin';set 'password' => 'password';<br />
  72. 72. Expressive<br />Routes with regex<br />get qr{A/(?<code>[A-Za-z0-9]+)Z} => sub {<br /> my $decode = decode_base36(uccaptures->{'code'}<br /> );<br />...;<br />};<br />
  73. 73. Expressive<br />Routes with regex<br />getqr{A/(?<code>[A-Za-z0-9]+)Z} => sub {<br /> my $decode = decode_base36(uccaptures->{'code'}<br /> );<br />...;<br />};<br />
  74. 74. Expressive<br />Routes with regex<br />use v5.10;getqr{A/(?<code>[A-Za-z0-9]+)Z} => sub {<br /> my $decode = decode_base36(uccaptures->{'code'}<br /> );<br />...;<br />};<br />
  75. 75. Expressive<br />Routes with regex<br />use v5.10;getqr{A/(?<code>[A-Za-z0-9]+)Z} => sub {<br /> my $decode = decode_base36(uccaptures->{'code'}<br /> );<br />...;<br />};<br />
  76. 76. Expressive<br />Routes with named params<br />get '/:code/stats' => sub {<br /> my $decode = decode_base36( uc params->{'code'} );<br />...;<br />};<br />
  77. 77. Expressive<br />Routes with named params<br />get'/:code/stats' => sub {<br /> my $decode = decode_base36( uc params->{'code'} );<br />...;<br />};<br />
  78. 78. Expressive<br />Routes with named params<br />getqr{^/(.+)/stats$} => sub {params(‘code’) = $1; # input sanity goes here ...;};<br />
  79. 79. Expressive<br />use CGI.pm;<br />my $q = CGI->new();<br />my ($a, $b, $c) = $q->param();<br />if ($a !~ /d+/) {<br />print $q->header(-status => ‘400 Bad request’);<br />print “<h1>Value of ‘a’ ($a) is not an integer</h1>”;<br />exit 0;<br />}<br /># yada, yada<br />
  80. 80. Expressive<br />use v5.10;use Dancer;<br />get qr{/(?<a>d+)/(?<b>.+)/(?<c>.+)} => sub {<br /> # Route will only match if a is an integer! # No more sanitation/validation necessary ...;};<br />
  81. 81. Dancer is...<br />Efficient<br />
  82. 82. Efficient<br />any ['get', 'post'] => '/login' => sub {<br /> my $err;<br />if ( request->is_post ) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session 'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  83. 83. Efficient<br />any ['get', 'post'] => '/login' => sub {<br />my $err;<br />if ( request->is_post ) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session 'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  84. 84. Efficient<br />any ['get', 'post'] => '/login' => sub {<br />my $err;<br />if ( request->is_post ) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session 'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  85. 85. Efficient<br />any ['get', 'post'] => '/login' => sub {<br /> my $err;<br />if ( request->is_post) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session 'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  86. 86. Efficient<br />any ['get', 'post'] => '/login' => sub {<br /> my $err;<br />if ( request->is_post ) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  87. 87. Efficient<br />any ['get', 'post'] => '/login' => sub {<br /> my $err;<br />if ( request->is_post ) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session 'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  88. 88. Efficient<br />any ['get', 'post'] => '/login' => sub {<br /> my $err;<br />if ( request->is_post ) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session 'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  89. 89. Efficient<br />any ['get', 'post'] => '/login' => sub {<br /> my $err;<br />if ( request->is_post ) {<br /> if ( params->{'username'} ne setting('username') ) {<br /> $err = "Invalid username”;<br />}<br />elsif( params->{'password'} ne setting('password') ) {<br />$err = "Invalid password”;<br />}<br />else {<br />session 'logged_in' => true;<br />set_flash('You are logged in.');<br />redirect '/’;<br />}<br /> }<br />template'login.tt', {<br /> 'err' => $err,<br />};<br />};<br />
  90. 90. Efficient<br />Hook Before / After<br /><ul><li>De/Serialization
  91. 91. Rendering
  92. 92. Template
  93. 93. Errors</li></li></ul><li>Efficient<br />Forward<br />get '/demo/foo/:bar' => sub {<br /> my $bar = param->{'bar'};<br /> # magically use demo DB<br /> ...;<br /> return forward "/foo/$bar";<br />};<br />
  94. 94. Efficient<br />Prefix<br />prefix '/user'; # begins scope<br />get '/view/:id' => sub { ...; };<br />post '/add' => sub { ...; };<br />any ['get', 'post'] => '/edit/:id' => sub { ...; };<br />prefix undef; # ends scope<br />get '/view/:id' => sub { ...; };<br />
  95. 95. Efficient<br />Dancer Plugins add keywords<br /><ul><li>Auto-create RSS feeds
  96. 96. Integrate Twitter for authN
  97. 97. DBIx::Class
  98. 98. DWIM CRUD apps
  99. 99. ...and more</li></li></ul><li>Efficient<br />Dancer::Plugin::Database<br />database keyword gets $dbh<br />my $sth = database->prepare("SELECT * FROM mytable WHERE id = ?");<br />$sth->execute(42);<br />template 'userdetail.tt', {<br /> row => $sth->fetchrow_hashref()<br />};<br />
  100. 100. Efficient<br />Sweet, sweet syntactic sugar:<br />database->quick_insert('mytable', %data);<br />template 'userdetail.tt', {<br /> row => database->quick_select('mytable', { id => 42 })<br />};<br />
  101. 101. Dancer is...<br />Awesome<br />
  102. 102. Awesome<br />Source code:<br />{ hg | git } clone https://bitbucket.org/mrallen1/dancr<br />See also:<br />https://metacpan.org/module/Dancer<br />https://metacpan.org/module/Dancer::Plugin::Database<br />Install:<br />curl -L http://cpanmin.us | perl - Dancer YAML Template<br />
  103. 103. Awesome<br />Thank You!<br />

×