第14回 Smartyでケータイサイトを作ってみる (その2)
絵文字関数プラグインを作ろう
さて、ケータイコンテンツを作る上で一番重要で、かつ一番頭を悩ませる問題が絵文字対応です。
絵文字はケータイコンテンツを作る際に欠かせないものになっていますが、複数のキャリアに共通して対応させようとすると、とたんに大変になります。
そもそもキャリアによって文字コードが全然違いますし、キャリアによって絵文字があるものとないものがあったりします。
そこでキャリアの違いを吸収し、テンプレートを作成するデザイナーが極力負担を感じず絵文字を扱えるようにするためのテンプレート関数を作ってみたいと思います。
以下の3つの方針で実装します。
- 関数のパラメータでキャリア共通の絵文字コードを指定する。
- 関数内でクライアントのキャリアを判定し、それに応じた絵文字コードを出力する。
- キャリアによって表示する絵文字を指定できるようにする。
3つめは、キャリアによって該当する絵文字が複数存在するものがあり、一意に置き換えるだけでは不十分という場合があるので用意しました。
例えばauには色違いのハートマークがいくつもあったり、Softbankには針の位置が違う時計マークがいくつもあったりします。

テンプレート関数は以下のような記述が出来るようにします。
{emoji code='***'}
{emoji docomo='***' au='***' softbank='***'}
上が共通コードになります。共通コードはこの後説明するテーブルで指定されているコードを指定します。
下がキャリアごとにパラメータを指定するための記述方法です。
ではこのテンプレート関数をプラグインとして実装してみましょう。
plugins/function.emoji.php
1
<?php
2 require_once('Net/UserAgent/Mobile.php');
3 require_once('../libs/EmojiTable.class.php');
4
5 /*
6 * Smarty plugin
7 * -------------------------------------------------------------
8 * File: function.emoji.php
9 * Type: function
10 * Name: emoji
11 * Purpose: ケータイ用絵文字を表示する
12 * -------------------------------------------------------------
13 */
14 function smarty_function_emoji($params, &$smarty)
15 {
16 // 現在のキャリアを取得
17 $agent = Net_UserAgent_Mobile::singleton();
18 if($agent->isDoCoMo()){
19 $carrier = 'docomo';
20 }
21 elseif($agent->isEZweb()){
22 $carrier = 'au';
23 }
24 elseif($agent->isSoftBank()){
25 $carrier = 'softbank';
26 }
27 else{
28 $carrier = null;
29 }
30
31 $emoji_tbl = EmojiTable::getInstance();
32
33 // キャリア指定のパラメータがあるか?
34 if($carrier && isset($params[$carrier])){
35 $emoji = $emoji_tbl->get($params[$carrier], $carrier);
36 }
37
38 // 絵文字コードの指定があるか?
39 elseif(isset($params['code'])){
40 $emoji = $emoji_tbl->get($params['code'], $carrier);
41 }
42
43 return $emoji ? $emoji : EmojiTable::UNKNOWN_CHAR;
44 }
まず17行目から29行目でキャリア判定します。先ほど説明したNet_UserAgent_Mobileを使って判別しています。
続いて、EmojiTableクラスのインスタンスを呼び出しています。これはlibsディレクトリに以下のファイルを作成しクラスを定義します。
libs/EmojiTable.class.php
1
<?php
2 class EmojiTable
3 {
4 const UNKNOWN_CHAR = '〓';
5
6 public static function getInstance()
7 {
8 static $instance = null;
9 if(is_null($instance)){
10 $instance = new EmojiTable();
11 }
12 return $instance;
13 }
14
15 public function get($code, $carrier = null)
16 {
17 if($carrier && isset(self::$_table[$code][$carrier])){
18 return self::$_table[$code][$carrier];
19 }
20 elseif(isset(self::$_table[$code]['caption'])){
21 return '[' . self::$_table[$code]['caption'] . ']';
22 }
23 else{
24 return null;
25 }
26 }
27
28 protected static $_table = array(
29 'hare' => array(
30 'caption' => '晴れ',
31 'docomo' => '',
32 'au' => '',
33 'softbank' => ''
34 ),
35 'kumori' => array(
36 'caption' => '曇り',
37 'docomo' => '',
38 'au' => '',
39 'softbank' => ''
40 ),
41 'ame' => array(
42 'caption' => '雨',
43 'docomo' => '',
44 'au' => '',
45 'softbank' => ''
46 ),
47 'yuki' => array(
48 'caption' => '雪',
49 'docomo' => '',
50 'au' => '',
51 'softbank' => ''
52 ),
53 'kaminari' => array(
54 'caption' => '雷',
55 'docomo' => '',
56 'au' => '',
57 'softbank' => ''
58 ),
59 :
60 :
61 );
62 }
63 ?>
EmojiTableクラスのstatic変数として絵文字変換のテーブルを用意しています。
これを参照することにより、テンプレート関数のパラメータで指定したコードからキャリアごとのエンティティに変換します。
今回の実装ではEmojiTableクラスのstatic変数としてテーブルを持たせましたが、メンテナンスの容易さを考慮してDBやCSVなどの別ファイルで管理したり、パフォーマンス優先でmemcachedなどキャッシュを利用する方法などを検討してもいいかもしれません。
また、プラグインとして配布することを検討するのであれば、テーブル自体をプラグインファイル側に持たせてもいいかもしれませんね。
そのあたりはお好みでどうぞ。
さて、以下のようなテンプレートを表示してみます。
<html>
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=Shift_JIS" />
<title>てすと</title>
</head>
<body>
<p>今日はいい天気ですね{emoji code=hare}</p>
</body>
</html>
表示結果は以下のようになります。キャリアによって絵文字が変換されているのが分かると思います。








