引っ越すぞ
Smarty でタブを作るプラグイン
phpを書くときは、Smarty 必須状態なのですが、今まで外部プラグイン機能は一切付け加えず、デフォルトのコマンドだけで作っていました。それで特に困ったことはないんだけれど、プラグインを使ってみたくなり作ったのが、smarty_function_hetima_tab。
公式WikiのSmarty Pluginsページ に html_tabs というのが投稿されてますが、これはタブごとに異なるページを呼び出す、いわばタブ風リンク生成プラグイン。
そういうのではなくて、1ページの中でdisplay属性を切り替えるプラグインが欲しかった。これまではベタにHTMLとスクリプトを書いていましたが、プラグイン化することでテンプレートがすっきりしました。使い方はサンプルやソースのコメントを参照してください(ファイルの文字コードはUTF-8)。スタイルシートもスクリプトも自動生成します。スタイルシートに関してはページに合わせる必要がある場合は別途記入するかソースを直接いじるかしないといけないですが。
PEAR::Auth の Auth_Container_DB に前もって用意していた PEAR::DB を与える
PEAR::Auth (1.3.0) とPEAR::DBを使っていると、Authで使われるDBがメインで使うものと別個に生成されるのが気持ち悪い。また、MySQL4.1以降では、"SET NAMES 'utf8'"を実行しておかないと、環境によっては$auth->getAuthData()の結果が文字化けする。そういう理由からもメインで用意したDBを使いたい。
AuthやAuth_Container_DBのコンストラクタにはオブジェクトを直接与えることが可能なので、先にDBを与えたAuth_Container_DBを作ってからAuthを作れば良さそうだと思った。しかし実際試してみると、この方法ではパラメータの初期化が行われないのでテーブル名などを設定できない。んで、ソースを読んで突き止めたのが、DSN文字列の代わりにPEAR::DBのインスタンスを渡すという方法。
$params=array(
"dsn" => "mysqli://localhost/...", //普通はここでDSN文字列だが
"table" => "account",
"usernamecol" => "id",
"passwordcol" => "pass",
"db_fields" => "*"
);
$params["dsn"] = $db; //DSN文字列ではなくDBオブジェクトをセット
$auth=new Auth("DB", $params, $app_auth_func);
これで正常に動いた。Auth_Container_DBの_connect($dsn)メソッド内で、$dsnが文字列か配列ならDB::Connect()を呼び、$dsnがdb_commonのサブクラスなら(つまりPEAR::DBのオブジェクトなら)直接インスタンス変数に代入、という振り分けをしているので上手く行く。ただし将来も動作が保証されるかどうかは分かりません。PHP4だと参照渡ししてくれないかもしれんので、PHP5専用ということで。
Ethna のアプリケーションマネージャを使うべきかどうか
アプリケーションマネージャ機能を積極的に使うべきだろうがちょっと気になる点がある。
アプリケーションマネージャとは、アクションからロジックを分離する為に、Ethna_AppManagerクラスを継承したものを「[project_id]_[manager_name]Manager」という命名規則で作って、[project_id]_Controller の var $managerに書き足すことで、主要クラスから$this->Test/*マネージャの変数名*/->echo();などと使えるようになる仕組みのこと。
で、何が気になるかというと使う使わないに関わらず初期化のときに全部インスタンス化されてしまうこと。更にデータベースにも繋げてしまう。また、$manager配列に記述するだけでは駄目で、(当たり前といえば当たり前だが)あらかじめファイルをインクルードしておかないといけない。
---- Testapp_Controller.php ----
require_once('Testapp_TestManager.php');class Testapp_Controller extends Ethna_Controller
{
....
var $manager = array(
'testmanager' => 'Test'
'af' => 'Hoge' // afを上書きしてしまう
//この配列のキーと値はどっちが何なんだか分かりにくい
);
....
}
インスタンス変数としてアクセスできるようにするため全部読み込んでいるのだろう、たぶん。データベースも$manager->dbと変数アクセスできるようにインスタンス化しているのだと思われる。また、アクセスするための変数名はノーチェックで上書きされてしまうので「af」とか既存の名前を使うと壊れてしまう。
__get()で大改造は、サブクラスでやるとしてもバージョンアップに対応できるか自信がないし、面倒くさすぎる。別のオブジェクト管理機能を付けてマネージャは使わないようにした方が楽かもしれん。
参考:
Ethna をインストール & UTF-8 化
Ethna(ethna.jp, beta.ethna.jp)を試してみることにする。PHP5にPEARでインストール。
$ pear channel-discover pear.ethna.jp $ pear install ethna/ethna-beta
ファイルの文字コードがEUC-JPなので全部UTF-8にする。テンプレートのcharsetも置き換える。
<?php $ethna_dir= '/path/to/lib/php/Ethna'; //ここで決め打ち $pattern = $ethna_dir.'/*'; $files=glob($pattern);while(count($files) > 0){
foreach($files as $file) {
conv_file($file);
}
$pattern.='/*';
$files=glob($pattern);
}function conv_file($file) {
global $ethna_dir;
if(is_dir($file)) return;
$body = file_get_contents($file);
if(stripos($body, 'EUC-JP')){
if($file!=$ethna_dir.'/class/Ethna_SmartyPlugin.php'){
$body=str_ireplace('EUC-JP', 'UTF-8', $body);
}
}
$body = mb_convert_encoding($body, 'UTF-8', 'EUC-JP');
file_put_contents($file, $body);
}
?>
というスクリプトを書いて、php cliで実行。Ethna_SmartyPlugin.phpにEUC-JPのみ対応の関数があるが、使わないので放っておく。bin/ethnaの中にパス決め打ちの箇所があるので書き直す。準備完了。
del.icio.us をコンテンツナビゲーションとして使う
自分のblogのpermalinkをdel.icio.usに全部突っ込んでみた。index.phpを改造してブックマーク.htmlを書き出し、del.icio.usでそれをimport。URLは http://del.icio.us/hetima/hetima_blog。サイトメニューに「blog 一覧 (by del.icio.us)」として追加。P_BLOGにはタイトルだけを一覧するページがないので補助になる。タグをAND検索で絞り込んだり、「他に何人ブックマークしているか」を見ることができて便利だ。
心機一転 はてなダイアリー に引っ越します。今までありがとう、P_BLOG。というわけで、基本的にここはもう更新しないだろうと思われます。