Nucleus(JP)フォーラム

NucleusCMS日本語版ユーザーのためのサポートフォーラムです。疑問が生じたらまずは記事検索をご利用ください。

ログインしていません。

#1 2005-05-13 12:23:46

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: Tips:プラグインの国際化

最近,プラグインを作るときに,メッセージなどをハードコーディングするのではなく,Nucleus本体と同じように
言語ファイルを使うようにしています(実際には途中までハードコーディングで作っていて,完成が近づくと
言語ファイル化するという感じですが)。

一応,覚書とほかの方にも参考になるかと思って方法を書いておきます。

(1)プラグインと同じ名前のディレクトリを作る
  ただし,NP_は取って,小文字にする必要があります。
  例えばNP_ABC.phpなら abc というディレクトリをプラグイン・ディレクトリの下に作ります
(2)ディレクトリの中に,開発環境と同じ言語用の言語ファイルを作る
  UTF-8ならjapanese-utf8.php,EUC-JPならjapanese-euc.phpが標準です
(3)

<?php
define('_ABC_MESSAGENAME',						'じっさいのメッセージ');
  ・
  ・
  ・
?>

といった形でプログラム中の日本語メッセージを定義していき,並行してプログラムのメッセージを _ABC_MESSAGENAME などに置き換える。
メッセージはグローバルな名前になるので,プラグイン名を最初に付けるようにしています。
(4)プラグインのinit関数を以下のようにする

	function init() {
		// include language file for this plugin
		$language = ereg_replace( '[\\|/]', '', getLanguageName());
		if (file_exists($this->getDirectory().$language.'.php'))
			include_once($this->getDirectory().$language.'.php');
		else
			include_once($this->getDirectory().'english.php');
	}

(5)言語ファイルを増やしていく
UTF-8からEUC-JPや,その逆はエディタでエンコードを変えるだけでできます。
あと,english.phpは日本語以外のデフォルトなのでなるべく作るようにします。

以上です。
これで,後から他の言語を追加するのも容易になります。

オフライン

#2 2005-07-25 12:39:22

nakahara21
メンバー
From: 尼崎
登録日: 2003-11-14
投稿: 1,298
ウェブサイト

Re: Tips:プラグインの国際化

最新版ではhelp.htmlをadminディレクトリに置いて、

		function supportsFeature($feature) {
			switch($feature) {
				case 'SqlTablePrefix':
					return 1;
				case 'HelpPage':
					return 1;
				default:
					return 0;
			}
		}

と書くと、プラグイン一覧ページの「アクション」に『ヘルプ』リンクが生成されて、ヘルプ表示が可能となっているようですが。

このhelp.htmlを他言語化したい(言語ファイルを使いたい)場合は、どのようにすれば一番簡単なのでしょう?
言語ファイルを読み込ませるよりも、japanese-euc.help.htmlとかを用意する方が作成時は楽チンなのですが、ADMIN.phpのfunction action_pluginhelp()を改良してもらった方がいいような気がします。
改良例がないと誰も賛同してくれないような気がしますが...


nakahara21
http://nakahara21.com/
(ただいま調整中です)

オフライン

#3 2005-07-25 13:00:11

nakahara21
メンバー
From: 尼崎
登録日: 2003-11-14
投稿: 1,298
ウェブサイト

Re: Tips:プラグインの国際化

ADMIN.phpのfunction action_pluginhelp()の後半は、

		echo '<h2>',_PLUGS_HELP_TITLE,': ',htmlspecialchars($plugName),'</h2>';

		$plug =& $manager->getPlugin($plugName);
		
		$language = ereg_replace( '[\\|/]', '', getLanguageName());
		
		$helpFile = $DIR_PLUGINS.$plug->getShortName().'/help.html';
		if(@file_exists($DIR_PLUGINS.$plug->getShortName().'/'.$language.'.help.html')){
			$helpFile = $DIR_PLUGINS.$plug->getShortName().'/'.$language.'.help.html';
		}
		
		if (($plug->supportsFeature('HelpPage') > 0) && (@file_exists($helpFile))) {
			@readfile($helpFile);
		} else {
			echo '<p>Error: ', _ERROR_PLUGNOHELPFILE,'</p>';
			echo '<p><a href="index.php?action=pluginlist">(',_BACK,')</a></p>';
		}

