0

I have a view that lists nodes of a certain type "TypeA" using their titles (and a link to click on).
The view filters out the current TypeA node from that list using a contextual filter set to Content:ID with a default value passed in through the request URL, and the "Exclude" checkbox ticked.
Consequently, when the currently displayed node is not of TypeA, all nodes of TypeA are listed.

I want the block in which the view is displayed to change title depending on whether I view a node of TypeA or not, as follows:

  1. Node is of TypeA, the title is set to "Other TypeAs"
  2. Otherwise, the title is set to "All TypeAs"

I don't know how to further test the query result for the condition, or change the contextual filter (since I always have a Content:ID passed in) to make that happen.

One possible workaround could be to trigger on the URL path because all nodes of TypeA have a custom URL path (via the Pathauto module) configured.

I am using Drupal 8.4.6, soon to migrate to 8.5.

2
  • Instead of putting this logic into the view, could you not have two block instances with different block titles, one for each case, and have them displayed on the pages of respective types accordingly?
    – Hendrik
    Mar 31, 2018 at 9:45
  • Yes, I could - I experimented with that workaround. But that's a lot of duplication for something that is so similar, because I - in my case - would have to maintain two blocks in the same view definition, plus two templates (because blocks must have unique IDs) and two almost identical blocks in the block layout showing almost the same content. Quite a lot of manual config that could go wrong and harder to maintain when the site gets more complex...
    – MDr
    Mar 31, 2018 at 9:58

1 Answer 1

0

You can implement a hook in your module. Ex:

/**
 * Update title of block based on the node type currently being viewed.
 *
 * Implements hook_block_view_alter().
 */
function my_module_block_view_alter(&$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  // Only act on the block you want.
  if ($build['#id'] == 'your_block_id') {
    // Attempt to get the current node object from the route.
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node instanceof \Drupal\node\NodeInterface) {
      if ($node->getType() == 'type_a') {
        $build['#configuration']['label'] = t('Other Type As');
      }
      else {
        $build['#configuration']['label'] = t('All Type As');
      }
    }
  }
}

See api documentation for hook_block_view_alter for more info.

6
  • Thanks, that works! However - and I didn't know that that was important/not automatic/not implemented - I now have two titles. I use the view in a block, and the block is configured to show the title. I expected that to be updated, but that is static (set to the static title value in the respective view display). The dynamic title of the view is displayed within the "div.form-group div.view" element, just before the div.view-content.How can I make the block title dynamic instead?
    – MDr
    Mar 31, 2018 at 18:45
  • Can you configure the block to not show the title instead?
    – sonfd
    Mar 31, 2018 at 18:57
  • Actually, there's no reason you need to do this in a view hook. Updating my answer
    – sonfd
    Mar 31, 2018 at 19:00
  • That doesn't work, but I don't know why. :-( I am not familiar at all with Drupal's internal APIs, so I'll revert for now to the workaround suggested by @Hendrik. Thanks for your help anyway!
    – MDr
    Mar 31, 2018 at 20:10
  • Ok, you can also use the original solution that was giving you 2 titles and just go to your block on the manage display and uncheck "Display Title". That will prevent the block title from appearing, but you'll still get the title just before div.view-content.
    – sonfd
    Mar 31, 2018 at 20:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.