You should write a PathProcessor that implements:
Drupal\Core\PathProcessor\InboundPathProcessorInterface
Drupal\Core\PathProcessor\OutboundPathProcessorInterface
Example:
file: modules/custom/mymodule/src/PathProcessor/MymodulePathProcessor.php
namespace Drupal\mymodule\PathProcessor;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Drupal\Core\Render\BubbleableMetadata;
class MymodulePathProcessor implements InboundPathProcessorInterface, OutboundPathProcessorInterface {
public function processInbound($path, Request $request) {
if (strpos($path, '/my-page-') !== 0) {
return $path;
}
$page = preg_replace("/^\/my-page-(\d+)/", '$1', $path);
if (ctype_digit($page)) {
\Drupal::request()->query->set('page', $page);
return "/my-page";
}
else {
\Drupal::request()->query->set('page', 0);
return "/my-page";
}
return $path;
}
public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
if ($path === '/my-page' && isset($options['query']['page'])) {
$page = $options['query']['page'];
unset($options['query']['page']);
return '/my-page-' . $page;
}
return $path;
}
}
file: modules/custom/mymodule/mymodule.services.yml
services:
mymodule.path_processor:
class: Drupal\mymodule\PathProcessor\MymodulePathProcessor
tags:
- { name: path_processor_outbound}
- { name: path_processor_inbound}
We also need to do a custom alteration to the pager. For the full pager the links are not created as the usual link render elements, so they don't go through the processOutboud
, instead the twig file (classy/templates/navigation/pager.html.twig) uses a custom format. The next hook function does the adjustment.
file: modules/custom/mymodule/mymodule.module
/**
* Implements hook_preprocess_HOOK().
* Implements hook_preprocess_pager().
*
* @param $variables
*/
function mymodule_preprocess_pager(&$variables) {
$current_path = \Drupal::service('path.current')->getPath();
if ($current_path === '/my-page')
foreach ($variables['items']['pages'] as &$page_link) {
$page = preg_replace("/^\?page=(\d+)/", '$1', $page_link['href']);
$page_link['href'] = 'my-page-' . $page;
}
}