traveler has asked for the wisdom of the Perl Monks concerning the following question:

I have been away from the monastery for a while, but I have a very perplexing issue. I am migrating a Dancer2 site from Apache 2.2 to Apache 2.4 (Apache2 under Ubuntu). It works under 2.2 on CentOS, but not on the Ubuntu with 2.4. I copied the whole Dancer2 directory to the new server. I do the output with template commands, if that matters. I read the Apache2 error log and put perl debugs before and after the template command. There are no errors between the debugs. Here is the meaningful part of the Apache conf file. I have verified that apache reads it.
DocumentRoot /var/webapps/sandbox/public <FilesMatch "\.(?:cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory "/var/webapps/sandbox/public"> Options +Indexes +FollowSymLinks +MultiViews +ExecCGI AddHandler cgi-script .cgi AllowOverride None Require all granted SSLOptions +StdEnvVars </Directory> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /dispatch.cgi$1 [QSA,L] # ScriptAlias / /var/webapps/sandbox/public/dispatch.cgi/ <Location /> # Set up your Dancer2 application SetHandler cgi-script AddHandler application/x-httpd-perl .cgi PerlSetEnv Dancer2_APP /var/webapps/sandbox/bin/app.pl PerlSetEnv DANCER2_CONFDIR /var/webapps/sandbox PerlSetEnv DANCER_CONFDIR /var/webapps/sandbox PerlSetEnv DANCER2_ENV development </Location>
Here is my Dancer2 config.yml
# Your application's name appname: "sandbox" # We want to keep session data around so engines: session: YAML: session_dir: /tmp/dancer-sessionstore engines: template: template_toolkit: start_tag: '<%' end_tag: '%>' template: "template_toolkit" session: YAML # The default layout to use for your application (located in # views/layouts/main.tt) layout: "main" # when the charset is set to UTF-8 Dancer2 will handle for you # all the magic of encoding and decoding. You should not care # about unicode within your app when this setting is set (recommended) +. charset: "UTF-8" # template engine # simple: default and very basic template engine # template_toolkit: TT # template: "simple" plugins: Database: driver: 'mysql' database: 'vlabs' host:'something' port: 3306 username: 'rouser' password: 'xxxxxxxxxx' connection_check_threshold: 10
Here is a code snippet:
debug "displaying login page"; template 'login.tt', { path => param('requested_path') }; debug "showed login page";
And the log snippet:
[sandbox:12160] debug @2025-04-05 15:07:00> displaying login page in / +var/webapps/sandbox/public/../lib/sandbox.pm l. 45 [sandbox:12160] debug @2025-04-05 15:07:00> showed login page in /var/ +webapps/sandbox/public/../lib/sandbox.pm l. 47
There is a main.tt and a login.tt in the correct places. I get no output in my browser. The page is empty even when I look at the page source. (I do see the favicon.ico.) I am stumped, monks. Any ideas? TIA

Replies are listed 'Best First'.
Re: Why won't my Dancer2 app render any output???
by hippo (Archbishop) on Apr 06, 2025 at 09:59 UTC

    I don't use Dancer2, but I do use TT. You have not shown the contents of login.tt but it is highly likely that your new installation has a newer version of TT also. Perhaps vastly newer.

    I would suggest replacing login.tt temporarily with a trivial file which should just display "Hello World" or similar. If that works, then your template is the problem and you can then investigate that file further.


    🦛

      Thanks, but no joy. I tried a tiny login.tt:
      <b>Hello, world!</b>
      I used the main.tt from the Tutorial (the inclusion tags are changed in my config file, but I did try the default ones).
      <!doctype html> <html> <head> <title>dancr</title> <link rel=stylesheet type=text/css href="<% css_url %>"> </head> <body> <div class=page> <h1>dancr</h1> <div class=metanav> <% content %> </div> </body> </html>
Re: Why won't my Dancer2 app render any output???
by 1nickt (Canon) on Apr 06, 2025 at 19:28 UTC

    Hi,

    One thing to note is that only the last engines block will have effect in your config (although that is clearly not the source of this problem).

    I was able to reproduce your issue with the test app generated by dancer2 gen -a by adding a line after the template ... statement. My failing file:

    package My::TestApp; use Dancer2; our $VERSION = '0.1'; get '/' => sub { template 'index' => { 'title' => 'My::TestApp' }; debug 'after templating'; }; true;
    The debug log statement was printed to the log but no output was shown in the browser. Removing/commenting the line fixed the problem. I believe this is because the output of the last line in the handler is what is returned to the browser. (From the doc: "Note that template simply returns the content, so when you use it in a route handler, if execution of the route handler should stop at that point, make sure you use return to ensure your route handler returns the content.") Adding a line with output shows this:
    package My::TestApp; use Dancer2; our $VERSION = '0.1'; get '/' => sub { template 'index' => { 'title' => 'My::TestApp' }; debug 'after templating'; 'foo'; }; true;
    The browser shows 'foo' with this code.

    Do you have any other code in the route handler in sandbox.pm after the template statement?

    Hope this helps!

    Update: added quote from the doc


    The way forward always starts with a minimal test.
      Thanks. I took out both debugs. Now I have:
      get '/login' => sub { # Display a login page; the original URL they requested is availab +le as # param('requested_path'), so could be put in a hidden field in th +e form # debug "displaying login page"; template 'login', { path => param('requested_path') }; };
      and still no output. I tried the "foo" and didn't see that either. I am getting the error:
      [sandbox:22720] core @2025-04-06 16:28:17> Failed to serialize content +: hash- or arrayref expected (not a simple scalar, use allow_nonref t +o allow this) at /usr/local/share/perl/5.34.0/Dancer2/Serializer/JSON +.pm line 40. in (eval 333) l. 1
      But I can't tell what's causing it. When I put the debug before the "template" call, the error vanished. Curious. Also, I have seen examples with multiple engines in the config. Can you point me to an example that says only one is allowed? I had 2 in the old working version. Updates: I found that beginning with 1.3091 it is again permitted to have statement after template. I did a debug template ... and the proper "output" is in the log. Now I need to figure out where it's going...

        I was able to produce that JSON error by adding set serializer => 'JSON'; to the app package, and then requesting the URI with the Accept header set to 'application/json'.

        Could that be the cause of your error?


        The way forward always starts with a minimal test.

        With regard to the engines question, from the config file created in the generated app:

        # NOTE: All the engine configurations need to be under a single "engines:"
        # key.  If you uncomment engine configurations below, make sure to delete
        # all "engines:" lines except the first.  Otherwise, only the last
        # "engines:" block will take effect.
        


        The way forward always starts with a minimal test.