こんなかんじでどうでしょうか。
file_existsが2回実行されるのでスマートではないですが、例えばって事で。


nakahara21
http://nakahara21.com/
(ただいま調整中です)

オフライン

#4 2005-07-25 14:05:59

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: Tips:プラグインの国際化

まみおさんの書いた方法が現実的ではないかと思います。
install()内で言語調べてリネームなんていうのも考えたのですが,
そうなると今度はパーミッションが引っかかってくるし… roll

オフライン

#5 2005-07-25 14:14:28

nakahara21
メンバー
From: 尼崎
登録日: 2003-11-14
投稿: 1,298
ウェブサイト

Re: Tips:プラグインの国際化

あつかましいですが、本家に意見投稿をお願いできたら嬉しいです。
くだんのスキン内変数の件と一緒でも良いです。


nakahara21
http://nakahara21.com/
(ただいま調整中です)

オフライン

#6 2005-07-25 14:17:03

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: Tips:プラグインの国際化

了解です。 smile

オフライン

#7 2006-08-24 17:03:51

shizuki
Administrator
From: 西播磨
登録日: 2006-03-23
投稿: 900
ウェブサイト

Re: Tips:プラグインの国際化

古い話を引っ張り出して恐縮ですが、この話はその後どうなったんでしょう?

もし都合が悪くなければ日本語版だけでも・・・

オフライン

#8 2006-08-24 17:16:41

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: Tips:プラグインの国際化

ここはまだ入れてないです。すみません…
3.3日本語版に入れますか?→Kimitakeさん

オフライン

#9 2006-08-26 20:40:15

yama
Administrator
登録日: 2005-07-07
投稿: 1,277
ウェブサイト

Re: Tips:プラグインの国際化

もしこのようにヘルプのページを簡単に作れるようになるなら、自分もできる範囲で
いくつかのプラグインのヘルプの作成をお手伝いしたいと思います。
よろしくお願いします。

オフライン

#10 2006-08-26 21:29:05

kosugiatkips
メンバー
From: 金沢区
登録日: 2006-01-15
投稿: 353

Re: Tips:プラグインの国際化

コア側で言語を判定して読んでくれるのはありがたいのかもしれませんが、プラグイン一覧からヘルプを呼ぶだけではなく、管理画面の他のシチュエーションから呼ぶことも考えられるので、そもそもhelp.html決め打ちじゃなくて、help.phpを呼ぶようにすれば、ダイナミックなヘルプページが作れるからいいと思います。

リンク元の状況や、見る人の権限によっては不要なヘルプコンテンツもあるでしょうから。

help.phpがなかったらhelp.htmlを呼ぶようにすれば下位互換性も保てるわけですし。

	function action_pluginhelp() {
		global $member, $manager, $DIR_PLUGINS, $CONF;

		// check if allowed
		$member->isAdmin() or $this->disallow();

		$plugid = intGetVar('plugid');

		if (!$manager->pidInstalled($plugid))
			$this->error(_ERROR_NOSUCHPLUGIN);

		$plugName = getPluginNameFromPid($plugid);

		$this->pagehead();

		echo '<p><a href="index.php?action=pluginlist">(',_PLUGS_BACK,')</a></p>';

		echo '<h2>',_PLUGS_HELP_TITLE,': ',htmlspecialchars($plugName),'</h2>';

		$plug =& $manager->getPlugin($plugName);
		$helpFile = $DIR_PLUGINS.$plug->getShortName().'/help.html';
		$helpPHP =  $DIR_PLUGINS.$plug->getShortName().'/help.php';

		if (($plug->supportsFeature('HelpPage') > 0) && (@file_exists($helpPHP))) {
			@include($helpPHP);
		} elseif (($plug->supportsFeature('HelpPage') > 0) && (@file_exists($helpFile))) {
			@readfile($helpFile);
		} else {
			echo '<p>Error: ', _ERROR_PLUGNOHELPFILE,'</p>';
			echo '<p><a href="index.php?action=pluginlist">(',_BACK,')</a></p>';
		}


		$this->pagefoot();
	}

