Skip to main content

To assist in finding possible solutions some of the queries that I made include:

  • Drupal 9 pager with items_per_page
  • Drupal 9 pager merged with exposed form items_per_page

 

I wanted to resolve this issue through the theme file rather than in a custom module.  While most of the time my preference is to create a custom module, the project I'm working at the moment we are working to minimal or no custom modules.  Subsequently, solutions need to be managed via theme file.

 

How did I resolve this using the theme?

I added a hook template_preprocessor_pager function.

/**
 * template_preprocess_pager
 *
 * @param array $variables
 *
 */
function themename_preprocess_pager(&$variables) {

  $view_id = 'magazine';

  $view = \Drupal\views\Views::getView($view_id);
  $view->initHandlers();
  $form_state = new \Drupal\Core\Form\FormState();
  $form_state->setFormState([
    'view' => $view,
    'display' => $view->display_handler->display,
    'exposed_form_plugin' => $view->display_handler->getPlugin('exposed_form'),
    'method' => 'get',
    'rerender' => TRUE,
    'no_redirect' => TRUE,
    'always_process' => TRUE, // This is important for handle the form status.
  ]);

  $variables['sort'] = $form;
}

 

As you will se in this solution, not only did prepare the exposed form for the pager, but I also 

Altered the drop down list, so rather than displaying ## numbers only ie. 5, 10, 25, 50... we wanted to display the number with a label.  Therefore becoming 

  • 5 results per page
  • 10 results per page
  • 25 results per page
  // alter the options so the items_per_page title is added to the output
  foreach ($form['items_per_page']['#options'] as $key => $option) {
    $form['items_per_page']['#options'][$key] = $option . ' ' . $form['items_per_page']['#title'];
  }

Also as the theme was managed via Tailwind, I needed to tweak the class.  The class needed to include

  • tw-text-blue-dark
  • tw-text-sm
  • tw-w-52
$form['#attributes']['class'] = ['tw-text-blue-dark',
                                   'tw-text-sm',
                                   'tw-w-52'];

Finally, remove the label from display.  While I could set the id in css to hidden, I wanted to have nothing displayed at all.

$form['items_per_page']['#title'] = '';

 

Complete solution

/**
 * template_preprocess_pager
 *
 * @param array $variables
 *
 */
function themename_preprocess_pager(&$variables) {

  $view_id = 'magazine';

  $view = \Drupal\views\Views::getView($view_id);
  $view->initHandlers();
  $form_state = new \Drupal\Core\Form\FormState();
  $form_state->setFormState([
    'view' => $view,
    'display' => $view->display_handler->display,
    'exposed_form_plugin' => $view->display_handler->getPlugin('exposed_form'),
    'method' => 'get',
    'rerender' => TRUE,
    'no_redirect' => TRUE,
    'always_process' => TRUE, // This is important for handle the form status.
  ]);

  $form = \Drupal::formBuilder()->buildForm('Drupal\views\Form\ViewsExposedForm', $form_state);
  // alter the options so the items_per_page title is added to the output
  foreach ($form['items_per_page']['#options'] as $key => $option) {
    $form['items_per_page']['#options'][$key] = $option . ' ' . $form['items_per_page']['#title'];
  }
  $form['#attributes']['class'] = ['tw-text-blue-dark',
                                   'tw-text-sm',
                                   'tw-w-52'];
  $form['items_per_page']['#title'] = '';

  $variables['sort'] = $form;
}

 

A few other tips

You can also set #access to false to prevent fields from rendering.

$form = \Drupal::formBuilder()->buildForm('\Drupal\views\Form\ViewsExposedForm', $form_state);
// Hide unnecessary fields.
$form['sort_by']['#access'] = false;
$form['items_per_page']['#access'] = false;

Or hiding the fields that also requires css

$form['search_fulltext']['#type'] = 'hidden';
$form['sort_by']['#type'] = 'hidden';
$form['actions']['#type'] = 'hidden';

And then in your theme CSS:

.form-type-hidden {
  display: none;
}

 

Related articles

Andrew Fletcher04 Apr 2025
Managing .gitignore changes
When working with Git, the .gitignore file plays a critical role in controlling which files and folders are tracked by version control. Yet, many developers are unsure when changes to .gitignore take effect and how to manage files that are already being tracked. This uncertainty can lead to...
Andrew Fletcher26 Mar 2025
How to fix the ‘Undefined function t’ error in Drupal 10 or 11 code
Upgrading to Drupal 10.4+ you might have noticed a warning in their code editor stating “Undefined function ‘t’”. While Drupal’s `t()` function remains valid in procedural code, some language analysis tools — such as Intelephense — do not automatically recognise Drupal’s global functions. This...
Andrew Fletcher17 Mar 2025
Upgrading to PHP 8.4 challenges with Drupal contrib modules
The upgrade from PHP 8.3.14 to PHP 8.4.4 presents challenges for Drupal 10.4 websites, particularly when dealing with contributed modules. While Drupal core operates seamlessly, various contrib modules have not yet been updated to accommodate changes introduced in PHP 8.4.x. This has resulted in...