0

I have a search page with a Views exposed filter for the name of a taxonomy term. I have added an #autocomplete_route_name to the form element to make this an autocomplete selector for my term names. The autocomplete controller returns this:

foreach ($terms as $term) {
  if($term->hasTranslation($langcode)){
    $translated_term = \Drupal::service('entity.repository')->getTranslationFromContext($term, $langcode);
    $results[] = [
      'value' => $translated_term->getName(),
      'label' => $translated_term->getName(),
    ];
  }
}
return new JsonResponse($results);

this works fine, except the url ends up with the term name in the GET (url). Is there any way to have term id here?

I have seen many answers to this question to use hook_views_pre_view. These are fine to modify the value used in the views query, but has no impact on the url variable.

2
  • Can you bit clarify your query like you want to alter the query parameter name or specific query parameter value in the URL? Commented Oct 12, 2023 at 17:00
  • query is something like term=hybrid+workplace but i want it to be tid=34
    – liquidcms
    Commented Oct 12, 2023 at 21:08

2 Answers 2

0

#1: To alter Query parameter value in the url of View page: redirect event subscriber approach used

<?php
    
    namespace Drupal\custom_module;
    
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpKernel\KernelEvents;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Drupal\Core\Routing\RouteMatchInterface;
    use Symfony\Component\HttpFoundation\RequestStack;
    use Drupal\Core\Url;
    
    /**
     * Execute to changes query parameter value in the url of view page.
     */
    class RedirectSubscriber implements EventSubscriberInterface {
    
      /**
       * Current Route.
       *
       * @var \Drupal\Core\Routing\RouteMatchInterface
       */
      protected $route;
    
      /**
       * The request stack.
       *
       * @var \Symfony\Component\HttpFoundation\RequestStack
       */
      protected $requestStack;
    
      /**
       * Constructs a RedirectSubscriber object.
       *
       * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
       *   The route match.
       * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
       *   The request stack.
       */
      public function __construct(RouteMatchInterface $current_route_match, RequestStack $requestStack) {
        $this->route = $current_route_match;
        $this->requestStack = $requestStack;
      }
    
      /**
       * {@inheritdoc}
       */
      public function redirect(GetResponseEvent $event) {
        $route_name = $this->route->getRouteName();
        // Get category name
        $term_name = $this->requestStack->getCurrentRequest()->query->get('category_name');
        // Get term id from category name
        $ary = preg_split('/[()]/', $term_name);
        $tid = $ary[1];
        if ($route_name == 'view.speaker.page_2' && isset($term_name)) {
          if (isset($tid)) {
            // Get all paramters page
            $params = $this->requestStack->getCurrentRequest()->query->All();
            // Alter the category_name query parameter value
            if ($params['category_name']) {
              $params['category_name'] = $tid;
            }
            // Set redirect url & pass all parameters to it
            $redirect_url = Url::fromRoute('view.view_bulk_test.page_2')->setOptions(['query' => $params])->toString();
            if ($redirect_url) {
              // Pass Redirect URL.
              $event->setResponse(new RedirectResponse($redirect_url, 301));
            }
          }
        }
      }
    
      /**
       * {@inheritdoc}
       */
      public static function getSubscribedEvents() {
        $events[KernelEvents::REQUEST][] = ['Redirect', 20];
        return $events;
      }
    
}

File path: : module_name/src/RedirectSubscriber.php

Define: module_name.services.yml (inside custom module)

 services:
  module_name.redirect_subscriber:
    class: Drupal\module_name\RedirectSubscriber
    arguments: ['@current_route_match', '@request_stack']
    tags:
      - { name: 'event_subscriber' }  

In this scenario query parameter whose value altered is autocomplete taxonomy referenced type field & if tid passed then error 'll display: There are no taxonomy terms matching "2".

To fix it: Used hook hook_views_pre_view():

use Drupal\taxonomy\Entity\Term;

function module_name_views_pre_view(ViewExecutable $view, string $display_id, array $args) {
  if (($view->id() == 'speaker')) {
    $exposedInput = $view->getExposedInput();
    // Get term id from category name
    $tid = $exposedInput['category_name'];
    if(isset($tid)){
      // Load term object from term id
      $term = Term::load($tid);
      if(isset($term)){
        // Set value of filter in required format
        $val = $term->label().' '.'('.$tid.')'; 
        $exposedInput['category_name'] = $val;
      }
      // Set the exposed filter value in the view
      $view->setExposedInput($exposedInput); 
    }
  }
}

#2: Query paramter name in the url of view page can be altered by the view UI.

Steps:

  1. Go to the required view and edit the view

  2. Click the filter & filter settings 'll open in the modal

  3. You will find 'Filter identifier' field , here you can specify the required parameter name. enter image description here

3
  • Hmm, yes, just redirecting the page to a different url. Seems inefficient but that should work. Thanks. I'll try this out.
    – liquidcms
    Commented Oct 14, 2023 at 18:18
  • Yeah it's redirecting approach in which redirect to same page with query parameter value altered, Commented Oct 15, 2023 at 6:54
  • Tried to work with diff hooks of view before that hook's code execute , the page redirect so for now found redirect event subscriber approach helps to achieve functionality. Commented Oct 15, 2023 at 6:58
0

If you want to replace term name in the URL by term id. Add this code inot html.html.twig file.

// For Example => https://www.abc.com/yourview_path?termname=your_term_name
{% set Your_url = url('<current>')|render|split('/') %} 
{% if Your_url[3] == 'yourview_path' %}
<script type="text/javascript">
$(document).ready(function(){
 var url = new URL(window.location.href);
 var termname = url.searchParams.get("termname");
 var termid = '{{getTermIdfromName(termname)}}';
 var pageurl =  '/yourview_path?termname=' + termid;
 window.history.pushState({ page: pageurl }, '', pageurl);
  });
</script>
{% endif %}

This is a custom Twig Extenstion to call Drupal function at twig file. I have call at html.html.twig as above. file src/MyTwigExtension.php

<?php

    namespace Drupal\MyTwigModule;

   class MyTwigExtension extends \Twig_Extension {
     public function getName() {
        return 'term_id_by_name';
     }

      public function getFunctions() {
        return array(new \Twig_SimpleFunction('getTermIdfromName', array($this, 'getTermIdfromName'),array('is_safe' => array('html')))
      );
     }
public function getTermIdfromName($name) {
$properties = [];
if (!empty($name)) {
  $properties['name'] = $name;
}
$properties['vid'] = 'section';

$terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadByProperties($properties);
$term = reset($terms);
return !empty($term) ? $term->id() : 0;
}

src/MyTwigModule.services.yml

services:
  MyTwigModule.twig.MyTwigExtension:
   class: Drupal\MyTwigModule\MyTwigExtension
    tags:
     - { name: twig.extension }




Output will be =>  https://www.abc.com/yourview_path?termname=termid (For exp:6912)

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.