Movable Type + Windows で日本語ファイル名を扱う方法

Movable Type + Windows で日本語ファイル名を扱う方法

Posted at May 22,2009 2:55 AM
Tag:[Asset, Customize, Image, MovableType, patch]

Movable Type を Windows で運用し、日本語ファイル名を扱うための方法です。ここでは Movable Type 4.25 を使ったカスタマイズを紹介します。

1.概要

Movable Type デフォルトの状態では、Window 上に構築した Movalbe Type で日本語ファイル名を扱うことはできません(仕様です)。

例えば、「コーヒーカップ.jpg」というファイルをアップロードすると、アップロード自体はできますが、アイテム一覧は次のように、アップロードした画像が表示されません(同じ画像のcoffee.jpgと比較)。画像のリンクをクリックしても 404 Not Found になります。

半角英数ファイル名の画像をクリックすると拡大画像を次のように表示できますが、

日本語ファイルでは表示されません。

サムネイルも正常に表示されません。

ブログ記事への挿入は、半角英数ファイル名であれば正常に挿入できますが、

日本語ファイルでは正常に挿入できません。

アップロードしたファイルをエクスプローラーで参照すると、次のように文字化けしています。

asset_c 配下のサムネイルやキャッシュファイルも文字化けしています。

ということで、本エントリーでは、ファイルのアップロード時にファイル名を Shift_JIS で保存し、アイテム一覧などでのファイル名操作での文字コードを修正して、日本語ファイル名を正常に処理できるようにカスタマイズする方法を以下に紹介します。

2.カスタマイズ

カスタマイズは、パッチを利用して、lib/MT 配下の4つのファイルを修正します。パッチが分からない方は、手修正できる方法も併せて掲載しています。なお、修正対象のファイルは、修正前に必ずバックアップを保存してください。

lib/MT/FileMgr/Local.pm

lib/MT/FileMgr/Local.pm を修正します。修正目的は次の通りです。

  • ファイルアップロード時の元ファイル名の文字コード変更
  • 元ファイルの削除時のファイル名の文字コード変更
--- lib/MT/FileMgr/Local.pm.bak        Fri May 22 01:48:47 2009
+++ lib/MT/FileMgr/Local.pm    Fri May 22 01:49:05 2009
@@ -12,6 +12,7 @@
 
 use Symbol;
 use Fcntl qw( :DEFAULT :flock );
+use Jcode;
 
 sub get_data {
     my $fmgr = shift;
@@ -68,6 +69,7 @@
         $perms = $cfg->HTMLPerms;
     }
     my $old = umask(oct $umask);
+    $to = jcode($to)->sjis;
     sysopen FH, $to, O_RDWR|O_CREAT|O_TRUNC, oct $perms
         or return $fmgr->error(MT->translate(
             "Opening local file '[_1]' failed: [_2]", $to, "$!"));
