2

些細な一意のIDを実行するTTプラグインがあります。

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;
}

ここで、テンプレート呼び出しは単純です。

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

「データ」はRDBオブジェクトであり、ユーザーはその関係の1つです。関係に1つまたは複数の要素があるかどうかに関係なく、「。users」がPerlでリストを直接返すことを確認しました。

ただし、TTは単一要素リストの要素を返し、複数要素のリストは適切に返すようです。

これを調べたところ、「。list」を使用してリストコンテキストを強制できることがわかりました。

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

Data :: Dumperが明らかにしたように、これは単一要素リストの意図どおりには機能しません。

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

期待される代わりに

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

単一要素のリストであっても、オブジェクトのリストを取得するためのTTの他の簡単な方法はありますか?(1つのアプローチは関数を書き直すことですが、そうでないものは望ましくありません)

4

2 に答える 2

6

TTメーリングリストでこれを見つけました:

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

TTの「.list」は、RDBOだけでなく、一般的にオブジェクトをリストに変換するのに問題があるようです。

提案はvmethodを作成することです:

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

これをコンテキストオブジェクトに追加しました(同じアイデア):

$context->define_vmethod(
    'list',
    'as_list',
    sub {
        return ref( $_[0] ) eq 'ARRAY' ? shift : [shift];
    },
);
于 2010-01-06T22:00:00.927 に答える
3

それはあなたが求めているものではありませんが、リストと単一のアイテムの両方を処理するようにTTプラグインを変更できますか?

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;
}
于 2010-01-06T22:00:25.920 に答える