9 September 2008
ページ ツール |
すべて
友人の勧めでMovable Type(以下、MT)を使って、2005年10月から個人ブログ「Cybermax」を始めました。趣味のクルマ遊びを中心とした内容で、3年近く続けています。その間、書いた記事はかなりの数となり、テーマ別に分けたカテゴリ項目も増える一方でした。最初の頃は、ブログのサイドバーに図1のようなカテゴリウィジェットを置いていました。しかし、カテゴリやサブカテゴリの数が多いために、非常に縦長なリストとなり、常にサイドバーを占有していました。実際1280×1024ピクセルの画面でも、ようやく1画面に収まるほどです。かといって、ユーザビリティのことを考えると設置しないわけにもいかず、定期的にカテゴリの統廃合を繰り返して、なるべく長くならないように工夫していました。
手軽に情報発信できることがMTの売りなのに、その情報管理に苦労している。なんだか矛盾している感じです。「必要な時に取り出せて、必要ない時はしまっておける」 そんなドラえもんの四次元ポケットのようなUIを考えていたところ、アドビ システムズ社が提供している「Spry Framework for Ajax」を知り、その中に含まれる「Spry Menubar」に辿り着きました。
図2は、現在のCybermaxサイトです。Spry Menubarを使ってメニューバーを作り、そこからカテゴリやサブカテゴリにアクセスできるようになっています。サイドバーにカテゴリウィジェットを設置していた頃より、ページもスッキリして、何よりもカテゴリ管理に悩まされることがなくなりました。
MEMO:Cybermaxは、現在、MTOS 4.21+Spry 1.6.1で運営中。仕事の案件で使う技術の運用テストの場も兼ねているため、突然仕様変更することもあります。現在のページ数約1,200。できるだけ毎日更新するように心掛けていますが、最近趣味に使う時間がとれないのが悩み。
この記事では、CybermaxのようなMTサイトで、Spry Menubarを使って、MTアーカイブを含むメニューバーを作成する方法を解説します。
まず、Spry Menubarを実装する上でどのようなHTMLコーディングが必要となるのかを調べます。私はDreamweaver CS3を使っていますが、Dreamweaver CS3には標準でSpry Framework for Ajaxが搭載されています(ただし、バージョンは1.4)。そのため、Dreamweaverのメニューから簡単にSpry Menubarを追加することができます。白紙のHTMLファイルを用意し、任意の場所を選んでSpry Menubarアイコンをクリックすると、以下の水平メニュー(図3)とHTMLコードが追加されます(メニューの方向は、縦方向を選ぶこともできます)。
<ul id="MenuBar1" class="MenuBarHorizontal">
<li><a class="MenuBarItemSubmenu" href="#">項目 1</a>
<ul>
<li><a href="#">項目 1.1</a></li>
<li><a href="#">項目 1.2</a></li>
<li><a href="#">項目 1.3</a></li>
</ul>
</li>
<li><a href="#">項目 2</a></li>
<li><a class="MenuBarItemSubmenu" href="#">項目 3</a>
<ul>
<li><a class="MenuBarItemSubmenu" href="#">項目 3.1</a>
<ul>
<li><a href="#">項目 3.1.1</a></li>
<li><a href="#">項目 3.1.2</a></li>
</ul>
</li>
<li><a href="#">項目 3.2</a></li>
<li><a href="#">項目 3.3</a></li>
</ul>
</li>
<li><a href="#">項目 4</a></li>
</ul>
HTMLコードを見ると、Spry Menubarは入れ子のリスト要素で構成されていることがわかります。青い文字の部分がSpryで使用するid属性やclass属性の指定です。「<code>id="MenuBar1"</code>」は、この親リスト要素がメニュー化するターゲットであることを示すもので、「<code>class="MenuBarHorizontal"</code>」はメニューの方向が水平であることを示すものです。「<code>class="MenuBarItemSubmenu"</code>」は、下階層があるメニュー項目に指定するようになっています。これらを踏まえて、MTのテンプレートをカスタマイズします。
先ほどの内容を参考にしながら、MTのテンプレートをカスタマイズしていきます。もし、MTタグが苦手というのであれば、いったん、Spry Menubar実装前のテンプレートでHTMLファイルを書き出し、それをDreamweaverで開き、そこにSpry Menubarを実装してカスタマイズの目星を付けてから、コードを編集するといいでしょう。
MEMO:私はMTテンプレートのカスタマイズ作業には、「Dreamweaver CS3 拡張機能 for Movable Type 4.1」を活用しています。コードヒントなどが表示されるので、MTタグ(時に非常に長いものがある)をすべて打つ必要がなく、またスペルミス防止にもなります。MTのバージョンアップに応じて、この拡張機能もアップデートされていくようなので、期待が持てます。欲を言えば、MTの外部コードエディタとしてDreamweaverが指定できたり、Dreamweaver側からMTの再構築などが行えたりするなど、より親和性が高まると最高ですね。
さて、今回のSpry Menubar部分のコードは、以下の3つのテンプレートで構成されています。
| No | テンプレート名 | テンプレート種別 | 用途 | インクルード先 |
|---|---|---|---|---|
| 1 | Spry(js) | モジュール | headタグに記述するSpry Menubar用のJavaScriptとcss | 「HTMLヘッダー」(MT4.2)、「ヘッダー」(MT4.0)テンプレート |
| 2 | Spry-Menubar | モジュール | メニューバー本体のコード | 各テンプレートの<body>内 |
| 3 | Spry-Footer | モジュール | bodyタグに記述するSpryのスクリプト | 各テンプレートの</body>の直前 |
それでは、各テンプレートの中身を解説していきます。
head内で読み込むJavaScriptとCSSのファイルを指定します。下記はブログの公開フォルダ直下に「spry」フォルダを置いた場合の記述例です。なお、Spryはバージョン1.6.1を使用しています。ダウンロードしたSpryフォルダ内にあるwidgetsフォルダの中のmenubarフォルダ内のファイルを使用します。
<script type="text/javascript" src="<$MTBlogURL$>spry/widgets/menubar/SpryMenuBar.js"></script>
<link href="<$MTBlogURL$>spry/widgets/menubar/SpryMenuBarHorizontal.css" rel="stylesheet" type="text/css" />
MEMO:Spryはバージョン1.6.1は、http://labs.adobe.com/technologies/spry/からダウンロードできます。なお、ダウンロードするには登録が必要です。ダウンロードページには、Spry本体である「Spry Prerelease 1.6.1」と、Dreamweaverの拡張機能のアップデート版「Spry Update Extension for Dreamweaver CS3」が用意されていますが、拡張機能のアップデート版は日本語版での動作検証が行われていないため、「Spry Prerelease 1.6.1」を使用することをオススメします。
メニューバー本体です。カテゴリアーカイブと年別・月別アーカイブのリストをメニューバーに組み込んでいます。なお、以下のテンプレートを有効にするには、MT設定のアーカイブテンプレートで、カテゴリ、年別、月別のアーカイブマッピングがされていることが条件となります。忘れずに設定してください。
<div id="main-navigation">
<ul id="SpryMenu" class="MenuBarHorizontal">
<MTIgnore><!-- Category Archives Spry Menu --></MTIgnore>
<li><a href="<$MTBlogURL$>archives.html" title="カテゴリ" class="MenuBarItemSubmenu">Category</a>
<ul>
<MTIfArchiveTypeEnabled archive_type="Category">
<MTTopLevelCategories>
<li class="MenuBarItemSubmenu"><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryLabel$>"><$MTCategoryLabel$></a>
<MTHasSubCategories>
<ul>
<MTSubCategories sort_order="ascend">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryLabel$>"><$MTCategoryLabel$></a></li>
</MTSubCategories>
</ul>
</MTHasSubCategories>
</li>
</MTTopLevelCategories>
</MTIfArchiveTypeEnabled>
</ul>
</li>
<MTIgnore><!-- Datebased Archives Spry Menu --></MTIgnore>
<li><a href="<$MTBlogURL$>archives.html" title="バックナンバー" class="MenuBarItemSubmenu">Monthly</a>
<ul>
<MTArchiveList archive_type="Yearly">
<li class="MenuBarItemSubmenu"><a href="<$MTArchiveLink$>" title="<$MTArchiveDate format="%Y"$>年"><$MTArchiveDate format="%Y"$></a>
<ul>
<MTArchiveList archive_type="Monthly">
<li><a href="<$MTArchiveLink$>" title="<$MTArchiveDate format="%B"$>月"><$MTArchiveDate language="en" format="%b"$></a></li>
</MTArchiveList>
</ul>
</li>
</MTArchiveList>
</ul>
</li>
<MTIgnore><!-- Contact Spry Menu --></MTIgnore>
<li><a href="<$MTBlogURL$>contact/index.html" title="お問合せ">Contact</a></li>
</ul>
</div>
改行とコメント行を入れていますが、このサンプルでは大きく3段構成になっています。
最初のブロックがカテゴリアーカイブのメニューを生成している部分です。メニューバーの第一階層に表示されている「Category」の文字がクリックされた場合は、アーカイブインデックス(archives.html)に飛ばすようにしています。
<ul>と<li>のリストタグの部分で、Spryのid属性やclass属性の指定を行っています。ここで注意してほしいのが、<li>に「class="MenuBarItemSubmenu"」を指定している点です。冒頭で、DreamweaverでSpry Menubarの仕組みを調べた時は、<a>に指定していました。なぜ<li>に指定したのか? 実は<a>に指定すると少々困った挙動になってしまったのです。
例えば、「MUSIC」カテゴリにはサブカテゴリがありません。したがって直下にブログ記事があります。<a>にclass属性を指定した場合、書き出されたHTMLコードは以下のようになります。
<li><a href="http://cybermax.jp/blog/music/" title="音楽" class="MenuBarItemSubmenu">MUSIC</a>
</li>
このときの表示結果は図4のようになります。「MUSIC」の上にマウスホバーさせると、サブカテゴリは存在しないのに右矢印が表示されてしまいます。展開されるはずのリストは存在しないので、いつまで待っていても表示されることはありません。
これではちょっとカッコ悪いし、ユーザーを迷わせてします。試行錯誤していると、<li>に指定すると意図した表示になることがわかりました(図5)。
サブカテゴリがあるかないかの判断は、この後の<MTHasSubCategories>以下で行っています。こういった条件分岐を<a>内に使えば、サブカテゴリの有無に連動して自動的に「class="MenuBarItemSubmenu"」を追加することも可能です。もしくは変数を定義して条件分岐に利用するなど、やり方はいろいろあると思います。本来ならそうすべきかもしれませんが、個人的には<li>に追加して意図通りの表示となるなら、これが最もシンプルな対応策だと思います。
クラス指定する部分の一覧
| メニュー階層 | 指定するclass属性名 | 指定するHTMLタグ | 備考 |
|---|---|---|---|
| 第一階層 (常時表示される水平メニュー) |
MenuBarItemSubmenu | <a> | 第二階層を展開する場合のみclass付加 |
| 第二階層 (プルダウンするメニュー) |
MenuBarItemSubmenu | <li> | 本例ではMTのトップレベルカテゴリの表示に利用 |
| 第三階層 (横にずれてプルダウンするメニュー) |
なし | なし | 本例ではMTのサブカテゴリの表示に利用 |
さて、次のブロックが年別・月別アーカイブのメニューを生成している部分です。カテゴリの場合と同様に、「Monthly」がクリックされた場合にはアーカイブインデックスページに飛ばしています。
最後が「お問い合わせ」へのリンクを設定している部分です。こちらは「contact/index.html」に飛ばすだけで、サブメニューの展開はしないため、Spry Menubar用のclass属性指定は不要となります。
最後に</body>の直前にインクルードするモジュールテンプレートを定義します。
<script type="text/javascript">
<!--
var MenuBar1 = new Spry.Widget.MenuBar("SpryMenu", {imgDown:"<$MTBlogURL$>spry/widgets/menubar/SpryMenuBarDownHover.gif", imgRight:"<$MTBlogURL$>spry/widgets/menubar/SpryMenuBarRightHover.gif"});
//-->
</script>
「SpryMenu」は、Spry-Menubarテンプレートでul要素に指定したid属性の値です。別なid属性値を指定した場合は、それに合わせて変更してください。「imgDown」と「imgRight」はマウスホバーさせたときに表示される矢印画像です。パスの指定を変更することでオリジナル画像を指定することもできます。
以上で、Spry Menubarを使ったメニューバーの完成です。
MEMO:実際のCybermaxでは、再構築パフォーマンス対策として、MT4.2で採用されたApache SSI(サーバーサイドインクルード)を使い、共通モジュール化をしています。これにより、約1200ページで毎回同じリスト生成処理が繰り返されることなく、1度生成したコードを全ページで再利用しています。そのため、データベースへの負荷も軽減されます。一時期は全ページの再構築を行うと50分ほど待たされていました。現在は他のパフォーマンス対策と併せて、3分台にまで短縮することができ、サイトの修正も容易に行えるようになりました。
メニューバーの文字表示をセンタリングしたく、SpryMenuBarHorizontal.cssに定義されている「ul.MenuBarHorizontal li」の「text-align: left」を「text-align: center」に変更したところ、Internet Explorerのみで、メニュー出現位置がずれる問題が発生しました(図6)。
そのため、「ul.MenuBarHorizontal li」の定義は元に戻し、他の方法を探ることになりました。試行錯誤の末、最終的に「Spry 1.6.1」ダウンロードファイル内の「Samples」→「menubar」にあった「Centering a Horizontal Menu Bar」を参考に、以下のCSS定義を「SpryMenuBarHorizontal.css」に追加したところ、問題を解決することができました。
ul.MenuBarHorizontal a {
text-align: center;
}
こういったサンプルが充実している点もSpryの魅力の一つだと思います。サンプルを見ているうちに新たな欲望が湧いてきます(笑)。
もう一つ苦労したのが、Lightboxと併用した際に起きた問題です。サムネイル画像の拡大表示にLightboxを追加した際に、cssのz-indexの指定値の関係で、Lightboxがページの背後でポップアップする現象が発生しました。SpryのSpryMenuBarHorizontal.css で1000番台を使っていたため、Lightbox側のlightbox.cssを以下のように変更しました(使用バージョンは2.0.4)
| Lightboxのclass | 標準のz-index値 | 変更後のz-index値 |
|---|---|---|
| #lightbox | 100 | 2000 |
| #hoverNav | 10 | 1900 |
| #overlay | 90 | 1990 |
個人ブログでSpry Menubarを使ったメニューバーを実装し、数か月間運用してみて問題がないことがわかったので、積極的に仕事で提案しています。今月リニューアルオープンした「栃木・蔵の街かど映画祭 公式ブログ」でも使っています。これは、蔵の街・栃木市に残る古い蔵をミニシアターに変えてしまうイベントです。開催日まで余裕がなく、構築よりも運用に時間を使いたかったので特別なことはしていませんが、もし興味を持っていただけたら10/4、5日はぜひ栃木市まで足を運んでみてください。私も実行委員として会場におりますので、ここには書いてないようなこぼれ話もできるかもしれません(笑)
図8 「栃木・蔵の街かど映画祭 公式ブログ」のメニューバーでもSpry Menubarを使っています