9

For a site I'm currently building I've got a variety of views, all with multiple display modes for different pages.

For example, I have a venues view, one block is named listing which lists all of my venues content type. I have another block which has some more specific contextual filters.

My issue is, this different block is styled the same, and has the same markup as my listing block so I don't want to have to duplicate my Twig templates for the rows and fields, for each display mode I have.

What my idea was is to add a function to my .theme file that would allow me to list display modes for a certain view, and add a single theme suggestion off that back of that. This way I can rename my Twig templates, and re-use the same ones for row and field level, on as many display modes as I'd like.

As I'm not using a theme suggestions alter hook, I'm not sure how I actually add theme suggestions.

Here's what I've got so far:

/**
 * Theme suggestions for views.
*/
function spve_preprocess_views_view(&$variables) {
  $view = $variables['view'];
  $id = $view->storage->id();

  // Venues
  if($id === 'venues') {
    // Venues grid
    switch($view->current_display) {
      case 'single_occasion_type_listing':
        $suggestion = 'views-view--venues-grid';
        break;

      default:
        $suggestion = null;
        break;
    }
  }
}

Obviously I'd need to replace either $suggestion with the correct function to add a theme suggestion, or add a bit at the end of my function to add a theme suggestion based of my $suggestion variable.

7 Answers 7

16

Had a similar question, and though answers were good, they didn't provide everything for my case. Plus it's been a minute, adding my 3 cents to help expansion...

Add views template suggestions:

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 *
 * Add views template suggestions.
 * 
 * @inheritdoc
 */
function HOOK_theme_suggestions_views_view_alter(array &$suggestions, array $variables) {
  return [
    'views_view__' . $variables['view']->id()
  ];
}

Add views display template suggestions???:

/**
 * Implements hook_theme_suggestions_HOOK().
 *
 * Add views template suggestions.
 * 
 * @inheritdoc
 */
function HOOK_theme_suggestions_views_view(array $variables) {
  return [
    'views_view_display__' . $variables['view']->current_display,
  ];
}

Add views unformatted template suggestions:

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 *
 * Add views unformatted template suggestions.
 * 
 * @inheritdoc
 */
function HOOK_theme_suggestions_views_view_unformatted_alter(array &$suggestions, array $variables) {
  return [
    'views_view_unformatted__' . $variables['view']->id()
  ];
}

Add views field template suggestions:

/**
 * Implements hook_theme_suggestions_HOOK().
 *
 * Add views field template suggestions.
 * 
 * @inheritdoc
 */
function HOOK_theme_suggestions_views_view_field(array $variables) {
  return [
    'views_view_field__' . $variables['field']->field
  ];
}

And I also want to add that if you're working in a custom module you may need to add the template files to your theme registry using hook_theme():

/**
 * Implements hook_theme().
 *
 * Add template files to the theme.
 * 
 * @inheritdoc
 */
function HOOK_theme($existing, $type, $theme, $path) {
  return [
    // Field templates.
    'views_view_field__my_field_name' => [
      'template' => 'views-view-field--my-field-name',
      'base hook' => 'views_view_field',
    ],
    // Views templates.
    'views_view__my_views_block' => [
      'template' => 'views-view--my-views-id',
      'base hook' => 'views_view',
    ],
    // Views unformatted templates.
    'views_view_unformatted__my_views_block' => [
      'template' => 'views-view-unformatted--my-views-id',
      'base hook' => 'views_view_unformatted',
    ],
  ];
}

And the above HOOK_theme() would correspond to the following Twig template files:

  1. views-view-field--my-field-name.html.twig
  2. views-view--my-views-id.html.twig
  3. views-view-unformatted--my-views-id.html.twig
2
  • 2
    Thanks for this!! Searched for half a day! Jul 19, 2019 at 8:19
  • Great answer with all the possible scenarios! Thank you @Prestosaurus!
    – ahimsauzi
    Sep 9, 2019 at 1:48
11

Your Solution is good, but there is a cleaner one. You can use the hook_theme_suggestions_HOOK_alter, so you do not have to check if it's a view or whatever you want to check.

