2010-01-06 3 views
2

J'ai un plugin TT qui fait les ids triviales uniques:Comment puis-je forcer le contexte de liste dans Template Toolkit avec RDBO?

sub get_unique_uid_tt { 
    my ($classname, $o) = @_; 

    my %h; 

    foreach my $item (@{$o}) { 
    unless (exists $h{ $item->id }) { 
     $h{ $item->id } = 1; 
    } 
    } 

    return keys %h; 
} 

où l'appel de modèle est tout simplement:

[% Namespace.get_unique_uid_tt(data.users) %] 

et « données » est un objet RDB, les utilisateurs étant l'une de ses relations . J'ai vérifié que le ".users" renvoie une liste en Perl directement, si la relation a un ou plusieurs éléments.

Toutefois, il semble que TT renvoie l'élément pour les listes d'éléments uniques, tout en renvoyant correctement les listes pour les éléments multiples.

Je regardé ce et a constaté que vous pouvez forcer un contexte de liste avec « .list »:

[% Namespace.get_unique_uid_tt(data.users.list) %] 

Cela ne fonctionne pas comme prévu pour les listes à un seul élément, comme Data :: Dumper a révélé:

$VAR1 = [ 
     { 
     'value' => 1, 
     'key' => '__xrdbopriv_in_db' 
     }, 
     { 
     'value' => bless(
     ... snip ... 
     ), 
     'key' => 'db' 
     }, 
     { 
     'value' => '1', 
     'key' => 'id' 
     } 
]; 

au lieu de l'attendre

$VAR1 = [ 
    bless({ 
      '__xrdbopriv_in_db' => 1, 
      'id' => '1', 
      'db' => ... snip ... 
    }, 'DataClass') 
]; 

est-il un autre moyen simple TT pour obtenir un lis t d'objets, même sur des listes d'éléments uniques? (Une approche consiste à réécrire la fonction, mais qui ne serait pas préférable)

Répondre

6

trouvé sur la liste de diffusion de TT:

http://lists.template-toolkit.org/pipermail/templates/2009-December/011061.html

semble comme « le .list » TT a des objets de conversion trouble aux listes en général, pas seulement les RDBO.

La suggestion est de faire une vmethod:

$Template::Stash::LIST_OPS->{ as_list } = sub { 
    return ref($_[0]) eq 'ARRAY' ? shift : [shift]; 
}; 

J'ai ajouté à mon objet de contexte (même idée):

$context->define_vmethod(
    'list', 
    'as_list', 
    sub { 
     return ref($_[0]) eq 'ARRAY' ? shift : [shift]; 
    }, 
); 
3

Ce n'est pas tout à fait ce que vous êtes après, mais pourriez-vous modifier le plugin TT pour gérer les listes et les éléments uniques?

sub get_unique_uid_tt { 
    my ($classname, $o) = @_; 

    my %h; 

    if (ref $o eq 'ARRAY') { 
    foreach my $item (@{$o}) { 
     unless (exists $h{ $item->id }) { 
     $h{ $item->id } = 1; 
     } 
    } 
    } 
    else { 
     return ($o->id); 
    } 

    return keys %h; 
} 
Questions connexes