I implement a menu on a region using a preprocess function to get a link with an anchor for each block of it with a title. I made a preprocess function for region, in my theme, where I test the region machine name.
I first used the $variables['elements'][XXX]['#id'] to load each block, to find out if the label was set to be display. But I quickly discover that on my server, where the cache is on, the $variables['elements'] only contain an array of cached render.
I then modify my preprocess hook to use the key of the $variables['elements'], witch is finally the block key.
use Drupal\block\Entity\Block;
/**
* Implements hook_preprocess_region().
*/
function MYTHEME_preprocess_region(&$variables) {
if ($variables['region'] == 'one_page') {
$blocs_menu = array();
foreach ($variables['elements'] as $key => $values) {
if (substr($key, 0, 1) == '#') {
continue;
}
$bloc_object = Block::load($key);
if (is_object($bloc_object)) {
$bloc_settings = $bloc_object->get('settings');
if ($bloc_settings['label_display']) {
$blocs_menu[] = array(
'id' => $key,
'label' => $bloc_settings['label'],
);
}
}
}
if (count($blocs_menu)) {
$variables['region_menu'] = $blocs_menu;
}
}
}
And in my override file region--one-page.html.twig
{%- if region_menu -%}
<nav class="page-nav-anchor">
<ul>
{%- for menu in region_menu -%}
<li><a rel="scroll" href="#block-{{ menu['id'] }}">{{ menu['label'] }}</a></li>
{%- endfor -%}
</ul>
</nav>
{%- endif -%}
Everything is working well, but I would like to improve the concept :
- Be able to detect if the cache is activated on the project
- Include in cache my 'region_menu' variable, and generate it only when cache have to be rebuild.
If I understand well, the twig template is also cached, then it is maybe just not really necessary to declare the menu if cache is ON ?
The thing is I'm really lost in the D8 cache API. I think I have to deal with the cache tags, because I don't have a render to cache.
I would appreciate some help, I cannot find some good (and easy) examples on the documentation or in the core modules.