Как создать пагинацию для записей в Drupal 8?
Все хорошо и удобно сделано в drupal. Можно легко научиться работать с нодами из кода. Сейчас будем разбираться, как создать пагинацию для нод и других сущностей в Drupal 8. Это для случая, когда нод/сущностей становится слишком много и нужно их выборку разбить на подстраницы с адресом [site url]/page/1..N.
В предыдущих моих статьях мы создали собственный модуль b83 и сущность Example.
Таблица сущности Example в БД у нас уже есть. Давайте заполним ее тестовыми данными.
Для этого создадим файл b83.install в директории модуля b83.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php function b83_update_8101() { $storage = \Drupal::entityTypeManager()->getStorage('example'); for ($i = 0; $i < 34; $i++) { $entity1 = $storage->create( ['cart_content_id' => rand(1, 1000000), 'order_comment' => 'Comment '.rand(1, 1000000), 'order_total' => rand(1, 1000000) ] ); $entity1->save(); } } |
Здесь мы создали функцию b83_update_8101()
, т.е. вызываем хук drupal — hook_update_N
. В этой функции мы подключаемся к хранилищу сущностей example, а затем при помощи метода create()
заполняем столбцы таблицы example.
Что здесь надо иметь ввиду. Поскольку мы создаем новые сущности типа Example, нет необходимости указывать id и uuid — они и так будут уникальными ключами.
Также мы не заполняем поля created
, поскольку это поле в классе сущности мы определили в BaseFieldDefinition
его как created
. Поэтому при создании сущности в него будет автоматически подставлен текущая дата timestamp.
Теперь нам необходимо из-под админа перейти по адресу: [site url]/update.php . Далее мы проходим по шагам этого мастера и в итоге получаем заполненную 34 новыми строками таблицу examples.
Теперь создадим в папке модуля b83/src/Controller файл контроллера Test.php с методом content()
, который будет выводить страницу с пагинацией:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?php namespace Drupal\b83\Controller; use Drupal\Core\Controller\ControllerBase; /** * An test controller. */ class Test extends ControllerBase { public function content() { $sql_count = \Drupal::entityQueryAggregate('example') ->aggregate('id', 'count') ->execute(); $total = $sql_count[0]['id_count']; $num_per_page = 5; $pager = \Drupal::service('pager.manager')->createPager($total, $num_per_page); $page = $pager->getCurrentPage(); $offset = $num_per_page * $page; $entity_ids = \Drupal::entityQuery('example') ->sort('id', 'ASC') ->range($offset, $num_per_page) ->execute(); $rows = []; $storage = \Drupal::entityTypeManager()->getStorage('example'); foreach ($entity_ids as $id) { $example = $storage->load($id); $rows[] = [ 'id' => $example->id->value, 'created' => \Drupal::service('date.formatter')->format($example->created->value, 'html_datetime'), 'order_total' => $example->order_total->value, ]; } $header = ['ID', 'Created', 'Order Total']; $build = []; $build[] = [ '#theme' => 'table', '#header' => $header, '#rows' => $rows, ]; $build[] = [ '#type' => 'pager', ]; return $build; } } |
В начале при помощи метода aggregate()
интерфейса entityQueryAggregate
мы подсчитываем общее количество строк в таблице example. Далее при помощи сервиса pager.manager
мы создаем pager и получаем номер текущей страницы. $num_per_page
— количество записей на странице, а $offset
— смещение относительно начала выборки базы данных в методе select.
При помощи интерфейса entityQuery мы получаем id записей с учетом смещения и количества записей на странице, отсортированных в нужном нам порядке. По сути, это аналог записи SELECT id FROM example ORDER BY id ASC LIMIT $offset, $num_per_page
.
Теперь в цикле мы при помощи хранилища entityTypeManager загружаем поочередно сущности методом load() и формируем массив $rows. Для формата даты я использую \Drupal::service('date.formatter')->format()
. Значения полей таблицы example получаем так: $example->order_total->value
.
Я не стал создавать шаблон темы для этого примера. Воспользовался стандартным рендер-массивом '#theme' => 'table'
, который автоматически генерирует таблицы с заголовками и строками данных.
Теперь осталось вывести pager и собственно саму таблицу данных.
1 2 3 4 5 6 7 8 9 10 11 12 | $build = []; $build[] = [ '#theme' => 'table', '#header' => $header, '#rows' => $rows, ]; $build[] = [ '#type' => 'pager', ]; return $build; |
Так, контроллер готов. Сейчас нам надо сделать маршрут для новой страницы.
В директории модуля создадим файл b83.routing.yml :
1 2 3 4 5 6 7 | b83.content: path: '/my-test-page' defaults: _controller: '\Drupal\b83\Controller\Test::content' _title: 'Testing example entities' requirements: _permission: 'access to testing example entities' |
Здесь:
path: url страницы
_controller: путь до метода контроллера, который будет отвечать за рендеринг содержимого контента страницы
_title: заголовок страницы
_permission: имя разрешения для просмотра данной страницы
Коль уж мы создали разрешение drupal, давайте создадим в директории модуля и файлик b83.permissions.yml :
1 2 3 4 | access to testing example entities: title: 'Access to testing example entities' description: 'This permission creates access to testing example entities.' restrict access: TRUE |
Если захотите настроить права доступа для разных ролей — можете это сделать на странице [site url]/admin/people/permissions .
На этом все. Проверяем работу. Модуль b83 должен быть включен в админке. Также можно сбросить кэш, к примеру через команду linux — drush cr
или также из админки.
Если все ОК, то при открытии страницы [site url]/my-test-page вы увидите что-то похожее на:
Для удобства выкладываю вам [исходники] этой статьи.
Надеюсь, вам было интересно. Пишите комментарии, ставьте рейтинг сегодняшней статье. На этом пока все.