- 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がいい感じ - へぼい日記 より