How to add pagination to a page

March 27, 2023 ยท View on GitHub

  1. Add to app/Classes/WebsiteSettings::addFrontendRoutes:
if($indexedPageUrl = $this->urlService->getUrlByPageKey('PAGE_KEY')){
    $frontend->add('{url:' . $newsPageUrl . '}/{page:[0-9]+}', KikCMSConfig::NAMESPACE_PATH_CMS_CONTROLLERS . 'Frontend::page')->setName('PAGE_ROUTE_NAME');
}
  1. Replace PAGE_KEY with the key of the page that needs pagination. Replace PAGE_ROUTE_NAME with a desired route name.
  2. Copy to app/Classes/TemplateVariables.php in a function for the corresponding template:
$page      = $this->dispatcher->getParam('page') ?: 1;
$pageCount = $this->someService->getPageCount();
$itemMap   = $this->someService->getMap($page);
$pages     = $this->paginateListService->getPageList($pageCount, $page);

return [
    'itemMap'     => $itemMap,
    'pages'       => $pages,
    'currentPage' => $page,
];
  1. Replace someService with your own.
  2. In your created service, make the functions to retrieve the paginated content, for example:
/**
  * @param int $page
  * @return FullPageMap
  */
 public function getMap(int $page): FullPageMap
 {
     // todo: this is an example, modify with your own logic
     $query = $this->getNewsBaseQuery()
         ->limit(Config::ITEMS_PER_PAGE, ($page - 1) * Config::ITEMS_PER_PAGE);

     $pageMap = $this->dbService->getObjectMap($query, PageMap::class);

     return $this->fullPageService->getByPageMap($pageMap);
 }

 /**
  * @return Builder
  */
 public function getBaseQuery(): Builder
 {
     // todo: write a query
 }

 /**
  * @return int
  */
 public function getPageCount(): int
 {
     $query = $this->getBaseQuery()->columns('COUNT(id)');

     return ceil($this->dbService->getValue($query) / Config::ITEMS_PER_PAGE);
 }
  1. Where you make a config variable ITEMS_PER_PAGE and you replace, and you add your own logic.
  2. In the template, you add this code to add the pages:
<ul class="pagination">
    {% for pageIndex in pages %}
        {% if pageIndex %}
            <li class="{{ pageIndex == currentPage ? 'active' : '' }}">
                <a href="{{ urlPath }}/{{ pageIndex }}" data-page="{{ pageIndex }}">{{ pageIndex }}</a>
            </li>
        {% else %}
            <li class="disabled"><a>...</a></li>
        {% endif %}
    {% endfor %}
</ul>