Checking for empty View Results in Views Block Displays
admin

/**
* Implements hook_preprocess_views_view().
* Adds a custom class to the main view wrapper, which includes .view-content.
*/
function yourtheme_preprocess_views_view(&$variables) {
// The $variables array represents the top-level view wrapper.
// Target only block displays for safety (optional).
if (strpos($variables['view']->current_display, 'block') === 0) {
// Target a specific view/display ID (highly recommended).
// if ($variables['view']->id() == 'my_table_view_id') {
// Ensure the attributes array exists.
if (!isset($variables['attributes']['class'])) {
$variables['attributes']['class'] = [];
}
// Add your custom class.
$variables['attributes']['class'][] = 'my-custom-table-view-class';
// }
}
}
_preprocess_views_view_unformatted(&$variables) {
// Check if the current view is the one you want to target (optional but recommended).
// Example: if ($variables['view']->id() == 'my_view_id' && $variables['view']->current_display == 'block_1') {
// The .view-content class is typically part of the unformatted list wrapper.
// This template's variables directly control that wrapper.
if (!isset($variables['attributes']['class'])) {
$variables['attributes']['class'] = [];
}
// Add your custom class to the existing classes.
$variables['attributes']['class'][] = 'my-custom-view-class';
// Example for adding a class based on the view's machine name and display
$variables['attributes']['class'][] = 'view-id-' . $variables['view']->id() . '-' . $variables['view']->current_display;
}
/**
* Implements hook_views_view().
*
* Prevents rendering a view display if its results are empty.
*/
function your_module_views_view(\Drupal\views\ViewExecutable $view, $display_id) {
// 1. Target specific View Displays (Optional but Recommended)
// To avoid affecting all views, you can check for a specific view ID or display ID.
// Example: if ($view->id() !== 'my_view_id' || $display_id !== 'block_1') { return; }
// 2. Check if the current display is a Block display type.
// We only want to apply this logic to blocks.
if (strpos($display_id, 'block') === 0) {
// 3. Ensure the view has been executed and check the result count.
if ($view->executed) {
$result_count = count($view->result);
// 4. If the results are empty, set $view->build_renderable to FALSE.
if ($result_count === 0) {
// Setting build_renderable to FALSE stops the view from generating
// any render array, effectively skipping all rendering, including
// wrappers and contextual links associated with the view's output.
$view->build_renderable = FALSE;
}
}
}
}
/**
* Implements hook_preprocess_block().
*/
function your_module_or_theme_preprocess_block(&$variables) {
// Check if the block content is a 'view'.
if (isset($variables['content']['#block_content']) && $variables['content']['#block_content'] instanceof \Drupal\views\Plugin\Block\ViewsBlock) {
/** @var \Drupal\views\Plugin\Block\ViewsBlock $block_content */
$block_content = $variables['content']['#block_content'];
// Get the view executable object from the block.
// The view object is available after the block is built.
// If the view hasn't been executed yet, you might need to
// check for the 'view' property on the #view_id and #display_id.
if (isset($block_content->get('view'))) {
/** @var \Drupal\views\ViewExecutable $view */
$view = $block_content->get('view');
// Ensure the view has been executed and has results data.
if (isset($view) && $view->executed) {
$result_count = count($view->result);
// Check if the view results are empty.
if ($result_count === 0) {
// Skip rendering the block entirely by setting #access to FALSE.
// This is the standard Drupal way to prevent rendering.
$variables['#access'] = FALSE;
}
}
}
}
}