MT5.0系で"template_setのファイナライズ中にエラーが発生しました"

久々の MovableType ネタです。
僕が使っているバージョンは 5.0 系なのですが、ある条件下でブログテーマのエクスポートを行うと必ず下記のエラーが表示されて処理に失敗します。

"template_setのファイナライズ中にエラーが発生しました"

原因は以前調べて対処したつもりだったのですが当時メモを残さなかったため、また同じエラーで同じ調査をして途中で思い出すという無駄な行為をしてしまったのでブログに記しておこうと思った次第です。

- スポンサーリンク -

ファイナライズ中のエラーが発生するパターン

テンプレートやヴィジェットテンプレートのテンプレートデータが NULL の場合(名前のみ定義されていて本文が未定義)にこのエラーが発生します。

まず解決方法。
全てのテンプレートで本文が未定義のものがないかを調査し、未定義のものがあれば半角スペースなどをいれて保存する。これだけで解決すると思います。※これ以外でエラーが出る場合があれば逆に教えて欲しいです。

ちなみに、僕の MT5 の使い方としては意外とこのエラーが発生するパターンは多くて、例えばテンプレートを変更するときの手順としてこんな感じの運用をしています。

1. 既存のテンプレートのテンプレート名を変更
2. 新しいテンプレートとして変更テンプレートを登録
3. 問題が無いことが確認できたら古いテンプレートの本文を削除
4. 次回の新しいテンプレート登録時はステップ 3 のテンプレートを書き換えて使用する

原因はステップ3にあります。本文をわざわざ未定義状態にして保存してるんですよね。
まぁこの運用をしなければすむ話ですが、phpMyAdmin などで MT のテーブル内容を直接見ることとかあり、ヘンに内部 ID が増えていくのが気持ち悪い&記憶が追いつかないので、こんな運用を取っています。

で最近は本文に半角スペースを入れて対処していたはずなのですが、見た目が未定義と同じなので、いつの間にか運用方法を忘れて未定義状態でクリアしてしまっていました。

そもそもの原因は lib/MT/Theme/TemplateSet.pm のコードが悪いんです。このコードでは本文が未定義の場合にエラーになってしまいます。

sub finalize {
    my $app = shift;
    my ( $blog, $theme_hash, $tmpdir, $setting ) = @_;
    my $ts_hash = $theme_hash->{elements}{template_set}
        or return 1;
    my $templates = $ts_hash->{data}{objs};
    delete $ts_hash->{data}{objs};

    require MT::FileMgr;
    require File::Spec;
    my $fmgr = MT::FileMgr->new('Local');
    my $outdir = File::Spec->catdir( $tmpdir, 'templates' );
    $fmgr->mkpath( $outdir )
        or return $app->error(
            $app->translate(
                'Failed to make templates directory: [_1]',
                $fmgr->errstr,
        ));
    for my $t (@$templates) {
        my $tmpl_id = $t->identifier || 'template_' . $t->id;
        my $path = File::Spec->catfile( $outdir, $tmpl_id . '.mtml' );
        $fmgr->put_data( $t->text || '', $path )
            or return $app->error(
                $app->translate(
                    #'Failed to publish template file: [_1]',
                    "Failed to publish template " . $t->id . ": file: [_1]",
                    $fmgr->errstr,
            ));
    }
    return 1;
}

最新の Movabletype 5.12 では不具合該当箇所のコードに修正が加えられているのでバグフィックスされているように見えますが未確認です。put_data関数が本文未定義の時に undef を返すのか "" を返すのかコードを深追いしていないので分かりかねますが、もし undef を返すなら下記コードでもだめでしょう。

    for my $t (@$templates) {
        my $tmpl_id = $t->identifier || 'template_' . $t->id;
        my $path = File::Spec->catfile( $outdir, $tmpl_id . '.mtml' );
        defined $fmgr->put_data( $t->text, $path )
            or return $app->error(
            $app->translate(
                'Failed to publish template file: [_1]',
                $fmgr->errstr,
            )
            );
    }

ちなみに僕のお手製修正コードはこんな感じにして patch を当てて運用しています。半角スペースなら何ら影響を及ぼさないので、本分未定義の場合には半角スペースと読み替える処理にしています。

    for my $t (@$templates) {
        my $tmpl_id = $t->identifier || 'template_' . $t->id;
        my $path = File::Spec->catfile( $outdir, $tmpl_id . '.mtml' );
        $fmgr->put_data( $t->text || ' ', $path )
            or return $app->error(
                $app->translate(
                    #'Failed to publish template file: [_1]',
                    "Failed to publish template " . $t->id . ": file: [_1]",
                    $fmgr->errstr,
            ));
    }
- スポンサーリンク -