By Rizoen


2019-05-15 21:39:50 8 Comments

Views page show content. How to redirect to content page if views has only one result?

1 comments

@No Sssweat 2019-05-16 03:25:08

In your theme's themename.theme file add:

At the very top add:

use Drupal\views\ViewExecutable;
use Symfony\Component\HttpFoundation\RedirectResponse;

Then add:

/*
 * Implements hook_views_pre_render()
 */
function THEMENAME_views_pre_render(ViewExecutable $view) {
    if($view->id() == "view_name" && $view->current_display == 'view_machine_name') {
      if (!empty($view->result) && count($view->result) == 1) {
        $url = $view->result[0]->_entity->toUrl()->toString();
        $response = new RedirectResponse($url);
        $response->send();
      }
    }
}

Clear the cache so changes kick in.


my_module/src/Controller/ViewPageController.php

namespace Drupal\my_module\Controller;

use Drupal\Core\Cache\CacheableRedirectResponse;
use Drupal\Core\Controller\ControllerBase;
use Drupal\views\Views;

/**
 * Defines HelloController class.
 */
class ViewPageController extends ControllerBase {

  public function content() {

    $view = Views::getView('view_name');
    $view->setDisplay('view_machine_name');
    $view->execute();

    if (!empty($view->result) && count($view->result) == 1) {

      $url = $view->result[0]->_entity->toUrl()->toString(TRUE);
      $response = new CacheableRedirectResponse($url->getGeneratedUrl());
      $response->getCacheableMetadata()->addCacheTags($view->getCacheTags());
      $response->addCacheableDependency($url);
      return $response;

    }
    else {

      return [
        '#type' => 'view',
        '#name' => 'view_name',
        '#view' => $view,
        '#display_id' => 'view_machine_name',
        '#embed' => TRUE,
        '#cache' => $view->getCacheTags(),
      ];

    }

  }

}

This is the view_machine_name.

@4k4 2019-05-16 08:57:41

You need to clear the cache every time ;-). It's never a good idea to send a response instead of returning it. But for this use case when a redirect depends on database content I think a custom controller which either returns the view or a cacheable redirect response containing the correct cache metadata would be the best approach.

@No Sssweat 2019-05-16 09:06:16

@4k4 You need to clear the cache every time Doesn't the view get invalidated via cache tag? Or are you referring to when adding a new hook?

@4k4 2019-05-16 09:11:13

Yes, but the redirect needs to get invalidated, too, when the view result is no longer 1. The problem with sending is you have to responses, one you've sent and one which is getting cached, which makes this quite unpredictable what happens.

@No Sssweat 2019-05-16 09:32:50

@4k4 you're right, I could've sworn it worked for me without having to clear the cache, but now it won't work unless I clear the cache. Oh I see now, I prob got a false positive due to having multiple view blocks on the page. I didn't do a view_name conditional.

@No Sssweat 2019-05-16 09:56:03

@4k4 I thought of custom controller at first, but was too lazy for that. So I tried to see if there was quicker alternative.

@No Sssweat 2019-05-16 11:30:02

@4k4 this seems to work fine, tho I am not sure if that's the proper way to return the response, as I'm suppose to be returning an array. I couldn't find a RenderElement that would fit the bill for this.

@4k4 2019-05-16 11:45:16

Yes, a controller can return a response, but use a CacheableRedirectResponse and add the cache tags: $response->getCacheableMetadata()->addCacheTags($view->getCa‌​cheTags());. The OP might also need to add more cache data, the question doesn't provide any details on which the result might depend on.

@No Sssweat 2019-05-16 12:10:33

@4k4 getCacheableMetadata() is not a valid method for RedirectResponse. Anyhow, I did a $response->isCacheable(); and it came back false, so we good.

@4k4 2019-05-16 12:21:29

The problem is that Drupal still caches the uncacheable RedirectResponse, then without cache tags. Only if you use CacheableRedirectResponse and add the cache tags it will get invalidated when the content changes in the database.

@No Sssweat 2019-05-16 12:33:43

@4k4 Using CacheableRedirectResponse gave an error The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\Core\Cache\CacheableMetadata. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperS‌​ubscriber... clearing the cache does not fix it.

@4k4 2019-05-16 12:40:36

Yes, this is another tricky one. When you convert a URL to a string use toString(TRUE) and add the resulting cache dependency to the response as well, see drupal.stackexchange.com/questions/225956/…

@No Sssweat 2019-05-16 12:52:12

@4k4 when using TRUE you need ->getGeneratedUrl(); after it; otherwise, it throws an error. Cheers!

@Clive 2019-05-16 12:53:24

@NoSssweat I just reverted that edit (you missed the line immediately after, which uses $generated_url->getGeneratedUrl())

@4k4 2019-05-16 12:53:56

No, $response->addCacheableDependency($url); doesn't work when this is already applied.

@No Sssweat 2019-05-16 13:07:06

@4k4 sorry I'm a bit confused, 6 am here, you're talking about your other answer that Clive reverted, right? OR are you saying I don't need that line here?

@4k4 2019-05-16 13:19:18

You need the line, but for $url without getGeneratedUrl() applied. I'll edit the answer.

@No Sssweat 2019-05-16 13:26:41

@4k4 ha, I fee like an idiot, time to go to bed.

Related Questions

Sponsored Content

0 Answered Questions

Redirect Page on Change of Exposed Filter

  • 2019-04-05 17:06:47
  • usernameabc
  • 32 View
  • 1 Score
  • 0 Answer
  • Tags:   views 8 hooks ajax

2 Answered Questions

1 Answered Questions

[SOLVED] how to create a static view page which gets result from a content type?

  • 2015-06-15 05:20:41
  • Abdulaziz Hamdan
  • 215 View
  • 1 Score
  • 1 Answer
  • Tags:   7 views nodes

2 Answered Questions

[SOLVED] How to redirect search result page in drupal

2 Answered Questions

[SOLVED] Can I redirect the user to some other page if the result of a view is empty?

  • 2013-05-24 08:18:03
  • qasimzee
  • 1465 View
  • 3 Score
  • 2 Answer
  • Tags:   7 views redirection

3 Answered Questions

[SOLVED] Using view result as an input filter for another view

  • 2013-10-06 22:27:43
  • Mehrdad201
  • 1672 View
  • 1 Score
  • 3 Answer
  • Tags:   views

1 Answered Questions

Let Parent View child's result

  • 2015-12-25 08:06:47
  • primerater01
  • 83 View
  • 1 Score
  • 1 Answer
  • Tags:   7 views

2 Answered Questions

[SOLVED] Taxonomy view resulting content fields

1 Answered Questions

[SOLVED] get result count of a view in another

  • 2015-02-14 17:52:00
  • drup
  • 84 View
  • 0 Score
  • 1 Answer
  • Tags:   views

2 Answered Questions

[SOLVED] How can I lead to 404 Page Not Found when View page has no result?

  • 2012-05-26 06:42:57
  • chinita7
  • 805 View
  • 3 Score
  • 2 Answer
  • Tags:   views 6

Sponsored Content