コンテンツのタブナビゲーション-jstoolsに同梱されているtabsのIE対応四苦八苦の跡-
さて。
このサイトのモジュール情報のリニューアルをしたのは以前のブログエントリで語らせていただきました。
その時に、前からやってみたかったタブナビゲーションによるコンテンツのページングに挑んでみましたが、これが思いの外難産となりましたのでその痕跡を記述しようかな…と。
今回、挑んだモノはこちらです。
Javascript Tools
このツール群の中にあるtabsモジュールによるタブナビゲーションです。
tabsモジュールは
$form = array();</p>
<p> $form['example1'] = array(
'#type' => 'tabset',
);
$form['example1']['tab1'] = array(
'#type' => 'tabpage',
'#title' => t('One'),
'#content' => t('First tab content.'),
);
$form['example1']['tab2'] = array(
'#type' => 'tabpage',
'#title' => t('Two'),
'#content' => t('Second tab content.'),
);
$form['example1']['tab3'] = array(
'#type' => 'tabpage',
'#title' => t('Three'),
'#content' => t('Third tab content.'),
);</p>
<p> return tabs_render($form);
といったPHPコードを記述してあげなければ使うことが出来ません。
お手軽に使うのなら、
'#content' => t('First tab content.'),のt('First tab content.')の部分を文字列で与えてあげればよいので、ちょっと使ってみたいというのでしたら、お手軽に試すことは出来ます。
モジュール情報というコンテンツはCCKを使って構築されています。
ストーリーや、ページ・ブログと言ったコンテンツタイプであれば入力書式をPHP codeにして、PHPを記述すれば利用できますが、CCKで構築されたモノとなると、そうは行きません。
そこで出番なのが、
Content Templates (Contemplate)です。
このモジュールはあらゆるコンテンツタイプにテンプレートを持たせて、そのテンプレートをカスタマイズすることによって出力を制御しようというモジュールです。ただし、このモジュール、PHPが必須です。テンプレートはPHPによって記述されなければならないので、お手軽というわけにはなかなか参りません。もちろんPHPに熟知されている方には簡単なことなんだろうなとは思いますが…(うらやましい限りです)。
ワタシの場合は、ドと言うカタカナが冒頭についてしまう素人ですからPHPのマニュアルサイトとにらめっこしながら幾多のトライアンドエラーを繰り返しました1。
CCKをConTemplateで扱うためには注意しなければいけないことを発見しました。
それは、「本文」を使わないことです。
なぜ、本文は使わない方がいいのか。
CCKだけを使っている分には問題に遭遇しませんが、ConTemplateでテンプレートのカスタマイズをすると、本文はbodyというフィールド名ですが、ConTemplateで扱った場合、bodyというフィールドそのものではなく、コンテンツそのものをbodyとして返してしまっていると言うことでした。つまり、bodyというフィールドの内容として表示されるモノは、テンプレートでの出力全体になってしまうと言うことでした。もちろん、その他に、他のCCKのフィールドが表示されてしまうことになったというわけです2。
そんなすったもんだを繰り返しながら、とりあえずテンプレートは完成し、コンテンツを入力し始めてふたたび悪夢到来です(笑)
tabsモジュールによるタブナビゲーションにはちょっとした落とし穴が潜んでしました。
タブナビゲーションによるコンテンツのページングはCSSを利用して行われています。
モジュールにはブラウザの挙動の違いを吸収するためにIEで閲覧したときにはCSSをオーバーライドする仕組みが用意されていましたが、どうも挙動が安定していませんでした。
本文の抜粋を表示する「要約版」では正しい挙動で表示されるのですが、いざ、「本文」表示となるとおかしな挙動で表示されました。タブの下に表示されるはずのコンテンツがタブの横から始まるのです。
要約版では正しいが、本文では正しくない
これは、非常にやっかいな状態です。両方駄目だというのなら対処は簡単3なのですが、片方だけです。モジュールに手を入れるにしても片方にだけ対処する…というのはいかにも面倒です。
いろいろ、CSSをあちこちいじってみましたが、なかなか上手くできませんでした。
この辺の顛末は0829@drupal.orgさんとのやりとりに克明に(笑)記録されています。興味があったらご覧ください。
CSSのプロパティの冒頭に_(アンダーバー)を付けるとIE6は読んでくれる(一種のバグ)が他のブラウザは無視してくれるので、IE6への対応策は意外と簡単(強引?)に見つけられました。
ところが、一番新しい、ぐっとFirefoxなどの他のブラウザに肉薄できるようになったと言われているIE7では、このトラップは機能しなくなりました。
tabsモジュールでは、これらをまとめてIE用のオーバーライドして使うCSSにまとめていて、IEでブラウズしたらブラウザに読み込ませてCSSを書き換えていたようですが、これがどうも正しく機能していないのでIE6でも、IE7でも正しくない挙動が見えたようです。
モジュールを改造して4対処するというのもありだったのですが、モジュールがアップデートする度に手を加えなければならなくなるかもしれないし、そんな面倒なことはしたくないしリスクが高い(^_^;)
では、どうするのか?願望は1つのCSSで両方のブラウザをサポートする5。
そんなわけで、IEのバグを利用したCSSハックを追求することにしました。で、IE7用のCSSハックを施してみたのですが、どうも上手くいきません。
もう、煮詰まってきたので一転、開き直る作戦に出てみました(笑)
どんな開き直りかというと、IE6対策で入れたCSSハックをハックではなくしてみました(笑)
具体的にと言うと、
ul.anchors {
_display: block;
_height: 100%;
}
IE6対策でこのようなスタイルをtabs.cssに追加しておいたのですが、このプロパティの冒頭にある _ を取っ払ってしまいました(笑)
正直に言うと、ヤケです(笑)Firefoxなどで、おかしな表示になるかもしれません。過去に何度も経験しましたから。
しかし、予想に反して、Firefoxでは表示はおかしくなりませんでした。
IE6では、正しく表示されるはずです。もともと、IE6対策で入れたモノだったのですから。
さて、興味津々はIE7です。
残念ながらワタシはIE7を入れていないので確認することが出来ませんでしたから、0829@drupal.orgさんに見ていただきました。
なんと、正しく表示できました(バンザーイッ)。
理由はなぜなのかはわかりません。いや、考えたくありません(笑)これは解決したのです。そっと静かにしておいてください(笑)
ま、そんなわけで色々とトラブルに恵まれましたが、収穫も多いリニューアルでした。
IE7のテストをしていただいたり、アドバイスを頂いた0829@drupal.orgさんには本当に感謝しております。ありがとうございます。
おまけ::現在、tabsモジュールで使っているtabs.cssを添付しておきました。
- 1. 実は、tabsモジュールで一度挫折しました(^_^;)
- 2. もしかすると、bodyではなく、他のフィールド名で参照すると良いという落とし穴があるかもしれませんが(笑)とりあえず、ワタシには発見できなかったので、本文不使用で代用のCCKフィールドを作って回避しました。
- 3. 言葉のアヤです(^_^;)実際には面倒です
- 4. 0829@drupal.orgさんに改造ポイントは伝授いただきました。
- 5. オーバーライドしないので、それしか方法はないのですけど(笑)
| 添付 | サイズ |
|---|---|
| tabs.css | 2.01 KB |
本家のプロジェクトには報告があがっているかもしれない1のですが。
IEで、タブが上手く表示されない件は、tabs.module のスクリプトの一文で、IE用のオーバーライドcssを読み込ませている呪文を吐き出している部分があるのですが、そこで吐き出すURLを作成する呪文にミス(?)があり、正しいURLが吐き出されていなかったというのが原因のようです。
69行目から72行目あたりに
<!--[if lte IE 7]> <link rel="stylesheet" href="'. $path . '/tabs-ie.css" type="text/css" media="projection, screen" /> <![endif]-->という部分があります。
2行目(スクリプトでは70行目くらい)に
<link rel=がありますね。この行の中で
href="'. $pathという部分があり、この、href="と'. $pathの間に/を入れなければならないと、そう言う訳です。つまり、
<!--[if lte IE 7]> <link rel="stylesheet" href="/'. $path . '/tabs-ie.css" type="text/css" media="projection, screen" /> <![endif]-->てな具合になります。
オリジナルのままだと、
<link rel="stylesheet" href="sites/all/modules/jstools/tabs/tabs-ie.css" type="text/css" media="projection, screen" />というURLになります。
例えばこのサイトのあるページの場合は
http://drupal-j.com/info/modules/data2/bbcodeと同じ階層にある
sitesフォルダ以下のall/modules/jstools/tabs/tabs-ie.cssと、言う解釈になってしまうのだと思います。
では、どういうURLなら良いのか?
index.phpから見た(?)相対URLで呼ばないといけないので
/sites/all/modules/jstools/tabs/tabs-ie.cssにならなければいけないはず2。
それで、
href="の後に/を加えたのです。ま、ワタシはモジュールの作者ではないので本当のところは判りませんが、この呪文の上に、Drupalにcssや、スクリプトをロードさせているDrupalの呪文があるのですが、そこで、変数$pathを使って、モジュールの場所3を共有しているのです。
実はDrupalにcssやスクリプトをロードさせるためのAPIでは先頭の / はAPI側で付加してくれるのです。
ところが問題のセクションはHTMLタグをhead領域に吐き出しなさいというAPIのため、先頭に / は付加してくれないので、このようなトラブルが起きてしまったのではないか?と、想像してみた訳です。
IE7では確認していないのですが、とりあえず、ログにエラーメッセージは残っていません。
でも、IE7でしかイベントが起こらないのだとしたら…確認できないよなー(笑)
とりあえず、このサイトの場合、tabs.cssに施した細工でIE用のオーバーライドcssのロードに拘わらず、正しく表示されているようですので(笑)
ま、タダの余興と言うことで…。
お粗末様でした<(__)>
原因不明というところがちょっと気持ち悪いですが、追求していたらもっと気持ち悪くなりそうですしね。
確認担当だなんて…(笑)色々と本当に参考になりました。
原因というのは何となく察しはついているのですが、確認する意気込みがないので見て見ぬ振りという…(笑)
おそらく、タブをフロートで右に並べて、タブの下線を表現するために行の高さを1%(だったかな?)にして、下線を表示して、その後にフロートをクリアしているのだと思うのですが、それを、行の高さを1行分に戻してブロック表示にしたので、その後に実行されているクリアを意味のないモノにしてしまっているんだと思ってます。
想像だけで、本当にそう言う動きなのかどうかは判りませんけど(ヲイ)
ま、結果オーライで行きましょう(^-^;△フキフキ
あまり役に立つコメントはできませんでしたが、一応、確認担当ということで勘弁してください。
原因不明というところがちょっと気持ち悪いですが、追求していたらもっと気持ち悪くなりそうですしね。