NanoAプラグインの書き方

そのまま使っても簡単にCGIが書けるNanoAですが、プラグインを書くとアプリケーションのコード全体的が見通しよくなります。

単純なプラグインの例を見ていきます。

app/plugin/hello.pm

package plugin::hello;

use strict;
use warnings;
use utf8;

use base qw(NanoA::Plugin);

sub init_plugin {
    my ($klass, $controller) = @_;

    NanoA::register_hook($controller, 'prerun', \&_prerun);
    NanoA::register_hook($controller, 'postrun', \&_postrun);

    no strict 'refs';
    no warnings 'redefine';
    *{$controller . '::hello'} = sub {
        my $app  = shift;
        my $name = $app->query->param('name');
        return 'Hello ' . $name;
    };
}

sub _prerun {
    my $app = shift;

    my $query = $app->query;
    $query->param('name' => 'World') unless $query->param('name');
}

sub _postrun {
    my ($app,$bodyref) = @_;

    $app->header( -charset => 'Shift_JIS');
}

__PACKAGE__->init_plugin(__PACKAGE__);
sub run {
    my $app = shift;
    return $app->hello;
}

1;

頭から順々に説明すると

package plugin::hello;

use strict;
use warnings;
use utf8;

use base qw(NanoA::Plugin);

NanoA::Pluginを継承して、パッケージ名をplugin::*としてapp/plugin/以下に置くことよってアプリケーションからuse plugnin::hello;として使うことが出来るようになります。
この例ではapp/plugin/hello.pmとして保存します。

sub init_plugin {
    my ($klass, $controller) = @_;

    NanoA::register_hook($controller, 'prerun', \&_prerun);
    NanoA::register_hook($controller, 'postrun', \&_postrun);

init_pluginの中でプラグインの初期化を行います。
NanoAにはprerunとposutrunというトリガーが用意されています。
それぞれにサブルーチンのリファレンスをトリガーに渡すことによってアプリケーションがそれぞれのタイミングでフックします。

    no strict 'refs';
    no warnings 'redefine';
    *{$controller . '::hello'} = sub {
        my $app  = shift;
        my $name = $app->query->param('name');
        return 'Hello ' . $name;
    };

NanoAでは型グロブを使うことによって動的にメソッドを生やします。
上の例で$はapp->helloというメソッドが使えるようになります。

__PACKAGE__->init_plugin(__PACKAGE__);
sub run {
    my $app = shift;
    return $app->hello;
}

NanoAではプラグイン自身もrunメソッドを書くことによってアプリケーションとして起動することが出来ます。
使い方やサンプル動作などに使うと良いでしょう。
ちなみに__PACKAGE__->init_plugin(__PACKAGE__);は自分自身をロードするおまじないです。

このようにNanoAでは極シンプルなフックポイントと単純なメソッド追加をすることによってプラグイン機構を実現しています。

NanoWikiでも全体的にスッキリさせるため意図的にプラグインを作って使っています。