ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

処理中にエラーが発生した場合、redirectではなくて、symfonyのようにforwardしたい時

Akelosのcontrollerにはforward()相当のメソッドがありません。あえて似ているような機能を実現できるのが、

  • renderAction() : 指定されたアクションを実行
  • renderWithLayout() : レイアウトを指定してViewを実行
  • renderWithoutLayout() : レイアウト無しでViewを実行

などになります。

AkelosではActionメソッドの戻り値は使われていない*1ので、Akelosでテンプレートを切り替えたい場合は手動でrender()シリーズのメソッドを呼ぶことになります。
で、render()シリーズのメソッドでのテンプレートやPartialの指定方法って、結構混沌としてます。AkActionController#render()メソッドを参照してみてください。ややこしいです。
ので、今回は限定的に

  • renderWithLayout()で404相当エラー用のレイアウトを指定して実行
  • app/views/common/error.tpl は空のダミーファイル

として話を進めます。

いきなり解答です。
適当なコントローラ中:

<?php
class FooController extends ApplicationController
{
    function bar() {
        // ...
        $this->flash_now['notice'] = "指定されたデータが見つかりません。";
        $this->renderWithLayout(AK_VIEWS_DIR . '/common/error.tpl', 404, 'error');
        return;
    }
  • 第一引数:テンプレートファイルフルパス:これが一番確実です。今回はレイアウトの方でflashでメッセージを表示させていますので、テンプレートファイルの方は中身空っぽの単なるダミーファイルです。
  • 第二引数:HTTPステータスコード
  • 第三引数:使用するレイアウト。今回は、デフォルトのpage.tplをコピーして app/views/layouts/error.tpl としました。

また、page.tplをコピーしていますので AkActionController::$flashが使えます。ただし通常の$flashですと、次のリクエストにならないとView側で取れません。リクエストの遷移が無い今回のようなケースでは、$flash_nowの方を使います。
これで一旦、renderしてしまえばあとはそのままreturnしちゃいます。

*1:AkActionController#process(), performActionWithoutFilters(), performActionWithFilters(), performAction()のコードを参照