前回、resouce.db.php をフックできると操作性・開発性などで大きな改善が出来るよ、などと気を持たせておきながら、2ヶ月以上も放置してしまいました。
まず resource.db.php とは何か一応説明しておきます。これは、Smartyのリソースプラグインと呼ばれるものです。中身には「どこからテンプレートを持ってくるか」「更新状況をどうチェックするか」という処理が記述されています。
XOOPSの場合、特に指定しなければ、"db:"テンプレートが呼ばれるために、"db"リソースプラグインが重要なのです。
次に、標準のresource.db.phpによって実装されているDBテンプレートの問題点・要改善点を下に列挙してみます。
(1) テーマがdefaultだとDBテンプレートのリセット処理が入ってしまう
(2) テーマ下テンプレートによってコンパイルキャッシュが作成されるとテーマを切り替えてもそのまま残ってしまう
(3) テーマ下テンプレートのパス themes/(theme)/templates/(dirname)/(block/)? という階層構造は面倒なだけではないか? しかもDBテンプレートの実態を反映していないので余計な混乱を招く恐れがある
(4) テーマ下テンプレートの置き場所がバラバラ 本家だと themes/(theme)/modules/(dirname)/(block/)? だったりする
(5) テーマ下テンプレートが削除されても認識しない
(6) テーマ下テンプレートが追加されてもコンパイルキャッシュより古いと認識しない
このうち、(1)〜(4)について対応した resource.db.php を作ってみました(下リスト参照)。
もちろん、XoopsTplフックのおかげで、このresource.db.phpの置き場所は、XOOPS_TRUST_PATH/libs/smartyplugins/ で良く、Hackではなくなります。
残った(5)と(6)についても、なんとか対応したいと考えてます。
ホダ塾ディストリビューションでは、jidaikoboさんが、skel_flexテーマに対して積極的にテーマ下テンプレートを導入してくれていますが、このresource.db.phpによって、テーマとテンプレートがうまく連動することがお判りいただけるでしょう。(もちろん従来もテーマ下テンプレートは有効でしたが、連動はしなかった)
最新のNightlyアーカイブで試せるはずです。
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* File: resource.db.php
* Type: resource
* Name: db
* Purpose: Fetches templates from a database
* -------------------------------------------------------------
*/
function smarty_resource_db_systemTpl($tpl_name)
{
// Replace Legacy System Template name to Legacy Module Template name
static $patterns = null;
static $replacements = null;
if (!$patterns) {
$root=&XCube_Root::getSingleton();
$systemTemplates = explode(',',$root->getSiteConfig('Legacy_RenderSystem','SystemTemplate',''));
$prefix = $root->getSiteConfig('Legacy_RenderSystem','SystemTemplatePrefix','legacy');
$patterns = preg_replace('/^\s*([^\s]*)\s*$/e', '"/".preg_quote("\1","/")."/"', $systemTemplates);
$replacements = preg_replace('/^\s*system_([^\s]*)\s*/', $prefix.'_\1', $systemTemplates);
}
if ($patterns) {
$tpl_name = preg_replace($patterns, $replacements,$tpl_name);
}
return $tpl_name;
}
function smarty_resource_db_source($tpl_name, &$tpl_source, &$smarty)
{
$tpl_name = smarty_resource_db_systemTpl($tpl_name);
if ( !$tpl = smarty_resource_db_tplinfo( $tpl_name ) ) {
return false;
}
if ( is_object( $tpl ) ) {
$tpl_source = $tpl->getVar( 'tpl_source', 'n' );
} else {
$tpl_source = file_get_contents( $tpl ) ;
}
return true;
}
function smarty_resource_db_timestamp($tpl_name, &$tpl_timestamp, &$smarty)
{
$tpl_name = smarty_resource_db_systemTpl($tpl_name);
if ( !$tpl = smarty_resource_db_tplinfo( $tpl_name ) ) {
return false;
}
if ( is_object( $tpl ) ) {
$tpl_timestamp = $tpl->getVar( 'tpl_lastmodified', 'n' );
} else {
$tpl_timestamp = filemtime( $tpl );
}
return true;
}
function smarty_resource_db_secure($tpl_name, &$smarty)
{
// assume all templates are secure
return true;
}
function smarty_resource_db_trusted($tpl_name, &$smarty)
{
// not used for templates
}
// return object(XoopsTplfile) or string(filepath)
function smarty_resource_db_tplinfo( $tpl_name )
{
static $cache = array();
global $xoopsConfig;
// First, check the cache
if ( isset( $cache[$tpl_name] ) ) {
return $cache[$tpl_name];
}
$tplset = isset( $xoopsConfig['template_set'] ) ? $xoopsConfig['template_set']: 'default' ;
$theme = isset( $xoopsConfig['theme_set'] ) ? $xoopsConfig['theme_set'] : 'default';
// Second, check templates under themes/(theme)/templates/ (file template)
$filepath = XOOPS_THEME_PATH . '/' . $theme . '/templates/' . $tpl_name ;
if ( file_exists( $filepath ) ) {
return $cache[$tpl_name] = $filepath ;
}
// Third, find a DB template of the selected tplset
$tplfile_handler =& xoops_gethandler('tplfile');
$tplobj = $tplfile_handler->find( $tplset, null, null, null, $tpl_name, true); if ( empty( $tplobj ) ) {
// Forth, find a DB template in default tplset
$tplobj = $tplfile_handler->find( 'default', null, null, null, $tpl_name, true);
if( empty( $tplobj ) ) return false ;
}
return $cache[$tpl_name] = $tplobj[0];
}
?>
preload/HdXoopsTplHook.class.phpとresource.db.phpの2ファイルですけどね
今回のような1ファイル添付のみが良いです。
テンプレート配布に関してテストしておりますが、配布用のテーマ内テンプレートファイル保存時期が現在使用中のDBテンプレートより古いと反映されませんでした。
おそらくは、ローカルの編集環境の問題だと思いますよ。
今回のはX2がもともと持っていた機能の改善に過ぎないのですが、同じtrustdirname同士の共通テンプレートのクラス化、となれば、それなりに大規模な工事が必要です。
ローカルでX.C.Lを導入してテストをしましたが、theme内DBテンプレートファイルへ日本語を記入している場合は文字化けします。
また、当初の話なのですがroot内のd3forumを例えばQandAへ変えている場合と、同じd3モジュールを複数設置している場合はそれらを指定し処理を分ける事はできないものでしょうか?
先日ダウンロードしたhd_nightlyの中に入っていたskel_flexテーマを参考に疑問点をコメントさせていただきました。
skel_flex/templates/pico/ 以下にはinc_breadcrumbs.htmlが入っています。
skel_flex/ 以下にはpico_inc_breadcrumbs.htmlが入っています。
D3モジュールのtemplates/ 下にあるファイルはあくまで雛形です。
たまたま中身が書き換わっていないだけで、XOOPSのDBテンプレートそのものとは本来別物です。
逆に、テーマ下テンプレートとして置けるのはDBテンプレートと同じレベルのテンプレートです。
1) d3モジュールのテンプレートをテーマファイルへ入れる場合にテンプレート名はtrust側dirnameをxoops_trust_path側に入っているテンプレート名の前へつけるのでしょうか?
2) それともtrust側dirnameをxoops_trust_path側に入っているテンプレート名そのままで良いのでしょうか?
3) またroot側dirnameを変更している場合はroot側dirnameをxoops_trust_path側に入っているテンプレート名の前へつけるのですか?
後、使用していないモジュールのテンプレートを入れておいても特に問題は無いのでしょうか?