Question

I followed this recipe to disable Dancer's "layout" and re-enable TT's "WRAPPER":

How to make a page-specific title in Dancer templates?

which appears to be necessary to change tokens within the layout/wrapper at the route level. Briefly, the linked recipe requires specifying a single layout/wrapper in the config.yml file.

The recipe works great when using one layout/wrapper, but how do I go about changing (or disabling) the template layout/wrapper at the route level?

Since Dancer's native layout is disabled, this does not work:

 template('mytemplate', { ... }, { layout => 'some_other_layout' });   # NO GOOD

Also, I tried changing the config prior to rendering template, but that doesn't appear to work either:

 # ALSO NO GOOD
 config->{'engines'}->{'template_toolkit'}->{'WRAPPER'} = 'some_other_layout';
 return template('mytemplate', { ... });

And I also tried using the Dancer set/setting, but also no good:

 # ALSO NO GOOD
 my $engines = setting('engines');
 $engines->{'template_toolkit'}->{'WRAPPER'} = 'some_other_layout';
 set engines => $engines;

Any ideas?

Was it helpful?

Solution

I think I figured it out. Thanks to Yanick and to the link referenced in my other answer (Kludgy Workaround #2) for the inspiration. Here's the recipe:

  1. Create a single wrapper file for use in your entire project, and make it:

    <% IF layout %>
    <% INCLUDE "$layout" %>
    <% ELSE %>
    <% content %>
    <% END %>
    
  2. Within your route:

    return template('mytemplate', {
      layout => 'layouts/some_layout.tt',
      param1 => data1,
      param2 => data2,
      ...
      });
    

And bingo, you're done. Leave out the layout parameter, and will get no layout at all.

OTHER TIPS

I'm no TT expert, but it seems that once WRAPPER is set for the TemplateToolkit object, it can't be changed.

If that's the case, here's a slightly devious workaround.

  1. Set the layout to be, say, 'base.tt'.

  2. make that layout to be:

    print $context->process( $stash->get('wrapper'), { content => $context->process( $stash->get( 'template.name' ) ) });
  3. and then in your route:

    get '/' => sub { template 'index', { wrapper => 'layouts/main.tt' }; };

Tadah!

This being said, if you are using Dancer's native layouts, the tokens you're passing to template should make it to the wrapper code.

Two incredibly kludgy workarounds (please don't hate me):

Kludgy Workaround #1

set template => 'simple';
my $html = template('mytemplate', {}, { layout => 'some_other_layout' });
set template => 'template_toolkit';
return $html;

Basically, we temporarily switch out template_toolkit for Dancer's 'simple' template renderer.

Kludgy Workaround #2

Give up and keep the WRAPPER, but add conditionals so that it gets itself out of the way as described in this post:

How can I override WRAPPER in a Template Toolkit template file?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top