タグ別アーカイブ: psgi

MojoliciousアプリにPlack::Middlewareをプラグインするプラグイン

レスポンスフィルター系のPlack::Middleware::*をMojoliciousのafter_dispachフックにねじ込むプラグインMojolicious-Plugin-PlackMiddlewareです。そんなニーズない?

MojoX::Tusuで古いウェブサイトを移植するとき、/mobile/なんてディレクトリがあったら、「Plack-Middleware-ForceCharset」で強制的にShift_JISで出力するとかしたい。現状でもソースでauto_detectするオプションがあるからいいんだけど、明示的にしたい。

enable_ifっぽい判定もできるようにしたので、きっとできると思う。

use MojoX::Util::ResponseFilter 'enable';

sub startup {

    my $self = shift;

    $self->plugin('plack_middleware', [
        'Plack::Middleware::Some1',
        'Plack::Middleware::Some2', {arg1 => 'some_vale'},
        'Plack::Middleware::ForceCharset', sub {
            my $c = shift;
            if (ルートが/mobile/だったら) {
                return 1;
            }
        }, {charset => 'Shift_JIS'},
    ]);
}

 

モバイル用にHTMLを圧縮するPlack::Middlewareらしきもの

HTMLソースを携帯用に圧縮するPlack::Middlewareらしきもの。スペースや改行を削除するのと、全角→半角変換などを適当にやってくれる。絵文字はできてない。

package Plack::Middleware::KetaiMinimize;
use strict;
use warnings;
use Lingua::JA::Regular::Unicode;
our $VERSION = '0.01';
use utf8;
use Encode;
use Encode::JP::Emoji;
use Encode::JP::Emoji::Property;
use base qw( Plack::Middleware );
use Plack::Util;

sub call {

    my $self = shift;
    my $res = $self->app->(@_);
    $self->response_cb($res, sub {
        my $res = shift;
        my $h = Plack::Util::headers($res->[1]);
        if ($h->get('Content-Type') =~ 'text/html') {
            return sub {
                my $chunk = shift;
                if (! defined $chunk) {
                    return;
                }
                $chunk =~ s{(rn|r|n|s)+}{ }g;
                $chunk =~ s{(^|>)([^<]+)}{
                    my $a = $1;
                    my $b = Lingua::JA::Regular::Unicode::katakana_z2h($2);
                    $b =~ tr{-}{0-9};
                    $b =~ tr{、。()!?}{、。()!?};
                    if ($b eq ' ') {
                        $a;
                    } else {
                        $a. $b;
                    }
                }ge;
                #$chunk = emoji_conv($chunk);
                return $chunk;
            };
        }
        $res;
    });
}

モバイル用Analyticsを埋め込むPlack::Middlewareらしきもの

[ Neurolab Inc. ] MainStore @ Phoen-X City, FRANCE3D Cyber City (124, 133,  1500) - General
Creative Commons License photo credit: Torley

モバイル用のGoogle Analyticsを埋め込むPlack::Middlewareらしきものをつくった。たぶん下記のようなインターフェースで動くはずだけど、ニセPSGI実装上でしかチェックしてないので、Plackで動くかどうかわからない。

なお、ga.plはGoogle Analytics公式サイトからGETしてドキュメントルートなどに設置する必要があります。

builder {
    enable 'GoogleMobileAnalytics',
    GA_ACCOUNT => 'UA-XXXXXX-1',
    GA_PIXEL => '/ga.pl';
    $app;
};
package Plack::Middleware::GoogleMobileAnalytics;
use strict;
use warnings;
our $VERSION = '0.01';
use base qw( Plack::Middleware );
use Plack::Util;
use Plack::Util::Accessor qw( GA_ACCOUNT );
use Plack::Util::Accessor qw( GA_PIXEL );
use URI::Escape;

sub call {

    my $self = shift;
    my $res = $self->app->(@_);
    $self->response_cb($res, sub {
        my $res = shift;
        my $h = Plack::Util::headers($res->[1]);
        if ($h->get('Content-Type') =~ 'text/html') {
            return sub {
                my $chunk = shift;
                if (! defined $chunk) {
                    return;
                }
                $chunk =~ s{</body>}{'<img src="' . $self->google_analytics_get_image_url() . '" /></body>'}e;
                return $chunk;
            };
        }
        $res;
    });
}

sub google_analytics_get_image_url {

    my $self = shift;
    my $url = '';
    $url .= $self->GA_PIXEL . '?';
    $url .= 'utmac=' . $self->GA_ACCOUNT;
    $url .= '&utmn=' . int(rand(0x7fffffff));
    $url .= '&utmr=' . uri_escape($ENV{'HTTP_REFERER'} || '-');
    $url .= '&utmp=' . uri_escape($ENV{'REQUEST_URI'});
    $url .= '&guid=ON';
    $url =~ s/&/&amp;/g;
    $url;
}

1;