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... :-)
Thank you anyway! Prairie Nyx On Sat, May 30, 2015 at 11:10 PM, Prairie Nyx <[email protected]> wrote: > 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] > -- Prairie Nyx [email protected]
_______________________________________________ dancer-users mailing list [email protected] http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
