CMSのポテンシャルを引き出す─MODxで作る商用サイト

第12回MODxのLexicon機能

はじめに

前回の記事では、SimpleSearchスニペットの導入方法とLexicon(語彙)の機能について簡単に解説しました。今回は、前回不足していたLexiconのもう少し細かい部分に触れるとともに、開発者の視点から見たLexiconについても解説したいと思います。

おさらい

前回使用したスニペットが参照するチャンクの内容は次のようになっていました。

my_search_resultsチャンクの内容
<p>[[+resultInfo]]</p> 
[[+results]] 
検索結果[[+paging]]

この時、ページの都合上あえて「検索結果」という日本語を記入していたのですが、実際には次のような書式にするほうが望ましいと言えます。

my_search_resultsチャンクの内容
<p>[[+resultInfo]]</p> 
[[+results]] 
[[%sisea.result_pages? &namespace=`sisea` &topic=`default`]] [[+paging]]

このようにすると、

[[%sisea.result_pages? &namespace=`sisea` &topic=`default`]]

という部分はデフォルトで

Result pages: 

に置き換えられます。ここで、%から始まる文字列は翻訳文字列に対応するキーとなります。

これだけではわかりにくいので、実際の設定と比較してみましょう。

まず、⁠sisea.result_pages」という文字列は、 /var/www/html/core/components/simplesearch/lexicon/en/default.inc.phpの中で次のように定義されています。左辺のシングルクォートされたものがキー、右辺が値です。

$_lang['sisea.result_pages'] = 'Result pages:'; 

次に続く&namespaceや&topicはLexicon用のパラメータで、管理画面の「システム⁠⁠→⁠語彙トピックの管理」で表示される「ネームスペース」「トピック」に対応しています。ネームスペースとは文字通り名前空間で、⁠どの名前空間の言語設定を使用するか」を意味し、その下のトピックでカテゴリごとの翻訳環境が用意されています。SimpleSearchスニペットのようにLexiconに対応したパッケージが存在する場合、それぞれのパッケージは基本的に異なるネームスペースとなるため、

  • ネームスペース=パッケージ
  • トピック=パッケージの中の細かいカテゴリ

と覚えておくのが簡単かもしれません。

以上のように、キー、ネームスペースとトピックに着目すると、

[[%sisea.result_pages? &namespace=`sisea` &topic=`default`]]

という記述は

  • siseaネームスペースの
  • defaultトピックの中から
  • 設定言語に応じた
  • キー名 sisea.result_pagesに対応する翻訳を表示する

という意味になります。

言語キー書式の練習

