Tree::Simpleを使ってツリー表示を実装する(つづき)
Tree::Simpleを使ってツリー表示を実装する(つもりだったけど) - libnitsuji.so
これのつづき。
とにかく機能を出してしまえ、と思って無理やり実装した。どうもPerlらしくないコードになってしまうのがとても悔しい。実際の表示はツリーになってないけど、まあその辺は(たぶん)スタイルシートとかの問題なので今日はほおっておく。いちばん右側の値がツリーの深さで-1がルートでそこから一世代下るごとに+1です。
http://takatoshi.dyndns.org/bbs5/tree
コード。
IDをキーにしてツリーオブジェクトのハッシュを作るところまでは同じ。
my $iter = BBS::Message->retrieve_all; # make tree object hash my %message_tree; while (my $m = $iter->next) { my $parent = $message_tree{$m->parent} || Tree::Simple->ROOT; $message_tree{$m->id} = Tree::Simple->new($m, $parent); }
次に深さ優先で階層構造を下ってその順番で配列にぶち込む。
# make tree object list as hierarchy order my @message_tree_list = (); for my $id (sort {$a <=> $b} keys %message_tree) { my $tree = $message_tree{$id}; $self->_make_tree_list(\@message_tree_list, $tree) if $tree->isRoot(); } sub _make_tree_list { my $self = shift; my ($list, $tree) = @_; push @$list, $tree; my $children = $tree->getAllChildren(); return unless defined $children; $self->_make_tree_list($list, $_) for @$children; }
最後にテンプレートに渡す。
$self->tt_process('tree.tt', { query => $q, messages => \@message_tree_list, title_suffix => " - ツリー表示", });
テンプレートはこんな感じで。
[% INCLUDE header.tt %] [% FOREACH tree IN messages %] [% m = tree.getNodeValue() %] [% m.id %] : [% m.title %] : [% tree.getDepth() %]
[% END %]