オフライン

#11 2006-09-01 06:12:54

Katsumi
メンバー
From: CA
登録日: 2005-06-24
投稿: 637
ウェブサイト

Re: Tips:プラグインの国際化

nakahara21 さんの発言:

このhelp.htmlを他言語化したい(言語ファイルを使いたい)場合は、どのようにすれば一番簡単なのでしょう?

ちょっと強引ですが、あるプラグインで help.html を

<script type="text/javascript" src="../index.php?action=plugin&name=XXXX&type=help"></script>
<p>If you cannot see the help, please click <a href="plugins/xxxx/help-euc.html">here</a>,
or find the "help-euc.hml" file and open it by a browser.</p>

として実現させていたことがありました。

でも、やはり help.php をコアで読み込みに行くなどの方法が、簡単でいいですね。

オフライン

#12 2006-11-20 09:57:11

Katsumi
メンバー
From: CA
登録日: 2005-06-24
投稿: 637
ウェブサイト

Re: Tips:プラグインの国際化

最近、wiki のページが充実しているプラグインが増えていますが、プラグイン一覧ページの『ヘルプ』にwikiの内容を取り込めばいいなと思っていました。

このトピックスで議論のある多言語化の問題とか複雑なのですが、おそらく一番簡単にこれが実装できる方法を発見しました。

help.htmlに、

<iframe src="http://japan.nucleuscms.org/wiki/plugins:xxxxxxxx" width="750" height="600"></iframe>

と書くだけです。必要なら、wiki の内容を編集することも出来ますョ。

オフライン

#13 2008-02-19 00:21:06

yama
Administrator
登録日: 2005-07-07
投稿: 1,277
ウェブサイト

Re: Tips:プラグインの国際化

国際化をちょくちょくやるようになって気付いたことですが。。

自国語のlangファイルがなければenglish.phpを読みに行く。そこのところはいいのですが、
ファイルはあるけど中身のエントリー数が合ってないということがあると思います。
プラグインのバージョンアップに合わせてlangファイルもアップデートする必要があるわけで、
対応言語が多いほど単純作業が増えることになりますね。
この手間を惜しんでも_ABC_MESSAGENAMEなどのエントリー名がそのまんま表示されるだけで
さほど困ったことにはならないですが、もし該当エントリーが存在しない場合はデフォルトの
english.phpから読み出してくるという書き方もできそうな気がします。

オフライン

#14 2008-02-19 07:24:30

Katsumi
メンバー
From: CA
登録日: 2005-06-24
投稿: 637
ウェブサイト

Re: Tips:プラグインの国際化

yama.kyms さんの発言:

この手間を惜しんでも_ABC_MESSAGENAMEなどのエントリー名がそのまんま表示されるだけで
さほど困ったことにはならないですが、もし該当エントリーが存在しない場合はデフォルトの
english.phpから読み出してくるという書き方もできそうな気がします。

一番簡単な解決策は、例えば japanese-utf8.phpをインクルードした後に、english.phpをインクルードすることです。先にインクルードされたほうが優先になります。2回目のインクルードのときに Notice が出るので、@include()としておけばよいと思います。ただしこの方法だと1ミリ秒ほどのロスがあるので、ベータバージョンでのみ使うようにしたほうが良いと思います。

オフライン

#15 2008-02-19 10:32:28

yama
Administrator
登録日: 2005-07-07
投稿: 1,277
ウェブサイト

Re: Tips:プラグインの国際化

先にenglish.phpを読み込んで、後からjapanese.phpで上書きするのかと思ってましたが、逆なんですね。今度機会があったら試してみます。今やってるNP_MitasNomはまた違う方式のようですが。(MovableTypeみたい、と思いました)

オフライン

#16 2008-02-19 10:50:11

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: Tips:プラグインの国際化

   function init() {
      // include language file for this plugin
      $language = ereg_replace( '[\\|/]', '', getLanguageName());
      if (file_exists($this->getDirectory().$language.'.php'))
         include_once($this->getDirectory().$language.'.php');
      include_once($this->getDirectory().'english.php');
   } 

