Here is the entire source for the "almost working" dancr.pl tutorial demo, implemented as an application under Windows/Apache:
[*.../htdocs/dancr/lib/dancr.pm <http://dancr.pm>*] Note - Changes from " dancer.pl" in yellow... ----------------------------------------------------------------------------- package dancr; use strict; use warnings; use Dancer2; use DBI; use File::Spec; use File::Slurp; use Template; our $VERSION = '0.1'; # set 'database' => File::Spec->catfile(File::Spec->tmpdir(), 'dancr.db'); # Set the database to live under the application directory... set 'database' => 'C:\Apache24\htdocs\dancr\dancr.db'; #set 'session' => 'Simple'; set 'session' => 'YAML'; set 'template' => 'template_toolkit'; set 'logger' => 'console'; set 'log' => 'debug'; set 'show_errors' => 1; set 'startup_info' => 1; set 'warnings' => 1; set 'username' => 'admin'; set 'password' => 'password'; set 'layout' => 'main'; my $flash; sub set_flash { my $message = shift; $flash = $message; } sub get_flash { my $message = $flash; $flash = ''; return $message; } sub connect_db { my $dbh = DBI->connect("dbi:SQLite:dbname=".setting('database')) or die $DBI::errstr; return $dbh; } sub init_db { my $db = connect_db(); my $schema = read_file('./schema.sql'); $db->do($schema) or die $db->errstr; } hook before_template => sub { my $tokens = shift; # $tokens->{'css_url'} = request->base . 'css/dancr.css'; $tokens->{'css_url'} = request->base . '/css/dancr.css'; $tokens->{'login_url'} = uri_for('/login'); $tokens->{'logout_url'} = uri_for('/logout'); $flash=''; }; get '/' => sub { my $db = connect_db(); my $sql = 'select id, title, text from entries order by id desc'; my $sth = $db->prepare($sql) or die $db->errstr; $sth->execute or die $sth->errstr; template 'show_entries.tt', { 'msg' => get_flash, 'add_entry_url' => uri_for('/add'), 'entries' => $sth->fetchall_hashref('id'), }; }; post '/add' => sub { if ( not session('logged_in') ) { send_error("Not logged in", 401); } my $db = connect_db(); my $sql = 'insert into entries (title, text) values (?, ?)'; my $sth = $db->prepare($sql) or die $db->errstr; $sth->execute(params->{'title'}, params->{'text'}) or die $sth->errstr; set_flash('New entry posted!'); redirect '/'; }; any ['get', 'post'] => '/login' => sub { my $err; my $session = session; if ( request->method() eq "POST" ) { # process form input if ( params->{'username'} ne setting('username') ) { $err = "Invalid username"; } elsif ( params->{'password'} ne setting('password') ) { $err = "Invalid password"; } else { session 'logged_in' => true; set_flash('You are logged in.'); return redirect '/'; } } # display login form template 'login.tt', { 'err' => $err, }; }; get '/logout' => sub { app->destroy_session; set_flash('You are logged out.'); redirect '/'; }; init_db(); start; true; ----------------------------------------------------------------------------- [*http.conf*] <Directory "C:/Apache24/htdocs/dancr"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all AddHandler cgi-script .cgi </Directory> ScriptAlias /dancr "C:/Apache24/htdocs/dancr/public/dispatch.cgi" It all seems to boil down to the "*my $flash;*" global variable that never gets set correctly in "sub set_flash" (or read in get_flash)... I think it must be something about variable scope since the global and the subs are not part of a route in the context of the app... --------------------------------- my $flash; sub set_flash { my $message = shift; $flash = $message; } --------------------------------- Thank you for any input about this... I'm sure it's something obvious that I'm missing... but I'm hoping I can be enlightened... Prairie Nyx On Sat, May 30, 2015 at 10:47 PM, Prairie Nyx <[email protected]> wrote: > Perl Dancer Community: > > I am converting from Dancer to Dancer2 (better late than never) and also > developing some preliminary curriculum materials for CoderDojo using Perl > Dancer2 as a framework for web development. > > I started with SawyerX's tutorial page: > > http://search.cpan.org/~xsawyerx/Dancer2/lib/Dancer2/Tutorial.pod > > The "dancr.pl" tutorial program ran just fine under the port 3000 server > and the tutorial was useful and instructive: > > C:\Users\CoderDojo\Perl\Dancer\dancr>perl dancr.pl > >> Dancer2 v0.160001 server 2496 listening on http://0.0.0.0:3000 > > I ran into an issue when I tried to convert this demo into an app that > would run under Apache in a Windows environment, however. > > The *crux* of the issue is that the "$flash message" does not work in the > app (I suspect because the global variable $flash and the two subroutines > are not part of a route, but I could *really* use an explanation, if this > issue is obvious to someone: > > I created the app as normal: > > C:\Apache24\htdocs>*dancer2 -a dancr* > + dancr > + dancr\config.yml > + dancr\cpanfile > + dancr\Makefile.PL > + dancr\MANIFEST.SKIP > + dancr\bin > + dancr\bin\app.psgi > + dancr\environments > + dancr\environments\development.yml > + dancr\environments\production.yml > + dancr\lib > + dancr\lib\dancr.pm > + dancr\public > + dancr\public\dispatch.cgi > + dancr\public\dispatch.fcgi > + dancr\public\404.html > + dancr\public\500.html > + dancr\public\favicon.ico > + dancr\public\css > + dancr\public\css\error.css > + dancr\public\css\style.css > + dancr\public\images > + dancr\public\images\perldancer-bg.jpg > + dancr\public\images\perldancer.jpg > + dancr\public\javascripts > + dancr\public\javascripts\jquery.js > + dancr\t > + dancr\t\001_base.t > + dancr\t\002_index_route.t > + dancr\views > + dancr\views\index.tt > + dancr\views\layouts > + dancr\views\layouts\main.tt > > With the resulting app files, I added the code from the original "dancr.pl" > demo to the applications "dancr.pm" module: > > package dancr; > use Dancer2; > > our $VERSION = '0.1'; > > get '/' => sub { > template 'index'; > }; > > true; > > I had to make the following adjustments to the code for Windows/Apache: > > (1) Change the session to YAML > > #set 'session' => 'Simple'; > set 'session' => 'YAML'; > > (2) Adjust the path for request->base: > > # $tokens->{'css_url'} = request->base . 'css/dancr.css'; > $tokens->{'css_url'} = request->base . '/css/dancr.css'; > > Everything with the app works as expected *except* for the "$flash > message" code: > > my $flash; > > sub set_flash($message) { > my $message = shift; > > $flash = $message; > } > > sub get_flash { > my $message = $flash; > $flash = ''; > > return $message; > } > > I suspect that since these subs are outside a route, perhaps I'm getting > an effect about the scope of the variables... but calls to these > subroutines do *not* set $flash or $message as expected: > > template 'show_entries.tt', { > 'msg' => get_flash, > > set_flash('New entry posted!'); > > set_flash('You are logged in.'); > > set_flash('You are logged out.'); > > For each of these, the $flash variable (which is a free-standing global in > the module) is never set... and so the get_flash sub never returns a value. > > -- > Prairie Nyx > [email protected] > -- Prairie Nyx [email protected]
_______________________________________________ dancer-users mailing list [email protected] http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
