Score:2

How can I change the query string used in pages showing search results from keys=football to keyword=football?

eg flag

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?

sonfd avatar
in flag
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.
Score:4
us flag

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.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.