中文電脳/UTF-8で簡単多言語CGI のバックアップ差分(No.1)


  • 追加された行はこの色です。
  • 削除された行はこの色です。
*1.はじめに



掲示板やメールフォームなど、動的なWebサイトの構築には、Perlを使ったCGIが一番手軽だ。しかし、こと多言語処理となると、問題が多いとされてきた。



Perlで日本語を処理する場合、jcode.pl などの日本語コード対応のモジュールを用意するのが一般的だ。これでJISコードに定義される文字は使えるようになるが、しかし、例えば中国語との多言語混在処理になると、お手上げだ。



日本語のCGIでも、ブラウザがJIS外の文字を「&#xnnnn;」に自動変換する機能を使って、多言語を混在させることはできるのだが、InternetExplorerとNetscapeでは機種依存文字の扱いが異なる、IE5.0では、日本語フォントにUnicode対応フォントを指定しないと一部の文字が「・」化けするという問題がどうしても発生する。



しかし、文字コードにUTF-8を使うと、jcode.pl に頼ることなく、Perl5.xで、多言語処理をすることができる。UTF-8とは、Unicodeの文字を処理するための文字コード番号の付け方の一つだ。といわれてもよくわからない人が多いと思うが、要するに、インターネットでUnicodeの文字を使うときに使われる文字コードだということだ。衆知のように、Unicodeは世界のあらゆる文字コードを一つの文字コード体系にまとめたもので、これを使えば、欧州諸語はもとより、日本語と中国語、ハングルなども混在処理することができる。



以下、日本語・中国語混在掲示板を例に、多言語処理可能なCGIの作成方法について解説する。



*2.UTF-8でCGIを多言語化



**2.1 準備



多言語CGIを作るのは、実はとても簡単だ。作業に必要なのは、



-カスタマイズしてもよいフリーCGIや自作CGI 

-Unicodeに対応したエディタ 



近頃は、EmEditorをはじめとする多くのエディタがUTF-8に対応しているので、それら最新版のオンラインエディタをダウンロードして使おう。ただし、エディタで中国語・日本語を混在表示するためには、Unicodeに対応したフォントが必要になる。SimSun、MS Song、PMingLiUなどのフォントを使えば良いのだが、しかし、Windows2000で秀丸などを使う場合、日本語以外の拡張子が「.TTC」のフォントをうまく扱えないという問題がある。その場合は、Office2000/XP付属の「Arial Unicode MS」などのフォントを使おう。



**2.2 CGIの改造



日本語CGIをUTF-8対応に改造するポイントは、以下の三点だ。



-CGIスクリプト、データファイルなどを全てUTF-8で保存する。 

-HTMLファイル生成部分で、生成されるページのヘッダにUTF-8指定メタタグ<meta http-equiv="Content-Type" content="text/html; charset=utf-8">を追加あるいは更新する。 

-jcode.plによる日本語処理部分を無効にする。 



CGIを設置するサーバがPerl5.6に対応していたら、スクリプトの冒頭の行頭に「#」のついている行の後に「use utf8;」と一行書き加えよう。また、Perl5.8対応であれば、同様に「use encode;」と書き加える。そうすれば、完全にUnicodeに対応する。Perlのバージョンがそれ以前であったら、この行は書き加えない。現在、ほとんどのサーバでは相変わらずPerl5.5以前のバージョンがセットアップされているようである。そのため、以下では、Perl5.5以前を念頭に解説する。



それでは実際に、CGIをUTF-8によって多言語化してみよう。ここでは、CGI-StaTionが配布している掲示板CGI、JawaNoteを、秀丸エディタを使って改造する。



ダウンロードしたファイルを解凍すると、次の5つのファイルが得られる。



-jawaback.gif 

-jawanote.cgi 

-jawanote.log 

-jcode.pl 

-readme.htm 



これらのうち、改造しなくてはならないのは、「jawanote.cgi」だけ、その他のファイルに手を加える必要はないし、jcode.plは必要ない。



***CGIをUTF-8で保存する



それでは、「jawanote.cgi」を秀丸エディタで開く。次に、「ファイル」→「名前をつけて保存」を選択し、文字コードを「UTF-8」に設定して上書き保存する。



http://wagang.econ.hc.keio.ac.jp/pc/faq/images/6011.jpg



これで、CGIファイルがUTF-8で保存された。UTF-8で保存されたファイルを開く場合は、[ファイル]→[ファイルを開く]で同様に文字コードを「UTF-8」に設定する。



***UTF-8設定タグを追加する



次に、HTML生成部分に、UTF-8指定のメタタグを追加する。秀丸で「<html>」を検索すると、123行目以下に、次のように記述されている。



 <HTML><HEAD>

 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=$charset_code">

 <TITLE>$note_title</TITLE> 



124行目を書き換えて



 <HTML><HEAD>

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

 <TITLE>$note_title</TITLE> 



のように改造する。



また、



 if ($err) { print "Content-type: text/html\n\n<HTML><BODY>"; } 



の<HTML>と<BODY>の間にメタタグを入れる。""の中なので、タグの中の「"」を「\"」にするのを忘れずに。



 if ($err) { print "Content-type: text/html\n\n<HTML><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><BODY>"; } 



***jcodeの設定を無効にする



次に、「jcode」を検索する。まず72行目



 $jcode = './jcode.pl'; # jcode.pl のある場所 



行頭に「#」を記入し、無効にする。つづけて、218行目



 &jcode'convert(*comment,'euc'); 



と222行目、703行目の



 &jcode'convert(*comment,$mojicode); 



