連続する各ページへのリンクを作るプラグインです。連載記事なんかで使えるでしょう。
{{paginate(AGirlOfElm,1,2,3,4,5,6,7,8,9,10,11,12,13,14,後書|Afterwords)}}
は、Hiki記法で次のように書いたのと同様になります。
# [[1|AGirlOfElm1]] # [[2|AGirlOfElm2]] # [[3|AGirlOfElm3]] # [[4|AGirlOfElm4]] # [[5|AGirlOfElm5]] # [[6|AGirlOfElm6]] # [[7|AGirlOfElm7]] # [[8|AGirlOfElm8]] # [[9|AGirlOfElm9]] # [[10|AGirlOfElm10]] # [[11|AGirlOfElm11]] # [[12|AGirlOfElm12]] # [[13|AGirlOfElm13]] # [[14|AGirlOfElm14]] # [[後書|AGirlOfElmAfterwords]]
最初の文字(AGirlOfElm)がページ名の共通部分で、以下、その後に付く文字(1〜14と「後書|Afterwords」)です。「|」(半角)を使うと、表示には(複数ある場合は最後の)「|」の左側(後書)、実際のページ名には右側(Afterwords)が使われます。無ければ表示にはそのまま、ページ名には共通部分+文字が使われます。
但し、現在のページの所はリンクにならないで強調になり、前や次のページへのリンクも付きます。例えば「シーン3:影の部族の集落で宴会 - 楡の少女」というページで上のようにプラグインを呼ぶと次のようになります。
* [[<|AGirlOfElm2]] # [[1|AGirlOfElm1]] # [[2|AGirlOfElm2]] # ''3'' # [[4|AGirlOfElm4]] # [[5|AGirlOfElm5]] # [[6|AGirlOfElm6]] # [[7|AGirlOfElm7]] # [[8|AGirlOfElm8]] # [[9|AGirlOfElm9]] # [[10|AGirlOfElm10]] # [[11|AGirlOfElm11]] # [[12|AGirlOfElm12]] # [[13|AGirlOfElm13]] # [[14|AGirlOfElm14]] # [[後書|AGirlOfElmAfterwords]] * [[>|AGirlOfElm4]]
サイドバーならそのままでいいと思いますが、実際にはスタイルシートでインライン要素表示するのがいいでしょう(「display: inline」を使う)。
十数ページの連載記事全部に{ {paginate(SeriesTitle,1,2,3,4,5,6,7,8)}}といったソースをコピーするのはナンセンスなので*1、どれか一ページにこれを書いておいて、実際の連載記事ではquote_pageプラグインでそのページを読み込むのがいいでしょう。
ページ内で一度paginateプラグインを呼び出した後は、prev_page、next_pageプラグインが使えるようになります。それぞれ「前のページ」「次のページ」へのリンクを作ります。表示するテキストは管理画面から設定できますし、呼び出す時々で変えることもできます。
例えばこのサイトでは、next_pageのデフォルトの表示を「次のシーンに進む」にしているので{ {next_page}}と書くと「次のシーンに進む」というリンクができますが、次のページがシーンではなくて後書きの場合だけ{ {next_page(後書きに進む)}}としています。こうすると「後書きに進む」というリンクができます。詳しくは管理画面(ページネート)を見てください。
あと、地味だけど、head要素内に前や次のページへのlink要素が入ります。Operaの次のページへ移動するマウスジェスチャー*2を使ってページを進めるので便利かも。
module Paginate class Page attr_accessor :page, :text # Page.parse('1|First', 'AGirlOfElm').to_s # => '[[AGirlOfElm1|First]]' # Page.parse('3', 'AnEagleEye').to_s # => '[[AnEagleEye3]]' # Page.parse('Parrot').to_s # => '[[Parrot]]' def self.parse(frag, page_prefix = '') frag = frag.to_s idx = frag.rindex '|' if idx text = frag.slice(0 ... idx) num = frag.slice(idx+1 .. -1) else text = num = frag end new(page_prefix + num, text) end def initialize(page, text = nil) @page, @text = page, text end def to_s ret = "[[" ret << "#{@text}|" if @text ret << "#{@page}]]" end end end def paginate(prefix = '', *pages) parser = @conf.parser.new(@conf) anchors = [] current_page = nil pages.each_with_index do |page, i| anchors << p = Paginate::Page.parse(page, prefix) current_page = i if p.page == @page end if current_page anchors[current_page] = "''" + anchors[current_page].text + "''" if current_page != anchors.length - 1 @next_page_name = anchors[current_page + 1].page next_page_anchor = "[[>|#{@next_page_name}]]" end if current_page != 0 @prev_page_name = anchors[current_page - 1].page prev_page_anchor = "[[<|#{@prev_page_name}]]" end end add_header_proc do ret = '' ret << %Q|\n <link rel="prev" href="?#{@prev_page_name}">| if @prev_page_name ret << %Q|\n <link rel="next" href="?#{@next_page_name}">| if @next_page_name end src_ary = anchors.collect { |a| '# ' + a.to_s } src_ary.unshift('* ' + prev_page_anchor) if prev_page_anchor src_ary.push('* ' + next_page_anchor) if next_page_anchor src = src_ary.join("\n") html = parser.parse(src) @conf.formatter.new(html, @db, self, @conf).to_s end def prev_page(label = @conf['paginate.default_prev_page_label'].to_s) if @prev_page_name %Q|<a href="?#{@prev_page_name}" rel="prev">#{h label}</a>| else '' end end def next_page(label = @conf['paginate.default_next_page_label'].to_s) if @next_page_name %Q|<a href="?#{@next_page_name}" rel="next">#{h label}</a>| else '' end end def paginate_conf_template <<EOT <p>#{paginate_desc}</p> <ul> <li>#{paginate_prev_page_label}<input type="text" name="paginate.default_prev_page_label" value="#{h @conf['paginate.default_prev_page_label'].to_s}"></li> <li>#{paginate_next_page_label}<input type="text" name="paginate.default_next_page_label" value="#{h @conf['paginate.default_next_page_label'].to_s}"></li> </ul> EOT end def paginate_saveconf @conf['paginate.default_prev_page_label'] = @cgi.params['paginate.default_prev_page_label'][0] @conf['paginate.default_next_page_label'] = @cgi.params['paginate.default_next_page_label'][0] end add_conf_proc('paginate', paginate_label) do paginate_saveconf if @mode == 'saveconf' paginate_conf_template end export_plugin_methods :paginate, :prev_page, :next_page
def paginate_label; 'Paginate'; end def paginate_desc; 'Set text used by prev_page and next_page plugins. These are used when plugins are called without text like {{prev_page}}. When called with text like {{next_page("Go to next page")}}, the text("Go to next page") is used.'; end def paginate_prev_page_label; 'Default text for prev_page plugin: '; end def paginate_next_page_label; 'Default text for next_page plugin: '; end
# encoding: euc-jp def paginate_label; 'ページネート'; end def paginate_desc; 'prev_page、next_pageプラグインで使われるデフォルトのテキストを設定します。テキストで「{{prev_page}}」などと呼び出した場合に、ここで設定したテキストが使われます。「{{next_page(次のページに進む)}}」というように明確にテキストを設定してプラグインを呼び出した場合には、そちら(「次のページに進む」)が優先されます。'; end def paginate_prev_page_label; 'prev_pageプラグインのデフォルトのテキスト:'; end def paginate_next_page_label; 'next_pageプラグインのデフォルトのテキスト:'; end
……うーん、汚いなあ。pagenateが長いなあ。FiberとかEnumeratorとか使えればもう少し綺麗になりそうだけど、いかんせんここのサーバーはRuby 1.8.6だからな。Enumeratorは使えるようなので、後日これで作り直してみます。あと、実はクラスじゃなくてラムダ(とクロージャー?)を使ってもいいんじゃないかと思っているところなので、それも併せて。
最初はインスタンス変数を使わないでprev_pageとnext_pageを作ろうと色々やっていたのですが、結局できなくて諦めました。
Paginate::Paginationクラスでも作って、クラスメソッドとして機能を実装して、それをpaginateメソッドから呼ぶようにしたらいいのかな。それならpaginateメソッドはきれいになるしprev_pageとnext_pageも簡単そうだ。Paginationクラスのインスタンスを一つ@pluginオブジェクトのインスタンス変数に入れてしまえばいい。それってクラスでプラグインを作るってことだからHikiプラグインの思想(tDiaryプラグインの思想?)とは相容れないかもしれない。
一ページに複数種類のページネーションを作った時、prev_pageとnext_pageが一方の物しか使えないという難点があります。複数のprev_page等を使い分けたい時は、もう直接[[]]を使って書いちゃってください。