How to do a redirect in node.html.twig?
-
05-02-2021 - |
سؤال
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?
المحلول
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.
نصائح أخرى
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
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;
}
}