[dancer-users] Question about the Dancer2 tutorial under Windows/Apache as an app...
Prairie Nyx
prairienyx at gmail.com
Sun May 31 05:10:42 BST 2015
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.preshweb.co.uk/pipermail/dancer-users/attachments/20150530/ff7c70fc/attachment.html>
More information about the dancer-users
mailing list