@@ -165,7 +167,7 @@
 sub delete {
     my $fmgr = shift;
     my ($file) = @_;
-
+    $file = jcode($file)->sjis;
     return 1 unless -e $file or -l $file;
     unlink $file
        or return $fmgr->error(MT->translate(

パッチが分からない方は下記の青色部分を追加してください。

...前略...
use Symbol;
use Fcntl qw( :DEFAULT :flock );
use Jcode;
...中略...
sub _write_file {
    my $fmgr = shift;
    my($from, $to, $type) = @_;
    local *FH;
    my($umask, $perms);
    my $cfg = MT->config;
    if ($type && $type eq 'upload') {
        $umask = $cfg->UploadUmask;
        $perms = $cfg->UploadPerms;
    } else {
        $umask = $cfg->HTMLUmask;
        $perms = $cfg->HTMLPerms;
    }
    my $old = umask(oct $umask);
    $to = jcode($to)->sjis;
    sysopen FH, $to, O_RDWR|O_CREAT|O_TRUNC, oct $perms
        or return $fmgr->error(MT->translate(
            "Opening local file '[_1]' failed: [_2]", $to, "$!"));
...中略...
sub delete {
    my $fmgr = shift;
    my ($file) = @_;
    $file = jcode($file)->sjis;
    return 1 unless -e $file or -l $file;
...後略...

lib/MT/Asset/Image.pm

lib/MT/Asset/Image.pm を修正します。修正目的は次の通りです。

  • アイテムが画像の場合、オプションでサムネイルを指定した場合など、サムネイルのファイル名の文字コード変更
--- lib/MT/Asset/Image.pm.bak  Fri May 22 01:48:42 2009
+++ lib/MT/Asset/Image.pm      Fri May 22 01:49:10 2009
@@ -8,6 +8,7 @@
 
 use strict;
 use base qw( MT::Asset );
+use Jcode;
 
 __PACKAGE__->install_properties( {
     class_type => 'image',
@@ -91,7 +92,8 @@
     my $asset     = shift;
     my (%param)   = @_;
     my $file_path = $asset->file_path;
-    my @imginfo   = stat($file_path);
+    my $file_path2 = jcode($file_path)->sjis;
+    my @imginfo   = stat($file_path2);
     return undef unless @imginfo;
 
     my $blog = $param{Blog} || $asset->blog;
@@ -153,7 +155,7 @@
 
         # create a thumbnail for this file
         require MT::Image;
-        my $img = new MT::Image( Filename => $file_path )
+        my $img = new MT::Image( Filename => $file_path2 )
           or return $asset->error( MT::Image->errstr );
 
         # Really make the image square, so our scale calculation works out.

パッチが分からない方は下記の赤色部分を削除し、青色部分を追加してください。

...前略...
use strict;
use base qw( MT::Asset );
use Jcode;
...中略...
sub thumbnail_file {
    my $asset     = shift;
    my (%param)   = @_;
    my $file_path = $asset->file_path;
    my @imginfo   = stat($file_path);
    my $file_path2 = jcode($file_path)->sjis;
    my @imginfo   = stat($file_path2);
    return undef unless @imginfo;
...中略...
    else {
 
        # create a thumbnail for this file
        require MT::Image;
        my $img = new MT::Image( Filename => $file_path )
        my $img = new MT::Image( Filename => $file_path2 )
          or return $asset->error( MT::Image->errstr );
...後略...

lib/MT/Asset.pm

lib/MT/Asset.pm を修正します。修正目的は次の通りです。

  • キャッシュファイル(asset_c 配下のサムネイル画像)の削除時のファイル名の文字コード変更
--- lib/MT/Asset.pm.bak        Thu Mar 12 05:41:04 2009
+++ lib/MT/Asset.pm    Fri May 22 01:43:30 2009
@@ -9,6 +9,7 @@
 use strict;
 use MT::Tag; # Holds MT::Taggable
 use base qw( MT::Object MT::Taggable MT::Scorable );
+use Jcode;
 
 __PACKAGE__->install_properties({
     column_defs => {
@@ -182,6 +183,7 @@
                 my $basename = $asset->file_name;
                 my $ext = '.'.$asset->file_ext;
                 $basename =~ s/$ext$//;
+                $basename = jcode($basename)->sjis;
                 my $cache_glob = File::Spec->catfile($cache_dir,
                     $basename . '-thumb-*' . $ext);
                 my @files = glob($cache_glob);

パッチが分からない方は下記の青色部分を追加してください。

...前略...
use strict;
use MT::Tag; # Holds MT::Taggable
use base qw( MT::Object MT::Taggable MT::Scorable );
use Jcode;
...中略...
sub remove_cached_files {
    my $asset = shift;
 
    # remove any asset cache files that exist for this asset
    my $blog = $asset->blog;
    if ($asset->id && $blog) {
        my $cache_dir = $asset->_make_cache_path;
        if ($cache_dir) {
            require MT::FileMgr;
            my $fmgr = $blog->file_mgr || MT::FileMgr->new('Local');
            if ($fmgr) {
                my $basename = $asset->file_name;
                my $ext = '.'.$asset->file_ext;
                $basename =~ s/$ext$//;
                $basename = jcode($basename)->sjis;
                my $cache_glob = File::Spec->catfile($cache_dir,
                    $basename . '-thumb-*' . $ext);
...後略...

lib/MT/CMS/Asset.pm

lib/MT/CMS/Asset.pm を修正します。修正目的は次の通りです。

  • アイテム一覧でアイテムを正常に取得・表示するための文字コード変更
  • title属性に日本語を適正に表示するため、文字コードをUTF-8に戻す
--- lib/MT/CMS/Asset.pm.bak    Thu Feb 05 18:49:50 2009
+++ lib/MT/CMS/Asset.pm        Fri May 22 01:44:48 2009
@@ -3,6 +3,7 @@
 use strict;
 use Symbol;
 use MT::Util qw( epoch2ts encode_url format_ts relative_date );
+use Jcode;
 
 sub edit {
     my $cb = shift;
@@ -590,10 +591,12 @@
         $row->{asset_type} = $obj->class_type;
         $row->{asset_class_label} = $obj->class_label;
         my $file_path = $obj->file_path; # has to be called to calculate
+        $file_path = jcode($file_path)->sjis;
         my $meta = $obj->metadata;
         if ( $file_path && ( -f $file_path ) ) {
             $row->{file_path} = $file_path;
             $row->{file_name} = File::Basename::basename( $file_path );
+            $row->{file_name} = jcode($row->{file_name})->utf8;
             my @stat = stat( $file_path );
             my $size = $stat[7];
             $row->{file_size} = $size;

パッチが分からない方は下記の青色部分を追加してください。

...前略...
use strict;
use Symbol;
use MT::Util qw( epoch2ts encode_url format_ts relative_date );
use Jcode;
...中略...
sub build_asset_hasher {
    my $app = shift;
    my (%param) = @_;
    my ($default_thumb_width, $default_thumb_height, $default_preview_width,
        $default_preview_height) =
        @param{qw( ThumbWidth ThumbHeight PreviewWidth PreviewHeight )};
 
    require File::Basename;
    require JSON;
    my %blogs;
    return sub {
        my ( $obj, $row, %param ) = @_;
        my ($thumb_width, $thumb_height) = @param{qw( ThumbWidth ThumbHeight )};
        $row->{id} = $obj->id;
        my $blog = $blogs{ $obj->blog_id } ||= $obj->blog;
        $row->{blog_name} = $blog ? $blog->name : '-';
        $row->{url} = $obj->url; # this has to be called to calculate
        $row->{asset_type} = $obj->class_type;
        $row->{asset_class_label} = $obj->class_label;
        my $file_path = $obj->file_path; # has to be called to calculate
        $file_path = jcode($file_path)->sjis;
        my $meta = $obj->metadata;
        if ( $file_path && ( -f $file_path ) ) {
            $row->{file_path} = $file_path;
            $row->{file_name} = File::Basename::basename( $file_path );
            $row->{file_name} = jcode($row->{file_name})->utf8;
            my @stat = stat( $file_path );
...後略...

3.修正後の動作

アイテム一覧で画像が正常に表示されます。

拡大画像も正常に表示されます。

アップロードしたファイルをエクスプローラーで参照すると、次のように日本語が適正に表示されます。

asset_c 配下のサムネイルやキャッシュファイルも適正に表示されています。

ブログ記事への挿入もOKです。

サムネイルも表示されます。

4.注意事項

  • サムネイルの拡大画像が表示されません(分かり次第追記します)。
  • 確認しているのは、テキストファイルと画像ファイルのみです。音声・動画ファイルの動作は未確認です。
  • FastCGI を利用していると正常に動作しません。
関連記事
トラックバックURL


コメント

なるほど、ここへ向かっていたわけですか。
日本語ファイルじゃなきゃ納得いかない人も、いっぱい存在しますものね。

[1] Posted by oscar logo : May 22, 2009 11:11 PM

>oscarさん
こんばんは。
はい、ここでこのシリーズは終了です。
ちなみに Linux であればデフォルトで大丈夫みたいです。

[2] Posted by yujiro logo : May 23, 2009 1:03 AM
コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)