b2evolution 1.8.1 の日本語周りの改造
b2evolution 1.8.1 "Milestone"が出ています。Release Candidate(リリース候補版)なのでバグがあるかもしれませんが、それなりに安定しているらしいです。
(2006年9月6日追記:UTF-8絡みの問題が意外と多いようなので、日本語環境では思ったより安定していないかも)
内部的に大幅な変更が加えられているので、アップグレードする時は、事前にデータベースとファイルのバックアップをきちんととって、問題が起こっても元に戻せるようにしておいたほうがいいと思います。
この記事は、b2evolution の日本語周りの問題対策の改造に関するメモです。
従来の0.9.x系に施していた改造をとりあえず当てはめただけで、テストが不十分な部分があります。問題が起こるようでしたら報せてください。必ずしも対応できるとは限りませんが、努力はしたいと思います。
b2evolution は適切な設定を選択すれば、そのままで使ってもそれなりに日本語が使えます。
しかし、ブックマークレット、文字セットの違うブログとのトラックバック送受信、コメント等があった際の通知メールの文字コード処理などで問題が発生する可能性があります。ここではこれらの問題への対処を記しておきます。
さらに、メールでブログに記事を投稿する機能にも、おそらく問題があって正常に書き込めないと思います。これは、私は今のところ使う予定の無い機能ですので、どなたかが調査してくださると嬉しいです。
バージョン1.8.1について、私が行った対処を書いておきます。
他の環境、特にMySQL 4.1.x以降の環境でも通用するかは不明です。
(2006年8月27日追記:管理画面の一部でエラーが出ていたので、改造差し替えファイルのアーカイブに同梱している日本語メッセージ・ファイルを修正・更新しました。)
(2006年8月30日追記:「通知メール」の変更の改良と、日本語メッセージ・ファイルの誤訳の修正。b2evolution 1.8.1本体の既知の問題のうち影響の大きそうな部分の修正として、管理画面(backoffice)でContent-Typeヘッダのcharset指定が送信されない問題の対策と、8月27日追記のエラーの原因の回避策)
(2006年9月6日追記:ウェブブラウザの言語設定によっては文字化けすることがある問題の対処として、「デフォルト文字セット」を追加しました。)
簡単に変更が行えるように差し替えファイルをまとめたアーカイブ・ファイルを用意しました。
バージョン1.8.1用に作った日本語メッセージ・ファイルもアーカイブ内に同梱してあります (b2evolution/blogs/locales/ja_JP/_global.php
)。どうぞ、ご活用ください。
b2evolution-1.8.1-japanese-patch2006-09-06.zip
(ファイル・サイズ: 141,894 byte)(このXREA.COM無料サーバからのファイルのダウンロードは、混み合う時間帯には特に、途中で中断してしまう場合がありますので、ダウンロード後にファイル・サイズを確認して、もしサイズが小さい場合はダウンロードしなおしてみてください)
このアーカイブ内には、b2evolution の配布アーカイブのディレクトリ構造に対応した配置でファイルが収められていますので、展開した後、b2evolution の対応したファイルと置き換えてください。
なお「マルチバイト関数が使えない環境での対策」は含めていませんので、ご注意ください。
また、「通知メール」の変更は日本語限定ISO-2022-JP使用の対処のほうを使用していますので、言語汎用の対処を使用したい方は「通知メール」の項目をご覧になって、変更を行ってください。
注意事項:この後記述する変更点で、追加の際に示す目印となる行は区別の付けやすさで選んでいますので、追加する位置の指定は目印の前と後とが混在しています。ご注意ください。
- デフォルトのメッセージを日本語にする
-
インストールの際に、インストールページで最初に「Japanese (JP)」(日本語 (JP))のリンクを使って言語を日本語に指定しておくと、ブログやユーザのデフォルトの言語が日本語になり、後の設定が楽になりますので、「Japanese (JP)」(日本語 (JP))の選択を行ってください。
もし、インストール時に日本語(Japanese)以外の言語を指定していた場合、ブログ設定とユーザ設定の言語・地域設定(Locale)が「日本語」(Japanese)になっていないと思われます。
その状態では、日本語の投稿の書き込みがうまくいきませんので、管理画面の「ブログ設定」と「ユーザ」の2ヶ所でそれぞれ設定してください。(また、過去に管理画面の「アプリケーション設定 : 地域」で設定を変更していた場合、「アプリケーション設定 : 地域」ページの下のほうに「デフォルトにリセット (データベース テーブルを削除)」リンクが表示されています。この状態では
blogs/conf/_locales.php
の更新が反映されませんので、「デフォルトにリセット (データベース テーブルを削除)」でリセットを行ってください。なお、通常の使い方では「アプリケーション設定 : 地域」の設定を変更する必要はありませんので、リセット後はデフォルトそのままにしておいてください) - デフォルト文字セット
-
ログインしていないユーザ(非登録の訪問者含む)のアクセス時に、ウェブブラウザの言語設定(Accept-Language: ヘッダの指定内容)によっては、日本語のブログであっても、内部文字セットが ISO-8859-1 など不適切な扱いになってしまい、文字化けが起こることがあります。
なお、これは本質的な修正ではなく、日本語(UTF-8)環境での問題を回避するだけの対処になりますのでご注意ください。
blogs/conf/_locales.php
の40行目、$evo_charset = '';
を
$evo_charset = 'utf-8';
に変更します。
- ブックマークレット
-
ブックマークレットの問題は、ブックマークレットのJavaScriptで
escape()
が用いられていることが原因です(Mozilla用のサイドバーでも同様の問題があります)。encodeURIComponent()
を使用するように変更します。(欧文のみの環境ですと、escape()
のほうが問題が少ないようです。しかし日本語等、UTF-8を使用する場合ではencodeURIComponent()
のほうが無難です)blogs/plugins/_bookmarklet.plugin.php
の62行目、70行目、79行目、87行目の各行と、blogs/plugins/_sidebar.plugin.php
の79行目に、3個もしくは2個ずつあるescape(
を
encodeURIComponent(
に置き換えます。
この変更を行った後に、お気に入り/ブックマーク/サイドバーへのブックマークレットの登録を行ってください。
(
blogs/plugins/_bookmarklet.plugin.php
,blogs/plugins/_sidebar.plugin.php
を書き換えるより、ブラウザのお気に入り/ブックマーク/サイドバーに登録したブックマークレットURI / サイドバーURIを、後から変更(escape
をencodeURIComponent
に置き換え)したほうが簡単かもしれません。楽だと思うほうでやってみてください) - 通知メール
-
通知メール周りの改造について、日本語限定の対処と、言語に限定されない対処を切り替えれるようにしてあります。
変更点の中で、最初のほうに
$want_to_use_iso2022jp = 1;
という部分があります(変更後の行数で2002行目)。この= 1;
の数字を変えることで切り替えが可能です。$want_to_use_iso2022jp = 1;
のままにしておくと、日本語限定でメール出力の文字セットをISO-2022-JPにする対処方法になります。携帯電話や古い仕様のメーラーで通知メールを受け取る場合は、こちらの方法がいいと思います。この場合でも、日本語以外の設定になっているブログにおいては、文字化けや文字落ちを防ぐため、次の言語汎用の対処方法が用いられます。$want_to_use_iso2022jp = 0;
と数字を0
に変えると、言語汎用の対処方法になります。古い仕様のメーラーでは受信した文字コードを変換できなくて文字化けするなど、メールの受信環境によっては問題が起きる可能性もあります。blogs/inc/_misc/_misc.funcs.php
の2001行目の$NL = "\n";
という部分の前に、
// If you want to send a mail of ISO-2022-JP charset when the locale is ja_JP, set $want_to_use_iso2022jp to 1. If not, set $want_to_use_iso2022jp to 0. $want_to_use_iso2022jp = 1; if ( ($want_to_use_iso2022jp == 1) && ($current_locale == 'ja-JP') ) $use_iso2022jp = 1; else $use_iso2022jp = 0;
という8行を追加します。
次に、
blogs/inc/_misc/_misc.funcs.php
の2014行目(前述の変更をする前の行数。変更後は2022行目)、$headers['Content-Type'] = 'text/plain; charset='.$current_charset;
を
if ( $use_iso2022jp != 1 ) { $headers['Content-Type'] = 'text/plain; charset='.$current_charset; }
に変更します。
blogs/inc/_misc/_misc.funcs.php
の2046行目(前述の変更をする前の行数。変更後は2056行目)の$headers['From'] = $from; }
を
if ( function_exists('mb_encode_mimeheader') ) { $fromarray = array(); preg_match('/^(.*?)( <([^<>]+)>)?$/', $from, $fromarray); if ($use_iso2022jp == 1) { $fromarray[1] = mb_encode_mimeheader( mb_convert_encoding( $fromarray[1], 'ISO-2022-JP', mb_internal_encoding() ), 'ISO-2022-JP', 'B', $NL ); if ( $fromarray[3] != '' ) { if ( preg_match('/[^ -~]/', $fromarray[3]) ) { $fromarray[3] = mb_encode_mimeheader( mb_convert_encoding( $fromarray[3], 'ISO-2022-JP', mb_internal_encoding() ), 'ISO-2022-JP', 'B', $NL ); } $fromarray[3] = ' <' . $fromarray[3] . '>'; } $from = $fromarray[1] . $fromarray[3]; } else { $fromarray[1] = mb_encode_mimeheader( $fromarray[1], mb_internal_encoding(), 'B', $NL ); if ( $fromarray[3] != '' ) { if ( preg_match('/[^ -~]/', $fromarray[3]) ) { $fromarray[3] = mb_encode_mimeheader( $fromarray[3], mb_internal_encoding(), 'B', $NL ); } $fromarray[3] = ' <' . $fromarray[3] . '>'; } $from = $fromarray[1] . $fromarray[3]; $headers['MIME-Version'] = '1.0'; } } $headers['From'] = $from; } if( function_exists('mb_encode_mimeheader') && ($use_iso2022jp != 1) ) { // encode subject $subject = mb_encode_mimeheader( $subject, mb_internal_encoding(), 'B', $NL ); $headers['MIME-Version'] = '1.0'; }
に変更します。
blogs/inc/_misc/_misc.funcs.php
の2056行目(前述の変更をする前の行数。変更後は2109行目)のif( function_exists('mb_encode_mimeheader') ) { // encode subject $subject = mb_encode_mimeheader( $subject, mb_internal_encoding(), 'B', $NL ); } $message = str_replace( array( "\r\n", "\r" ), $NL, $message ); if( $debug > 1 ) { // We agree to die for debugging... if( ! mail( $to, $subject, $message, $headerstring ) ) { debug_die( 'Sending mail from «'.htmlspecialchars($from).'» to «'.htmlspecialchars($to).'», Subject «'.htmlspecialchars($subject).'» FAILED.' ); } } else { // Soft debugging only.... if( ! @mail( $to, $subject, $message, $headerstring ) ) { $Debuglog->add( 'Sending mail from «'.htmlspecialchars($from).'» to «'.htmlspecialchars($to).'», Subject «'.htmlspecialchars($subject).'» FAILED.' ); return false; } }
を
$message = str_replace( array( "\r\n", "\r" ), $NL, $message ); if ( ($use_iso2022jp == 1) && function_exists(mb_send_mail) ) { mb_language('Japanese'); mb_detect_order( $current_charset ); if( $debug > 1 ) { // We agree to die for debugging... if( ! mb_send_mail( $to, $subject, $message, $headerstring ) ) { debug_die( 'Sending mail from «'.htmlspecialchars($from).'» to «'.htmlspecialchars($to).'», Subject «'.htmlspecialchars($subject).'» FAILED.' ); } } else { // Soft debugging only.... if( ! @mb_send_mail( $to, $subject, $message, $headerstring ) ) { $Debuglog->add( 'Sending mail from «'.htmlspecialchars($from).'» to «'.htmlspecialchars($to).'», Subject «'.htmlspecialchars($subject).'» FAILED.' ); return false; } } } else { if( $debug > 1 ) { // We agree to die for debugging... if( ! mail( $to, $subject, $message, $headerstring ) ) { debug_die( 'Sending mail from «'.htmlspecialchars($from).'» to «'.htmlspecialchars($to).'», Subject «'.htmlspecialchars($subject).'» FAILED.' ); } } else { // Soft debugging only.... if( ! @mail( $to, $subject, $message, $headerstring ) ) { $Debuglog->add( 'Sending mail from «'.htmlspecialchars($from).'» to «'.htmlspecialchars($to).'», Subject «'.htmlspecialchars($subject).'» FAILED.' ); return false; } } }
に変更します。
- トラックバック
-
b2evolutionのトラックバック機能は、相手が同じ文字セットを使用していることを前提に作られていますので、文字セットの違うブログとのトラックバックのやり取りで文字化けを起こす可能性があります。文字セットUTF-8、EUC-JP、Shift_JISが混在する日本語のブログ間では起こりやすい問題ですので、それを防ぐための対策を施します。
送信に関しては、トラックバックの仕様 TrackBack Technical Specification Version 1.2 で導入された、POSTリクエスト・ヘッダへの charset 記載を行うようにします。加えて、日本の一部で独自に使用されているパラメータ
charset
も使用します。blogs/inc/_misc/_trackback.funcs.php
の89行目の$query_string = "title=$title&url=$url&blog_name=$blog_name&excerpt=$excerpt";
を
$charset = urlencode( locale_charset(false) ); $query_string = "title=$title&url=$url&blog_name=$blog_name&excerpt=$excerpt&charset=$charset";
に変更します。同じく、
blogs/inc/_misc/_trackback.funcs.php
の125行目(これは前述の変更を行う前の行数です。変更後なら126行目)の$http_request .= 'Content-Type: application/x-www-form-urlencoded'."\r\n";
を
$http_request .= 'Content-Type: application/x-www-form-urlencoded; charset='.$charset."\r\n";
に変更します。
次に、トラックバック受信に関してですが、文字セットの自動判別を行うほうが安心ではあるものの、PHPのマルチバイト関数(mbstring)の自動判別機能は、日本語以外の判別に関しては実用的ではありません。そのため、日本語の場合のみ自動判別を用いるようにしておきます。
/htsrv/trackback.php
の108行目の$title = strip_tags($title);
の前に、
param( 'charset', 'string', NULL ); if ( ($_SERVER['CONTENT_TYPE'] != '') && ($charset == '') ) { $request_header_content_type = array(); preg_match( '/;[ \r\n\t]*charset="?([A-Za-z0-9_\-]+)/i', $_SERVER['CONTENT_TYPE'], $request_header_content_type ); if ( $request_header_content_type[1] != '' ) $charset = $request_header_content_type[1]; } locale_temp_switch( get_bloginfo('locale', $blogparams) ); if ( ($charset != '') && function_exists('iconv') ) { $to_charset = locale_charset(false); $title = iconv( $charset, $to_charset, $title ); $excerpt = iconv( $charset, $to_charset, $excerpt ); $blog_name = iconv( $charset, $to_charset, $blog_name ); } elseif ( function_exists('mb_convert_encoding') ) { if ( ($charset == '') && ( locale_lang(false) == 'ja-JP') ) { $charset = mb_detect_encoding( $title . $excerpt . $blog_name, 'ASCII,JIS,UTF-8,EUC-JP,SJIS'); } if ( $charset != '' ) { $to_charset = locale_charset(false); $title = mb_convert_encoding( $title, $to_charset, $charset ); $excerpt = mb_convert_encoding( $excerpt, $to_charset, $charset ); $blog_name = mb_convert_encoding( $blog_name, $to_charset, $charset ); } } locale_restore_previous();
を追加します。
- 経由検索エンジンのキーワード
-
統計の検索エンジン経由アクセスの使用キーワード表示が日本語に対応していませんので、その文字化け対策です。設定が日本語になっている場合限定で、文字コードの自動判別も行います。日本語に関しては検索キーワード表示の文字化けがほぼ無くなります。
blogs/inc/MODEL/sessions/_hitlog.funcs.php
の315行目、return htmlentities($kwout);
を
$kwout = str_replace("\x00", '', $kwout); return htmlspecialchars($kwout);
に変更します。
(変更点の$kwout = str_replace("\x00", '', $kwout);
の1行は、XREA.COM無料サービスの自動広告挿入機能が NULL を適切に処理できないので加えています。他の環境、特に自動広告挿入がない環境では必要ないはずですので、この1行は外していただいても大丈夫だと思います)同じ
blogs/inc/MODEL/sessions/_hitlog.funcs.php
の304行目、if( strpos( $q, 'Ã' ) !== false )
(環境・設定によっては
'Ã'
(0xC3) の文字がこの字形でなく、'テ'
などと表示される場合もあります)
の部分を、if ( ( locale_charset(false) == 'iso-8859-1' ) && ( strpos( $q, "\xC3" ) !== false ) )
に変更します。
次に、
blogs/inc/MODEL/sessions/_hitlog.funcs.php
の309行目、$qwords = explode( ' ', $q );
の前に、
else if( ( locale_lang(false) == 'ja-JP' ) && function_exists('mb_convert_encoding') ) { $q = mb_convert_encoding($q, locale_charset(false), 'ASCII,JIS,UTF-8,EUC-JP,SJIS'); }
を追加します。
- 年月などの表示
-
日毎表示のタイトル部分、アーカイブ一覧の年月表示、カレンダーの年月表示では、日本語で一般的な語順でなく、「1月 2005, 24」や「1月 2005」のような表示になってしまいます。これを日本語らしい形式にする変更です。
(少々手間がかかるわりに、ありがたみの薄い改造ですので、面倒であればしなくていいと思います)
日毎表示・月毎表示などのタイトル部分。
blogs/inc/_misc/_template.funcs.php
の174行目、$arch = T_('Archives for').': '.$my_month.' '.$my_year; if( !empty( $my_day ) ) { // We also want to display a day $arch .= ", $my_day"; } if( !empty($w) && ($w>=0) ) // Note: week # can be 0 { // We also want to display a week number $arch .= ", week $w"; }
を、
if (locale_lang(false) == 'ja-JP') { $arch = T_('Archives for').': '.$my_year.'年'.$my_month; if( !empty( $my_day ) ) { // We also want to display a day $arch .= $my_day.'日'; } if( !empty($w) && ($w>=0) ) // Note: week # can be 0 { // We also want to display a week number $arch .= ', 第'.$w.'週'; } } else { $arch = T_('Archives for').': '.$my_month.' '.$my_year; if( !empty( $my_day ) ) { // We also want to display a day $arch .= ", $my_day"; } if( !empty($w) && ($w>=0) ) // Note: week # can be 0 { // We also want to display a week number $arch .= ", week $w"; } }
に変更します。
次に、
blogs/inc/_misc/_obsolete092.php
の1310行目、$title = $prefix.$my_month.' '.$my_year; if( !empty( $my_day ) ) { // We also want to display a day $title .= ", $my_day"; } if( !empty($w) && ($w>=0) ) // Note: week # can be 0 { // We also want to display a week number $title .= ", week $w"; }
を、
if (locale_lang(false) == 'ja-JP') { $title = $prefix.$my_year.'年'.$my_month; if( !empty( $my_day ) ) { // We also want to display a day $title .= $my_day.'日'; } if( !empty($w) && ($w>=0) ) // Note: week # can be 0 { // We also want to display a week number $title .= ', 第'.$w.'週'; } } else { $title = $prefix.$my_month.' '.$my_year; if( !empty( $my_day ) ) { // We also want to display a day $title .= ", $my_day"; } if( !empty($w) && ($w>=0) ) // Note: week # can be 0 { // We also want to display a week number $title .= ", week $w"; } }
に変更します。
アーカイブ一覧の部分。
blogs/plugins/_archives.plugin.php
の184行目、echo T_($month[zeroise($arc_month,2)]),' ',$arc_year;
を
if (locale_lang(false) == 'ja-JP') { echo $arc_year,'年',T_($month[zeroise($arc_month,2)]); } else { echo T_($month[zeroise($arc_month,2)]),' ',$arc_year; }
に変更します。
カレンダーの部分。
blogs/plugins/_calendar.plugin.php
の353行目、$this->monthformat = 'F Y';
を、
if (locale_lang(false) == 'ja-JP') $this->monthformat = 'Y年F'; else $this->monthformat = 'F Y';
に変更します。
- 管理画面でcharset指定が送信されない問題
-
これは日本語対応に限らず、b2evolution本体の既知の問題の対策です。管理画面(backoffice)でContent-Typeヘッダのcharset指定が送信されておらず、まれにブラウザが自動判定に失敗して文字化けする問題の修正を試みます。
blogs/inc/VIEW/_menutop.php
の38行目、if( !empty($generating_static) )
を
if( empty($generating_static) )
に変更します。
- UTF-8のメッセージ・ファイル使用時に管理画面の一部で発生するエラー対策
-
これも日本語対応に限らず、b2evolution本体の既知の問題の対策です。管理画面(backoffice)で、機能アイコン画像等を表示するために特殊な文字列置き換えとPHPコード実行処理が行われる際に、UTF-8のメッセージ・ファイル(日本語等)で定義される文字列の一部が誤って置き換え対象となり、エラーを引き起こす問題の回避策です。(これは完全な対処とは言えませんので、まだ条件が重なるとエラーが発生する可能性もわずかですが残っています)
注意:対象ファイル
blogs/inc/_misc/_results.class.php
を編集する際は、特殊な文字が含まれているため、できれば西ヨーロッパ言語 (ISO-8859-1) を編集可能なエディタを使用することをお勧めします。blogs/inc/_misc/_results.class.php
の1605行目、// Sometimes we need embedded function call, so we provide a second sign: $content = preg_replace( '#¤ (.+?) ¤#ix', "'.$1.'", $content );
を(“¤” (0xA4) は環境によっては “、” など別の字形で表示されます)、
// Sometimes we need embedded function call, so we provide a second sign: $content = preg_replace( '#¤ ([\t -~].*?[\t -~]) ¤#ix', "'.$1.'", $content );
に変更します。(“¤” (0xA4) が “、” など別の字形で表示されている環境では、その環境に合わせて 0xA4 を入力してください)
- マルチバイト関数が使えない環境での対策
-
海外のレンタルサーバなどでは、マルチバイト関数(mbstring)(
mb_
で始まる関数)が用意されていない場合があります。
Andy氏が作られた mbstringエミュレータ for Japanese を使うことで、対応しているのはほぼ日本語で用いられる文字セット限定ですが、マルチバイト関数が使えない環境でも、主要なmb_*
関数が使えるようになります。注意:マルチバイト関数(mbstring) が使える環境では、この変更を行う必要はありません。
まず、
blogs/inc/
ディレクトリにmb-emulator
という名前のディレクトリを作ります。次に、ダウンロードしたmbstringエミュレータのアーカイブファイルを展開して、出てきたファイル全てを、そのディレクトリ
blogs/inc/mb-emulator/
内に置きます。最後に、
blogs/conf/
ディレクトリにhacks.php
という名前のファイルを作ります。hacks.php
の内容は次の通りです。(すでにblogs/conf/hacks.php
がある場合は、適切に内容を追加してください。)<?php if (!extension_loaded('mbstring')) { require_once $inc_path.'mb-emulator/mb-emulator.php'; } ?>
内容の前後(
<?php
の前、?>
の後)に余分な改行を入れないよう注意してください。
2 コメント
コメント from: Jun MUTO メンバー
文字化けの指摘、ありがとうございました。
おっとぉさんの環境が特殊ということはないと思います。
例えば、WindowsのIE日本語版のデフォルト設定では文字化けしないはずですが、Mozilla Firefox日本語版のデフォルト設定だと文字化けしました。
私はFirefoxをメインで使っていますが、たまたま該当する設定を変更していたので、問題に気がついていませんでした。
指摘がなければずっと気づかなかったと思いますので、本当に助かりました。
どもです。いつも、おせわになっとります。
今はOKです。
MUTOさんのトコでは、文字化けしてなかったんですねぇ。
僕の環境が特殊なのかな?
ま、とりあえず、よかったです。