Tag: Mojolicious



2016年 12月 7

PerlのWebApplicationFrameworkであるMojoliciousでは様々なフックが用意されているのだけれど、actionの前後だけに実行したい場合は独自にフックポイントを追加しないといけない。

実装方法その1

一番単純な実装方法はaround_actionフックを使うのが良さそう。actionは$lastフラグが真の時に実行されるので前後に独自のフックをエミットする。

sub startup {
    my $self = shift;
    ...

    $self->hook(
        around_action => sub {
            my ( $next, $c, $action, $last ) = @_;
            return $next->() unless $last;

            # before_actionフックを実行
            $c->app->plugins->emit_hook( before_action => $c );

            # Controller::Actionを実行
            $c->$action();

            # after_actionフックを実行
            $c->app->plugins->emit_hook( after_action => $c );
        }
    );
}

このフックを使えば動的ページのみでフックを実行できる。session関連の操作とかに便利。

実装方法その2

上記のコードの場合は全てのactionに適用されてしまうので、フックを実行したくないcontrollerを作りたい場合はMojolicious::Controllerを継承したclassを作る事で実現できる。

# App
sub startup {
    my $self = shift;
    ...

    $self->hook(
        around_action => sub {
            my ( $next, $c, $action, $last ) = @_;
            return $next->() unless $last;

            $c->process($action);
        }
    );
}
# フックを使用するbase class
package MyApp::Controller;
use Mojo::Base 'Mojolicious::Controller';

sub process {
    my ( $c, $action ) = @_;
    $c->before();
    $c->action();
    $c->after();
}

sub before {
    my $c = shift;
    $c->app->plugins->emit_hook( before_action => $c );
}

sub after {
    my $c = shift;
    $c->app->plugins->emit_hook( after_action => $c );
}

1;
# フックを使用しない base class
package MyApp::NoHookController;
use Mojo::Base 'Mojolicious::Controller';

sub process {
    my ( $c, $action ) = @_;
    $c->action();
}

1;
# フックを使うcontroller
package MyApp::Controller::Fizz;
use Mojo::Base 'MyApp::Controller';

...


# フックを使わないcontroller
package MyApp::Controller::Buzz;
use Mojo::Base 'MyApp::NoHookController';

...

before/after_actionフックを使う場合はMyApp::Controllerを継承したcontrollerを作り、使わない場合はMyApp::NoHookControllerを継承したcontrollerにする。


Filed under: Mojolicious,perl

Trackback Uri






2016年 8月 25

Mojolicious::Plugin::LocaleTextDomainOO – I18N(GNU getext) for Mojolicious. – metacpan.org

きっかけ

Mojolicousで国際化するプラグインにはMojolicous::Plugin::I18Nというものがある。これは良く出来ていて、URLやドメイン名での振り分けが出来たりする。

国際化の部分はLocale::Maketextを使う。Locale::Maketext::Lexiconも使えばpoファイルなどもつかえる。

普通に使う分なら問題ないのだけど、GNU gettextのmsgctxttext domainのようなことは出来ない。

CPANをいろいろ漁ってみて、gettextコンバーチブルなモジュールでLocale::TextDomain::OOってのが自分の要件に合いそうなのでこちらをMojoliciousで使えるようにしてみた。

手順

Perl Moduleの作成にはMinillaを使った。MojoliciousプラグインをMinillaで開発する手順は別エントリーに書いた。

Minillaを使ってMojoliciousプラグインを開発する

PAUSEアカウントを取得

注意点は各エントリー等に書いてある通り。一番悩むのはA short description of why you would like a PAUSE ID:というPAUSEの申請理由でした。

長くかかる場合もあるみたいだけど、自分の場合はその日のうちに返信来ていました。

Minilla release

MinillaでCPANにアップロードする方法はCPAN に姉を公開した話とかを参考に。

モジュール開発で一番大変なのはドキュメントの作成。恐らく通じないであろう英語で書かなくてはならないのツラい。ま、コード載せておけば半分くらいつたわる、はず。

あと、cpanfile.snapshotの扱いをどうすればよいかが分からない。他のモジュール見て回ると一緒にパッケージングされていないので.gitignoreに書いておいたけど、この方法で良いか不明。

失敗談

Mojolicous::Plugin::I18N の機能はそのまま使いたかったのでパッケージに含めてアップロードしたらネームスペースの権限に引っかかってしまった。おれおれモジュールの場合には問題ない事(?)だったので注意したい。

おそらくはそれさえも平凡な日々: CPANで意図しない名前空間の取得を防ぐために

懸念点

Locale::TextDomain::OOは、Mooベースだし、結構依存が多い。Cartonでパッケージ管理しているなら特に問題ないのかな。

雑感

  • とにかくモジュール開発にはMinilla(やDist::Milla)が大変便利。
  • CPANに公開するとなるとそれなりにテストやドキュメントを整備しなくてはいけないので大変な反面、とても勉強になる。
  • いろいろ試行錯誤したけど、それも勉強になる。

と、どれをとっても勉強になるので是非挑戦して頂きたい。


Filed under: perl,プログラミング

Trackback Uri






2016年 8月 21

プラグインとしては Mojolicious::Plugin::Mount  がある。短いコードなの読むと参考になる。

