月日は百代の過客にして RSSフィード

2008/01/26

[][]TTのWrapperを変えたいよね、と言う話。

TTのWRAPPERって便利ですよね。ある程度のガワを用意すればbodyタグの中身だけを書くだけでいい。

けどWRAPPERの中身は変えられても外身は変えられないんですよね。


たとえばinner.htmlがこんなんで

This is inner!

outer.htmlがこんなん

This is outer!
[% contents %]

で、outer.htmlをWRAPPERに指定してinner.htmlをtemplateに指定すると

This is outer!
This is inner!

となるはずです。inner.htmlはすぐに変えられるんですがouter.htmlってどこで変えるのんと言うことでPOD探しても見つからなかったのでちょっと調査。


すると以外とあっさり見つかった。

#ref $self eq 'MyApp::View::TT'
$self->template->{SERVICE}->{WRAPPER}

をいじればWRAPPER変えられるみたいです!

ここにはarray refを入れなきゃ行けない模様で、それはTT内でのcontentsとプラスの使い方と同じみたいです。

[% contents a.html + b.html %]

$self->template->{SERVICE}->{WRAPPER} = [ qw/a.html b.html/ ]

と同じ見たいです。ごめんなさい逆さかもしれません、複数でプラスで結合は使ったこと無いのでよくわかりませんPOD見てください。


まぁこれだけじゃアレなので、templateはstashで指定するんだからwrapperもstashで指定出来たらいいんじゃね?と思い軽く書いてみた。

sub process {
    my($self,$c) = @_;

    if ( my $w = $c->stash->{wrapper} ) {
        $self->template->{SERVICE}->{WRAPPER} = ref $w eq 'ARRAY' ? $w : [$w];
    }

    $self->SUPER::process($c);
}

これをMyApp::View::TTに置きませう。WRAPPERが一つの時は文字列で、複数の時はarray refで。

#Controllerで
$c->stash->{wrapper} = 'another_wrapper.html'; #単数
$c->stash->{wrapper} = ['a.html', 'b.html'];   #複数

とかやったら幸せかなぁと思いました。作った後に思って今更ですけどWrapper変えるってそんなに無いですよね。まぁいいややったことなので。

2008/01/19

[]CatalystのDispatcherでえらく感動したのでメモ。

Catalystでログ的なウィンドウを出力したい訳です。エラーであるとか処理が完了したとか。

sub moge : Local {
  my($self,$c) = @_;

  if ($some_condition) {
    $c->stash->{info} = 'Some error happen!';
    $c->stash->{template} = 'info.html';
    return
  }
}

みたいな感じだと思うんです。stashにrenderするべきtemplateと値を入れてreturn。

何個もこれをやりたいとなるとこれをMyApp.pmとかに書いたりするわけです。


たとえばこれをrender_infoって名前でメソッドにして、普通に$c->render_infoって呼ぶと戻ってくる訳です。当たり前ですが。

sub MyApp::render_info {
  shift()->detach('/_render_info', \@_);
}

sub MyApp::_render_info : Private {
  # メッセージを表示するルーチン
}

なんてやれば戻ってこないが実現するんですがメソッド二つはどうよ、ということになってうーんとなる訳です。

それでdetachの元があるCatalyst::Dispatcherを見てみたら

sub detach {
    my ( $self, $c, $command, @args ) = @_;
    $c->forward( $command, @args ) if $command;
    die $Catalyst::DETACH;
}

$Catalyst::DETACHってなんだよ、とおもって倣ってdie $Catalyst::DETACHしてみたらstack戻ってない!

値を見てみたら

our $DETACH    = "catalyst_detach\n";

ってあるので定数ですね。

結論:die $Catalyst::DETACHするとそこでDispatcher止まります。それより先に行かないし戻らないみたいです。

throw-catchってこういう風に使うんだ、と感動した。