これでそうなります。

オフライン

#17 2008-02-19 12:31:16

yama
Administrator
登録日: 2005-07-07
投稿: 1,277
ウェブサイト

Re: Tips:プラグインの国際化

ありがとうございます。おかげで他国語対応少し手抜きができそうです。

オフライン

#18 2009-01-19 18:02:06

きゃしゃ
メンバー
From: 北河内
登録日: 2007-12-15
投稿: 351

Re: Tips:プラグインの国際化

プラグインの日本語化について、Katsumiさん方式と佐藤(な)さん方式の折衷でこんなルーチンを考えてみました。
開発効率の向上が目的です。arrayにすれば多言語化も可能です。

メリット
・langファイルを別途用意しなくて良い
・ソースの見通しがよい
・辞書の見通しがよい
・辞書に漏れやtypoがあっても英文が表示される
・グローバル定数とのバッティングを気にしなくてよい

デメリット
・いちいちfunction呼ぶので効率がよろしくない

	function lang($english) {
		$multilang = array(
//			'English'		=> array('日本語','another language',...),
			'Description'	=> '解説',
			'Eroor message'	=> 'エラーメッセージ',
		);
		if (array_key_exists($english,$multilang)) {
			switch (ereg_replace('[\\|/]', '', getLanguageName())) {
				case 'japanese-euc':
					$translated = mb_convert_encoding($multilang[$english],'EUC-JP','UTF-8');
					break;
				case 'japanese-utf8':
					$translated = $multilang[$english];
					break;
/*				case 'another-language':
					$translated = $multilang[$english][i];
					break;
*/
				default:
					$translated = $english;
					break;
			}
		} else {
			$translated = $english;
		}
	return $translated;
	}

実例として、試しにNP_Captchaを日本語化してみました

オフライン

#19 2009-02-05 18:13:33

きゃしゃ
メンバー
From: 北河内
登録日: 2007-12-15
投稿: 351

Re: Tips:プラグインの国際化

質問です。
っていうか、相談ていうか、意見を伺いたいんですが。
日本語版コアではglobalfunctionsのencode_descをHTML_ENTITIESからHTML_SPECIALCHARSに変更してあるので、
Descriptionも2バイト文字で表示できますけど、本家版では文字化けしますよね。
最新の本家版3.40RCで確認したんですが、HTML_ENTITIESのままでした。
日本語版コアで使う分にはよいのですが、プラグインを「国際版」と考えるなら、
「"歴史的理由により"Descriptionは英文にしておく」というのを暗黙のお作法にしたほうがいいんでしょうか?
そういえば、多言語化してあるプラグインでもDescriptionは英文にしてあるのが結構ありますよねぇ。
NP_Mediatocuも英文でしたわ、そういえば。勝手に日本語にしちゃったのですけど。

現実的には、日/英 以外の多言語化されているプラグインをあたしは知らないのですけど。

オフライン

#20 2009-02-07 19:06:27

Mocchi
メンバー
登録日: 2006-11-19
投稿: 438

Re: Tips:プラグインの国際化

折衷案は、言語ファイルの規模があまり大きくないプラグインに向いてそうですね。基本は配列操作なので、それほど重さを感じないようなルーチンではないでしょうか。

きゃしゃ さんの発言:

「"歴史的理由により"Descriptionは英文にしておく」というのを暗黙のお作法にしたほうがいいんでしょうか?

これは今まで気づきませんでした。言語ファイルでDescriptionもプラグイン・オプションの説明文も日本語化していましたが、これらって、インストールと同時にデータベースに登録されてしまうんですね。そうしたら、言語ファイルを準備しても、表示自体は、インストール時の言語設定に左右されてしまうという事態に。。。

ここ痒い。何とかして手が届くようにならないものか roll

オフライン

#21 2009-02-08 17:56:34

shizuki
Administrator
From: 西播磨
登録日: 2006-03-23
投稿: 900
ウェブサイト

Re: Tips:プラグインの国際化

