Edited at

XOOPSはPHPなんか分からなくとも何とかなるさあ(2)

More than 5 years have passed since last update.

⇒ アドベントカレンダーの参加者リスト

⇒ 前日の投稿 XOOPSのテーマで1~3カラム対応にする方法 by marine

⇒ 翌日の投稿 ブロックによって表示方法を変えるテーマの修正方法 by mika

先週は基礎中の基礎と言うことで、XOOPSにおいてのPHPとSmarty変数の役割について説明しました。「もうそんなこと知ってるよ、大体Qiita利用者の層から言ってもそんなの常識だろヴォケ!」とのお叱りが聞こえてきそうですが、私自身のレベルがその程度なので平にご容赦を。

さて今日はその応用編。XOOPS(あっと、ここで言うXOOPSっていうのはXOOPS Cubeも含んでのことですからねー)のテーマやテンプレートにおいてのSmartyは、プログラマーさんたちに怒られるかもしれないけど、ものすご〜く乱暴に分けて三種類あります。

一つは$block.contentとか$contentsとか言うような「HTMLのかたまり」がドカンッと入るもの、いわゆる「テンプレート変数」ってやつですな。次に$xoops_showlblockとかの表示の振り分けに使うコントロール系。そして非プログラマーにはこれが一番使い出がある、そこに変数の値が入る「変数系(今自分で名前付けた)」です。例を挙げると$xoops_urlとか$xoops_sitenameとかですよ。

これらの仲間に$xoops_dirnameと言う最も頻繁に利用されるSmarty変数があります。dirnameというのは要するに「ディレクトリ名称」の略です。これはあくまで「ディレクトリ名称」であって「モジュール名」では無いことに注意が必要です。

 例えばpicoをそのままのディレクトリ名でインストールしている場合、そのpicoの表示ページに行くと$dirnameに対して値「pico」が取得できます。もしpicoを「documents」などというディレクトリ名でインストールしてある場合はpicoでは無く「documents」という値になります。

よくこれをif-else文で振り分けに使うのは定番の利用方法ですが、非プログラマーとしてはもっと変態的な使い方もします。

例えば、そのモジュールだけに独自のCSSファイルを適用させたい場合、ここでは再びpicoとしましょうか。あらかじめそのcssをxoops_url/css/pico.cssとして置いておきます。そしてtheme.htmlの<head>部分に

<link rel="stylesheet" type="text/css" media="all" href="<{$xoops_url}>/css/<{$xoopd_dirname}>.css" />

等と書いておくと、picoのページを表示した時だけにそのpico.cssが読み込まれる訳です。ただし、この場合、pico以外のページではリンク切れしてしまいますし、dirnameが取得できないトップページなどでは〜/css/.css" />等と整合性の無いコードとなって甚だ都合が悪くなります。

そこでもう一手間掛けると、

<{if $xoops_dirname=='pico'}>

<link rel="stylesheet" type="text/css" media="all" href="<{$xoops_url}>/css/<{$xoopd_dirname}>.css" />
<{/if}>

と書けばディレクトリ「pico」になった時だけ上記のコードが有効化します。

え?「そしたら<{$xoopd_dirname}>.cssなんてしないでpico.cssって書けばいいじゃん」だって?

はい、その通り。しかしそれではそのコードはpicoにしか使えなくなります。<{$xoopd_dirname}>.cssと書くことによって、モジュールの数だけ<{$xoops_url}>/cssに「モジュールディレクトリ名.css」を放り込んでおけば、モジュールごとに異なるcssを読み込むことになっていろんな事が出来るようになります。ただし、この場合も$dirnameが取得できないページがあることを忘れてはなりません。なので、モジュールが動作しているときだけに有効になるようにしておきます。

<{if $xoops_dirname ne ""}>

<link rel="stylesheet" type="text/css" media="all" href="<{$xoops_url}>/css/<{$xoopd_dirname}>.css" />
<{/if}>

これで、dirnameが取得できるページだけにコードが有効になります。比較演算子neはNot equalの意味ですね。この場合「xoops_dirnameが空ではない場合」という指定になります。

え?「特定の二つだけに効かせたい」だって?

たぶんプログラマーさんたちは激怒すると思いますが、

<{if $xoops_dirname=='pico' or $xoops_dirname=='d3forum' or $xoops_dirname=='bulletin'}>

とかやっちゃってください。ええ、プログラマーさんのことなんか知ったこっちゃありません。正しく表示できりゃいいんです、ウェブなんて物は。スパゲッティだろうがラーメンだろうが、こちとらプログラマーじゃないんですからコードの美しさとか競ってる余裕なんかありません。

次に「モジュール別にCSSセレクタを替えたい」なんて場合。私なんてこんなことをやっちゃいます。

<div id="<{$xoopd_dirname}>">

これで、モジュールごとに別のidが入りますのでstyle.cssにでも何でもお好きなcssを書いちゃってください。idじゃなくclassだとページ内で何度も使えますね。

ただし、これもモジュール外のページではid=""という空タグになってしまうために、W3C ValidationやHTML lintに怒られちゃうことになります。これを回避するには相当強引ですが、

<div id="<{if $xoops_dirname ne ""}><{$xoops_dirname}><{else}>home<{/if}>">

とでもしておけばモジュールじゃないページの時はid="home"が入ります。もちろん

<div id="<{if !$xoops_dirname}>home<{else}><{$xoops_dirname}><{/if}>">

と言う書き方も出来ます。これは否定から入ってますね。びっくりマークはその後ろの値を否定します。

以前、テーマを作るときにモジュールごとに異なるヘッダ画像を置けないかと考えたことがありまして、その時にもこの応用をやりました。

まあカスタムブロックをweightで分けて手頃な位置に配置しておけばいいんですけどね。それじゃ今回のサンプルにはならないので。

あらかじめpico_header.jpg、d3forum_header.jpg、bulletin_header.jpg等と「モジュールディレクトリ名_header.jpg」のファイル名でヘッダ画像を作成しておき、適当な場所、例えばxoops_url/imgとしましょうか、そこに格納しておきます。

そしてそのヘッダ画像が入る位置に、

<{if $xoops_dirname ne ""}>

<img src="<{$xoops_url}/img/<{xoops_dirname}>_header.jpg" alt="Head Image" width="" height="">
<{else}>
モジュールじゃないときの画像または処理
<{/if}>

としておけば、多分モジュールごとに別の画像が表示されるんじゃないかなあ・・・なんて考える今日この頃。

と言うわけで、今日は$xoops_dirnameの強引な使い方についてでした。

もう続かないよ!