In your case it would look like this:

    function spve_theme_suggestions_views_view_alter(array &$suggestions, array $variables) {
        // If you want you can add a template suggestion for all views
        // based on their ID:
        $suggestions[] = sprintf('views_view__%s', $variables['view']->id());

        // Or you can check the ID, add suggestions, do whatever you want
        // ...
    }

    function spve_theme_suggestions_views_view_field_alter(array &$suggestions, array $variables) {
        // Check here the id, add suggestions, do whatever you want
        // ...
    }

More informations in the Drupal Theme API

6

So, eventually I came up with the following solution. Basically I'm checking if the current $hook is a view, and then checking if the view is the view I wish to add the suggestions for, and then checks for both row and field levels.

If you find/know a better solution, please share it!

function spve_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {

  /**
   * Venues Grid Twig Template Suggestions
   */
  // Firstly check it's a view
  if($hook === 'views_view') {
    // Check if it's the 'venue' view
    if($variables['view']->id() === 'venues') {
      // Check the display mode
      switch($variables['view']->current_display) {
        case 'listing':              
        case 'single_occasion_type_listing':
          $suggestions[] = 'views-view--venues-grid-rows';
          break;
        default:
          break;
      }
    }
  }

  // Firstly check it's a view field
  if($hook === 'views_view_field') {
    // Check if it's the 'venue' view
    if($variables['view']->id() === 'venues') {
      // Check the display mode
      switch($variables['view']->current_display) {
        case 'listing':              
        case 'single_occasion_type_listing':
          $suggestions[] = 'views-view--venues-grid-field';
          break;
        default:
          break;
      }
    }
  }
  /**
   * E/O Venues Grid Twig Template Suggestions
   */
}
2

(Cross-post from I don't see Views Theme Suggestions)

This is a bug in Drupal 8 core, currently being worked on for version 8.6 8.7

If you need the functionality now, you have two options:

  1. Try the patches from comment #22 (or more recent) on Issue #2923634 and the patches on Issue #2752443. Read the comment thread on #2923634 to get a full understanding of what's going on here.

  2. Or use the well-vetted patch from comment #139 on Issue #2118743 which has been postponed in favor of option 1 above.

I'm using the patch from option 2 (#2118743) successfully. Please note that this does go against the standard core contributor recommendations. But the reason is because #2118743 has a single, well-vetted and working patch for something that is only enabled / used during development, and instead of needing to test out various combinations of two separate patches that are still under development. Once the better solution (#2923634 and #2752443) get fixed in core, #2118743 should be obviated and no longer required.

0

Just to add to Daniels answer that suggestions should be formatted with underscores instead of dashes: $suggestions[] = 'views_view__venues_grid_rows';

0

My problem was a little different, but I think it is relevant here. I need to provide a theme hook suggestion for an entity that is rendered through the field plugin "Rendered Entity". Here's my solution.

  • My module is named "entry"
  • My view id is "entries"

In the entry.module file:

/**
 * Adds theme suggestions for Field in a View
 *
 * @see hook_theme_suggestions_HOOK_alter()
 * @param array $suggestions
 * @param array $variables
 */
function entry_theme_suggestions_views_view_field_alter(array &$suggestions, array $variables) {
  /** @var \Drupal\views\Entity\View $view */
  $view = $variables['view'];
  if ($view->id() == 'entries') {
    $field = $variables['field'];
    if ($field instanceof \Drupal\views\Plugin\views\field\RenderedEntity) {
      $suggestions[] = 'views_view_field__' . $field->options['view_mode'];
    }
  }
}
0

This answer is true - Adding Theme Suggestions Programmatically For Views (Rows & Fields)

/**
 * Implements hook_theme_suggestions_alter().
 */
function hayly_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
  $template = '';
  $view_id = $variables['view']->id();
  switch ($hook) {
    case 'views_view':
      $template = 'views_view__' . $view_id;
      break;

    case 'views_view_unformatted':
      $template = 'views_view_unformatted__' . $view_id;
      break;

    case 'views_view_fields':
      $template = 'views_view_fields__' . $view_id;
      break;
  }
  return [$template];
}

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.