[dancer-users] Dancer2::Manual: confused as to use of 'appname' keyword to distribute code across packages

James E Keenan jkeen at verizon.net
Fri Jul 15 20:50:43 BST 2016


On 07/14/2016 11:35 PM, Amelia Ireland wrote:
> I didn't read the first email properly -- I think what you want to do is
> this:
>
> in WebApp.pm:
>
> package WebApp;
>
> use Dancer2 appname => 'test';
> # plus the other dependencies
>
> hook before => sub {
>      if (!session('user') && request->dispatch_path !~ m{^/login}) {
>          forward '/login', { requested_path => request->dispatch_path };
>      }
> };
>
> get '/' => sub { template 'index'; };
> get '/index' => sub { redirect '/' };
>
> # etc.
>
> 1;
>
> in WebApp::API.pm:
>
> package WebApp::API;
> use Dancer2 appname => 'test';
>
> # handles everything under /api
> prefix '/api' => sub {
>
>      any ['get', 'post'] => '/userdata/:user' => sub {
>
>          my $user_value = route_parameters->get('user');
>          my $user = database->quick_select('users', { username =>
> $user_value });
>          # etc.
>      };
> };
>
> 1;
>
>
> in app.psgi:
>
> use WebApp;
> use WebApp::API;
>
> builder {
>      mount '/' => WebApp->to_app   # note that WebApp::API->to_app also
> works here
> };
>
> To make life even easier for yourself, you can make a wrapper to hold your
> various route modules:
>
> package WebAppWrap;
> use Dancer2 appname => 'test';
> use WebApp;
> use WebApp::API;
> use WebApp::JSON;
> use WebApp::Complex::Package; # each of these modules has appname 'test'
> # etc.
>
> in app.psgi:
>
> use WebAppWrap;
>
> builder {
>       mount '/' => WebAppWrap->to_app   # pulls in all loaded modules with
> appname 'test'
> };
>
>
>

Amelia,

Thank you for taking the time to respond.  Starting from the same 
starting point as previously, I tried to follow your suggestions as 
explicitly as possible (i.e., using the existing name of the app and the 
modules).  That meant that I was applying this diff:

#####
$ git diff -w | cat
diff --git a/bin/app.psgi b/bin/app.psgi
index 46d8845..3ced854 100755
--- a/bin/app.psgi
+++ b/bin/app.psgi
@@ -7,10 +7,8 @@ use lib "$FindBin::Bin/../lib";

  use mywebapp;
  use mywebapp::api;
-use Plack::Builder;

  builder {
      mount '/'       => mywebapp->to_app;
-    mount '/api'    => mywebapp::api->to_app;
  };

diff --git a/lib/mywebapp.pm b/lib/mywebapp.pm
index ce3cdc8..826d80e 100644
--- a/lib/mywebapp.pm
+++ b/lib/mywebapp.pm
@@ -1,6 +1,6 @@
  package mywebapp;
  use v5.10.1;
-use Dancer2;
+use Dancer2 appname => 'mywebapp';
  use Dancer2::Plugin::Database;
  use Crypt::SaltedHash;
  use Data::Dump;
diff --git a/lib/mywebapp/api.pm b/lib/mywebapp/api.pm
index 3af1adf..160b06b 100644
--- a/lib/mywebapp/api.pm
+++ b/lib/mywebapp/api.pm
@@ -1,6 +1,6 @@
  package mywebapp::api;
  use v5.10.1;
-use Dancer2;
+use Dancer2 appname => 'mywebapp';
  use Dancer2::Plugin::Database;
  use Crypt::SaltedHash;
  use Data::Dump;
@@ -13,6 +13,7 @@ set session => 'Simple';
  set views => path( app->location, "templates" );
  set serializer => 'JSON';

+prefix '/api' => sub {
      any ['get', 'post'] => '/userdata/:user' => sub {

          my $user_value = route_parameters->get('user');
@@ -34,6 +35,7 @@ any ['get', 'post'] => '/userdata/:user' => sub {
              }
          }
      };
+};

  start;
#####

But this led to an error as soon as I started the web server:

#####
$ plackup -R . -p 5000 bin/app.psgi
Watching . bin/lib bin/app.psgi for file updates.
String found where operator expected at 
/home/jkeenan/learn/perl/dancer2/mywebapp/bin/app.psgi line 12, near 
"mount '/'"
	(Do you need to predeclare mount?)
Error while loading 
/home/jkeenan/learn/perl/dancer2/mywebapp/bin/app.psgi: syntax error at 
/home/jkeenan/learn/perl/dancer2/mywebapp/bin/app.psgi line 12, near 
"mount '/'"
#####

Adding 'use Plack::Builder;' to bin/app.psgi resolved this error.

#####
-- /home/jkeenan/learn/perl/dancer2/mywebapp/bin/app.psgi updated.
Killing the existing server (pid:3375)
Successfully killed! Restarting the new server process.
HTTP::Server::PSGI: Accepting connections at http://0:5000/
#####

However, when I then went to the browser and issued a previously working 
API call, I got this error output:

#####
{"status":"500","title":"Error 500 - Internal Server 
Error","exception":"Failed to render template: file error - login.tt: 
not found at 
/home/jkeenan/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/Dancer2/Core/Role/Template.pm 
line 132.\n","message":""}
#####

In the server I got output like this:
#####
[mywebapp:3420] core @2016-07-15 15:45:55> looking for get /login in 
/home/jkeenan/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/Dancer2/Core/App.pm 
l. 840
[mywebapp:3420] core @2016-07-15 15:45:55> Entering hook 
core.app.before_request in 
/home/jkeenan/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/Dancer2/Core/App.pm 
l. 840
[mywebapp:3420] error @2016-07-15 15:45:55> Route exception: Failed to 
render template: file error - login.tt: not found at 
/home/jkeenan/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/Dancer2/Core/Role/Template.pm 
line 132. in 
/home/jkeenan/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/Dancer2/Core/App.pm 
l. 840
#####

Needless to say, if I can't locate 'login.tt', I can't login and 
therefore can't make any of the other previously working API calls.

I've spent more than 10 hours over several days trying to figure this 
out, and I'm beginning to lose hope that it will ever work.  Or, more 
precisely, I'm beginning to think that the documentation in 
Dancer2::Manual is claiming that something will work which just will not 
do so.

Thoughts?

Thank you very much.
Jim Keenan




More information about the dancer-users mailing list