Pager pagination with ajax always points to first page for comment fields that are rendered using #lazy_builder

Created on 22 December 2020, about 4 years ago
Updated 24 January 2025, 11 days ago

Problem/Motivation

Pagination does not work correctly for comment fields that are rendered using #lazy_builder.
So, for the content type, a comments field has been added, for which a custom FieldFormatter has been created that extends CommentDefaultFormatter, and render comments with pagination using #lazy_builder.

Everything is displayed correctly, but the path to the pages in pagination is not formed correctly and when you click to pages then will be displayed comments from the first page.

There are 2 problems here:

First.

The numbering does not work as it always displays the results from the 1st page.
Description:
Pagination that added on the build of comments causes
html/core/modules/comment/src/CommentStorage.php (

$query = $query->extend('Drupal\Core\Database\Query\PagerSelectExtender')
        ->limit($comments_per_page);

), which calls html/core/lib/Drupal/Core/Database/Query/PagerSelectExtender.php and in the execute() method calls the createPager method from PageManager ($pager = $pager_manager->createPager($total_items, $this->limit, $this->element);), according to the createPager method in html/core/lib/Drupal/Core/Pager/PagerManager.php calls the findPage method with html/core/lib/Drupal/Core/Pager/PagerParameters.php, and it is this method that returns the ID of the page to which the link is in the pager, and it is this method that returns it incorrectly if #lazy_builder is used, since this method receives an array of 2 values, and always returns 0, although it should be only one meaning.

Second.

An additional parameter is added to the page ID in the pager link (E.G.? Page = 1,2), and accordingly ",2" is an extra parameter, it is added only if comments are displayed using #lazy_builder (see attachments). This parameter completely breaks pagination work.
Description:
At the moment when the links for the pager (html/core/includes/pager.inc) are canceled, the getUpdatedParameters method is called on the preprocess_pager from the PagerManager

    $options = [
      'query' => $pager_manager->getUpdatedParameters($parameters, $element, $pager_max - 1),
    ];
    $items['last']['href'] = Url::fromRoute($route_name, $route_parameters, $options)->toString();

This method contains 2 parameters, one of which is unnecessary and does not need to be added to the query.

Proposed resolution

Solution for the first problem:

  /**
   * {@inheritdoc}
   */
  public function findPage($pager_id = 0) {
    $pages = $this->getPagerQuery();

    if (count($pages) === 1) {
      return (int) reset($pages);
    }
    return (int) ($pages[$pager_id] ?? 0);
  }

Was added:

    if (count($pages) === 1) {
      return (int) reset($pages);
    }

The solution may be better, but this is a working version at the moment.

Solution for the second problem:
Preprocess pager

  $items = &$variables['items'];
  $pattern = '/%2C.$/';

  // Change href for all pager items except "pages"
  // (E.G. first, previous, next, last, etc.).
  foreach ($items as $key => $item) {
    if (isset($item['href'])) {
      $items[$key]['href'] = preg_replace($pattern, '', $item['href']);
    }
  }

  // Change href for pager "pages" items.
  foreach ($items['pages'] ?? [] as $key => &$item) {
    $items['pages'][$key]['href'] = preg_replace($pattern, '', $item['href']);
  }

This is also a working version, but the solution may be better :)

Steps to reproduce

  • Add comments field to the node bundle
  • Create a custom field formatter and render comments via #lazy_builder
  • Create some node with this bundle
  • Add a few comments to display pagination
  • The pagination shouldn't work properly
πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component

base system

Created by

πŸ‡ΊπŸ‡¦Ukraine rolki

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024