<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>