も無効にする。たいていのCGIは、以上の設定だけで大丈夫だが、サンプルのCGIはちょっと凝っていて、文字コード判別処理を600行目以下でしている。



 # [ 文字コード関連 ]

 #

 

 sub check_code {

     if (!(-r $jcode)) { &error(1,"jcode.pl がみつかりません。"); }

     require $jcode;

     local($text) = ord(substr("中澤重人=じゃわ(^-^;;",0,1));

     if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "x-euc-jp"; }

     elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "x-sjis"; }

     else { &error(1,"サポートしてない文字コードです"); }

 }

 sub change_code {

     local($text)=$_[0];

     &jcode'convert(*text,$mojicode);

     if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); }

     if ($mojicode eq 'euc') { &jcode'h2z_euc(*text); }

     $text =~ s/</&lt;/g;

     $text =~ s/>/&gt;/g;

     return $text;

 } 



ここも、jcodeと文字コード関係の部分を全て無効にする。



 # [ 文字コード関連 ]

 #

 

 sub check_code {

 #     if (!(-r $jcode)) { &error(1,"jcode.pl がみつかりません。"); }

 #     require $jcode;

      local($text) = ord(substr("中澤重人=じゃわ(^-^;;",0,1));

 #     if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "x-euc-jp"; }

 #     elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "x-sjis"; }

 #     else { &error(1,"サポートしてない文字コードです"); }

 }

 sub change_code {

      local($text)=$_[0];

 #     &jcode'convert(*text,$mojicode);

 #     if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); }

 #     if ($mojicode eq 'euc') { &jcode'h2z_euc(*text); }

     $text =~ s/</&lt;/g;

     $text =~ s/>/&gt;/g;

     return $text;

 } 



このような文字コードチェック部分を備えているCGIは、むしろ少数派だ。もしも、Perlの知識が無くてよくわからなければ、以上のような複雑な文字コード処理部分の無いフリーCGIを選ぼう。



掲示板のフォームが日本語と中国語で表示されるようにするには、CGIファイルのフォームの説明部分を書き換える。フォームの表示部分は、270行目以下なので、そこを例えば下のように加筆修正すればよい。



 <B>タイトル(标题)</B>

 </TT></TD><TD>

 <INPUT TYPE=text NAME=title SIZE=42 MAXLENGTH=80 VALUE="$title_area">

 </TD></TR><TR><TD><TT>

 <B>ハンドル(笔名)</B>

 </TT></TD><TD>

 <INPUT TYPE=text NAME=name SIZE=42 MAXLENGTH=42 VALUE="$COOKIE{'name'}">

 </TD></TR><TR><TD><TT>

 <B>URL(家页)</B>

 </TT></TD><TD> 



これで、CGIの改造は完了した。あとは、日本語CGIを設置するのと同じように各種設定をおこない、アップロード、パーミッションを変更すればよい。



http://wagang.econ.hc.keio.ac.jp/pc/faq/images/6012.jpg



改造したCGI:http://wagang.econ.hc.keio.ac.jp/pc/faq/jawanote.lzh



CGIファイルのみです。CGI-StaTionさんからログファイルなどのセットをダウンロードして、CGIファイルを上書きして設置してください。設置方法もCGI-StaTionさん参照。なお、このCGIを利用することによって生じたあらゆる損害に対して、千田大介は責任をとりません。自己責任において、ご利用ください。転載等については、CGI-StaTionさんの規定に準じます。



他のCGIでも改造のポイントは同様だが、メール送信機能を持ったCGIの場合は、メールヘッダ部分の文字コード指定を「Content-Type: text/plain; charset="UTF-8"」に変更しなくてはならない。



*3.問題点



Perlは5.6で正式にUTF-8に対応し、5.8でマルチコード対応がほぼ完成した。

これは、文字列を文字単位で扱えるようにした、ということであり、

バイト単位で扱う場合にはPerl5.xでも問題が生じないようだ。

もちろん、文字の字数をカウントするようなUTF-8 CGIは、Perl5.6、

できれば5.8以上でなくては作れないが、掲示板程度であれば問題なく動作する。



しかし、UTF-8のCGIであるということで、幾つかの制限事項がある。



**3.1ブラウザの対応



Internet Explorerの場合は、バージョン4以降であれば、問題なくUTF-8のCGI

を使ったページを閲覧・投稿ができるが、Netscapeの場合はバージョ

ン6以降を使わなくてはならない。バージョン4.xもUTF-8には対応しているが、

しかし、Unicode内部処理化されていないため、書き込みができない。



**3.2表示フォントの問題



もう一つの問題が、表示フォントの問題だ。よく言われるように、「骨」の字は日本

と中国で字形が違う。しかし、前述の設定では、フォントの指定を全くしていないため、

日本語と中国語の「骨」を区別することができない。この問題は、spanタグで言語を指定

するように改造すれば解決するが、最新版ブラウザでしか期待する効果が得

られない。旧版ブラウザでも見られるようにするには、カスケード

スタイルシートを設定し、かつ書き込み部分に言語指定タグ・符号などを書き込むようにして、

言語によってフォント指定を切り替えるようにするしかないが、かなり面倒である。



多少の問題点はあるものの、上述の方法を使えば英語・日本語の豊富なCGIスクリプトを簡単に多言語化できるのであるから、その利点は大きいと言えよう。



なお、Perl5.6以前の環境でCGIをUTF-8化が出来るか否かは、実はかなり簡単に見分けられる。正規表現の置換先文字列にダブルバイトが入っていると、Perl5.6以前では動作不良が発生する、ということである。



※UTF-8ページであるため、半角「¥」は「\」で表示されています。日本語環境で作業する場合は、読み替えてください。



*フォローアップ



[[#rcomment]]