「システム」⁠語彙トピックの管理」より、いろいろなネームスペースやトピックを見ていくと、もともとパッケージに含まれている「core」ネームスペースの「user」トピックにはさまざまな日本語訳が登録されています(MODx Japanのみなさま、ありがとうございます!⁠⁠。

図1 ⁠システム⁠⁠→⁠語彙トピックの管理」より日本語訳を表示
図1 「システム」→「語彙トピックの管理」より日本語訳を表示

では、試しに任意のリソースから「管理者」という値を取り出してみましょう。前述のように、書式は次のようになります。このタグを使えば、⁠管理者」というハードコーディングされた値ではなく、⁠administratorを言語設定に基づいて翻訳した値」を表示することができます。

[[%administrator? &namespace=`core` &topic=`user`]]

ユーザやデザイナーであれば普段それほどLexiconを意識する必要はないかもしれませんが、もしスニペットを開発、公開する予定があるのであれば、日本語をハードコードするのではなく、積極的にLexicon機能を活用してみてください。

チャンクを使ったカスタムスニペット

ここで突然ですが、スニペット作成の話をさせてください。たとえば日時や時刻を表示するためのスニペットは、次のように簡単に作成することができます。

ShowDateスニペット
<?php
return strftime("%Y/%m/%d %H:%M:%S");

このスニペットを使用すれば、リソースの至るところから現在の日時を

  • 2011/08/01 12:34:56

のような形で取得することができます。しかし、英語圏での書式としては、

  • 08/01/2011 12:34:56

のような形が一般的である場合があります(ソートしにくいので筆者は嫌いです⁠⁠。この場合、スニペットを改造すれば英語圏向けの表示は可能ですが、仮にサイト内に日本語向けコンテンツ、英語コンテンツが混在した場合、ひとつのスニペットを共有させることができません。

このように、⁠特にPHPを熟知していない)ユーザに自由な書式を設定させるためには、スニペット開発者はチャンクを意識する必要があります。前述のスニペットをチャンクを用いた形で書き換えると、次のようになります。

ShowDateスニペット改
<?php
// チャンクから参照可能なプレースホルダーを作成
$modx->setPlaceholder('year', strftime('%Y'));
$modx->setPlaceholder('mon', strftime('%m'));
$modx->setPlaceholder('day', strftime('%d'));
$modx->setPlaceholder('hour', strftime('%H'));
$modx->setPlaceholder('min', strftime('%M'));
$modx->setPlaceholder('sec', strftime('%S'));

// $chknameというチャンクをロード。この値はスニペットコール時に変更可能。
return $modx->getChunk($chkname);

showdateチャンクの内容は次のとおりです。スニペットと異なりチャンクはPHPスクリプトではないため、誰でも簡単に書式を変更することができます。

showdate_ja(日本語向け)
[[+year]]年[[+mon]]月[[+day]]日 [[+hour]]時[[+min]]分[[+sec]]秒
showdate_en(英語向け)
[[+mon]]/[[+day]]/[[+year]] [[+hour]]:[[+min]]:[[+sec]]

最後に、スニペットの呼び出しは次のようにします。

日本語向け
[[!ShowDate? &chkname=`showdate_ja`]]
英語向け
[[!ShowDate? &chkname=`showdate_en`]]

実際にページを表示すると、次のようになります。

図2 チャンクを使ったスニペットのテスト
図2 チャンクを使ったスニペットのテスト

開発者としてのLexicon

チャンクを使った簡単なスニペットの作り方がわかったところで、本題のLexiconに話を戻し、多言語に対応したスニペットの作り方を紹介します。内容は非常にシンプルなもので、言語に応じて「こんにちは」「Hello」という文字列を表示する、いわゆるHello World的なスニペットです。

まずは、シンプルな言語ファイルを用意してみます。これまでに出てきたSimpleSearchスニペットのlexiconディレクトリの構造を参考に、/var/www/html/core/components/helloworld/lexiconというディレクトリを作成します。その中に、ja、enというディレクトリを作成し、次の言語ファイルを設置してください。

/var/www/html/core/components/helloworld/lexicon/en/daily.inc.php
<?php 
$_lang['helloworld.goodmorning'] = 'Good morning.'; 
$_lang['helloworld.hello'] = 'Hello.'; 
$_lang['helloworld.goodnight'] = 'Good night.'; 
/var/www/html/core/components/helloworld/lexicon/ja/daily.inc.php
<?php 
$_lang['helloworld.goodmorning'] = 'おはよう。'; 
$_lang['helloworld.hello'] = 'こんにちは。'; 
$_lang['helloworld.goodnight'] = 'おやすみ。';

これで翻訳ファイルの準備はOK、といきたいところですが、このままでは管理画面の「語彙トピックの管理」から、今回作成したつもりの「helloworld」ネームスペースや「daily」トピックは見つかりませんので、ディレクトリやファイルを置いただけでは翻訳ファイルを使用できないようです……。どうすればシステムに翻訳ファイルを追加できるのでしょうか?

その答えは、MySQLデータベース上の「modx_namespaces」テーブルにあります。試しに現在のテーブルの内容を表示してみましょう。

modx_namespacesテーブルの内容を表示
mysql> select * from modx_namespaces; 
+-----------+-------------------------------------+ 
| name      | path                                | 
+-----------+-------------------------------------+ 
| core      | {core_path}                         | 
| tinymce   | {core_path}components/tinymce/      | 
| wayfinder | {core_path}components/wayfinder/    | 
| sisea     | {core_path}components/simplesearch/ | 
+-----------+-------------------------------------+ 
4 rows in set (0.00 sec) 

このように、このテーブルの中にはネームスペースとそのディレクトリの対応が格納されているようです。これに従って、helloworld用のエントリを追加してみます。

helloworld用ネームスペースの追加
# mysql -u root modx
mysql> insert into modx_namespaces values ('helloworld','{core_path}components/helloworld/'); 
mysql> select * from modx_namespaces; 
+------------+-------------------------------------+ 
| name       | path                                | 
+------------+-------------------------------------+ 
| core       | {core_path}                         | 
| tinymce    | {core_path}components/tinymce/      | 
| wayfinder  | {core_path}components/wayfinder/    | 
| sisea      | {core_path}components/simplesearch/ | 
| helloworld | {core_path}components/helloworld/   | 
+------------+-------------------------------------+ 
5 rows in set (0.00 sec) 

以上の操作を行ったあと、再び管理画面を覗いてみると、語彙トピックを確認することができます。

図3 カスタム語彙トピックが表示されている様子
図3 カスタム語彙トピックが表示されている様子

これらの翻訳データは、/var/www/html/core/components/helloworld/lexicon以下のファイルから取得されたものですが、例のごとくブラウザからデータを更新することで、内容を上書きすることができます。前回の復習になりますが、⁠こんにちは。」という内容を「はろー。」に書き換えてみましょう。

では、続いてHelloWorldスニペットの作成です。スニペットをLexiconに対応させるためには

  • getServiceメソッドによりイニシャライズ
  • ネームスペース(helloworld)とトピック(daily)をロード
  • 翻訳メッセージのためのキー(helloworld.hello)をロード

という簡単な手順が必要になります。

HelloWorldスニペットの内容
<?php
// Lexicon機能を使用するための準備
$modx->getService('lexicon','modLexicon');

// helloworldネームスペースのdailyトピックを参照
$modx->lexicon->load('helloworld:daily');

// helloworld.helloというキーに対応した翻訳情報をロード
$modx->lexicon('helloworld.hello');

// mynameパラメータをプレースホルダに格納
$modx->setPlaceholder('myname', $myname);

// チャンクをロード。チャンク名はスニペット側のパラメータで指定可能。
return $modx->getChunk($chkname);

次に、スニペットから呼び出されるhelloworldチャンクを定義します。

helloworldチャンクの内容
[[%helloworld.goodmorning? &namespace=`helloworld` &topic=`daily`]]
[[%helloworld.hello? &namespace=`helloworld` &topic=`daily`]]
[[%helloworld.goodnight? &namespace=`helloworld` &topic=`daily`]]
[[+myname]]

最後に、リソースに定義するスニペットの内容です。

リソース中でのスニペットの記述
[[!HelloWorld? &chkname=`helloworld` &myname=`John`]]

以上により、スニペットの表示は次のようになります。

図4 言語設定が日本語になっている場合
図4 言語設定が日本語になっている場合
図5 言語設定が英語になっている場合
図5 言語設定が英語になっている場合

少し駆け足でしたが、比較的簡単にスニペットを多言語化させることが理解できたかと思います。

最後に

いろいろな解説を後回しにすることで有名な本連載ですが、MODx Revolutionから使用可能になったLexicon機能については、今回でやっとすべてを解説することができました。

読者のみなさんが多言語対応のスニペットを作成される機会は少ないかもしれませんが、MODxや関連スニペットのドキュメントを見ていくと、後々必ず%から始まるLexicon用の書式を目にするはずです。その際に「なんだこれは!?」と戸惑わないよう、Lexiconの基本を押さえておきましょう。

おすすめ記事

記事・ニュース一覧