Plack::Middlewareを作ってみた(Plack::Middleware::GoogleAnalytics)

理解を深めるために.元ネタはRack::GoogleAnalytics.コードはほとんどPlack::Middleware::Debugから.そのなかでいろいろ試しながら書いた.htmlなどの特定の場所にコードを差し込んだりするのは,もっといい方法があるような気もする,あるといいな

あとMiddlewareにどこまで書くのかがわからない.こんなのはアプリやテンプレートで書けばいいような気もする

(2010/02/08 スペルミス修正)

以下コード

package Plack::Middleware::GoogleAnalytics;
use strict;
use warnings;
our $VERSION = '0.01';

use parent qw( Plack::Middleware );
use Plack::Util;
use Plack::Util::Accessor qw( web_property_id );

sub call {
    my $self = shift;

    my $res = $self->app->(@_);
    $self->response_cb($res, sub {
        my $res = shift;
        my $h = Plack::Util::headers($res->[1]);
        my $content = $self->tracking_code;

        if ($h->get('Content-Type') eq 'text/html') {
            return sub {
                my $chunk = shift;
                return unless defined $chunk;
                $chunk =~ s!(?=</body>)!$content!i;
                return $chunk;
            };
        }
        $res;
    });
}

sub tracking_code {
    my $self = shift;
    my $web_property_id = $self->web_property_id;
    my $content =<<"SCRIPT";
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl."
: "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost +
"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("$web_property_id");
pageTracker._trackPageview();
} catch(err) {}</script>
SCRIPT
}

1;

こんなふうに使う.の前にGoogle Analyticsのコードが指定したweb property idとともに差し込まれる

use Plack::Builder;

$app = sub {
    return [200,
                 [ 'Content-Type' => $content_type ],
                 [ '<html><body>hello world</body></html>' ]
    ]
};

builder {
      enable 'GoogleAnalytics', web_property_id => 'UA-00000-1';
      $app;
};