Problem/Motivation

bs_base_preprocess_block() applies the menu__navbar theme suggestion (and the related bs_base.navbar_onhover
drupalSettings flag) only when $variables['base_plugin_id'] === 'system_menu_block':

switch ($variables['base_plugin_id']) {
    case 'system_menu_block':
      if (isset($variables['content']['#menu_name']) && !empty($variables['elements']['#id'])) {
        $block = Block::load($variables['elements']['#id']);
        if ($block && $block->getRegion() == 'navbar') {
          $variables['content']['#theme'] = 'menu__navbar';
          // ...
        }
      }
      break;
    // ...
  }

Projects sometimes provide their own menu block plugin extending \Drupal\system\Plugin\Block\SystemMenuBlock (for example a domain-aware menu block that resolves the menu name from the active domain). Those plugins register their own id, so base_plugin_id is no longer system_menu_block and the check above never matches. The block falls back to the default menu.html.twig, which means:

  • no navbar-nav / nav-item dropdown / dropdown-menu markup,
  • no data-bs-toggle="dropdown" / aria-haspopup wiring,
  • Navbar type theme setting (Second level dropdown, Second level horizontal) has no effect,
  • navbar.onhover drupalSetting is not attached.

Steps to reproduce

  1. Create a block plugin that extends \Drupal\system\Plugin\Block\SystemMenuBlock and registers its own plugin id (e.g. my_module_main_nav).
  2. Place that block in the navbar region of a bs_base-based theme.
  3. Set theme setting Navbar type to Second level dropdown.
  4. Inspect the rendered menu — it uses menu.html.twig instead of menu--navbar.html.twig, and the dropdown classes / Bootstrap wiring are missing.

Proposed resolution

Detect menu blocks by plugin class (instanceof SystemMenuBlock) instead of relying on base_plugin_id. This keeps existing behavior for the core system_menu_block plugin while also covering any subclass.

use Drupal\system\Plugin\Block\SystemMenuBlock;

  function bs_base_preprocess_block(&$variables) {
    if (isset($variables['content']['#menu_name']) && !empty($variables['elements']['#id'])) {
      $block = Block::load($variables['elements']['#id']);
      if ($block && $block->getRegion() == 'navbar' && $block->getPlugin() instanceof SystemMenuBlock) {
        $variables['content']['#theme'] = 'menu__navbar';
        $variables['content']['#attached']['drupalSettings']['bs_base']['navbar_onhover'] = bs_base_get_setting('navbar.onhover') &&
  (bs_base_get_setting('navbar_type') === 'second-level-horizontal');
      }
    }

    switch ($variables['base_plugin_id']) {
      case 'system_branding_block':
        // ... unchanged.
    }
  }

Remaining tasks

  • Review MR.

Issue fork bs_base-3589968

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

pivica created an issue. See original summary.

pivica’s picture

Status: Active » Needs review

  • pivica committed 816c0788 on 2.0.x
    fix: #3589968 bs_base_preprocess_block() does not apply menu__navbar...
pivica’s picture

Status: Needs review » Fixed

Checked with @berdir, he agrees with the changes.

Merged.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.