in reply to Format and Join an Array in a Template

TT has some nice meta information included in all loops (size, max, index, count, first, last, prev, next). I think this is much easier to read than the slice stuff-

[% FOR item IN my_stuff %] .[% item %]([% item %])[% "," UNLESS loop.last %] [% END %]

You can also bake this stuff into your templates if you want.

use Template::Stash; $Template::Stash::LIST_OPS->{my_weird_join} = sub { join(",\n", map { "$_.($_)" } @{ +shift || [] }; }; # then... [% my_stuff.my_weird_join %]

Not tested but looks right.

Replies are listed 'Best First'.
Re^2: Format and Join an Array in a Template
by mscharrer (Hermit) on Jun 20, 2009 at 09:32 UTC
    Ah, thanks! Both look quite interesting. I will check them out. Template seems to be quite powerful.

      Great. I adore TT and this example goes to the root of why and why I break from the View purists who say TT is a disaster and you should use something like HTML::Template. These simple loop controls can solve many common display logic problems.

      TT can do just about anything. Beware of moving too much into it (it can write files, run macros, run plain Perl, do recursion, etc, etc, etc). If you want a ton of code in templates, Mason is probably the right choice. TT lets you separate and plugin really well though so you can do your own methods and filters, for example, without writing anything but glue code; The Right Way to Do It™. Just another example-

      use warnings; use strict; use Template; use Lingua::EN::Numbers::Ordinate "ordinate"; my %config = ( FILTERS => { ordinal => sub { ordinate($_[0]) }, ordinal_html => sub { my $ord = ordinate($_[0]); $ord =~ s,(\D\D)\z,<sup>$1</sup>,; return $ord; } } ); my $tt2 = Template->new(\%config); $tt2->process(\*DATA, { numbers => [ 0 .. 121 ] }) or die $tt2->error; __DATA__ [% FOR i IN numbers %] Plain: [% i | ordinal %] -- HTML: [% i | ordinal_html %] [%-END %]

      I'd also point you toward Template::Alloy. It's a well behaved implementation of the TT2(3) syntax with a few improvements and supports several other template types. I've used it on my last couple of projects and haven't hit any reasons to go back.

Re^2: Format and Join an Array in a Template
by mscharrer (Hermit) on Jun 22, 2009 at 14:51 UTC
    I now implemented this as follows. I also added alignment of the listed names by calculating the maximum length.

    Is there any possibility to get the indention level of the template code, so that all produced lines are indented the same amount (by adding the number of spaces in join( ))?

    Thanks again.

    Update: I know fixed the indention problem by (re-)adding a join argument:

    use Template::Stash; use List::Util qw(max); $Template::Stash::LIST_OPS->{signal_list} = sub { my $aref = +shift || []; my $sep = shift || "\n "; my $l = max map { length $_ } @$aref; join(",$sep", map { sprintf ".%-${l}s (%-${l}s)", $_, $_ } @$aref) +; };