第6回 Smartyを使って実用的なページを作ってみる(その2) - Smarty講座

PHPセキュリティ

yossy先生のSmarty講座

Lecutures on PHP

第6回 Smartyを使って実用的なページを作ってみる(その2) (その1)

 このエントリーをはてなブックマークに追加

問い合わせフォームを多言語対応に

yossy先生

前回説明した問い合わせフォームですが、Smartyテンプレートには各項目の見出しや挨拶など、すべて日本語で書かれています。日本人のみターゲットとしたコンテンツであれば、これで何ら問題ないのですが、昨今、海外の人もターゲットとしたコンテンツも多く見受けられるようになり、あらかじめ多言語対応しておくことはもはや当たり前のことになりつつあります。

そこで、Smartyを使って多言語対応したコンテンツを作るための方法を考えてみたいと思います(*1)。

多言語対応をする際、各言語に対応した文字列リソースファイルを用意します。リソースファイル内で、各言語に対応した文言を定義しておき、それをテンプレートファイル上で読み込み表示します。

今回、Smartyの設定ファイルを文字列リソースファイルとして活用する方法を紹介します。設定ファイルについては第2回で紹介しましたので、是非もう一度読み返して思い出してください。

まず設定ファイルを2つ用意します。日本語の文字列リソースファイルと英語の文字列リソースファイルです。ここではファイル名をlang_(ロケールID).confとします。日本語であればlang_ja.conf、英語であればlang_en.confとなります。(*2)

lang_ja.conf
pageTitle "問い合わせフォーム"
topMessage "お問い合わせやご意見・ご要望を以下のフォームにご記入の上ご送信ください。"
sendButton "送信する"

titleName "お名前"
titleAddress "メールアドレス"
titleInquiryType "お問い合わせ種類"
titleInquiryTitle "お問い合わせ件名"
titleInquiryContent "お問い合わせ内容"

typeRequest '意見、要望'
typeQuestion '質問、問い合わせ'
typeOther 'その他'

errorName "名前を入力してください。"
errorAddress "アドレスが不正です。"
errorType "お問い合わせ種類が不正です。"
errorTitle "件名を入力してください。"
errorContent "お問い合わせ内容を入力してください。"

acceptMessage "以下の内容で受理しました。お問い合わせありがとうございました。"
lang_en.conf
pageTitle "Inquiry Form"
topMessage "Please type in each field and click submit."
sendButton "Submit"

titleName "Name"
titleAddress "E-Mail"
titleInquiryType "Type"
titleInquiryTitle "Title"
titleInquiryContent "Contents"

typeRequest 'Request'
typeQuestion 'Question'
typeOther 'Other'

errorName "Please enter your name."
errorAddress "Please enter a valid email address."
errorType "Please select a type of inquiry."
errorTitle "Please enter a title."
errorContent "Please enter contents."

acceptMessage "Thank you for your inquiry."

次にこれらの設定ファイルを読み込みます。日本語表示の時はlang_ja.conf、英語表示の時はlang_en.confのみ読み込むようにします。

設定ファイルの読み込み方法については、第2回でSmartyテンプレートから{config_load}関数を呼び出す方法を説明しました。しかし今回は、あらかじめPHP側から設定ファイルを読み込んでおく方法を用います。

第5回で紹介したソースファイルを修正していきます。

common.php
<?php
define
'SMARTY_DIR''/usr/local/lib/Smarty-2.6.18/libs/' );
require_once( 
SMARTY_DIR .'Smarty.class.php' );

/**
 *  Smartyオブジェクトを取得する。
 *
 *  @return Smartyオブジェクトへの参照
 */
function & getSmartyObj()
{
    static 
$smarty null

    if( 
is_null$smarty ) ){
        
$smarty = new Smarty();
        
$smarty->template_dir '/var/www/smarty/templates/';
        
$smarty->compile_dir  '/var/www/smarty/templates_c/';
        
$smarty->config_dir   '/var/www/smarty/configs/';
        
$smarty->cache_dir    '/var/www/smarty/cache/';

        
// ロケールIDを取得
        
$lang getLocale();

        
// Smarty設定ファイルを読み込む
        
$smarty->config_load"lang_$lang.conf" );
    }

    return 
$smarty;
}

/**
 *  ロケールIDを取得する。
 *  (ここでは仮にenで決め打ち)
 *
 *  @return ロケールID
 */
function getLocale()
{
    return 
'en';
}
?>

yossy先生

まずは共通設定のcommon.phpから。getSmartyObj()関数の中に注目してください。$smartyオブジェクトのconfig_load()というメソッドを呼んでいます。実はSmartyクラスにも{config_load}と同じ名前のメソッドがあり、引数で設定ファイルを指定することで、それを読み込むことができます。これを用いてSmartyテンプレート表示前に設定ファイルを読み込んでおきます。

