Plone で Batch を使って○件毎にページ分割する
Plone で検索結果や News の記事とかを30件ずつ表示したいって感じのときに便利な Batch ってクラスがあったのでメモ。
~/Plone-3.0.6/zinstance/Products/CMFPlone/PloneBatch.py ってとこにある。
基本的な使い方
ページテンプレート上での使い方は ZMI から portal_skins/plone_forms/search を見てもらうとなんとなくわかる。例えば Plone サイト上の News を10件ずつ表示させるページでも作るとするとこんな感じ。
<div tal:define="results python:context.portal_catalog.searchResults(Type='News'); Batch python:modules['Products.CMFPlone'].Batch; b_start python:0;b_start request/b_start|b_start;"> <tal:results define="batch python:Batch(results, 10, int(b_start));"> <tal:block repeat="result batch"> <p> <a href="#" tal:content="result/Title" tal:attributes="href result/getURL" /> </p> </tal:block> <div metal:use-macro="here/batch_macros/macros/navigation" /> </tal:results> </div>
この部分でページナビゲーションのテンプレートを呼び出していて
<div metal:use-macro="here/batch_macros/macros/navigation" />
こんな感じで表示される。(おそらくデフォルト)
<< Previous 10 items Next 10 items >> 2 3 4 [5] 6 7 8
もしもこのナビゲーション部分のデザインが気に入らんようなら portal_skins/plone_templates/batch_macros をカスタマイズするなり、参考にして新たなマクロを定義するなりすればいいと思う。
色んなオプションがあるらしい
Batch に渡せる引数は全部で9個。で、基本的に必須なのは上の3つ。あとのやつでカスタマイズ。
- sequence
- 分割して表示させたいオブジェクトのリスト。上の例でいう searchResults とかで取得したリスト。(必須)
- size
- 1ページあたりの表示件数。(必須)
- start
- 1番最初にページに表示するオブジェクトのインデックス。ここは int(b_start) とかやって動的に取得しとかないとちゃんとナビゲーションが動いてくれない。(とりあえず必須)
- end
- ページで最後に表示するオブジェクトのインデックス。普通、指定することはないと思う。
- orphan
- 残りのオブジェクトがこの数字以下に収まるなら前のページと統合して表示する。なので、最後のページの表示件数は size+orphan になるはず。デフォルトは0。
- overlap
- 各ページで前のページから被らせて表示させる件数。例えば、overlap=2, size=5 って指定した場合 [1, 2, 3, ..., 20] ってリストがあったら、[1, 2, 3, 4, 5] → [4, 5, 6, 7, 8] → [7, 8, 9, 10, 11] って感じでページ分割されていく。デフォルトは0。
- pagerange
- ナビゲーション部分に表示されるページ番号リンクの数。デフォルトは7。
- quantumleap
- ページ数が多いとき、通常のナビゲーションに表示されるページ番号リンクに便利なショートカットを増やす。値は0か1(1で有効)を指定する。デフォルトは0。例えばページ数が100あって現在表示中のページが50の場合、こんな感じで表示される。はず。
<< Previous 10 items Next 10 items >> 17 32 46 47 49 [50] 51 52 53 68 83
ページテンプレート上で表示させるには leapback, leapforward って関数を使う。カスタマイズするときに間違って消してしまわないよう注意。
- b_start_str
- 各ページへのリンクURLから start の値を得るためのクエリ変数名。デフォルトでは b_start になっている。なんか違和感があるなら page とか指定してみると自然かも。
-C ってクエリが勝手にくっついてくる問題
上の方法のようにページテンプレート内で searchResults とかして表示させようとすると、次ページのリンクURLに「?b_start=int:10&-C=」って感じで身に覚えのない -C って輩が出てきたりすることがある。このページによると、どうやらバグらしいんだけどなんか気持ち悪い。
なので、無理矢理だけど、 portal_skins/plone_templates/batch_macros から request.form を消して直してみた。
この方法だと、リクエストで投げた他のクエリも全部受け取ってくれなくなっちゃうけど、そもそも他のクエリを投げた場合にはこの「-C が勝手についてくる問題」は発生しないので大丈夫。だと思う。
いやー Django とかにはちゃんと pagination ってあるのになんで Plone にはないんだろうってずっと思ってたけど、探してみたら普通に使われてたっていう。今までこいつの存在を知らんかったので、ページテンプレートとスクリプトで無理矢理ページ分割&ナビゲーションを実装しちゃったりしてた。まじで無駄だ。。
一応簡単な説明は以下にありました。
Using Plone's built-in batching mechanism — Plone CMS: Open Source Content Management