Search code examples
perltemplate-enginedancer

Configuring Template::Toolkit in Dancer2's config.yml (trimming whitespace)


I'm using Dancer2 to build a web application. It works great but when I view source in the browser, the generated HTML source code is full of scattered whitespace, like so

    <tr>
        <td>2</td>



            <td>Cheeseburger</td>

        <td>4.50&nbsp;€</td>
    </tr>

My templates had <% ... %> code at the places where now the whitespace is. I'd prefer if it looked like this:

    <tr>
        <td>2</td>
            <td>Cheeseburger</td>
        <td>4.50&nbsp;€</td>
    </tr>

or, even better:

<tr><td>2</td><td>Cheeseburger</td><td>4.50&nbsp;€</td></tr>

I'm using Template::Toolkit and thought the TRIM attribute is exactly what I need and added it to my config.yml:

template: "template_toolkit"
session: "YAML"

engines:
  session:
    YAML:
      cookie_duration: 6 months
  template:
    template_toolkit:
      start_tag: '<%'
      end_tag:   '%>'
      TRIM:      '1'

But this doesn't work. I already changed start_tag and end_tag to something different (to verify this file is read) and that actually worked. But the TRIM option does not.

Am I using the wrong option or giving it at the wrong place? All the googling I did showed how to set TT-options programmatically as e.g. in this answer. But as I do not explicitely instantiate anything TT related, I don't even know where I should put such code.


I created my app with dancer2 -a so.

views/index.tt

<table>
    <tbody>
        <% FOREACH item in group.items %>
            <tr>
                <td><% item.order_num %></td>
                <%# one-line comment %>
                <%# one-line comment %>
                <%# one-line comment %>
                    <td><% item.desc %></td>
                <%# one-line comment %>
                <td><% currency(item.price) %></td>
            </tr>
        <% END %>
    </tbody>
</table>

group.items is an array of hashrefs; currency is a function to format the price. The <%# one-line comment %> are my old code (I'm migrating from Handlebars to Dancer2).

lib/so.pm (the app's module)

package so;
use Dancer2;

our $VERSION = '0.1';

get '/' => sub {

    my $group = {
        items => [
            {
                order_num => 1,
                desc => 'Hamburger',
                price => 350,
            },
            {
                order_num => 2,
                desc => 'Cheeseburger',
                price => 450,
            },
        ]
    };

    template 'index', {
        group => $group,
        currency => sub { sprintf('%.2f&nbsp;€', $_[0]/100); },
    };
};

true;

Solution

  • You're enabling TRIM correctly in your config file, but TRIM only removes whitespace from the very beginning and the very end of a block or template file. To remove whitespace from the middle of a template file, use PRE_CHOMP/POST_CHOMP:

    Anything outside a directive tag is considered plain text and is generally passed through unaltered...This includes all whitespace and newlines characters surrounding directive tags. Directives that don't generate any output will leave gaps in the output document.

    Example:

    Foo
    [% a = 10 %]
    Bar
    

    Output:

    Foo
    
    Bar
    

    The PRE_CHOMP and POST_CHOMP options can help to clean up some of this extraneous whitespace. Both are disabled by default.

    There are several possible settings for PRE_CHOMP and POST_CHOMP that affect how much whitespace is stripped; none of them generates really pretty output, so you'll have to play around and decide which you like best.