1

I am trying to figure out how to create a block that displays recent content using a pager that can fetch the next set of nodes here is what I have so far /modules/example_module/example_module.info.yml

name: Example Module block with pager
description: 'Example Module block with pager'
core: 8.x
type: module
dependencies:
- node
- block
type: module

/modules/example_module/src/Plugin/Block/ExampleModuleBlock.php

<?php
namespace Drupal\example_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
 * Display all instances for 'ExampleModuleBlock' block plugin.
 *
 * @Block(
 *   id = "example_module_block",
 *   admin_label = @Translation("Example Module"),
 *   category = @Translation("Example Module"),
 * )
 */
class ExampleModuleBlock extends BlockBase {
  public function build() {
    $output = example_module_get_content();
    $out = [
      '#markup' => $output,
      ],
    ];
    return $out;
  }
}

and /modules/example_module/example_module.module

<?php

function example_module_get_content(){
  $out = "";
  $nids = example_module_query();
  foreach($nids as $nid){
    $node = \Drupal\node\Entity\Node::load($nid);    
    $out .= "<div>" . $node->getTitle() . "</div>"; 
  }
  return $out;
}

function example_module_query() {
  $query = \Drupal::entityQuery('node')
    ->condition('status', 1)
    ->sort('created', 'DESC') 
    ->pager(10);
  $nids = $query->execute();
  return $nids;
}

which creates a block that can be placed on a theme and displays the latest/recent 10 nodes on the drupal site.

Well I can probably devise a way to query the database and figure out a way to create a custom pager and probably use $current_path = \Drupal::service('path.current')->getPath(); to get the pager PAGE but I was wondering if there is an obvious way that could greatly help and I don't have to reinvent the wheel

what is the deal with pagers are they of any help here ?

3

The first step is to include a pager in the query $query->pager(10), which you have already done. Then you need a render element pager:

  $build['result'] => $out;
  $build['pager'] = [
    '#type' => 'pager',
  ];
  return $build;

If you have multiple pagers on the site, which is probably the case for a block placed on different pages, you have to connect query and pager with a pager id:

  $element = '123';

  $query->pager(10, $element);

  $build['pager'] = [
    '#type' => 'pager',
    '#element' => $element,
  ];
5
  • Thanks how does this build array relate to the block build array ... are they the same ? does the pager hold any pager logic to it ? or just renders a ready made pager ? would really appreciate a more complete example than this ...
    – GiorgosK
    Mar 29 '17 at 7:42
  • The pager logic is in the render element. You can read more about it in the linked documentation. You can put the pager element anywhere in the build array, see edit. But this is more about how to build render arrays in general.
    – 4k4
    Mar 29 '17 at 7:52
  • Thanks its getting clearer now, 1. does the pager logic of the pager include the handling of the paging ? no need to modify my entityQuery ? it will know for example if we are in 2nd or 3rd page of results ? and an extra question 2. entityQuery pager does it work together with range in D7 it could not D8 ? a workaround ?
    – GiorgosK
    Mar 29 '17 at 8:21
  • If you click on the pager a query string "&page=x" is added to the url and then the database query knows what do when you modified it with ->pager(). In D8 this is all build in.
    – 4k4
    Mar 29 '17 at 8:31
  • the 2nd question was actually for FILTERING out the first N elements which will be rendered in a different block on the same page ... can you do pager and range on the same query in D8 ... I am testing your solution and might find my own answer to this.
    – GiorgosK
    Mar 29 '17 at 8:38
0

If you're trying to insert a block with list of nodes and pager then views will be your best bet. Drupal 8 comes pre installed with views so its just a matter of creating a view block and assign it to a region. Of course you can turn ajax on and attach a pager to it.

2
  • Thanks I have thought about it but there is a lot of custom logic around it that will make it cleaner with entityQuery instead of views (insert arbitrary text in the middle of listing, output depending on other listing etc)
    – GiorgosK
    Mar 29 '17 at 5:27
  • You can make heaps of modification by overriding views template. Have you looked into editing templates? You can also look into using views_php ( drupal.org/project/views_php) for adding in your custom logics.
    – Ash U
    Mar 29 '17 at 5:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.