2

I'm attempting to provide a field to users to enable them to enter an external url. If they enter a url I would like that basic page to redirect to the url the user provided instead of actually opening the node. I've made some attempts by using a preprocess node hook in my custom .theme file as seen here:

function mytheme_preprocess_node(&$variables){
    $node = Drupal::request()->attributes->get('node');
    $type = $node->getType();
    if($type == 'page'){
        $redirect = $node->get('field_redirect')->value;
        if($redirect != ''){

            $response = new Symfony\Component\HttpFoundation\RedirectResponse($redirect);
            $response->send();
            Drupal::entityManager()->getViewBuilder('node')->resetCache();
            return;
        }
    }
}

And I've also tried creating a module to do it and using an entity_view hook like so

<?php

function mymodule_entity_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {
  if ($entity->getEntityType()->id() == 'node' && $entity->bundle() == 'page' && !$entity->field_redirect->isEmpty()) {
    $value = $entity->field_redirect->getValue();
    $redirect = $value[0]['value'];
    $response = new Symfony\Component\HttpFoundation\RedirectResponse($redirect);
    $response->send();
    return;
  }
}

Each of these solutions work the first time, but don't work the 2nd time or any time after that until I clear the cache. I'm assuming this is a caching issue. I've heard that using cache tags could resolve this issue but I'm not sure how I would use them. Also I'm not married to making any of these solutions work I merely want to implement some way to perform redirects on pages, it doesn't matter to me how.

Is it possible to perform redirects on node pages?

2 Answers 2

1

this is a cache problem. You need to set correctly the cache tags and context for the entity and it will work. You need to do something like this to skip the cache:

  '#cache' => ['max-age' => 0],

you can find more info here: https://www.drupal.org/developing/api/8/cache/tags

Notes:

  • This needs to be put on hook_entity_view_alter() on the entity in your case the node, or if you want in just one field for which you want to set it. This is a work around for your redirect issue!
  • Try to add it to the $entity, if it doesn't work you need to replace the default '#cache' or you can add it to the $build array, this is case dependent.
0
1

You could extend the NodeViewController (and invoke it via an own NoteRouteProvider) in your module and return the redirect there instead of the $build array. Feels much cleaner to me.

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.