[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Omaha.pm] Template::Alloy contexts



... wow. Template::Alloy is ... wow. 

Check it out if you've always wished Perl 5's context stuff was more complicated.  :)

Perl++ # you can do ANYTHING.  :)

j



Begin forwarded message:
From: Paul Seamons <mail@seamons.com>
Subject: Re: [Templates] force resultset as array
Date: October 18, 2013 7:33:45 AM MDT

On 10/18/2013 05:03 AM, Spevak, Martin wrote:
Hello,

I have small problem with TT while getting DBIx::ResultSet. For instance
I have stash variable team which ich DBIx::Result (one entry). In DBIx
exists relations team_accesses as has_many. So in TT I am using:

team_accesses = team.team_accesses;

Problem is: 
	when team has no accesses, variable team_accesses is empty string ('')
	when 1 access exists, variable contain hash which is result
DBIx::TeamAccess. 
	when exists more than 1 access, variable contains array of
DBIx::TreamAccess.
Is the way how to say TT, that result needs to be converted to array?

I tried: team_access = [ team.team_accesses ], but my results are,
[ '' ], [DBIx::Result], [[DBIx::Result]]


I had tried to get CALL_CONTEXT added to Template::Toolkit, but as I was giving patches for adding various features, it was deemed that that would make the grammar grow too large.  So, while it isn't a good direct answer for how to do it in Template::Toolkit, it is possible to do this in Template::Alloy, but either way this portion from the Template::Alloy documentation does give more information about Template::Toolkit smart context:


CALL_CONTEXT (Not in TT)

Can be one of 'item', 'list', or 'smart'. The default type is 'smart'. The CALL_CONTEXT configuration specifies in what Perl context coderefs and methods used in the processed templates will be called. TT historically has avoided the distinction of item (scalar) vs list context. To avoid worrying about this, TT introduced 'smart' context. The @() and $() context specifiers make it easier to use CALL_CONTEXT in some situations.

The following table shows the relationship between the various contexts:

       return values      smart context   list context    item context
       -------------      -------------   ------------    ------------
    A   'foo'              'foo'           ['foo']         'foo'
    B   undef              undef           [undef]         undef
    C   (no return value)  undef           []              undef
    D   (7)                7               [7]             7
    E   (7,8,9)            [7,8,9]         [7,8,9]         9
    F   @a = (7)           7               [7]             1
    G   @a = (7,8,9)       [7,8,9]         [7,8,9]         3
    H   ({b=>"c"})         {b=>"c"}        [{b=>"c"}]      {b=>"c"}
    I   ([1])              [1]             [[1]]           [1]
    J   ([1],[2])          [[1],[2]]       [[1],[2]]       [2]
    K   [7,8,9]            [7,8,9]         [[7,8,9]]       [7,8,9]
    L   (undef, "foo")     die "foo"       [undef, "foo"]  "foo"
    M   wantarray?1:0      1               [1]             0

Cases F, H, I and M are common sticking points of the smart context in TT2. Note that list context always returns an arrayref from a method or function call. Smart context can give confusing results sometimes, especially the I and J cases. Case L for smart match is very surprising.

The list and item context provide another feature for method calls. In smart context, TT will look for a hash key in the object by the same name as the method, if a method by that name doesn't exist. In item and list context Alloy will die if a method by that name cannot be found.

The CALL_CONTEXT configuration item can be passed to new or it may also be set during runtime using the CONFIG directive. The following method call would be in list context:

    [% CONFIG CALL_CONTEXT => 'list';
       results = my_obj.get_results;
       CONFIG CALL_CONTEXT => 'smart'
    %]

Note that we needed to restore CALL_CONTEXT to the default 'smart' value. Template::Alloy has added the @() (list) and the $() (item) context specifiers. The previous example could be written as:

    [% results = @( my_obj.get_results ) %]

To call that same method in item (scalar) context you would do the following:

    [% results = $( my_obj.get_results ) %]
_______________________________________________
templates mailing list
templates@template-toolkit.org
http://mail.template-toolkit.org/mailman/listinfo/templates