K-12向け言語パックへのMoodleからのアクセス

K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿
返信数: 7

 言語パックを追加するには手動インストールと自動更新の二つの方法がある.
 自動更新はサイト管理ブロックの[言語]-[言語パック]より,インストールされている言語パックの更新を選択すれば自動的に行われる.ただしこれはmoodle.orgで正式に管理されている言語パックのみに許された手段であり,K-12向け日本語言語パックには用いることができない.
 更新は手作業によって行わなくてはならない.まだ公開(それ以前に作業に^^;)されていないが,将来的には以下のURLよりzip形式での公開を予定している.
http://sourceforge.jp/projects/jak12/releases/

 ここからダウンロードした標準の言語パックをmoodledata/langフォルダ内に展開すれば,自動的にMoodleは新しい言語の言語パック(ヘルプファイルを含む)と認識し,管理者による指定,ユーザ個人による選択が可能となる.たとえば,日本語(ja)の代わりに,日本語(ja_g01)(:小学校一年生用)など.
 基本的にはこれで問題は無い.しかし標準ではないサードバーティ製プラグイン(モジュール,ブロック)用の言語パックはどうだろう? メジャーなプラグインの言語パックは吉田氏によって標準の日本語言語パックに同梱jされているが,それほどメジャーではないものについては各人で言語パックを作成するなどの手段が取られているだろう.それらは成人向けにja_utf8というフォルダに作成されているだろう.これらの日本語言語パックに,K-12の日本語言語パックを選択した学生(ja_g**)はアクセスできない.名前は似ているが,ja_utf8とja_g**_utfは全く別の言語パックと認識されるためである.もし希望する言語用の翻訳語が見つからない場合,Moodleはen_utf8(つまり英語)の単語を翻訳語として返す.これでは余計に問題である.

 色々と調べたところ,選択した言語パックのフォルダの中にあるlangconfig.phpに,$string['parentlanguage'] = '****'; という指定があれば,選択する候補であるフォルダに選択した言語の言語パックファイルが存在しなかった場合,言語を英語ではなく,指定した言語に置き換えて再度選択する仕組みア備わっていることが分かった.つまり,ja_g1_utf8, ja_g2_utf8,..., ja_g12_utf8の各K-12向け日本語言語パックのlangconfig.phpに,$string['parentlanguage'] = 'ja_utf8';を追加すれば良さそうであることが分かった.K-12向け日本語言語パックに指定されたモジュール類の言語パックが存在しなかった場合,ja_utf8向けの言語パックから目的の単語の翻訳語を探索する.

 とりあえずこれから実験を行ってみます.この仕組みを流用できれば,Moodle本体に改造は必要ない.

#しかし,moodle/lib/moodlelib.phpのfunction get_string(),もっと効率よく書けるなぁ.ちょっと手を加えたら同じ改良を何箇所にも施さなくてはならない.外側にもう一つループを追加すれば,ja_g**_local_utf8, ja_g**_utf8, ja_local_utf8, ja_utf8, en_utf8の順で探索できるように改善できるのに.

Tatsuya Shirai への返信

Re: K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿

 ターゲットはfs_moodle用に私が勝手に追加した言語パック.これはmoodledata/langフォルダではなく,moodle/lib/fs_moodle/langに追加したja_utf8とen_utf8の2系統の言語パック.当然,ja_g**_utf8は存在しない.

 いま,moodledata/lang/ja_g01_utf/langconfig.phpに,$string['parentlanguage'] = 'ja_utf8'; を追加したところ,ヘルプファイルは英語用のヘルプファイルではなく,日本語用(ja_utf8)のヘルプファイルを開くことが確認できた.
 残念ながら,get_string()でアクセスする単語類の翻訳は英語で表示される.もう少し調査が必要かな.

Tatsuya Shirai への返信

Re: K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿

ああ,これは仕様なのかバグなのか?

langconfig.phpファイルは標準のロケーション($CFG->dataroot.'/lang/',$CFG->dirroot.'/lang/')だけではなく,モジュールのロケーションも探すようになっている.そしてそのロケーションにlangconfig.phpが無ければ無効である.ヘルプファイルはこういう挙動ではなかったから,探し方が違うと見た.

うむ.moodle/lib/fs_moodle/langにja_g01_utf8フォルダを作成し,以下の内容のlangconfig.phpファイルのみを格納したところ,moodle/lib/fs_moodle/lang/ja_utf8フォルダ内の言語パックを使って代替表示を行ってくれた.ちょっとこれはバグっぽいですね.あまりうまく活用されていないようだ.多分,$CFG->dataroot.'/lang/langconfig.php'だけをチェックするようにするべきだ.


moodle/help.phpでは,冒頭で,

if (!empty($file)) {
    // The help to display is from a help file.

    // Get the list of parent languages.
    if (empty($forcelang)) {
        $langs = array(current_language(), get_string('parentlanguage'), 'en_utf8');  // Fallback
    } else {
        $langs = array($forcelang, 'en_utf8');
    }

このように,探索する言語パックの種類を,(1)選択された言語パック,(2)その言語パックで指示された親言語パック,(3)en_utf8の順に指定している.シンプルだ.がっつり書き換えたい...

Tatsuya Shirai への返信

Re: K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿

 つまり,現在のmoodle/lib/moodlelib.phpのfunction get_string()の後半,選択された言語パックに翻訳語が見つからなかった場合に,次の候補として探す言語としてen_utf8に行く前にparentlangが指定されているならば,それを探す部分.オリジナルはこう.

 /// Is a parent language defined?  If so, try to find this string in a parent language file

    foreach ($locations as $location) {
        $langfile = $location.$lang.'/'.$filetocheck;
        if (file_exists($langfile)) {
            if ($result = get_string_from_file('parentlanguage', $langfile, "\$parentlang")) {
                if (eval($result) === FALSE) {
                    trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
                }
                if (!empty($parentlang)) {   // found it!

                    //first, see if there's a local file for parent
                    $locallangfile = $location.$parentlang.'_local'.'/'.$module.'.php';
                    if (file_exists($locallangfile)) {
                        if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
                            if (eval($result) === FALSE) {
                                trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
                            }
                            return $resultstring;
                        }
                    }

                    //if local directory not found, or particular string does not exist in local direcotry
                    $langfile = $location.$parentlang.'/'.$module.'.php';
                    if (file_exists($langfile)) {
                        if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
                            eval($result);
                            return $resultstring;
                        }
                    }
                }
            }
        }
    }

