blog スタッフブログ
HOME > スタッフブログ > CMS > PowerCMS > PowerCMS Xで高度な動的ページネーションを実装する

PowerCMS Xで高度な動的ページネーションを実装する

PowerCMS Xでは、新着情報一覧ページなど静的に生成されたオブジェクトの一覧ページに所定のパラメータを付与することで、動的ページネーションを実装できます。動的ページネーションの基本的な仕組みについては PowerCMS Xドキュメント(ページネーション)を読むと良いでしょう。

今回は分割するページ数が多くページネーションの一部を…と省略表示したい場合の実装例を紹介します。

高度なページ送りのイメージ: ページ数が多い場合に…とページ数を省略表示している

事前準備

動的ページネーションを動作させるためには、パラメータ付きリクエストをダイナミック・パブリッシングの対象にする必要があります。 PowerCMS Xドキュメント(ページネーション)を参考に設定してください。

インクルード・モジュール「ページネーション」を作成

ビューに以下のインクルード・モジュールを作成します。コメントで簡単に説明を入れていますので、変数及びページネーションのHTMLは適宜調整してください。

<mt:Var name="pagination_max_pages" value="3" note="ページネーションに表示する最大ページ数。奇数指定を推奨" />
<mt:Math eq="floor(x / 2)" x="$pagination_max_pages" setvar="pagination_half_number" />
<mt:Math eq="ceil(x / y)" x="$object_count" y="$pagination_limit" setvar="pagination_total_pages"  />
<mt:SetVarBlock name="is_omit"><mt:If name="pagination_total_pages" gt="$pagination_max_pages">1</mt:If></mt:SetVarBlock>

<mt:SetVarTemplate name="create_pager_link" note="ページネーションのリンク生成">
  <mt:Var name="current_archive_url" />?limit=<mt:Var name="pagination_limit" />
  <mt:If name="pager_offset">&offset=<mt:Var name="pager_offset" /></mt:If>
  &_filter=<mt:Var name="pagination_filter_model" />
</mt:SetVarTemplate>
<mt:Var name="regex_pattern" value="/[\r|\n|\t|\s| | ]/g" note="create_pager_linkの不要な改行とスペース置換" />

<mt:If name="is_omit" note="pagination_max_pagesよりページが多ければ省略表示">
  <mt:Var name="current_page" decrement="$pagination_half_number" setvar="pagination_start_page" />
  <mt:Var name="current_page" increment="$pagination_half_number" setvar="pagination_end_page" />
  <mt:If name="pagination_start_page" lt="1">
    <mt:Var name="pagination_start_page" value="1" />
    <mt:Var name="pagination_end_page" value="$pagination_max_pages" />
  <mt:ElseIf name="pagination_end_page" gt="$pagination_total_pages">
    <mt:Math eq="x - (y - 1)" x="$pagination_total_pages" y="$pagination_max_pages" setvar="pagination_start_page" />
    <mt:Var name="pagination_end_page" value="$pagination_total_pages" />
  </mt:If>

<mt:Else note="pagination_max_pagesよりページが少なければ全て表示">
  <mt:Var name="pagination_start_page" value="1" />
  <mt:Var name="pagination_end_page" value="$pagination_max_pages" />
  <mt:If name="pagination_total_pages" lt="$pagination_max_pages">
    <mt:Var name="pagination_end_page" value="$pagination_total_pages" />
  </mt:If>
</mt:If>

