<div dir="ltr"><div><div>Well... looks like I'm going to answer my own question after thinking about how as a CGI app, the vars are completely fresh with each call... so I'll play with setting a "session variable" and then not look back at this example... :-)<br><br></div>Thank you anyway!<br><br></div>Prairie Nyx<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, May 30, 2015 at 11:10 PM, Prairie Nyx <span dir="ltr"><<a href="mailto:prairienyx@gmail.com" target="_blank">prairienyx@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Here is the entire source for the "almost working" <a href="http://dancr.pl" target="_blank">dancr.pl</a> tutorial demo, implemented as an application under Windows/Apache:<br><br>[<b>.../htdocs/dancr/lib/<a href="http://dancr.pm" target="_blank">dancr.pm</a></b>]Â Â Note - Changes from "<a href="http://dancer.pl" target="_blank">dancer.pl</a>" in yellow...<br><br></div><span style="font-family:monospace,monospace">-----------------------------------------------------------------------------</span><br><br><div><span style="font-family:monospace,monospace">package dancr;<br><br>use strict;<br>use warnings;<br><br>use Dancer2;<br>use DBI;<br>use File::Spec;<br>use File::Slurp;<br>use Template;<br><br>our $VERSION = '0.1';<br>Â <br># set 'database'Â Â Â Â => File::Spec->catfile(File::Spec->tmpdir(), 'dancr.db');<br></span></div><div><span style="font-family:monospace,monospace"># Set the database to live under the application directory...<br></span></div><div><span style="font-family:monospace,monospace"><span style="background-color:rgb(255,255,0)">set 'database'Â Â Â Â => 'C:\Apache24\htdocs\dancr\dancr.db';</span><span class=""><br>#set 'session'Â Â Â Â Â => 'Simple';<br><span style="background-color:rgb(255,255,0)">set 'session'Â Â Â Â Â => 'YAML';</span><br></span>set 'template'Â Â Â Â => 'template_toolkit';<br>set 'logger'Â Â Â Â Â Â => 'console';<br>set 'log'Â Â Â Â Â Â Â Â Â => 'debug';<br>set 'show_errors'Â => 1;<br>set 'startup_info' => 1;<br>set 'warnings'Â Â Â Â => 1;<br>set 'username'Â Â Â Â => 'admin';<br>set 'password'Â Â Â Â => 'password';<br>set 'layout'Â Â Â Â Â Â => 'main';<br><br>my $flash;<br><br>sub set_flash {<span class=""><br>Â Â Â my $message = shift;<br><br>Â Â Â $flash = $message;<br>}<br><br>sub get_flash {<br>Â Â Â my $message = $flash;<br>Â Â Â $flash = '';<br>Â Â Â <br>Â Â Â return $message;<br>}<br><br></span>sub connect_db {<br>Â Â Â my $dbh = DBI->connect("dbi:SQLite:dbname=".setting('database')) or<br>Â Â Â Â Â Â Â die $DBI::errstr;<br>Â <br>Â Â Â return $dbh;<br>}<br>Â <br>sub init_db {<br>Â Â Â my $db = connect_db();<br>Â Â Â my $schema = read_file('./schema.sql');<br>Â Â Â $db->do($schema) or die $db->errstr;<br>}<br>Â <br>hook before_template => sub {<br>Â Â Â my $tokens = shift;<span class=""><br>Â <br>#Â Â Â $tokens->{'css_url'} = request->base . 'css/dancr.css';<br>Â Â Â <span style="background-color:rgb(255,255,0)">$tokens->{'css_url'} = request->base . '/css/dancr.css';</span><br></span>Â Â Â $tokens->{'login_url'} = uri_for('/login');<br>Â Â Â $tokens->{'logout_url'} = uri_for('/logout');<br>Â Â Â $flash='';<br>};<br>Â <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;<span class=""><br>Â Â Â <br>Â Â Â template '<a href="http://show_entries.tt" target="_blank">show_entries.tt</a>', {<br>Â Â Â Â Â Â Â 'msg' => get_flash,<br></span>Â Â Â Â Â Â Â 'add_entry_url' => uri_for('/add'),<br>Â Â Â Â Â Â Â 'entries' => $sth->fetchall_hashref('id'),<br>Â Â Â };<br>Â Â Â <br>};<br>Â <br>post '/add' => sub {<br>Â Â Â if ( not session('logged_in') ) {<br>Â Â Â Â Â Â Â send_error("Not logged in", 401);<br>Â Â Â }<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;<span class=""><br>Â <br>Â Â Â set_flash('New entry posted!');<br></span>Â Â Â redirect '/';<br>};<br>Â <br>any ['get', 'post'] => '/login' => sub {<br>Â Â Â my $err;<br>Â Â Â my $session = session;<br>Â Â Â <br>Â Â Â if ( request->method() eq "POST" ) {<br>Â Â Â Â Â Â Â # process form input<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;<span class=""><br>Â Â Â Â Â Â Â Â Â Â Â set_flash('You are logged in.');<br></span>Â Â Â Â Â Â Â Â Â Â Â return redirect '/';<br>Â Â Â Â Â Â Â }<br>Â Â }<br>Â <br>Â Â # display login form<br>Â Â template '<a href="http://login.tt" target="_blank">login.tt</a>', {<br>Â Â Â Â Â Â 'err' => $err,<br>Â Â };<br>Â <br>};<br>Â <br>get '/logout' => sub {<br>Â Â app->destroy_session;<span class=""><br>Â Â set_flash('You are logged out.');<br></span>Â Â redirect '/';<br>};<br>Â <br>init_db();<br>start;<br><br>true;<br><br>-----------------------------------------------------------------------------</span><br><br><div>[<b>http.conf</b>]<br><br></div><span style="font-family:monospace,monospace"><Directory "C:/Apache24/htdocs/dancr"><br>Â Â Â AllowOverride None<br>Â Â Â Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch<br>Â Â Â Order allow,deny<br>Â Â Â Allow from all<br>Â Â Â AddHandler cgi-script .cgi<br></Directory><br>Â <br>ScriptAlias /dancr "C:/Apache24/htdocs/dancr/public/dispatch.cgi"</span><br><br><span style="font-family:monospace,monospace"></span><br></div><div>It all seems to boil down to the "<b>my $flash;</b>" 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...<br><br><span style="font-family:monospace,monospace">---------------------------------</span><br><span style="font-family:monospace,monospace">my $flash;<br><br>sub set_flash {<span class=""><br>Â Â Â my $message = shift;<br><br>Â Â Â $flash = $message;<br>}</span></span><br><span style="font-family:monospace,monospace">---------------------------------<br><br></span></div><div>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...<br><br></div><div>Prairie Nyx<br><br></div></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On Sat, May 30, 2015 at 10:47 PM, Prairie Nyx <span dir="ltr"><<a href="mailto:prairienyx@gmail.com" target="_blank">prairienyx@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div>Perl Dancer Community:<br><br>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.<br><br></div><div>I started with SawyerX's tutorial page:<br><br>Â Â <a href="http://search.cpan.org/~xsawyerx/Dancer2/lib/Dancer2/Tutorial.pod" target="_blank">http://search.cpan.org/~xsawyerx/Dancer2/lib/Dancer2/Tutorial.pod</a><br><br>The "<a href="http://dancr.pl" target="_blank">dancr.pl</a>" tutorial program ran just fine under the port 3000 server and the tutorial was useful and instructive:<br></div><br></div>C:\Users\CoderDojo\Perl\Dancer\dancr>perl <a href="http://dancr.pl" target="_blank">dancr.pl</a><br>>> Dancer2 v0.160001 server 2496 listening on <a href="http://0.0.0.0:3000" target="_blank">http://0.0.0.0:3000</a><br><br></div>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.<br><br></div>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:<br><br></div>I created the app as normal:<br><br><span style="font-family:monospace,monospace">C:\Apache24\htdocs><b>dancer2 -a dancr</b><br>+ dancr<br>+ dancr\config.yml<br>+ dancr\cpanfile<br>+ dancr\Makefile.PL<br>+ dancr\MANIFEST.SKIP<br>+ dancr\bin<br>+ dancr\bin\app.psgi<br>+ dancr\environments<br>+ dancr\environments\development.yml<br>+ dancr\environments\production.yml<br>+ dancr\lib<br>+ dancr\lib\<a href="http://dancr.pm" target="_blank">dancr.pm</a><br>+ dancr\public<br>+ dancr\public\dispatch.cgi<br>+ dancr\public\dispatch.fcgi<br>+ dancr\public\404.html<br>+ dancr\public\500.html<br>+ dancr\public\favicon.ico<br>+ dancr\public\css<br>+ dancr\public\css\error.css<br>+ dancr\public\css\style.css<br>+ dancr\public\images<br>+ dancr\public\images\perldancer-bg.jpg<br>+ dancr\public\images\perldancer.jpg<br>+ dancr\public\javascripts<br>+ dancr\public\javascripts\jquery.js<br>+ dancr\t<br>+ dancr\t\001_base.t<br>+ dancr\t\002_index_route.t<br>+ dancr\views<br>+ dancr\views\<a href="http://index.tt" target="_blank">index.tt</a><br>+ dancr\views\layouts<br>+ dancr\views\layouts\<a href="http://main.tt" target="_blank">main.tt</a><br><br></span></div>With the resulting app files, I added the code from the original "<a href="http://dancr.pl" target="_blank">dancr.pl</a>" demo to the applications "<a href="http://dancr.pm" target="_blank">dancr.pm</a>" module:<br><br><span style="font-family:monospace,monospace">package dancr;<br>use Dancer2;<br><br>our $VERSION = '0.1';<br><br>get '/' => sub {<br>Â Â Â template 'index';<br>};<br><br>true;</span><br><div><div><div><div><div><div><div><div><div><div><br></div><div>I had to make the following adjustments to the code for Windows/Apache:<br><br></div><div>(1) Change the session to YAML<br><br><span style="font-family:monospace,monospace">#set 'session'Â Â Â Â Â => 'Simple';<br>set 'session'Â Â Â Â Â => 'YAML';</span><br><br></div><div>(2) Adjust the path for request->base:<br><span style="font-family:monospace,monospace"><br>#Â Â $tokens->{'css_url'} = request->base . 'css/dancr.css';<br>Â Â Â $tokens->{'css_url'} = request->base . '<span style="background-color:rgb(255,255,0)">/</span>css/dancr.css';<br></span><br></div><div>Everything with the app works as expected *except* for the "$flash message" code:<br><br>my $flash;<br><br>sub set_flash($message) {<br>Â Â Â my $message = shift;<br><br>Â Â Â $flash = $message;<br>}<br><br>sub get_flash {<br>Â Â Â my $message = $flash;<br>Â Â Â $flash = '';<br>Â Â Â <br>Â Â Â return $message;<br>}<br><br></div><div>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:<br><br>Â Â template '<a href="http://show_entries.tt" target="_blank">show_entries.tt</a>', {<br>Â Â 'msg' => get_flash,<br><br>Â Â set_flash('New entry posted!');<br><br>Â Â set_flash('You are logged in.');<br><br>Â Â set_flash('You are logged out.');<br></div><div><br></div><div>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.<span><font color="#888888"><br><br></font></span></div><span><font color="#888888"><div>-- <br><div>Prairie Nyx<br><a href="mailto:prairienyx@gmail.com" target="_blank">prairienyx@gmail.com</a></div>
</div></font></span></div></div></div></div></div></div></div></div></div></div>
</blockquote></div><br><br clear="all"><br></div></div><span class="HOEnZb"><font color="#888888">-- <br><div>Prairie Nyx<br><a href="mailto:prairienyx@gmail.com" target="_blank">prairienyx@gmail.com</a></div>
</font></span></div>
</blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">Prairie Nyx<br><a href="mailto:prairienyx@gmail.com" target="_blank">prairienyx@gmail.com</a></div>
</div>