0

I'm trying to do a redirect on my node.html.twig template based on the content type because I'm using views for my content.

I tried this:

{% do redirect('/example') %}

or this:

{% redirect '/example' %}

but nothing works. Any idea?

2
  • 1
    You shouldn't (and hopefully can't) perform a redirect in the template layer. This needs to be done much further up the chain
    – Clive
    Nov 29, 2018 at 15:08
  • Did you try just having a Views path set to node/%nid to overtake content?
    – Kevin
    Nov 29, 2018 at 15:11

3 Answers 3

4

Don't do it in the Twig file. This is not where that logic belongs. It should be in an Event.

See this similar question: EventSubscriber called on specific node type or path

All that is left is checking the node type and sending a RedirectResponse.

Gabe Sullice has a Gist that sounds very close to what you are trying to accomplish: https://gist.github.com/gabesullice/96bdae1518d11bb4565e72c33ffcae4c

So your code would fill in something like:

  /**
   * Determines whether we should send a RedirectResponse for this node.
   */
  protected function redirectApplies(NodeInterface $node) : bool {
    $redirect_types = ['type_1', 'type_2', 'type_3'];
    return in_array($node->getType(), $redirect_types);
  }

But if you go to different urls for different types, you will need to adjust it a little more.

2
  • 1
    Yes, the logic belongs either in the controller or in an event subscriber. Instead of the response event (as in the linked Gist) a faster option would be the request event, see this change record drupal.org/node/2013014.
    – 4uk4
    Nov 29, 2018 at 16:53
  • This method works perfectly, i used and modified a few this code and works finally @kevin
    – Mauricio
    Nov 29, 2018 at 17:22
0

Where did you see the redirect functionality? I dont think it's part of standard twig or anything drupal provides: https://www.drupal.org/docs/8/theming/twig/functions-in-twig-templates

You'd be better of doing the redirect in a proprocess function maybe. This might help Redirect basic page to external url when visiting page

2
  • It looks like its a function in CraftCMS but not in Twig itself. docs.craftcms.com/v2/templating/redirect.html
    – Kevin
    Nov 29, 2018 at 15:18
  • (that is to say, they must have created a custom Twig function and it shows up in google results - it also appears in BranchCMS).
    – Kevin
    Nov 29, 2018 at 15:27
0

As @Kevin suggested i created a custom module based on Gabe Sullice code: https://gist.github.com/gabesullice/96bdae1518d11bb4565e72c33ffcae4c

My final code redirect to custom url by content type:

    namespace Drupal\redirect_node_module\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\Event;
use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\node\NodeInterface;
use Drupal\Core\Cache\CacheableRedirectResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
 * Class ResponseSubscriber.
 *
 * @package Drupal\redirect_node_module
 */
class ResponseSubscriber implements EventSubscriberInterface {
  /**
   * Drupal\Core\Routing\CurrentRouteMatch definition.
   *
   * @var Drupal\Core\Routing\CurrentRouteMatch
   */
  protected $routeMatch;
  /**
   * Constructor.
   */
  public function __construct(CurrentRouteMatch $current_route_match) {
    $this->routeMatch = $current_route_match;
  }
  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events['kernel.response'] = ['handle'];
    return $events;
  }
  /**
   * This method is called whenever the kernel.response event is
   * dispatched.
   *
   * @param GetResponseEvent $event
   */
  public function handle(Event $event) {
    $route_name = $this->routeMatch->getRouteName();
    switch ($route_name) {
      case 'entity.node.canonical':
        $node = $this->routeMatch->getParameter('node');
        if ($this->redirectApplies($node)) {
          $event->setResponse(new RedirectResponse($this->getRedirect($node)));
        }
    }
  }
  /**
   * Determines whether we should send a RedirectResponse for this node.
   */
   protected function redirectApplies(NodeInterface $node) {
    // One should have logic here returning TRUE or FALSE for whether we should redirect this response.
    $redirect_on = ['programas', 'servicios', 'aliados', 'testimonios', 'nosotros', 'nuestro_equipo', 'datos_de_contacto', 'banner', 'seccion'];
    return (in_array($node->getType(), $redirect_on));

  }
  protected function getRedirect(NodeInterface $node) {
    // We can cache this response when this is fixed: https://www.drupal.org/node/2573807
    // $response = CacheableRedirectResponse::create($url);
    // $response->addCacheableDependency($node);
    // return $response;

    switch ($node->getType()) {
      case 'nuestro_equipo':
        $url = "/profesionales";
        break;

      case 'datos_de_contacto':
        $url = "/contacto";
        break;

      case 'nosotros':
        $url = "/nosotros";
        break; 

      case 'banner':
        $url = "/";
        break;  

      case 'testimonios':
        $url = "/testimonios";
        break;

      case 'aliados':
        $url = "/aliados";
        break;

      default:
        $search_chars = array('á','é','í','ó','ú','ñ','Á','É','Í','Ó','Ú','Ñ',' ');
        $replace_chars= array('a','e','i','o','u','n','a','e','i','o','u','n','-');
        $node_title = str_replace($search_chars, $replace_chars, strtolower( $node->getTitle() ));
        $url = "/".$node->getType()."/".$node_title;
        break;
    }
    return $url;
  }
}

Your Answer

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

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