<mt:If name="pagination_total_pages" gt="1" note="2ページ以上あればページネーションを生成">
  <mt:For from="$pagination_start_page" to="$pagination_end_page" step="1">
    <mt:If name="__first__">
      <div class="pagination">
        <mt:SetVarBlock name="has_prev"><mt:If name="current_page" gt="1">1</mt:If></mt:SetVarBlock>
        <mt:If name="has_prev" note="現在のページが2ページ目以降なら前ページへのリンクを生成">
          <div class="pagination__prev">
            <mt:SetVarBlock name="pager_offset"><mt:If name="prev_offset"><mt:Var name="prev_offset" /></mt:If></mt:SetVarBlock>
            <a href="<mt:Var name="create_pager_link" regex_replace="'$regex_pattern',''" />">前へ</a>
          </div><!-- /.pagination__prev -->
        </mt:If>

        <div class="pagination__page">
          <mt:If name="is_omit" note="省略表示する場合">
            <mt:If name="__value__" ne="1" note="最初のページへのリンクがない場合、リンクを生成">
              <mt:Var name="pager_offset" value="" />
              <a href="<mt:Var name="create_pager_link" regex_replace="'$regex_pattern',''" />"<mt:If name="__value__" eq="$current_page"> class="-is-current"</mt:If>>1</a>

              <mt:If name="__value__" gt="2" note="pagination_start_pageが3以上なら...を挿入">
                <span class="pagination__omission">...</span>
              </mt:If>
            </mt:If>
          </mt:If>
    </mt:If>

    <mt:SetVarBlock name="pager_offset"><mt:Math eq="(x - 1) * y" x="$__value__" y="$pagination_limit" /></mt:SetVarBlock>
    <a href="<mt:Var name="create_pager_link" regex_replace="'$regex_pattern',''" />"<mt:If name="__value__" eq="$current_page"> class="-is-current"</mt:If>><mt:Var name="__value__" /></a>

    <mt:If name="__last__">
          <mt:If name="is_omit" note="省略表示する場合">
            <mt:If name="__value__" ne="$pagination_total_pages" note="最後のページへのリンクがない場合、リンクを生成">
              <mt:SetVarBlock name="end_prev_page"><mt:Var name="pagination_total_pages" decrement="1" /></mt:SetVarBlock>
              <mt:If name="__value__" ne="$end_prev_page" note="pagination_end_pageが最後のページより2以上小さければ...を挿入">
                <span class="pagination__omission">...</span>
              </mt:If>

              <mt:SetVarBlock name="pager_offset"><mt:Math eq="(x - 1) * y" x="$pagination_total_pages" y="$pagination_limit" /></mt:SetVarBlock>
              <a href="<mt:Var name="create_pager_link" regex_replace="'$regex_pattern',''" />"<mt:If name="__value__" eq="$current_page"> class="-is-current"</mt:If>><mt:Var name="pagination_total_pages" /></a>
            </mt:If>
          </mt:If>
        </div><!-- /.pagination__page -->

        <mt:SetVarBlock name="has_next"><mt:If name="current_page" lt="$pagination_total_pages">1</mt:If></mt:SetVarBlock>
        <mt:If name="has_next" note="現在のページが最後のページ以外なら次ページへのリンクを生成">
          <div class="pagination__next">
            <mt:SetVarBlock name="pager_offset"><mt:If name="next_offset"><mt:Var name="next_offset" /><mt:Else><mt:Var name="pagination_limit" /></mt:If></mt:SetVarBlock>
            <a href="<mt:Var name="create_pager_link" regex_replace="'$regex_pattern',''" />">次へ</a>
          </div><!-- /.pagination__next -->
        </mt:If>
      </div><!-- / .pagination -->
    </mt:If>
  </mt:For>
</mt:If>

モデル「ページ」一覧のページネーションの例

この例では、 PowerCMS Xドキュメント(ページネーション)同様に1ページ目については静的生成、2ページ目以降は動的生成を想定していますが、1ページ目が動的生成でも動作します。

<mt:Var name="pagination_limit" value="10" note="ページ送り件数" />
<mt:Var name="pagination_filter_model" value="page" note="オブジェクト一覧の対象モデル" />
<mt:Pages sort_by="published_on" sort_order="ascend" limit="$pagination_limit">
  <mt:If name="__first__">
    <ul>
  </mt:If>
  // 中略
  <mt:If name="__last__">
    </ul>
    <mt:Include module="ページネーション">
  </mt:If>
</mt:Pages>

まとめ

PowerCMS Xでは柔軟にページネーションを実装できます。公開サーバーでダイナミック・パブリッシングが利用できない場合、今回ご紹介した方法では実現できませんので、静的ページ分割を実現する 有償プラグイン(SplitPage)の導入を検討すると良いでしょう。

最近の記事

カテゴリ

アーカイブ

スタッフ別