パンくずリストの実現
※このページは考慮中です。
wicket-extensionsにパンくずリストパネルが用意されているが、これは使い物にならない。 ここでは独自のパンくずリストの実装について考えてみる。
パンくずリストの要件
目標とする形
パンくずリストは以下のような構成となる。
トップ / 顧客グループ一覧 / A店顧客一覧 / 顧客X ~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~
現在ページをトップからのパスで示し、現在ページ以外のページ名はそのページへのリンクとする。これらのリンクをクリックすることで、そのページへの遷移を行う。
構成ページの要件
要件1
当然のことながら、パンくずリストに表示されるページは「右端ページ」(この場合は顧客X)を除いてブックマーク可能でなくてはいけない。でなければ、リンクをクリックした時にそのページに戻ることができない。
もちろん、Wicketの場合は、ブックマーク不可能なページでもページキャッシュに格納されているため、何らかの方法でそのページを「再生」することはできると思われるが、しかしページキャッシュはいつクリアされるかわからない。リンクをクリックされた時に「ページキャッシュに格納されたであろう個別状態」を再生するには、ページキャッシュから取得するか、それができなければそのページが作成された時の条件(ページパラメータ)を指定して再作成するしかない。
結局のところ、ページキャッシュに依存することはできないので、そのページを再生成可能なように、ページパラメータ付のコンストラクタを用意し、生成時のページパラメータ自体をパンくずリストに保持しなければならない。もちろん、ページパラメータ不要な場合は、引数無しコンストラクタがあればよい。
したがって、この場合にもし顧客Xがブックマーク可能であるならば、以下の二つのうちいずれかを実現しなくてはならない。
- ブックマークされた顧客Xページのパラメータとして、顧客Xを示すパラメータのほかにその上位すべてのページ(顧客グループ一覧、A店顧客一覧)を再生できるようなパラメータが付加されていなければならない。
- 上位すべてのページのパラメータが付加できないのであれば、顧客Xページにいたるパスが固定されていなければならない。
要件2
ページ階層は「右端ページ」を除いて、固定していなければならない。逆に言えば、階層の固定していないページは、「右端ページ」以外には現れることができない。これは純粋にユーザビリティ上の問題である。
例としたパンくずリストでは、以下のようになっているが、
トップ / 顧客グループ一覧 / A店顧客一覧 / 顧客X ~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~
以下のようなパンくずが作成できてしまってはいけない。
トップ / A店詳細 / A店顧客一覧 / 顧客X ~~~~ ~~~~~~~ ~~~~~~~~~~
なぜなら、いずれの場合でも「A店顧客一覧」をクリックすると、その顧客一覧ページが表示されるが、このときのパンくずは、
トップ / 顧客グループ一覧 / A店顧客一覧 ~~~~ ~~~~~~~~~~~~~~
とすべきか、
トップ / A店詳細 / A店顧客一覧 ~~~~ ~~~~~~~
とすべきか決定することができないからである。「パンくずの内容を見て、それぞれの階層として表示すればいいではないか」と思うかもしれないが、それではうまくいかない。 もしユーザがA店顧客一覧を表示中にそれをブックマークしたとする。それを後で表示した場合、パンくずとしてどちらの階層を表示すべきかは決定できない。
したがって、パンくずリストに現れる右端ページ以外は、以下のようなきれいな木構造となっていなければならない。
A +- B | +- D | +- E +- C +- F +- G
右端ページについて
右端ページについては、もしブックマーク可能でないならば、複数の階層に現れることができる。
トップ / 顧客グループ一覧 / A店顧客一覧 / 顧客X ~~~~ ~~~~~~~~~~~~~~ ~~~~~~~~~~
この場合、顧客Xのページはブックマークされないので、後からこのパンくずを再生する必要はない。したがって、
トップ / 製品一覧 / 購入者一覧 / 顧客X ~~~~ ~~~~~~~~ ~~~~~~~~~
のいずれのパンくずにも現れることが可能である。もちろんこれに対してブックマーク可能な場合は、階層を固定しなくてはいけない。
要件のまとめ
- 基本的にパンくずとして表示されるページはブックマーク可能でなければならないが、ただし
- 右端だけにはブックマーク不可能なページが現れても問題ない。
- 右端以外にブックマーク不可能なページが現れた場合には、そのページのリンクは表示できない。
- ブックマーク可能なページが表示されたときに、何らかのページパラメータが指定されているのであれば、パンくずをクリックした時もそのページパラメータを指定して再作成できなければならない。
実装の方針
ページパラメータの再生問題
パンくずリスト上にあるリンクをクリックされた時には、それがページパラメータ付である場合は、そのページをページパラメータ付で作成したい。逆にいえば、あらかじめリンクにはこれらのパラメータを仕込んでおく必要がある。
しかし、これは非常に難しい。以下のようなパンくずリストがあり、
トップ / 製品一覧 / 購入者一覧 / 顧客X ~~~~ ~~~~~~~~ ~~~~~~~~~
この中の「製品一覧」ページが実は「group=冬物」というパラメータ指定がされている冬物製品の一覧であったとすると、このパンくずのリンクには、そのパラメータが含まれていなければならない。そして、「製品一覧」をクリックされたら、その冬物製品一覧を表示しなければならない。
さらに、元のパンくずリストで「購入者一覧」をクリックされた場合は、
トップ / 製品一覧 / 購入者一覧 ~~~~ ~~~~~~~~
というパンくずを表示しなければならないが、この場合にも製品一覧には冬物指定がなければいけない。つまり、「購入者一覧」のリンクには(もしあれば)購入者一覧ページのパラメータだけではなく、その上位の製品一覧ページのパラメータも含まれていなければならない。これは非常に面倒である。
おそらく、このような仕様の実現は複雑な割にメリットはあまりないと思われるので、ブックマーク可能ページのパラメータは今回の実装では諦めることにする。
その他の実装上の決定
- あるページがブックマーク可能であり、どのようなURLにマウントし、どのようなタイトルを持ち、どのページが木構造の親であるかを示すには、そのページクラス自体にアノテーションをつけることによって示す。この情報は以下の場所で使われる。
- あるページのパンくずを作成するためのパスリストの作成。
- メニューページに表示されるそのページのタイトル。
- Application初期化時にそのページをマウントするURLの取得
- ブックマーク可能ページの表示あるいは他の可能ページへの遷移時には、パンくずのためのパスリストは上の情報から自動的に取得することができる。ブックマーク不能ページへの遷移時には、そのページ生成時に親ページのパスを明示的に与えることにより、そのページ自体のパスリストを作成するようにする。