Catalyst::Plugin::I18Nを使ってメッセージ類をControllerに直接書かないようにする

例えばカテゴリを削除するアクションを実行した結果を表示したい。
flashを使って例えばこんな感じにする。

    if ($c->form_submitted) {
        if (my $name = $c->forward('do_delete')) {
            $c->flash->{notice} = sprintf('カテゴリ「%s」を削除しました', $name);
            $c->res->redirect($c->uri_for('/admin/category/list'));
        }   
        else {
            $c->flash->{notice} = 'カテゴリを削除できませんでした';
            $c->res->redirect($c->uri_for('/admin/category/list'));
        }   
    }

でもこういうメッセージ類がコントローラの中にあるとあとでなにかと面倒です。
そこでCatalyst::Plugin::I18Nを使ってみました。
MyApp.pmにI18Nを追加。

use Catalyst qw/
    I18N
/;

lib/MyApp/I18N/ja.pmを作成(日本語の場合)してメッセージを定義する。

package MyApp::I18N::ja;
use base 'MyApp::I18N';
our %Lexicon = (
    DELETE_CATEGORY => 'カテゴリ「%s」を削除しました',
    CANNOT_DELETE_CATEGORY => 'カテゴリを削除できませんでした',
);

1;

で、Controllerの方はこんな感じにする。

    if ($c->form_submitted) {
        if (my $name = $c->forward('do_delete')) {
            $c->flash->{notice} = sprintf($c->localize('DELETE_CATEGORY'), $name);
            $c->res->redirect($c->uri_for('/admin/category/list'));
        }   
        else {
            $c->flash->{notice} = $c->localize('CANNOT_DELETE_CATEGORY');
            $c->res->redirect($c->uri_for('/admin/category/list'));
        }   
    }

言語が明示的に指定されていない場合はリクエストヘッダのAccept-Languageが使われます。
ja.pmに書くキーのルールをちゃんと決めておかないと数が増えたときにごちゃごちゃになりそうだけど、ひとまず目的は達成できているかなと思います。
やりたいことがあってちょっと探すとこういうのがパッと見つかったりするとPerlでよかったなーと実感します。

    • -

Catalyst::Plugin::I18N - I18N for Catalyst - metacpan.org