これをこうするだけで良い.

/// Is a parent language defined?  If so, try to find this string in a parent language file

    $parentlang = get_string('parentlanguage');
    if (!empty($parentlang)) {   // found it!
        foreach ($locations as $location) {

            //first, see if there's a local file for parent
            $locallangfile = $location.$parentlang.'_local'.'/'.$module.'.php';
            if (file_exists($locallangfile)) {
                if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
                    if (eval($result) === FALSE) {
                        trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
                    }
                    return $resultstring;
                }
            }

            //if local directory not found, or particular string does not exist in local direcotry
            $langfile = $location.$parentlang.'/'.$module.'.php';
            if (file_exists($langfile)) {
                if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
                    eval($result);
                    return $resultstring;
                }
            }
        }
    }

外側の三重のループは不要.削除して,赤い1行を追加するだけで良い.この$parentlangだって,staticにすればいちいち,調べる必要は無い.


 上記修正を行うことで,moodledata/lang/ja_g**_utf8/langconfig.phpに$string['parentlanguage'] = 'ja_utf8';
を設定するだけでOKになりました.標準の日本語パックに含まれないサードパーティ製モジュールがja_utf8の言語パックしか持たなくても,ja_g**の言語選択で援護ではなくja_utf8の翻訳語が表示されます.素晴らしい仕組みが用意されていますね.さすがは全世界で利用されているシステムです.ちょっと実装の詰めが甘かっただけです.軽く感動.

Tatsuya Shirai への返信

Re: K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿

 失礼! この改造では副作用が発生することを確認しました.現在,原因を調査中です.

Tatsuya Shirai への返信

Re: K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿

パッチを作成しました.

ところでTrackerを検索していたらこの問題に関する解決済みの課題が発見されました.つまりいまのコードはこの課題を解決するために改善された結果のようです.MDL-17763

どうかなー.この解決策では,サードパーティー製ブロックのそれぞれのlangフォルダにlangconfig.phpファイルが必要ですよ.

私の対策ではblocksやmodのフォルダは見に行かない.もしそれが極端な割り切りだと言うのであれば,MDL-17763との折衷案,もしblocksやmodのサードパーティ製プラグインのlangフォルダにlangconfig.phpが見つからなかった場合は標準のlangconfig.phpの値を利用する,という手もできますが...無駄な気がしますけれども,どうなのでしょう.


MDL-17763に,もしblocksやmodにlangconfig.phpが無かった時は標準の言語パックで指定したparentlanguageを使用して下さいとお願いしてみました.

Tatsuya Shirai への返信

Re: K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿

 たとえば”関西弁日本語言語パック”を作りたいという時.

  1. ja_kansai_utf8のようなフォルダをmoodleldataに作成する.
  2. ja_utf8のフォルダからlangconfig.phpをja_kansai_utf8フォルダにコピーする.
  3. コピーしたlangconfig.phpファイル中のthislanguageを'日本語'から'関西弁'に変更.
  4. さらに$string['parentlanguage']='ja_utf8';を追加する.
  5. 関西弁に置き換えたい言葉の含まれている言語ファイルのみをja_kansai_utf8フォルダにコピーする.
  6. そのファイル中の関西弁に翻訳した$stringのみを残して他は削除してしまう.
  7. サイト管理ブロックの[言語]-[言語パック]を表示する(これが重要!)

これでja_kansai_utf8にて定義された$stringのみ”関西弁”で表示され,未定義の単語はja_utf8の単語が利用される.はず.

 私は関西人ではありませんので,以下の関西弁変換ページを利用しました.
 http://www.e-yanagase.com/kansai.html

 サンプルとして作成した ja_kansai_utf8フォルダを貼付します.このようにparentlanguageを適切に設定すると,元となる言語と異なる部分のみ翻訳すれば良い.ローカルで言語を編集するよりもポータビリティが高いですね.
 おふざけとして,言語パックの仕組みを検証する目的でこのようなことを行いましたが,もし本気で方言版言語パックを作ろうと考えている方は,標準の言語パック(ja_utf8)との同期を真剣に考える必要があります.SubversionやGitなどのリビジョン管理の可能なシステムを利用して,標準の日本語言語パックに生じた修正を反映させる仕組みを整備することが重要です.不完全な言語パックが乱立するのはMoodleコミュニティ全体の信頼を傷つける恐れがあります.

 

最大評点: お役立ち度: ★★★★★★★ (1)
Tatsuya Shirai への返信

Re: K-12向け言語パックへのMoodleからのアクセス

- Tatsuya Shirai の投稿

 こんな感じですね.あくまでもログイン画面だけです.それ以外は標準の日本語言語パック(ja_utf8)が使用されます(:これが凄いところですねぇ~).

 いやぁ勉強になります.さすがはMoodle,懐が深い.

添付 KansakLogin.jpg