govCMS / GovCMS8

Current stable release of the main GovCMS8 distribution.
GNU General Public License v2.0
60 stars 58 forks source link

Context: Cache collision, block configuration not respected #329

Open joshua-graham-adelphi opened 4 years ago

joshua-graham-adelphi commented 4 years ago

This is an issue with thw current release of context module.

If two blocks using same menu is is used (on same page?), only the first block cache version is used.

Example Menu block for 3 levels for mega menu Sidebar with 2 levels

End result Sidebar is render with 3 levels expectantly.

This is fixed in the latest development release.

https://www.drupal.org/project/context/issues/2976587

joshua-graham-adelphi commented 3 years ago

To clarify: this is when two different context use the same block but with different configuration. (and main menu has 2 levels but footer has only 1 level shown)

This is fixed in the Govcms 9 release.

Theme layer workaround:

use Drupal\Core\Render\Element;

/**
 * Implements hook_preprocess_page().
 */
function mytheme_preprocess_page(&$variables) {
  $region_keys = Element::children($variables['page']);
  foreach ($region_keys as $region_key) {
    $region = $variables['page'][$region_key];
    $region_block_keys = Element::children($region);
    foreach ($region_block_keys as $region_block_key) {
      $block = $region[$region_block_key];
      if (isset($block['#configuration']['context_id'])) {
        $block['#cache'] = isset($block['#cache']) ? $block['#cache'] : [];
        $block['#cache']['keys'] = isset($block['#cache']['keys']) ? $block['#cache']['keys'] : [];
        // Only add keys to those existing.
        if ($block['#cache']['keys'] && in_array('context_blocks_reaction', $block['#cache']['keys'])) {
          if (!in_array($block['#configuration']['context_id'], $block['#cache']['keys'])) {
            $block['#cache']['keys'][] = $block['#configuration']['context_id'];
            // Change original array now with context name.
            // If two blocks are used in the same context is used, then "unique" checkbox must be checked.
            $variables['page'][$region_key][$region_block_key] = $block;
          }
        }
      }
    }
  }
}