<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>Suinasia</title>
<link>http://suin.asia</link>
<description>XOOPS, PHP and Korean</description>
<language>ja</language>
<lastBuildDate>Sat, 04 Feb 2012 21:52:50 +0900</lastBuildDate>
<docs>http://backend.userland.com/rss/</docs>
<item>
<title>XOOPS Cube &amp; TOKYOPenでパワフルなデバッグツールAdelieDebug</title>
<link>http://suin.asia/2012/01/06/xoops-adelie-debug</link>
<description><![CDATA[<p>XOOPS Cubeの開発者なら必ず入れておきたいデバッグツール AdelieDebug について紹介します。</p>

<h3>AdelieDebugって何？</h3>

<p>AdelieDebug(アデリーデバッグ)は、XOOPS Cube Legacy や <a href="http://tokyopen.jp">TOKYOPen</a> でモジュール・プリロードなどを開発するデベロッパー向けのパワフルな開発支援ツールです。どのあたりが、パワフルかいくつか特徴を紹介しましょう。</p>

<h4>特徴1: 見やすいデバッグ画面</h4>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/38bZCxP_0kYIu8zXhzF2kdMTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-6eASUD-qeYk/TwaPZpHaY9I/AAAAAAAABno/GcZuarntiGM/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202012-01-06%25252014.14.33.png" height="258" width="400" /></a></p>

<p>XOOPS Cube標準のデバッグモードでは、PHP・MySQL・Smartyなど各モードを切り替えなければなりません。一方、AdelieDebugではPHP・MySQLをひとつの画面に出すことができます。PHPについては、エラーがあれば<span style="color:red">赤</span>でハイライトされて表示されるので、標準のものと違い見落とす危険性が少ないです。MySQLについては、クエリーログを表示します。もちろんエラーが起こっているクエリーはハイライト表示がされます。加えて、var_dump()で確認することが多い、$_GET, $_POST, $COOKIE, $_FILES, $_SESSION, $_SERVER, 送信されたHTTPヘッダなどの環境変数も自動で表示してくれます。</p>

<p>PHPやSQLのログはひとつの<strong>タイムライン</strong>にまとめて表示してくれます。これにより、処理の時系列や前後関係が把握しやすくなっています。例えば、あるクエリーがどこで発行されているか知りたい場合があります。従来であれば、var_dump(__FILE__, __LINE__); を随所に仕込んだうえで、出力されたファイル名と行数をなんとなく頭の中にいれて判断するといった具合でした。AdelieDebugでは、adump() を任意の箇所に仕込めば、タイムライン上でadump()とクエリーの関係を一目で知ることが可能です。</p>

<h4>特徴2: 便利なデバッグ関数</h4>

<p>AdelieDebugは便利なデバッグ関数を提供します。それはvar_dump()よりも強力で、var_dump()+Xdebugよりも導入が簡単です。</p>

<p>adump(): var_dump()関数と同じ働きをしますが、出力内容を&lt;pre&gt;タグで囲むので見やすくなっています。var_dump()は、あちこちに仕込むとどこに仕込んだた分からなくなることがありました。adump()は仕込んだファイル名と行数を表示するので、見失う心配がありません。</p>

<pre name="code" class="php">
adump($uid);
</pre>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/tIOseCd_Ng-4MC-JfqzZgNMTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-iaqUbSyDuvE/TwaPZyItxAI/AAAAAAAABns/LGgrmvu_BLU/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202012-01-06%25252014.14.07.png" height="166" width="400" /></a></p>

<p>atrace(): その行がどの関数で呼ばれているかを表示します。PHPビルトイン関数の<a href="http://php.net/manual/ja/function.debug-print-backtrace.php">debug_print_backtrace()</a>と同等の働きをしますが、debug_print_backtrace()のようにメモリオーバーになる心配はありません。</p>

<pre name="code" class="php">
atrace();
</pre>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/cl0BAxTj-LEmOXkINxIsrtMTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh6.googleusercontent.com/-u6bvc6PrqlE/TwaPe5u8MuI/AAAAAAAABoA/YVTogUUoQ-g/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202012-01-06%25252014.41.15.png" height="160" width="400" /></a></p>

<p>awhich(): オブジェクトやクラス、関数がどのファイルの何行目で定義されているかを表示します。awhich()を使えば、わざわざファイル全体をgrep検索する必要はありません。</p>

<pre name="code" class="php">
awhich('Legacy_Controller');
awhich($mRoot);
</pre>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/NhXPShpVzYN6_1tLMzx8l9MTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh5.googleusercontent.com/-CTufJRnd2tk/TwaPY8znD_I/AAAAAAAABng/f-4zA0u3as0/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202012-01-06%25252014.52.44.png" height="21" width="400" /></a></p>

<p>asynop(): クラスやインターフェイスの概要(synopsys)を表示します。継承した親クラス、実装したインターフェイス、クラスが持っている定数・プロパティ・メソッドが一目でわかるようになります。</p>

<pre name="code" class="php">
asynop('Legacy_Controller');
asynop($this);
</pre>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/QTsAzOLO3QjRGglhdbLCm9MTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-MZ2rYtdhFTY/TwaPZAqAUjI/AAAAAAAABnk/zbYbW9SEwRc/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202012-01-06%25252013.36.56.png" height="276" width="400" /></a></p>

<h4>特徴3: XOOPS Cube Legacyのためのツールであること</h4>

<p>XOOPS Cube Legacy は標準出力をバッファでのみこんでしまいます。なので var_dump() しても何も表示されず、すぐあとに exit() をつけないといけませんでした。さもなければ、&lt;{stdout}&gt;をテーマに書く必要がありました。AdelieDebugは、そのような手間は不要です。XOOPSのob_bufferを自動的に回避するからです。</p>

<p>var_dump() は問答無用で文字列を出力します。なので、XML出力画面にダンプしてしまって、Ajaxのテストがうまくできない、なんてことがありました。AdelieDebugでは、AJAXリクエストのときやHTML出力以外のコンテクストではデバッグ出力を自動でオフにすることで、そういったストレスを軽減します。</p>


<h4>特徴4: 実践で使われているツールであること</h4>

<p>AdelieDebug は開発現場から生まれた実践的ツールです。XOOPSを用いたシステム開発を数多く手がける<a href="http://ryus.co.jp">株式会社RYUS</a>では(地道な布教活動により 笑)プログラマに広く活用されています。</p>

<h3>導入・使い方</h3>

<p>AdelieDebug はプリロードといわれるワンファイルのXOOPS Cube用のプラグインです。ですので、導入は至って簡単。<a href="https://raw.github.com/suin/xoops-adelie-debug/master/build/AdelieDebug.class.php">こちらのAdelieDebug.class.php</a>をダウンロードして、 preload フォルダに放り込むだけです。</p>

<p>不要になった場合は、このプリロードを削除します。</p>


<h3>AdelieDebug</h3>

<ul>
	<li>github: <a href="https://github.com/suin/xoops-adelie-debug">https://github.com/suin/xoops-adelie-debug</a></li>
	<li>ライセンス: たぶんGPL</li>
	<li>動く環境: PHP 5.2 ~</li>
	<li>動くプラットフォーム: XOOPS Cube Legacy 2.1 ~, TOKYOPen 1.0 ~</li>
</ul>]]></description>
<pubDate>Fri, 06 Jan 2012 15:16:58 +0900</pubDate>
<guid>http://suin.asia/2012/01/06/xoops-adelie-debug</guid>
<category domain="http://suin.asia/tag/XOOPS">XOOPS</category>
<category domain="http://suin.asia/tag/AdelieDebug">AdelieDebug</category>
<category domain="http://suin.asia/tag/TOKYOPen">TOKYOPen</category>
<category domain="http://suin.asia/tag/%E3%83%97%E3%83%AA%E3%83%AD%E3%83%BC%E3%83%89">プリロード</category>
<category domain="http://suin.asia/tag/%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89">ダウンロード</category>
</item>
<item>
<title>[PHP] array_diff()は文字列比較だから注意してね</title>
<link>http://suin.asia/2011/08/19/array_diff</link>
<description><![CDATA[<script src="https://gist.github.com/1155934.js?file=gistfile1.aw"></script>

<p><a href="http://www.php.net/manual/ja/function.array-diff.php">PHP: array_diff - Manual</a>をよく読むと、こんな注意書きが。</p>

<blockquote class="note"><p><b class="note">注意</b>: 
   </p><p class="para">
    二つの要素は、<i>(string) $elem1 === (string) $elem2</i>
    の場合のみ等しいと見直されます。言い換えると、文字列表現が同じ場合となります。
    
   </p>
  <p></p></blockquote>

<p>要素が配列だと、string(5) "Array"同士の比較になっちゃうのね(´・ω・｀) </p>]]></description>
<pubDate>Fri, 19 Aug 2011 12:06:22 +0900</pubDate>
<guid>http://suin.asia/2011/08/19/array_diff</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>[XOOPS Cube]プリロードでブロックの内容を取得するサンプル</title>
<link>http://suin.asia/2011/08/17/xoops_preload_get_block_contents</link>
<description><![CDATA[<p>プリロードでブロックの内容を取得するサンプルです。ブロックのタイトルすべてに「<a href="http://www.warna.info/archives/1620/">だぷー</a>」を付けます</p>
<p class="photo"><a href="https://picasaweb.google.com/lh/photo/mlSjOsrw-AUwUldsYH6ilQ?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-qTuu6EqRc1I/Tkni-NP2bSI/AAAAAAAABgU/YicdOMr-c04/s800/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202011-08-16%25252012.24.04.png" height="314" width="187" /></a></p>
<script src="https://gist.github.com/1148371.js?file=gistfile1.aw"></script>]]></description>
<pubDate>Wed, 17 Aug 2011 00:00:00 +0900</pubDate>
<guid>http://suin.asia/2011/08/17/xoops_preload_get_block_contents</guid>
<category domain="http://suin.asia/tag/XOOPS">XOOPS</category>
<category domain="http://suin.asia/tag/%E3%83%97%E3%83%AA%E3%83%AD%E3%83%BC%E3%83%89">プリロード</category>
<category domain="http://suin.asia/tag/Tips">Tips</category>
</item>
<item>
<title>Durarara Chat Translation</title>
<link>http://suin.asia/2011/08/11/durarara_chat_translation</link>
<description><![CDATA[<p>Please see here: <a href="http://drrrchat.com/localize.php">http://drrrchat.com/localize.php</a></p>

<p>If your language has not be translated yet, I hope you translate it to your language. Copy English, just translate gray parts into your language, and please post it as this blog comment below↓. With the translation, I need to know how your language is written in your language. For example, Japanese is written as '日本語' in Japanese.</p>

<h3>How to post</h3>

<p></p>

<p class="photo">
<a href="https://picasaweb.google.com/lh/photo/t7syWE4hmjKQwvi1-Z64VA?feat=embedwebsite"><img src="https://lh6.googleusercontent.com/-TwxsRCWh6xM/TkKySuFJoBI/AAAAAAAABe4/0GbKqjGvYn8/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202011-08-11%2525201.28.34.jpg" height="182" width="400" /></a>
</p>]]></description>
<pubDate>Thu, 11 Aug 2011 01:18:33 +0900</pubDate>
<guid>http://suin.asia/2011/08/11/durarara_chat_translation</guid>
</item>
<item>
<title>[PHP] 配列を文字列に変換して取っておく4つの方法</title>
<link>http://suin.asia/2011/08/09/4_tips_to_preserve_array_as_string</link>
<description><![CDATA[<p>配列をデータベースやテキストファイルに保存したいときってありますよね。リレーショナルデータベース的には、ちゃんと最適化すべきだけど、並び替えや検索する必要がない場合は、とりあえず配列を文字列として保存したりします。<code>serialize()</code>関数を使う方法はよく知られています。この関数以外にも、PHPでは配列を文字列に変換できるものがあります。このエントリーでは、<code>serialize()</code>、<code>var_export()</code>、<code>json_encode()</code>、<code>http_build_query()</code>の4つの使い方について書きます。</p>


<h3>今回文字列化を試す変数</h3>

<p>今回文字列化を試す変数は、bool型・int型・float型・string型・添字配列・連想配列を含んだ連想配列です。</p>

<pre name="code" class="php">
$data = array(
	'bool'   => true,
	'int'    => 1,
	'float'  => 1.23,
	'string' => 'foobar',
	'array'  => array('apple', 'orange', 'strawberry'),
	'key-value' => array(
		'jp' => 'Japan', 
		'us' => 'USA', 
		'cn' => 'China',
	),
);
</pre>


<h3>1. serialize()</h3>

<p>この関数は変数を文字列化できることでよく知られています。変換された文字列は型・大きさ・値を保持するようになっています。</p>

<pre name="code" class="php">
$serial = serialize($data);
var_dump($serial);
// string(285) "a:6:{s:4:"bool";b:1;s:3:"int";i:1;s:5:"float";d:1.229999999999999982236431605997495353221893310546875;s:6:"string";s:6:"foobar";s:5:"array";a:3:{i:0;s:5:"apple";i:1;s:6:"orange";i:2;s:10:"strawberry";}s:9:"key-value";a:3:{s:2:"jp";s:5:"Japan";s:2:"us";s:3:"USA";s:2:"cn";s:5:"China";}}"
</pre>

<p>シリアライズされた文字列を、再び配列に戻すには<code>unserialize()</code>関数を使います。元のデータをしっかり復元してくれます。</p>

<pre name="code" class="php">
$serialImported = unserialize($serial);
var_dump($serialImported);
/*
array(6) {
  ["bool"]=>
  bool(true)
  ["int"]=>
  int(1)
  ["float"]=>
  float(1.23)
  ["string"]=>
  string(6) "foobar"
  ["array"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
    [2]=>
    string(10) "strawberry"
  }
  ["key-value"]=>
  array(3) {
    ["jp"]=>
    string(5) "Japan"
    ["us"]=>
    string(3) "USA"
    ["cn"]=>
    string(5) "China"
  }
}
*/
var_dump($data === $serialImported); // true

</pre>

<h3>2. var_export()</h3>

<p><code>var_export()</code>関数はPHPとして解釈可能な文字列に変換します。第二引数に何も指定しないと、文字列に変換した結果が出力されます。変数に代入するときは第二引数にtrueを指定します。</p>

<pre name="code" class="php">
$php = var_export($data, true);
var_dump($php);
/*
string(267) "array (
  'bool' => true,
  'int' => 1,
  'float' => 1.23,
  'string' => 'foobar',
  'array' => 
  array (
    0 => 'apple',
    1 => 'orange',
    2 => 'strawberry',
  ),
  'key-value' => 
  array (
    'jp' => 'Japan',
    'us' => 'USA',
    'cn' => 'China',
  ),
)"
*/
</pre>

<p><code>var_export()</code>関数には、<code>unserialize()</code>関数のようにインポートする直接的に対応する関数はありません。そのかわりに、<code>eval()</code>関数で文字列を評価します。</p>

<pre name="code" class="php">
eval('$phpImported = '.$php.';');

var_dump($phpImported);

/*
array(6) {
  ["bool"]=>
  bool(true)
  ["int"]=>
  int(1)
  ["float"]=>
  float(1.23)
  ["string"]=>
  string(6) "foobar"
  ["array"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
    [2]=>
    string(10) "strawberry"
  }
  ["key-value"]=>
  array(3) {
    ["jp"]=>
    string(5) "Japan"
    ["us"]=>
    string(3) "USA"
    ["cn"]=>
    string(5) "China"
  }
}
*/

var_dump($data === $phpImported); // true
</pre>

<h3>3. json_encode()</h3>

<p><code>json_encode()</code>関数は、JSON形式の文字列に変換します。この関数はPHP5.2で導入されました。</p>

<pre name="code" class="php">
$json = json_encode($data);
var_dump($json);
// string(143) "{"bool":true,"int":1,"float":1.23,"string":"foobar","array":["apple","orange","strawberry"],"key-value":{"jp":"Japan","us":"USA","cn":"China"}}"
</pre>

<p>再び配列に戻すときは<code>json_decode()</code>関数を使います。第二引数を指定しないと、戻り値がオブジェクト型になります。戻り値を配列型として受け取るには、第二引数にtrueを指定する必要があります。</p>

<pre name="code" class="php">
$jsonImported = json_decode($json, true);

var_dump($jsonImported);
/*
array(6) {
  ["bool"]=>
  bool(true)
  ["int"]=>
  int(1)
  ["float"]=>
  float(1.23)
  ["string"]=>
  string(6) "foobar"
  ["array"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
    [2]=>
    string(10) "strawberry"
  }
  ["key-value"]=>
  array(3) {
    ["jp"]=>
    string(5) "Japan"
    ["us"]=>
    string(3) "USA"
    ["cn"]=>
    string(5) "China"
  }
}
*/

</pre>

<h3>4. http_build_query()</h3>

<p><code>http_build_query()</code>関数は、配列をクエリーストリング形式に変換します。この関数はPHP5から利用できます。</p>

<pre name="code" class="php">
$query = http_build_query($data);
var_dump($query);
// string(170) "bool=1&int=1&float=1.23&string=foobar&array%5B0%5D=apple&array%5B1%5D=orange&array%5B2%5D=strawberry&key-value%5Bjp%5D=Japan&key-value%5Bus%5D=USA&key-value%5Bcn%5D=China"
</pre>

<p>デコードには、<code>parse_str()</code>関数を使います。第二引数を指定しないと<code>extract()</code>関数のように、配列のキーで変数を定義します。第二引数を変数すると、デコードした結果がその変数に代入されます。<code>parse_str()</code>関数はすべて文字列型に解釈するので注意が必要です。</p>

<pre name="code" class="php">
parse_str($query, $queryImported);

var_dump($queryImported);
/*
array(6) {
  ["bool"]=>
  string(1) "1"
  ["int"]=>
  string(1) "1"
  ["float"]=>
  string(4) "1.23"
  ["string"]=>
  string(6) "foobar"
  ["array"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
    [2]=>
    string(10) "strawberry"
  }
  ["key-value"]=>
  array(3) {
    ["jp"]=>
    string(5) "Japan"
    ["us"]=>
    string(3) "USA"
    ["cn"]=>
    string(5) "China"
  }
}
*/

var_dump($data === $queryImported); // false
</pre>]]></description>
<pubDate>Tue, 09 Aug 2011 15:30:30 +0900</pubDate>
<guid>http://suin.asia/2011/08/09/4_tips_to_preserve_array_as_string</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>XOOPS Cubeでスライドショーを作れるプリロード JquerySlideShow</title>
<link>http://suin.asia/2011/08/08/xoops_slide_show</link>
<description><![CDATA[<a href="http://dl.dropbox.com/u/949822/Downloads/JquerySlideShow.class.php" class="download">JquerySlideShow</a>

<p><a href="http://usadeki.jp/modules/d3forum/index.php?topic_id=667">うさでき</a>のmikaさんの投稿を読みながら、もう少し手軽にできるようになるといいなーと思って、XOOPS Cubeで簡単にスライドショーを作れるプリロードを作ってみました。急いで作ったので、結構テキトーです。なにか問題があったら教えてください。</p>

<p>ちなみに、どんなスライドショーができるかは、<a href="http://usadeki.jp/">うさできのトップページ</a>を見てみてください。</p>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/m2AolCeRPfoq5qrO89S-IA?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-FMxHqFrWCcU/Tj7R1K5EGxI/AAAAAAAABec/DHKW8k5snFc/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202011-08-08%2525202.45.17.jpg" height="135" width="400" /></a></p>

<h3>インストール方法</h3>

<p>ダウンロードした JquerySlideShow.class.php を/preloadフォルダにアップロードするだけです。</p>

<p>ちなみに、このファイルだけでは動作しません。jquery.jsが必要です。XCL2.2ならデフォルトで入ってます。XCL2.1の人でよく分からない人は<a href="http://dl.dropbox.com/u/949822/Downloads/Jquery.class.php.zip">Jquery.class.php</a>を/preloadフォルダに入れといてください。</p>

<h3>使い方</h3>


<p>基本的にテーマのすきなところにタグを埋め込めこんで使います。編集するテーマのファイはたぶん/themes/あなたのテーマ/theme.htmlです。埋め込み方は下の説明を御覧ください。</p>


<h4>[基本編] テーマで使う</h4>

<p>画像の大きさを指定して、画像のURLを1行ずつ列挙するだけ</p>

<pre>
&lt;{slideshow width=680 height=80}&gt;
http://example.com/path/to/image1.png
http://example.com/path/to/image2.png
http://example.com/path/to/image3.png
&lt;{/slideshow}&gt;
</pre>


<h4>[発展編] 画像のリンク先を指定する</h4>

<p>画像のURLの次に、半角スペースを挟んでリンク先のURLを指定すると、画像にリンクがつきます。</p>

<pre>
&lt;{slideshow width=680 height=80}&gt;
http://example.com/path/to/image1.png http://example.com/page1.html
http://example.com/path/to/image2.png http://example.com/page2.html
http://example.com/path/to/image3.png http://example.com/page3.html
&lt;{/slideshow}&gt;
</pre>


<h4>[応用編] 画像のURLに&lt;{$xoops_url}&gt;を使う</h4>

<p>画像のURLに&lt;{$xoops_url}&gt;を使うと、サイトのURLが変わったときに、URLを書き換える必要がないので便利です</p>

<pre>
&lt;{slideshow width=680 height=80}&gt;
&lt;{$xoops_url}&gt;/uploads/myalbum/1.png &lt;{$xoops_url}&gt;/modules/pico/index.php?content_id=1
&lt;{$xoops_url}&gt;/uploads/myalbum/2.png &lt;{$xoops_url}&gt;/modules/pico/index.php?content_id=2
&lt;{$xoops_url}&gt;/uploads/myalbum/3.png &lt;{$xoops_url}&gt;/modules/pico/index.php?content_id=3
&lt;{/slideshow}&gt;
</pre>

-----------------------------------------------------

<h4>[応用編] カスタムブロックで使う</h4>

<p>カスタムブロックの「コンテンツ」に次のようなコードを埋め込みます。
カスタムブロックの「タイプ」は「PHPスクリプト」を指定します。</p>

<pre class="php" name="code">
$params = array(
  'width' => 680, // 幅指定
  'height' => 80, // 縦指定
);
$images ="
http://example.com/path/to/image1.png
http://example.com/path/to/image2.png
http://example.com/path/to/image3.png
";
JquerySlideShow::renderSlideShow($params, $images);
</pre>]]></description>
<pubDate>Mon, 08 Aug 2011 02:57:45 +0900</pubDate>
<guid>http://suin.asia/2011/08/08/xoops_slide_show</guid>
<category domain="http://suin.asia/tag/XOOPS">XOOPS</category>
<category domain="http://suin.asia/tag/jQuery">jQuery</category>
</item>
<item>
<title>[PHP]interfaceの命名規約いろいろ</title>
<link>http://suin.asia/2011/08/06/interface_naming</link>
<description><![CDATA[<p>PHPのinterfaceの命名規約ってどういうのがいいんだろう？Javaや他の言語の命名規則をあつめてみた。うちは、こんな命名規則でやってます、というのがあったら教えてください。</p>

<h3>1. Iを接頭辞にする</h2>

<pre class="php" name="code">
interface IUser {}
</pre>

<ul>
<li>○ 慣れればインターフェイスだと比較的分かりやすいかも。</li>
<li>○ ファイル名でソートしたときに、インターフェイスが集まる。</li>
<li>× Iが見えにくい。細い。</li>
<li>感想: ハンガリアン記法っぽくて嫌い。</li>
</ul>

<h3>2. Interfaceを接尾辞にする</h3>

<pre class="php" name="code">
interface UserInterface {}
</pre>

<ul>
<li>○ インターフェイスって分かりやすい。</li>
<li>○ もうクラスがあって、それをインターフェイスに抽象化するときは、クラス名に接尾辞つけるだけ。</li>
<li>× インターフェイス定義だけ見ると冗長。</li>
<li>× 長い。</li>
<li>感想: 悪くないと思う。</li>
</ul>


<h3>3. -ableを接尾辞にする</h3>

<pre class="php" name="code">
interface Countable {}
</pre>

<ul>
<li>インターフェイスは能力を表すという世界観。</li>
<li>○ 慣れればインターフェイスって分かりやすい。</li>
<li>→ クラスに-ableを使うことを禁止しないとごっちゃになる。</li>
<li>× 英語力がないとインターフェイス名考えるのが辛い。</li>
<li>感想: なんとなくいいかも。</li>
</ul>


<h3>4. 完全に自由</h3>

<pre class="php" name="code">
interface FooBar {}
</pre>

<ul>
<li>× クラス名とかぶるとめんどくさい。</li>
<li>× type-hintingとかuseとかinstanceofでインターフェイスって分かりにくい。</li>
<li>→ 分からなくても困らないかも？</li>
<li>○ 臨機応変に名前をつけられる。</li>
</ul>]]></description>
<pubDate>Sat, 06 Aug 2011 13:13:00 +0900</pubDate>
<guid>http://suin.asia/2011/08/06/interface_naming</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>とりあえず自分のPCからxoopscube.jpを見られるようにする方法(MacOSX)</title>
<link>http://suin.asia/2011/08/01/xoopscube.jp</link>
<description><![CDATA[<p>2011/08/01現在xoopscube.jpが閲覧できなくなっています。
Google(8.8.8.8)にnslookupしてみると、解決できないじょうたいです。
推測ですが、xoopscube.jpのDNSの設定が変わったか、設定が削除されたんじゃないでしょうか。</p>

<p>xoopscube.jpが見れないのは不便なので、とりあえず自分のPCからだけは見られるようにする方法を紹介します。
自分がMac使いなので、Macでのやり方になります。（ここでは専用のアプリを入れますが、やっていることはhostsファイルを書き換えるだけです。Windowsにもhostsファイルがあるので同じようなことができるはずです。）</p>

<p>まず、<a href="http://www.redwinder.com/macapp/hoster/">Hoster</a>というアプリをダウンロードしてください。
ダウンロードが完了したらインストールします。
インストールが終わったら起動してみましょう。起動すると下のような画面が出ます。</p>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/CoZHPnOqgCI7YJ8JqZKAeg?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-ax3Wmgyuxm0/TjaBGnIne4I/AAAAAAAABd8/27XEZY1A8bk/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525EF%2525BC%2525882011-08-01%25252019.21.16%2525EF%2525BC%252589.png" height="400" width="270" /></a></p>

<p>緑のプラスボタンをクリックします。フォームが出ると思うので、下の内容のとおりに値を入力してください。</p>

<pre>
セット名：XOOPS Cube
ホスト名：xoopscube.jp
IP: 210.143.106.113
</pre>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/DJthljrj2aLw12oQvIYxcw?feat=embedwebsite"><img src="https://lh4.googleusercontent.com/-uV1AuPPLTYk/TjaBGZFEx6I/AAAAAAAABd8/liCKmEvWqc0/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525EF%2525BC%2525882011-08-01%25252019.22.08%2525EF%2525BC%252589.png" height="400" width="265" /></a></p>

<p>入力が終わったら、「ホスト追加」ボタンを押してホストを追加し、「終了」でフォームを閉じます。
閉じると、「セット名」にXOOPS Cubeが追加されていると思います。</p>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/-CNFoOQuLIznka8rZuHmJw?feat=embedwebsite"><img src="https://lh5.googleusercontent.com/-F67hd1Cg44s/TjaBGWixoHI/AAAAAAAABd8/rwmQaelIMA4/s400/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525EF%2525BC%2525882011-08-01%25252019.22.41%2525EF%2525BC%252589.png" height="400" width="270" /></a></p>

<p>最後に、「XOOPS Cube」の左にある、グレーのまるポチをクリックします。
すると、「1件の設定をホスツファイルへ反映しました」というポップアップが表示されます。</p>

<p class="photo"><a href="https://picasaweb.google.com/lh/photo/eJulCPowwuBItKmyOTlI9A?feat=embedwebsite"><img src="https://lh6.googleusercontent.com/-QS6xTIhfRQk/TjaBGfsa1nI/AAAAAAAABd8/T1N2INDIttE/s800/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525EF%2525BC%2525882011-08-01%25252019.23.27%2525EF%2525BC%252589.png" height="97" width="325" /></a></p>

<p>この状態で、http://xoopscube.jp を開いてみてください。今まで通り、xoopscube.jpのサイトが見れるはずです。</p>

<p>なお、xoopscube.jp が復活したときは、上で追加したXOOPS Cubeセットを削除するだけです。
またHosterが起動していないときは、xoopscube.jp から 210.143.106.113へのホスティングはされないので、
xoopscube.jpを見たいときはHosterを起動するようにします。</p>


<p>ちなみに、xoopscube.jpのドメイン有効期間は2011/08/31までなので、ドメイン自体がなくなったわけではなさそうです。</p>]]></description>
<pubDate>Mon, 01 Aug 2011 19:35:49 +0900</pubDate>
<guid>http://suin.asia/2011/08/01/xoopscube.jp</guid>
<category domain="http://suin.asia/tag/xoops">xoops</category>
<category domain="http://suin.asia/tag/cube">cube</category>
</item>
<item>
<title>[PHP] abstractとinterfaceの使い分けを整理してみる</title>
<link>http://suin.asia/2011/07/18/php_abstract_vs_interface</link>
<description><![CDATA[<h3>abstractとinterfaceの違いを自信持って使い分けてる?</h3>

<p>abstractとinterfaceの言語仕様はよく似てる。とても混同しやすい。PHPで自身をもって使い分けている人はどれくらいいるかな？少なくとも自分は全部abstractでもいいと思っている（いた）。でも、interfaceはオブジェクト指向できっと重要な概念だろうから、しっかり区別したいな。Twitterでオブジェクト指向に詳しそうな人に聞きいたり、ググったりして調べて自分なりに理解した内容をまとめてみるよ。</p>

<h3>似てる点</h3>

<ul>
<li>そのままでは呼び出せない。abstractはextends、interfaceはimplementsしてはじめて使える。</li>
<li>抽象メソッドを定義できる(see code.1)。ちなみにそれらは子クラスで必ず実装しないといけない。</li>
</ul>

<pre class="php" name="code">
// code.1
abstract class AbstractFoo
{
	abstract public function bar();
}

interface InterfaceFoo
{
	public function bar();
}
</pre>

<h3>異なる点</h3>

<ul>
<li>classはabstractを1つだけextendsできるが、classはinterfaceを複数implementsできる(see code.2)。</li>
<li>abstractは具体的な実装があるメソッドを持てる。interfaceは単に抽象メソッドを列挙するだけ(see code.3)。</li>
</ul>

<pre class="php" name="code">
// code.2
class Hoge extends AbstractFoo
{
}

class Hoge implements InterfaceFoo, InterfaceFoo2, InterfaceFoo3
{
}
</pre>


<pre class="php" name="code">
// code.3
abstract class AbstractFoo
{
	abstract public function bar();

	public function baz()
	{
		echo 'baz!';
	}
}

interface InterfaceFoo
{
	public function bar();
	public function baz();
}
</pre>

<h3>この言語仕様を踏まえてどう使い分けるか?</h3>

<p>「interfaceを使うくらいなら、abstract一辺倒でよくない？いざとなったらabstractに具体的な実装もできるしね」と思っている人はきっと自分だけじゃないと思う。ここではabstractじゃなくてinterfaceを使ったほうがいい、って例を説明していくよ。だから、interfaceのほうにフォーカスした内容になってる。読者はabstractの使い方をよく知っているし、よく使っているという前提ね。</p>

<h4>仕様書はinterfaceにできるかも</h4>

<p>interfaceは具体的な実装を持てない。これは設計書として利用できるかも知れない。今までドキュメントに書いていたクラスの仕様はinterfaceにすることができるってこと。例えば、こんな仕様書があったとする。</p>

<blockquote>
<p>仕様書</p>
<ul>
<li>データベースクライアントクラスは次の4つのメソッドを提供しなければなりません。</li>
<li>書き込みメソッド。メソッド名: create()。引数は保存するデータ(連想配列)。</li>
<li>読み込みメソッド。メソッド名: load()。引数は読み込む行のID(整数)。</li>
<li>上書きメソッド。メソッド名: update()。引数は上書きする行のID(整数)と保存するデータ(連想配列)。</li>
<li>削除メソッド。メソッド名: delete()。引数は削除する行のID(整数)。</li>
</ul>
</blockquote>

<p>文書の仕様書を否定するつもりはないけど、人の言葉で書かれた仕様書は曖昧だったりする。上の仕様書でも、戻り値がよくわかんないし、update()の引数の順番は曖昧だし、引数は必須なのか任意なのか分かんない。</p>

<p>紙の仕様書は、メンテナンスされないこともあるよね。仕様書がなくともプログラムは正常に動作するから。もし、仕様書がプログラムに組み込まれたらどうだろう？仕様書がメンテナンスされなければプログラムが動かないので、仕様書をメンテするようになるよね、きっと。</p>

<p>上の仕様書は、interfaceに翻訳することができるんだ(code.4)。下の例のほうが文書の仕様書より曖昧性が低いよね。それに、仕様変更があったときもエラーとして気が付きやすい。例えば、複数行を取得したくなって、メソッド<code>find(array $condition)</code>を追加したとする。find()を実装していないサブクラスはエラーになるんだ。</p>

<pre class="php" name="code">
// code.4
interface DatabaseClient
{
	/**
	 * テーブルに行を追加する
	 * @returns bool 保存に成功したらtrue、失敗したらfalse
	 */
	public function create(array $data);

	/**
	 * テーブルの行のデータを取得する
	 * @returns mixed 読み込みに成功したら配列、失敗したらfalse
	 */
	public function load($id);

	/**
	 * テーブルの行を更新する
	 * @returns bool 保存に成功したらtrue、失敗したらfalse
	 */
	public function update($id, array $data);

	/**
	 * テーブルの行を削除する
	 * @returns bool 削除に成功したらtrue、失敗したらfalse
	 */
	public function delete($id);
}
</pre>

<p>これはabstractでも同じような書き方ができるね。でも、具体的な実装を持たないならinterfaceにしたほうがいいかもしれないよ。interfaceは実装を持てない。これって、シンプルという長所でもあるよね。仕様を提供する側のコストがミニマムになる。それに、プログラマは最低限のリードタイムで「ここだけ実装しておけばいいのね」ということが分かるようになる。abstractだったら、そのクラスの内部実装にまで目を配らないといけないよね。つまり、interfaceのほうが設計者とプログラマの両者にとってストレスが少ないってことになるね。（ひとりで開発する場合は別かもしれないけど）</p>

<h4>呼び出し方は同じだけど、内部の処理は全然ちがう場合はinterface</h4>

<p>最近のウェブアプリはログインするものが多いよね。内部的なこと言ったら認証処理だね。認証処理ってのは、アプリ側が「あなたはだれ？」が特定できればよくて、それ以外の関心はない処理なんだけど、一方で、認証処理は様々なものがある。アプリ独自の認証方式、OpenID、LDAP、Basic認証、Twitter認証、Facebook認証、社内独自認証などなど。</p>

<p>このケースだと、interfaceを活用できる。ウェブアプリは、認証方法の詳細について口出ししない。その代わり、「interfaceに実装してほしいauthorize()っていうメソッドを定義しておいたよ。」っていう約束だけ決めて(code.5)、「うちはそれだけを呼び出すから、あとはうまいことやってね」と具体的な認証方法は各認証オブジェクトにまるなげする。</p>

<pre class="php" name="code">
// code.5
interface Auth
{
	/**
	 * 認証処理を行う
	 * @returns bool 成功したらtrue、失敗したらfalseを返す
	 */
	public function authorize();
}
</pre>

<p>それで、各認証方式を受け持つオブジェクトは、authorize()を独自に実装する(code.6)。</p>

<pre class="php" name="code">
// code.6
class OpenID implements Auth
{
	public function authorize()
	{
		if ( $this->_openIdAuth() )
		{
			return true;
		}

		return false;
	}

	protected function _openIdAuth()
	{
		// オープンIDで認証する処理
	}
}
</pre>

<p>この例では、abstractはほとんど役に立たないよね。だって、ウェブアプリは認証方式の詳細に口出し（具体的な実装を提供）することができないから。各認証処理は全く異なった実装になるだろうね。具体的な実装の共通化は容易じゃない。無理して共通化に心を砕くくらいなら、interfaceにしたほうがいさぎよい、と思う。</p>

<h3>まとめ</h3>

<p>今回、調べていて気づいた点をまとめると、interfaceの出番は次のようになる。もっと、勉強してinterfaceを上手く使えるようになりたいな。</p>

<ul>
<li>仕様書はinterfaceにできるかも</li>
<li>呼び出し方は同じだけど、内部の処理は全然ちがう場合はinterface</li>
</ul>

<h3>参考になるページ</h3>

<ul>
<li><a href="http://havelog.ayumusato.com/develop/php/e166-php-interface-abstract.html">PHPのinterfaceとabstractを正しく理解して使い分けたいぞー ::ハブろぐ</a></li>
<li><a href="http://d.hatena.ne.jp/anatoo/20080517/1211029059">PHPにはインターフェイスというものがありますよ、という話 - id:anatooのブログ</a></li>
<li><a href="http://www39.atwiki.jp/fujiyan/pages/28.html">ふじやん雑記帳 - とりあえずインターフェース入門</a></li>
<li><a href="http://members.jcom.home.ne.jp/maripiyo.k/UC/uc_lec100/cosc121/java_ch5.htm">５章　インターフェース --Interface--</a></li>
</ul>]]></description>
<pubDate>Mon, 18 Jul 2011 15:08:30 +0900</pubDate>
<guid>http://suin.asia/2011/07/18/php_abstract_vs_interface</guid>
<category domain="http://suin.asia/tag/PHP">PHP</category>
</item>
<item>
<title>「WeeklyCMS 6/24 マイクロソフト本社特番03」の補足など</title>
<link>http://suin.asia/2011/07/02/supporting_for_weeklycms_presentation</link>
<description><![CDATA[<p>「WeeklyCMS 6/24 マイクロソフト本社特番03」はセキュリティ回で、ちょっと補足したほうがいいかなーと思ったんで、ブログエントリにしちゃいます。XOOPSモジュール開発しようって人に参考になればなぁと。</p>

<p class="photo">
WeeklyCMS 6/24 マイクロソフト本社特番03<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="296" id="utv297310" name="utv_n_645199"><param name="flashvars" value="loc=%2F&amp;autoplay=false&amp;vid=15602462&amp;locale=ja_JP&amp;hasticket=false&amp;v3=1" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.ustream.tv/flash/viewer.swf" /><embed flashvars="loc=%2F&amp;autoplay=false&amp;vid=15602462&amp;locale=ja_JP&amp;hasticket=false&amp;v3=1" width="480" height="296" allowfullscreen="true" allowscriptaccess="always" id="utv297310" name="utv_n_645199" src="http://www.ustream.tv/flash/viewer.swf" type="application/x-shockwave-flash" /></object>
</p>

<h3>Check Secure Code (04:47〜)</h3>

<h4>$_POST/GETをforeach展開</h4>

<pre class="php" name="code">
foreach ( $_POST as $key => $value )
{
	$$key = $value;
}
</pre>

<p>「見かけたら即デリート」ということで、危険性と置き換え方がはしょられてる。時間の都合かなーと思いつつ…。</p>

<p>こういうコードの危険性としては、$_SERVERなどの変数を容易に乗っ取られてしまう点。置き換え方は、必要な変数だけ定義するようにすること。たとえば、下の例のように。</p>

<pre class="php" name="code">
// title, text, posterだけがあればいいとき
$title  = $_POST['title'];
$text   = $_POST['text'];
$poster = $_POST['poster'];
</pre>

<h4>intvalはエースケープ関数じゃない^^;</h4>

<p>bluemoonさんによると、下の例がまずいらしい。</p>

<pre class="php" name="code">
$hoge = isset($_GET['hoge']) ? $_GET['hoge'] : 0 ;</pre>

<p>そして、整数を受け取る前提のものは、次のように書き換えるべきだとしてる</p>

<pre class="php" name="code">
$hoge = isset($_GET['hoge']) ? intval($_GET['hoge']) : 0 ;</pre>

<p>最初に整数にしといたほうが安全になるのは確か。HTMLに出すとき、SQLのクエリに入れるときのどちらにも対応できるから。でも、ユーザの入力を勝手に書き換えるのはあまりベストじゃない。だから、この場合は$_GETから取るときはintvalしないでおいて、HTMLに出すときにhtmlspecialchars($hoge, ENT_QUOTES, 'UTF-8')、SQLのクエリにするときにmysql_real_escape_string($hoge)しておくのがいいと思う。</p>

<h4>htmlspecialchars()はHTMLに出す直前に</h4>

<p>「文字列だったら、htmlspecialcharsで」とのこと。そしてそのサンプルがこれ。</p>

<pre class="php" name="code">
$hoge = isset($_GET['hoge']) ? htmlspecialchars($_GET['hoge'], ENT_QUOTES) : "" ;</pre>

<p>そのとおりなんだけど、$_GETから取った直後にhtmlspecialchars()をかけることはXOOPSのモジュールではほとんどない。Smartyに変数を渡す直前でやるのが通常かなと。なぜなら、リクエストをもとに何かデータをこねくり回す(DBを参照したり)ことが多いから。そのとき、HTMLエンコードされた文字列だといろいろ不便だから。なので、やっぱりこれもintval同様に$_GETから値をとった段階では生にしとく。</p>

<pre class="php" name="code">
$hoge = isset($_GET['hoge']) ? $_GET['hoge'] : "" ;

// $hogeをもとにデータをこねくり回す処理

$hoge = htmlspecialchars($hoge, ENT_QUOTES, 'UTF-8');

$xoopsTpl->assign('hoge', $hoge); // smartyに$hogeを渡す

</pre>

<h3>SQL Injection (6:01〜)</h3>

<h4>addslashes()じゃなくてmysql_real_escape_string()を使おう</h4>

<p>録画の中でSQLインジェクションの対策として、addslashes()関数をつかうことを勧めてる。addslashes()でも、SQLのエスケープをうまくやってくれる。実際に、XOOPSのコードのいたるところにaddslashes()がある。でも、addslashes()はクエリエスケープ用の関数じゃないので、SQLインジェクション対策に使うのはちょっと意味が違う。やっぱり、ここはMySQL専用エスケープ関数のmysql_real_escape_string()を使おう。</p>

<p>Mac大好きな<a href="http://twitter.com/k_mikage">mikageさん</a>が会場がMicrosoftなのに「PCじゃなくてMacです、PCというとWindowsです」と言っちゃってるとこを見て、ポカリふきそうになったｗ そのあと、Microsoftの<a href="http://twitter.com/masakit_ms">武田さん</a>が発表の前振りで「すいません、PCでっ」ってｗｗ6/24ほんとに行きたかったし、行けなくてもリアルタイムで放送見たかったよーT_T</p>]]></description>
<pubDate>Sat, 02 Jul 2011 22:45:11 +0900</pubDate>
<guid>http://suin.asia/2011/07/02/supporting_for_weeklycms_presentation</guid>
<category domain="http://suin.asia/tag/WeeklyCMS">WeeklyCMS</category>
<category domain="http://suin.asia/tag/XOOPS">XOOPS</category>
</item>
<item>
<title>Concrete5:サイトタイトル日英対応のTips</title>
<link>http://suin.asia/2011/07/01/concrete5_switch_title_for_each_language</link>
<description><![CDATA[<p>Concrete5若葉マークのsuinです。サイトのタイトルを日英で切り替える方法を紹介します。</p>

<p>ます、前提としてConcrete5(5.4.0.5)は多言語対応機能がないみたいです。ググった範囲ですが。
(本気で日英対応しようと思ったら<a href="http://www.hodajuku.org/">XOOPSCubeホダ塾ディストリ</a>、<a href="http://modx.jp/">MODx</a>がいんじゃないかな...(´・ω・｀))さておき、多言語対応ない状況下で日英サイトを作る場合は次のようなサイトマップ構成にするのが定石みたいです。確かな情報じゃなくてすみません、なんせ初心者なので。</p>

<pre>
├── en
│   ├── page1
│   ├── page2
│   └── page3
└── ja
    ├── page1
    ├── page2
    └── page3
</pre>

<p>次に、サイトタイトル日英対応とはどういうものか簡単に説明します。日本語ページ(/ja以下)では「○○研究室」、英語ページ(/en以下)では「xxx Laboratory」といったように、サイトのタイトルを切り替える仕組みです。&lt;title&gt;タグはもちろん、&lt;h1&gt;タグに現れるタイトルを切り替えます。</p>

<p>最後に、サイトタイトル日英対応の実装方法を説明します。直感からするとテーマのテンプレートをいじるだけでできそうですが、titleタグをレンダリングしている<code>Loader::element('header_required')</code>が簡単にオーバーライドできないようなので、ちょっとまどろっこしい対応になります。</p>

<p>/config/site.phpに英語の時だけSITE定数を定義する処理を実装します。SITE定数はtitleタグに表示されるサイトタイトルとなります。Concrete5の仕様として、SITE定数が定義することでサイトタイトルをオーバーライドできるみたいです。なので、日本語ページのときは、管理画面で設定したサイトタイトルをそのままつかうことになります。コードの例としては次のようになります。</p>

<pre class="php" name="code">
function is_english()
{
	$requestUri = '/'.trim($_SERVER['REQUEST_URI'], '/').'/';
	return ( strpos($requestUri, '/en/') !== false );
}

if ( is_english() === true )
{
	define('SITE', 'English Site Title');
}
</pre>

<p>これで、サイトタイトルが現れる部分は一括して日英対応できるはずです。Concrete5のView、もうちょっと拡張性に融通がきくようになるといいなぁ〜</p>]]></description>
<pubDate>Fri, 01 Jul 2011 13:09:50 +0900</pubDate>
<guid>http://suin.asia/2011/07/01/concrete5_switch_title_for_each_language</guid>
<category domain="http://suin.asia/tag/concrete5">concrete5</category>
<category domain="http://suin.asia/tag/tips">tips</category>
</item>
<item>
<title>TwitterにいるXOOPSのすごい人リスト</title>
<link>http://suin.asia/2011/06/17/super_xoopsers_in_twitter</link>
<description><![CDATA[<p>最近、XOOPS関係のつぶやきが多い人や、XOOPSで活発な人のリスト。完全に、<a href="http://d.hatena.ne.jp/sotarok/20110617/1308227462">便乗</a>です。</p>

<p>
<a href="http://twitter.com/domifara">@domifara</a> (すごい活発な人)<br />
<a href="http://twitter.com/bluemooninc">@bluemooninc</a> (weeklycmsの人)<br />
<a href="http://twitter.com/love_marijuana">@love_marijuana</a> (デベロッパーズバイブルの人)<br />
<a href="http://twitter.com/umotti">@umotti</a> (うさできの人)<br />
<a href="http://twitter.com/nbuy">@nbuy</a> (eguideの人)<br />
<a href="http://twitter.com/naaon">@naaon</a> (d3diaryの人)<br />
<a href="http://twitter.com/AXYZ_SAK">@AXYZ_SAK</a> (アクシズの人)<br />
<a href="http://twitter.com/naomi_xoops">@naomi_xoops</a> (テーマの人)<br />
<a href="http://twitter.com/kilica">@kilica</a> (XCL2.2コアの人)<br />
<a href="http://twitter.com/naopon">@naopon</a> (xpWikiの人)<br />
<a href="http://twitter.com/nunoluciano">@nunoluciano</a> (XCL2.2コアの人)<br />
<a href="http://twitter.com/ohwada">@ohwada</a> (OpenIDの人)<br />
<a href="http://twitter.com/tohokuaiki">@tohokuaiki</a> (D3ブログの人)<br />
<a href="http://twitter.com/RyujiAMANO">@RyujiAMANO</a> (ryusの偉い人)
</p>]]></description>
<pubDate>Fri, 17 Jun 2011 12:12:57 +0900</pubDate>
<guid>http://suin.asia/2011/06/17/super_xoopsers_in_twitter</guid>
<category domain="http://suin.asia/tag/XOOPS">XOOPS</category>
<category domain="http://suin.asia/tag/Twitter">Twitter</category>
</item>
</channel>
</rss>
