2

Search results are given in a page whose URL is, for example, https://example.com/search/node?keys=football. This URL is not recognized by Google Analytics as a search result URL.

How can I change the search URL to https://example.com/search/node?keyword=football?

1
  • 1
    If you're using a view for your search page, they query key is part of the configuration for a filter. You can change it to whatever you'd like.
    – sonfd
    Jun 18, 2023 at 23:14

1 Answer 1

4

URLs output by Drupal can be altered by a tagged service that uses a class which implements two interfaces: OutboundPathProcessorInterface and InboundPathProcessorInterface. (I use links for Drupal 9 documentation pages simply because the Drupal 10 documentation pages do not yet show all the parameter descriptions.)

You can use the code used for the path_alias.path_processor service (the one that handles path aliases) as example code.

.services.yml

services:
  path_alias.path_processor:
    class: Drupal\path_alias\PathProcessor\AliasPathProcessor
    tags:
      - { name: path_processor_inbound, priority: 100 }
      - { name: path_processor_outbound, priority: 300 }
    arguments: ['@path_alias.manager']

Service class

class AliasPathProcessor implements InboundPathProcessorInterface, OutboundPathProcessorInterface {

  /**
   * An alias manager for looking up the system path.
   *
   * @var \Drupal\path_alias\AliasManagerInterface
   */
  protected $aliasManager;

  /**
   * Constructs a AliasPathProcessor object.
   *
   * @param \Drupal\path_alias\AliasManagerInterface $alias_manager
   *   An alias manager for looking up the system path.
   */
  public function __construct(AliasManagerInterface $alias_manager) {
    $this->aliasManager = $alias_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function processInbound($path, Request $request) {
    $path = $this->aliasManager->getPathByAlias($path);
    return $path;
  }

  /**
   * {@inheritdoc}
   */
  public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
    if (empty($options['alias'])) {
      $langcode = isset($options['language']) ? $options['language']->getId() : NULL;
      $path = $this->aliasManager->getAliasByPath($path, $langcode);

      // Ensure the resulting path has at most one leading slash, to prevent it
      // becoming an external URL without a protocol like //example.com. This
      // is done in \Drupal\Core\Routing\UrlGenerator::generateFromRoute()
      // also, to protect against this problem in arbitrary path processors,
      // but it is duplicated here to protect any other URL generation code
      // that might call this method separately.
      if (strpos($path, '//') === 0) {
        $path = '/' . ltrim($path, '/');
      }
    }
    return $path;
  }

}

processOutbound() changes the URLs output by Drupal. The query values are passed in $options['query']. To change the keys value to keyword, you just need to use code similar to the following one.

if (isset($options['query']['keys'])) {
  $keys = $options['query']['keys'];
  unset($options['query']['keys']);
  $options['query']['keyword'] = $keys;
}

You also need to check the path is the one you expect, for example with if ($path == '/search/node') { /* … */ }.

processInbound() changes the URLs received from Drupal before it can handle them. The query parameters are returned from $request->query->get() (for example, $request->query->get('keyword')). A query parameter is set with $request->query->set() (for example, $request->query->set('keyword', $request->query->get('keys'))).

You will also need to set the priority of your path_processor_inbound lower than the one used by path_alias.path_processor (so it is executed after it), and the priority of your path_processor_outbound higher than the one used by path_alias.path_processor (so it is executed before it, and it gets the original path, not the path alias, in $path).

This method works also in the case the search page showing the results is overridden by a view.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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