1

Template::Toolkitテンプレートエンジンとして使用するCatalystアプリを開発しています。1ページには、等しい入力要素のリストが必要です。それらは配列から取得できますが、要素の並べ替え順序と説明ラベルの両方が必要です。

並べ替え順序を設定するには、配列を使用します。キーごとに追加の値を格納するには、ハッシュが最適です。TTで両方を組み合わせる方法は?私は両方を使うことができましたが、それは醜く見え、フィールドを変更するときに間違いを引き起こす可能性があります。

ただし、フォーム要素の説明と順序の両方がフロントエンドのものであるため、TTでこれを行うことをお勧めします。

これは私が純粋なPerlでそれを行う方法です:

#!/usr/bin/perl -w

use 5.10.0;

# definition of description and order in 1 step
my @fields = (
        property_foo => "Some property",
        property_bar => "Important field",
        property_baz => "Something else",
);

# extract information
my %descriptions = @fields;
my @order = @fields[grep {($_ + 1) % 2} 0..(scalar @fields - 1)];

say "=== natural perl sort order ===";
foreach (keys %descriptions) {say $_};

say "=== wanted output ===";
foreach (@order) {
        say $descriptions{$_} . ": [label for $_]";
}

出力:

=== natural perl sort order ===
property_baz
property_foo
property_bar
=== wanted output ===
Some property: [label for property_foo]
Important field: [label for property_bar]
Something else: [label for property_baz]

これは私が私のテンプレートに書いたものです:

[%
order = (
    property_foo,
    property_bar,
    property_baz,
);

descriptions = {
    property_foo => "Some property",
    property_bar => "Important field",
    property_baz => "Something else",
}

FOREACH property IN order %]
    [% descriptions.$property %]: <input name="[% property %]" />
[% END %]

ただし、同じ情報(フィールドのリスト)を2回持つのは本当に醜いです。リストを2回編集することは避けたいのですが、フィールドのリストが長くなると、非常に煩わしくなります(約20項目、データベースの処理を行うのに十分な長さではありません)。

4

4 に答える 4

3

Tie::IxHashに興味があるかもしれません

これは、キーを追加する順序を維持する「ハッシュ」です(値の更新は並べ替えに影響しません)。

編集:簡単な例:

use warnings;
use strict;

use Tie::IxHash; 
tie my %H, "Tie::IxHash"; 
$H{foo} = 1; 
$H{bar} = 2; 
# order of keys is now always 'foo', 'bar'

print keys %H;

EDIT2:試してみましたが、実際に機能します:

#!/usr/bin/perl -w

use strict;
use Template;
use Tie::IxHash;

# my %h; # this breaks ordering
tie my %H, "Tie::IxHash"; # this keeps ordering
@H{qw/f oo b a r/} = 1..100;
# don't define $H{'keys'} or you'll get disappointed

my $tpl = Template->new();
$tpl->process(\*DATA, {hash=>\%H});

__DATA__
[% FOREACH k IN hash.keys %]
     [% k %] => [% hash.$k %]
[% END %]
于 2011-04-07T10:28:06.723 に答える
3

人々が簡単なことを複雑にするのは驚くべきことです!

@fields配列は必要ありません。キー並べ替えについては、perldocをお読みください。

# untested sketch
my %description = ( prop23 => "foo", prop24 => "bar" );
foreach my $key(sort (keys %description)) {
    print $key, " is: ", $description{$key}, "\n";   # or whatever
}

補遺:キーの順序については、次のようにしてください。

my @arbitraryOrder = qw(prop42 prop35 prop1 ...);  # allows to map number to key
my %keytoNumber = ();                              # will map keys to numbers
foreach my $i(0..$#arbitraryOrder) $keyToNumber{$arbitraryOrder[$i]} = $i;

ソート用の比較関数の作成は演習として残されています:)

于 2011-04-07T10:06:29.440 に答える
1

順序付けと複数の情報が必要な場合は、ハッシュ参照の配列を検討する必要があります。

my @fields = (
  { id => 'property_foo',
    label => 'Some property' },
  { id => 'property_bar',
    label => 'Important field' },
  { id => 'property_baz',
    label => 'Something else' },
);

foreach (@fields) {
  print "ID: $_->{id}, Label: $_->{label}\n";
}

複雑さがこれをはるかに超えて増加する場合は、ハッシュ参照を実際のオブジェクトに置き換えることを検討してください。

そして、TTでは次のようになります。

[%-
properties = [
  {id => 'property_foo',
   label => 'Some property'},
  {id => 'property_bar',
   label => 'Important field'},
  {id => 'property_baz',
   label => 'Something else'},
];
-%]

[%- FOREACH property IN properties %]
    [% property.label %]: <input name="[% property.id %]" />
[% END %]
于 2011-04-07T10:20:13.777 に答える
1

実際、ハッシュをキーでアルファベット順にソートしたい場合は、Template::Toolkitがそれを行います。

test.pl

use strict;
use warnings;

use Template;

my %hash = qw' a 1 b 2 c 3 ';

my $config = {
  INCLUDE_PATH => '/search/path',
};
my $input = 'test.tt2';

my $template = Template->new( $config );
$template->process( $input, {
  hash => \%hash,
})

test.tt2

[%FOREACHハッシュ-%]
[%キー%] => [%値%]
[% 終わり %]

出力

a => 1
b => 2
c => 3
于 2011-04-07T14:44:19.593 に答える