[dancer-users] Question about the Dancer2 tutorial under Windows/Apache as an app...

Prairie Nyx prairienyx at gmail.com
Sun May 31 06:34:55 BST 2015


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 <prairienyx at gmail.com> 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 <prairienyx at gmail.com>
> 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
>> prairienyx at gmail.com
>>
>
>
>
> --
> Prairie Nyx
> prairienyx at gmail.com
>



-- 
Prairie Nyx
prairienyx at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.preshweb.co.uk/pipermail/dancer-users/attachments/20150531/ded95a26/attachment.html>


More information about the dancer-users mailing list