きゃしゃ さんの発言:

「"歴史的理由により"Descriptionは英文にしておく」というのを暗黙のお作法にしたほうがいいんでしょうか?
そういえば、多言語化してあるプラグインでもDescriptionは英文にしてあるのが結構ありますよねぇ。

理由としては「忘れてた」とか「面倒」がトップな気もしますが…
それはさておき、Descriptionは多国語化しても大丈夫です。
ここは表示の都度呼び出されますから、ちゃんと言語ファイルを使う限り問題ないです。
但し、「プラグインオプション」は

Mocchi さんの発言:

インストールと同時にデータベースに登録されてしまう

ので、

Mocchi さんの発言:

インストール時の言語設定に左右されてしまうという

悲しい事になります。

これなんですが、showlist.php の listplug_plugOptionRow($current) にある

echo '<td>',htmlspecialchars($current['description']?$current['description']:$current['name']),'</td>';

の部分を

$plugDesc = $current['description'] ? (defined($current['description']) ? defined($current['description']) : $current['description']) : $current['name'];

として、オプション作成時に

createOption('optionName', '_PLUG_OPTION_DESC', ......);

で作成する(普段定数にしてるところを括って「文字列」として登録する)と、もしかするとうまくいくかもしれません。

オフライン

#22 2009-02-10 15:51:57

きゃしゃ
メンバー
From: 北河内
登録日: 2007-12-15
投稿: 351

Re: Tips:プラグインの国際化

Mocchi さんの発言:

ここ痒い。何とかして手が届くようにならないものか roll

痒いですよねぇ :cry:
さらに、メンバーごとに使用する言語を切り替えできる仕様にも関わらず、
プラグインのメンバーオプションは、インストールしたメンバーのインストール時の言語設定に固定される。
その言語で表示されるならまだかわいいけど文字化けするし。(双方UTF-8の場合以外は)

shizuki さんの発言:

もしかするとうまくいくかもしれません。

やっぱ後方互換は諦めれってことですよねぇ。うーん。 :?

オフライン

#23 2009-03-11 14:18:03

shizuki
Administrator
From: 西播磨
登録日: 2006-03-23
投稿: 900
ウェブサイト

Re: Tips:プラグインの国際化

プラグインAPIを使用して、オプションの多国語化に成功しました。

	function event_PrePluginOptionsEdit($data)
	{
		if ($data['plugid'] === $this->getID()) {
			foreach($data['options'] as $key => $value){
				if (defined($value['description'])) {
					$data['options'][$key]['description'] = constant($value['description']);
				}
//				if (!strcmp($value['type'], 'select') && defined($value['typeinfo'])) {
//					$data['options'][$key]['typeinfo'] = constant($value['typeinfo']);
//				}
			}
		}
	}

このコードでうまくいきます。

install() メソッドでオプションを作成する時に

createOption('optionName', '_PLUG_OPTION_DESC', ......);

として、「オプションの説明」を文字列として登録することで、呼び出されたときにその文字列に対応した定数を呼び出すことができます。
3行ほどコメントアウトしてある部分は「select」タイプに対応している部分で、「select」タイプのオプションで、選択肢も定数化して使っている場合などに使用できます。
コアの改造無しで、プラグインがフックするイベントを一つ追加するだけで出来るので結構お手軽だと思います。

NKJGさん、ありがとー!

オフライン

#24 2009-03-11 21:49:41

きゃしゃ
メンバー
From: 北河内
登録日: 2007-12-15
投稿: 351

Re: Tips:プラグインの国際化

すごい!
あー、PrePluginOptionsEdit。こんな簡単なことだったんだ。
shizukiさんNKJGさんありがとです。

オフライン

#25 2009-04-10 12:59:18

Mocchi
メンバー
登録日: 2006-11-19
投稿: 438

Re: Tips:プラグインの国際化

痒い痒い言っていたわりに反応がなくてすみません。。。
今制作中のプラグインで、PrePluginOptionsEditによる国際化を試してみたら、すごいっ!!できました。感激です tongue

shizukiさんNKJGさん、どうもありがとう

オフライン

Board footer