読者です 読者をやめる 読者になる 読者になる

Wicketで継承を利用したページのテンプレートを手軽(?)にプレビュー可能にしてみた

 Wicketのページテンプレートは、継承・パネル等を利用することにより、共通部分の再利用が簡単にできるのが便利です。ところが、継承を利用したページ(HTML)をプレビューする場合、継承元ページのCSS等は反映されないため、そのままでは表示結果が実際とは大きく異なるものとなります。この問題を解決するには、継承元ページと同じCSSを追加する、実際にアプリケーションサーバWicketを動かして確認する、という方法が考えられますが、あまり手軽ではないように思います。

 そこで、各ページにCSSを追加したり、Wicketを実際に動かさなくても、継承を利用したページ(HTML)をプレビュー出来るようにしてみました。具体的には、JavaScriptにより親ページと子ページを一つのHTML中に表示するスクリプトを作成しました。このスクリプトを各ページに埋め込むことで、HTML単体で開いても"ある程度"のプレビューができるようになります。

wicket-preview.js - https://github.com/madogiwa/wicket-preview/

基本的な使い方

1.各ページに wicket-preview.js を埋め込む

 親ページを含めた全てのページに wicket-preview.js を追加します。

<wicket:remove>
  <script src="./wicket-preview.js"></script>
</wicket:remove>

 Wicketアプリケーションサーバで実行する際には邪魔になりますので、実行時に削除されるよう <wicket:remove> で囲っておきます。

2.継承元ページを指定する

 <wicket:extend> の data-parent 属性に、継承元(親)ページへのパスを指定します。

<wicket:extend data-parent="ParentPage">
...
</wicket:extend>

これで準備は完了です。後はブラウザでページを開くと継承元のページを含めて表示されます。

サンプル で動作例を確認することができます。またGitHubの方にはサンプルのソースもあります。

その他の使い方

 継承を利用したページを表示する以外に、下記のようなことができます。

Panel

 Panelを埋め込みたい場所に data-panel 属性で Panel へのパスを指定します。

<div>
  <div wicket:id="panel" data-panel="SearchPanel"></div>
</div>

<wicket:fragment>

<wicket:fragment>の埋め込みも可能です。埋め込みたい場所に data-fragment 属性でidを指定します。

<div>
  <div wicket:id="" data-fragment="fragment1"></div>
</div>

<wicket:fragment wicket:id="fragment1">
...
</wicket:fragment>

<wicket:head>

 <wicket:head> で指定した内容はページに挿入されます。(単純に挿入するだけで、重複する要素の排除等はされません)

repeat

data-repeat 属性に反復回数を指定すると、指定された回数分だけ要素がコピーされます。

<ul>
  <li wicket:id="list" data-repeat="10">Item</li>
</ul>

おまけ(スクリプトの動作)

 スクリプトを埋め込んだページを開くと、下記のような処理が行われます。

  1. ページの読み込み時に <wicket:extend> の有無を調べる。
  2. ページ中に <wicket:extend> がある場合は、継承を利用したページと判断し、親ページにリダイレクトする。この際、親ページに対して child パラメータで子ページのURLを渡しておく。
  3. 1〜2を繰り返してルートの親ページまでたどり着いたら、child パラメータで指定された子ページを順番に埋め込む。

 1.と2.はどの子ページを表示すれば良いのか、という情報を親ページに渡しているだけです。そのため、実際には省略可能で、親ページで手動で child パラメータを指定しても同じ結果となります。

追記

IE7とIE8でも動くようにしてみました。jQuery経由ではネームスペース周りで問題が出るようなので、HTML文字列やDOMを直接操作する形で対応しています。