0

(Spin-off of Remove/Hide the block if the View is empty?. I find the other question a bit confusing, and want to reduce it to the essential question.)

When rendering a view programmatically, and there are no results, there is still some HTML returned from $view->render().

This can be desirable in the following cases:

  • There is a "No results behavior".
  • There are exposed filters, which need to be shown independent of the view result.
  • The view is using AJAX, so it could happen that new content appears dynamically.
  • Perhaps other reasons?

I want to write generic code that renders a view, but completely hides it if there are no results, and no other reason to show it.

So far I have this:

$view = \views_get_view($view_name);
if (NULL === $view) {
  return [];
}
$success = $view->set_display($display_id);
if (FALSE === $success) {
  return [];
}
$view->set_arguments($args);
// See https://www.drupal.org/node/525592#comment-1833824
$view->override_path = $_GET['q'];

$view->pre_execute();
$view->execute();

if (empty($view->result) && empty($view->empty)) {
  // @todo Also check for exposed filters!
  return [];
}

$markup = $view->render();

$view->post_execute();

if (FALSE === $markup) {
  return [];
}
return ['#markup' => $markup];

So the question is: Which other checks should I add when looking if the view is empty? (the place with the @todo).

How do I check if there are exposed filters? Which other criteria are relevant?

2
  • If it isn't massively important, this sort of thing is much easier in jQuery.. You just look for the length of a $('myView .views') and if it's 0, remove the view's div. The advantage of getting used to the jQuery approach is you can alter other things in the dom however you like. Commented Nov 21, 2017 at 17:31
  • For a basic check for exposed filters, you could search for class="views-exposed-form" in $view-result or $markup. If there are exposed filters, that class will be their parent. Commented Nov 23, 2017 at 5:35

2 Answers 2

0

Considering how many criteria might have to be considered to determine if a view can be hidden, I decided to make this a configuration option instead.

I see two ways to do this:

  • The component where the view is embedded can have a configuration option "Hide view if no results". This is what I went with.
  • One could make a symbolic views plugin for "no results behavior", named "Hide view if no results". Then one could implement e.g. hook_preprocess_views_view(), or possibly another hook, to hide the view if the new no results behavior is present.

I could write a lot more details, but for now I want to share the ideas behind these options, maybe this already helps.

I am marking this as the accepted answer. But if someone can come up with something more convincing, I will change it.

0

You can try to use such construction

if (count(views_get_view_result('view_name', 'display_name'))){
  $markup = views_embed_view('view_name', 'display_name');
}else{
  $markup = "";
}
3
  • Or check the empty($view->result), if one already has the view object. I think with your code it might execute the view twice..
    – donquixote
    Commented Nov 23, 2017 at 1:05
  • Also this does not consider the other stuff I wrote in the question: E.g. what if you have exposed filters, or some other reason why you want to show it even if empty?
    – donquixote
    Commented Nov 23, 2017 at 1:06
  • 1) empty() function returns TRUE if you have some HTML there, views returns <div> usually 2) You are right, exposed filters could add some difficulties Actually my code is very simple for embedding views into some template
    – AlexKh
    Commented Nov 23, 2017 at 14:51

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.