日本語と英語、どちらの設定ファイルを読み込むかですが、上の例ではgetLocale()という関数を用意し、そこでロケールIDを取得するようにしています。ここでは直接en決め打ちで指定しています。もし動的に変更させたいのであれば、GETパラメータで判別するように書き換えてもいいですし、$_SERVER['HTTP_ACCEPT_LANGUAGE']の値から自動的に決定するような処理を考えてもいいかもしれません(ここでは実装例は省略します)。

form.php
<?php
// 共通の設定を読み込む
require_once( 'common.php' );

// Smartyオブジェクト取得
$smarty =& getSmartyObj();

// ひな形のSmartyテンプレートでincludeするテンプレートを指定
$smarty->assign'content_tpl''form.tpl' );

// パラメータを渡す
$smarty->assign'params'array(
    
// 問い合わせ種類。文字列は設定ファイルから取得
    
'types' => array(
        
'request' => $smarty->get_config_vars'typeRequest' ),
        
'question' => $smarty->get_config_vars'typeQuestion' ),
        
'other' => $smarty->get_config_vars'typeOther' )
    )
) );

// ページを表示する
$smarty->display'template.tpl' );
?>

次に問い合わせフォームのソース、form.phpです。変更点はSmartyオブジェクトへパラメータを渡している箇所です。ここでget_config_vars()というメソッドが出てきました(*3)。これは読み込んだ設定ファイルから、引数で指定した名前の値を取得するSmartyクラスのメソッドです。問い合わせ種類の文字列を、文字列リソースファイルから取得します。ここで、読み込んだ設定ファイルによって日本語表記が取得されるか、英語表記が取得されるか分かれます。

例えばlang_en.confでは以下のように定義されています。

typeRequest 'Request'
typeQuestion 'Question'
typeOther 'Other'

これらの値がget_config_vars()メソッドで取得され、Smartyテンプレートへパラメータとして渡されます。

form.tpl
<p>{#topMessage#}</p>

<form method="post" action="test_post.php">
<
dl>
  <
dt>{#titleName#}</dt>
  
<dd>
    <
input type="text" name="name" 
           
value="{$params.name|escape:'html':'UTF-8'}" />
{if 
$params.errors.name}
    <
class="error-message">{#errorName#}</p>
{/if}
  </
dd>

  <
dt>{#titleAddress#}</dt>
  
<dd>
    <
input type="text" name="address" 
           
value="{$params.address|escape:'html':'UTF-8'}" />
{if 
$params.errors.address}
    <
class="error-message">{#errorAddress#}</p>
{/if}
  </
dd>

  <
dt>{#titleInquiryType#}</dt>
  
<dd>
    {
html_options name="type" options=$params.types selected=$params.type}
{if 
$params.errors.type}
    <
class="error-message">{#errorType#}</p>
{/if}
  </
dd>

  <
dt>{#titleInquiryTitle#}</dt>
  
<dd>
    <
input type="text" name="title" 
           
value="{$params.title|escape:'html':'UTF-8'}" />
{if 
$params.errors.title}
    <
class="error-message">{#errorTitle#}</p>
{/if}
  </
dd>

  <
dt>{#titleInquiryContent#}</dt>
  
<dd>
    <
textarea name="content" cols="60" rows="5">
      {
$params.content|escape:'html':'UTF-8'}
    </
textarea>
{if 
$params.errors.content}
    <
class="error-message">{#errorContent#}</p>
{/if}
  </
dd>
</
dl>

<
input type="submit" value="{#sendButton#}" />
</
form>

そして、Smartyテンプレートも書き換えます。前回、日本語文字列で書いていた箇所を設定ファイルで記述した値を読み込むように書き換えます。設定ファイルの値の展開方法は第2回で説明したように{#(名前)#}で記述します。

さて、アクセスしてみて英語表記で表示されるようになりましたか?

英語版の表示

同様にpost.php, post.tplのほうも書き換えてみてください。

----
*1)一般的に「国際化」というと、言語だけでなく時間とか通貨とか様々な問題があるのですが、ここでは言語の問題に絞って考えます。
*2)例を簡単にするために、ロケールIDをja,enのみにしていますが、言語だけでなく地域によって分ける必要があれば、ja_JP、en_USのようにしてもいいかもしれません。
*3)実は第2回でちょこっとだけ触れています。

  • 1
  • 2

  



Pick Up Q&A

Q
負荷時のmysql_connect()エラー
 このエントリーをはてなブックマークに追加 
A
これはPHPというよりOSまたはMySQLのコミュニティで質問されたほうがいいと思います。 ぱっと思いついた範囲で記すと MySQL等のDBに「ある時点において同時に接続可能なクライアントの最大数」に制限があるよう...

>>続きを読む

今回のような実践的な経験がエンジニアのキャリアに繋がると思います。是非サービスを成功させて下さい!

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)