softmoth / raku-Template-Mustache

Raku library for the Mustache template format
https://modules.raku.org/dist/Template::Mustache:cpan:SOFTMOTH
Artistic License 2.0
21 stars 19 forks source link

Weird ordering in rendered output #21

Closed scmorrison closed 6 years ago

scmorrison commented 7 years ago

Hello, I am seeing weird ordering on the rendered output when I provide the following as context to .render:

#!/usr/bin/env perl6

use v6;

use Template::Mustache;

my %h = categories => [
    category_pages => [
       {title => "Perl 6",
        url   => "https://www.perl6.org"},
       {title => "Perl 6 Modules",
        url   => "https://modules.perl6.org"}],
    title => "General tasks"];

my $html = q:to/EOF/;
{{#categories}}
{{ title }} <!-- should be first item -->
{{#category_pages}}
{{ title }} : {{ url }}</br>
{{/category_pages}}
{{/categories}}
EOF

say Template::Mustache.render: $html, %h;

# Output
#
# <!-- should be first item -->
# Perl 6 : https://www.perl6.org</br>
# Perl 6 Modules : https://modules.perl6.org</br>
# General tasks <!-- should be first item -->
softmoth commented 6 years ago

OK, I believe I found the problem with this test case. The category needs to be wrapped in a hash; as it is, categories is an array of two items. The first item (:category_pages([...])) gets applied to the template. It has no <title>, so {{title}} is null. It does have <category_pages>, so {{#category_pages}} section is expanded properly.

The second item is :title("General tasks"). So this time through {{#categories}} it fills in {{title}}, but the {{#category_pages}} section becomes null.

It took me a long time to figure this out, because the following does not wrap a hash around it as I'd expected:

my %h = categories => [
  {
    category_pages => [
       {title => "Perl 6",
        url   => "https://www.perl6.org"},
       {title => "Perl 6 Modules",
        url   => "https://modules.perl6.org"}],
    title => "General tasks"
  }
];

I'm a a few years behind on P6 syntax and it appears that [ { foo => bar } ] flattens the {} out. I'm sure there's a good reason for it. It needs a comma at the end to force it to keep the hash. So the following works as desired:

my %h = categories => [
    {
        title => "General tasks",
        category_pages => [
            { title => "Perl 6", url => "https://www.perl6.org" },
            { title => "Perl 6 Modules", url => "https://modules.perl6.org" },
        ],
    },
];

my $html = q:to/EOF/;
{{#categories}}
{{ title }} <!-- should be first item -->
{{#category_pages}}
{{ title }} : {{ url }}</br>
{{/category_pages}}
{{/categories}}
EOF

is Template::Mustache.render($html, %h),
    q:to/EOF/,
    General tasks <!-- should be first item -->
    Perl 6 : https://www.perl6.org</br>
    Perl 6 Modules : https://modules.perl6.org</br>
    EOF
    ;