Mojoliciouアプリを埋め込む


追記:Mojolicious::Commandsを使う方法があるらしい。こっちの方が正統?

$app->routes->any( '/sub' )->detour(
    app => Mojolicious::Commands->start_app('SubApp') 
);

Mojolicious::Liteのアプリをマウントする方法は日本語だと Mojolicious::Guides::Routing に書いてある。

この方法を使ってMojoliciousアプリ(Liteではない)を埋め込む場合は、下記コードのようにMojo::Serverを使えば出来る。

# SubApp が Mojolicous::Liteの場合
$app->routes->any('/sub')->detour(app => SubApp::app());

# SubApp が Mojoliciousの場合
my $sub_app = Mojo::Server->new->build_app('SubApp');
$app->routes->any('/sub')->detour(app => $sub_app);

MyAppにSubAppを埋め込むだけの簡単なコードだとこんな感じ。

package MyApp;
use Mojo::Base 'Mojolicious';

# Route
sub startup {
    my $self = shift;
    my $app = $self->app;

    # Main route
    $self->routes->get('/')->to('foo#hello');

    # SubApp route
    my $sub_app = Mojo::Server->new->build_app('SubApp');
    $app->routes->any('/sub')->detour(app => $sub_app);
}

# Controller
package MyApp::Controller::Foo;
use Mojo::Base 'Mojolicious::Controller';

# Action
sub hello {
    my $self = shift;
    $self->render(text => 'Hello MyApp!');
}

# Sub App
package SubApp;
use Mojo::Base 'Mojolicious';

# Route
sub startup {
    my $self = shift;
    $self->routes->get('/')->to('foo#hello');
}

# Controller
package SubApp::Controller::Foo;
use Mojo::Base 'Mojolicious::Controller';

# Action
sub hello {
    my $self = shift;
    $self->render(text => 'Hello SubApp!');
}


# /    -> Hello MyApp!
# /sub -> Hello SubApp!

アプリケーションプラグイン

上記コードを使えば、Mojoliciousアプリでも自身を含めた再利用可能なプラグイン アプリケーションプラグイン のような事も出来るはず。

package Mojolicious::Plugin::EmbeddedSubApp;
use Mojo::Base 'Mojolicious::Plugin';

sub register {
    my ($self, $app) = @_;

    # ルートを追加
    my $sub_app = Mojo::Server->new->build_app('SubApp');
    $app->routes->any('/sub')->detour(app => $sub_app);
}

# Sub App
package SubApp;
use Mojo::Base 'Mojolicious';

# Route
sub startup {
    my $self = shift;
    $self->routes->get('/')->to('foo#hello');
}

# Controller
package SubApp::Controller::Foo;
use Mojo::Base 'Mojolicious::Controller';

# Action
sub hello {
    my $self = shift;
    $self->render(text => 'Hello SubApp!');
}

1;

アプリケーションでプラグインをロードする

package MyApp;
use Mojo::Base 'Mojolicious';

sub startup {
    my $self = shift;

    # プラグイン
    $self->plugin('EmbeddedSubApp');
}

1;

リンク


Filed under: perl

Trackback Uri






2016年 8月 16

1. Mojoliciousプラグインの雛形作成

$ mojo generate plugin MyPlugin

カレントディレクトリに Mojolicious-Plugin-MyPlugin というディレクトリ名で雛形作成される。

2. ドキュメントにAuthor情報を追記する。

$ cd ./Mojolicious-Plugin-MyPlugin
$ vi lib/MyPlugin.pm

minillaではPODに書かれているAuthorが使われる。作成された雛形(MyPlugin.pm)のPODにはAuthorの項目がないので追記する。

vi lib/Mojolicious/Plugin/MyPlugin.pm

...

=head1 AUTHOR

Lastname Firstname <name@domain.com>

=head1 SEE ALSO

....

3. Minilizeする

$ minil migrate

minillaで必要なファイルが作成される。

3.5 Makefileを削除

Makefileは必要ないファイルなので削除する。

$ rm -f ./Makefile

※このファイルがあるとCPANにアップロードした時に

no_generated_files
Remove the offending files/directories!

とおこられるみたい。

4. commitする

$ git add -A
$ git commit -m'initial commit'

まずは全てをコミットしておく。開発準備完了。

5. バリバリ開発する

あとはもりもり開発をすすめる


Filed under: Mojolicious,perl

Trackback Uri






2014年 9月 8

MojoliciousでHTTP(S)の振り分けをリバースプロキシのバックエンドでも出来るようにしてみる
が、さいきんのバーションでは変更があったらしくmojoliciousをばーじょんあっぷしたらうごかない。

こちらのGistが参考になる。
「MojoliciousでHTTP(S)の振り分けをリバースプロキシのバックエンドでも出来るようにしてみる」の例(Apache + mod_proxy)

抜粋すると、

proxy_set_header X-Forwarded-HTTPS
ではなく、

proxy_set_header X-Forwarded-Proto $scheme;
がひつよう(になったらしい)

追記リンク:
MojoliciousのリバースプロキシのSSLの検知方法が変わります – サンプルコードによるPerl入門


Filed under: Mojolicious,perl

Trackback Uri