- 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を指定していますが、MicroMason、Text::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
コメント:0
トラックバック:0
- この記事のトラックバック URL
- https://blog.everqueue.com/chiba/2009/07/12/229/trackback/
- トラックバックの送信元リスト
- Email::MIMEの生成をtemplateエンジン経由で行ってくれるEmail::MIME::Kitがいい感じ - へぼい日記 より