Score:2

Set Body Class if Facet is active

in flag

I need to set a body class if a facet filter is active.

It should be done in yourtheme_preprocess_html

if Facet is active
then
$variables['attributes']['class'][] = 'facet-active';

for fulltext search terms it works like that

  $variables['attributes']['class'][] = 'search-' . \Drupal::request()->query->get('search_api_fulltext');

Anyone know how to dig out the information if a facet is active or not.

thanks in advance

Matthias

Score:2
cn flag

You don't know when the HTML template is rendered whether a facet is active or not. So in mytheme_preprocess_html() assume it is not:

$variables['attributes']['class'][] = 'facet-is-not-active-class';

In the facets block replace the placeholder class if the block is visible:

function mytheme_preprocess_block(&$variables) {
  if ($variables['configuration']['provider'] == 'facets') {
    if (!in_array('hidden', (array) $variables['attributes']['class'])) {
      $variables['#attached']['placeholders']['facet-is-not-active-class'] = [
        '#markup' => 'facet-active',
      ];
    }
  }
}

Important is that the placeholder string facet-is-not-active-class is unique, use a longer name or even a hash. Placeholders are replaced for all occurrences of the string on the page.

Issue with nested placeholders

This works only for blocks not auto-placeholdered. The facet block, unfortunately, is always placeholdered. It sets cache max-age 0 which meets the default condition for auto-placeholdering. See https://www.drupal.org/docs/drupal-apis/render-api/auto-placeholdering#s-what

To prevent that you can set #create_placeholder to FALSE:

/**
 * Implements hook_block_build_BASE_BLOCK_ID_alter().
 */
function mymodule_block_build_facet_block_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  $build['#create_placeholder'] = FALSE;
}

Caveat: This is a real performance killer, it doubles the page loading times in my tests. So if performance is important you probably should look for a client-side solution, better CSS or a javascript library which adds the necessary classes.

ru flag
I didn't know of that special `$variables['#attached']['placeholders']` before. Is there some sort of documentation for all the possibilities inside the `#attached` array? I know of `drupalSettings`, `libraries` and `html_head` keys in there, but there seems to be so much more.
ru flag
Regarding the magic keys in `$variables['#attached']`: googled myself from [this blog](https://davidjguru.github.io/blog/drupal-tips-the-magic-of-attached) to the [API docs](https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21HtmlResponseAttachmentsProcessor.php/function/HtmlResponseAttachmentsProcessor%3A%3AprocessAttachments/9.3.x). Important: Read beyond the docs in the header and look at the [(un-)supported keys in code](https://git.drupalcode.org/project/drupal/-/blob/9.4.x/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php#L140)
in flag
That is a fantastic approach. Thanks a lot. But I cant get it to work and dont know why not. The facet-is-not-active-class is defined in a preprocess_html hook before the preprocess_block hook. facet-is-not-active-class shows up in the body class, but is not replaced after using a facet filter.
in flag
must have to do with one of the two if clauses `if ($variables['configuration']['provider'] == 'myblockid') { if (!in_array('hidden', (array) $variables['attributes']['class'])) {` even if i test it with other blocks which are visible all the time it doesnt replace the initial `facet-is-not-active-class` bodyclass.
4uk4 avatar
cn flag
I've tested some blocks, too. Some work, others not. It seems like blocks which are placeholdered themselves can only placeholder within the block. Unfortunately the facet block is always placeholdered because it sets cache max-age 0. I delete the answer after a while if no solution comes up. As an alternative to this, you could attach a javascript library to the block to check the visibility of the facets client-side.
in flag
if I could do this, I could ;) but I dont know how to do it :(
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.