ホーム > perl > Email::MIMEの生成をtemplateエンジン経由で行ってくれるEmail::MIME::Kitがいい感じ

Email::MIMEの生成をtemplateエンジン経由で行ってくれるEmail::MIME::Kitがいい感じ

  • 投稿者: chiba
  • 2009/7/12 日曜日 14:36:44
  • perl

Email::MIME::Kitがいい感じです。内部ではEmail::MIME::Creatorを使っているのですが、MIME::LiteでいうところのMIME::Lite::TTのようなもので、更にheaderに関してもtemplateで書けます。

素のEmail::MIME::Creatorで

use strict;
use warnings;
use utf8;

use Encode;
use Email::MIME;
use Email::MIME::Creator;
use Email::Send;
use Template;

my $t = Template->new({ENCODING => 'UTF-8'});
my $mydata = {hoge => 'aaa'};

$t->process('subject.tt', $mydata, \my $subject);
$t->process('body.tt', $mydata, \my $body);

my $mail = Email::MIME->create(
    header => [
        From    => 'chiba+from@geminium.com',
        To      => 'chiba+to@geminium.com',
        Subject => Encode::encode('MIME-Header', $subject),
    ],
    attributes => {
        content_type => 'text/plain',
        charset      => 'UTF-8',
    },
    body => $body,
);

my $sender = Email::Send->new({mailer => 'SMTP', mailer_args => [Host => 'localhost']});
$sender->send($mail);

って感じで書いてたものをEmail::MIME::Kitを使うと

use strict;
use warnings;
use utf8;

use Email::Send;
use Email::MIME::Kit;


my $sender = Email::Send->new({mailer => 'SMTP', mailer_args => [Host => 'localhost'] });

my $kit = Email::MIME::Kit->new({
    manifest_reader => 'YAML',
    source => 'mkit/',
});


$sender->send(
    $kit->assemble({
        hoge => 'fuga',
    })
);

という感じでシンプルに書けます。

mkit/manifest.yamlにはこんな感じで設定を書いておくと、body.ttが自動で読み込まれますし、headerの部分は外部ファイルにはできませんがTT書式で書けます。ここではrendererとしてTTを指定していますが、MicroMasonText::TemplateあたりはCPANにアップされています。

renderer: TT
header:
  - Subject: 'てすと[% hoge %]'
  - From: 'Masahiro Chiba <chiba+from@geminium.com>'
  - To: 'Masahiro Chiba <chiba+to@geminium.com>'
attributes:
  content_type: text/plain
  charset: UTF-8
path: body.tt

マルチバイト文字コードはUTF-8のことしかほぼ考えられてないみたいなのでISO-2022-JPじゃないとだめだーって人は自分でEmail::MIME::Kit::Role::Assemblerの継承クラスを定義するといいと思います。Mooooseなモジュールなのでモダンに書けます。

で、標準のTTのrenderでちょっと不満だったのがprocessに渡されるのがテンプレートファイルの中身のリファレンスで、これだとTTがコンパイル結果をキャッシュしてくれないんですよね。ファイル名で渡しておくとキャッシュしてくれる。なのでpathが指定されている場合はrendererにpathをそのままスルーしてくれるAssemblerを書いてみました。

package Email::MIME::Kit::Assembler::PathThrough;
use Moose;
extends 'Email::MIME::Kit::Assembler::Standard';
with 'Email::MIME::Kit::Role::Assembler';
our $VERSION = '1.00';

use Template;

override '_assemble_from_kit' => sub {
    my ($self, $stash) = @_;

    my $fullpath = File::Spec->catfile($self->kit->source, $self->manifest->{path});
    my $body_ref = $self->render($fullpath, $stash);

    my %attr = %{ $self->manifest->{attributes} || {} };
    $attr{content_type} = $attr{content_type} || 'text/plain';

    if ($$body_ref =~ /[\x80-\xff]/) {
        $attr{encoding} ||= 'quoted-printable';
        $attr{charset}  ||= 'utf-8';
    }

    my $email = $self->_contain_attachments({
        attributes => \%attr,
        header     => $self->manifest->{header},
        stash      => $stash,
        body       => $$body_ref,
        container_type => $self->manifest->{container_type},
    });
};

after '_set_renderer' => sub {
    my $self = shift;
    $self->renderer->_tt(
        Template->new({
            ABSOLUTE => 1,
            ENCODING => 'UTF-8',
        }),
    );
};

no Moose;
1;

まぁやっぱりUTF-8前提だったりします。

manifestにはこんな感じで「assembler: PathThrough」を追加しておきます。

assembler: PathThrough
renderer: TT
header:
  - Subject: 'てすと[% hoge %]'
  - From: 'Masahiro Chiba <chiba+from@geminium.com>'
  - To: 'Masahiro Chiba <chiba+to@geminium.com>'
attributes:
  content_type: text/plain
  charset: UTF-8
path: body.tt
はてなブックマーク - Email::MIMEの生成をtemplateエンジン経由で行ってくれるEmail::MIME::Kitがいい感じ

コメント:0

コメントフォーム
入力した情報を記憶する

トラックバック:0

この記事のトラックバック URL
https://blog.everqueue.com/chiba/2009/07/12/229/trackback/
トラックバックの送信元リスト
Email::MIMEの生成をtemplateエンジン経由で行ってくれるEmail::MIME::Kitがいい感じ - へぼい日記 より

ホーム > perl > Email::MIMEの生成をtemplateエンジン経由で行ってくれるEmail::MIME::Kitがいい感じ

検索
フィード
メタ情報

ページの上部に戻る