template_preprocess_links__dropbutton() incomplete handling of first element

Created on 8 November 2024, 2 months ago

Problem/Motivation

The way radix_template_preprocess_links__dropbutton handles the first link (as a button) is by removing from $variables['links'] the first entry and assigning either the URL or the Text of the link (not the complete link) to a new variable $variables['button']. That is already lacking data for proper twig template component rendering,
at https://git.drupalcode.org/project/radix/-/blob/6.0.0-rc6/includes/menu....
Doing this

 $variables['split'] = FALSE;
  if (isset($link['link']) && ($url = $link['link']['#url'])) {
    $button = $link['link']; // THIS should be the complete link... if not the actual text is lost

    if ($variables['split'] = $url->getRouteName() !== '<nolink>') {
      $button['#options']['attributes']['class'][] = 'btn';
      $button['#options']['attributes']['class'][] = 'btn-outline-dark';
    }

    $variables['button'] = $button;

    // Remove first link from links.
    array_shift($links);

    foreach ($links as $key => $link) {
      $links[$key]['link']['#options']['attributes']['class'][] = 'dropdown-item';
    }
  } elseif (isset($link['text'])) {
    $button = $link['text']; // // THIS should be the complete link...there might be more to it!
    $variables['button'] = $button;

    // Remove first link from links.
    array_shift($links);
  }

but then, in the actual template never uses `button` and it assumes the first link is still here by doing this

https://git.drupalcode.org/project/radix/-/blob/6.0.x/src/kits/radix_sta...

{%
  embed 'radix:dropdown' with {
    dropdown_button_content: links[links|keys|first].text|render,
    dropdown_button_url: links[links|keys|first].link['#url']|render,
    dropdown_size: 'btn-sm',
    split_button: true,
    outline: true,
    items: links
  }
%}

Drop downs and Operation Buttons end being incomplete.

And because the preprocess_hook actually removes a link, a subtheme can not simply implement its own template_preprocess_links__dropbutton hook (the first link will be gone already) to fix this.

Steps to reproduce

Use any radix 6.x subtheme on page that has operations (e.g Node/Content list). Notice Drop Down operations will have (in the case of a NODE) EDIT removed.

Proposed resolution

  • Ideally $variables['links'] should not be altered. Other sub themes might want to have access to the actual data
  • $variables['button'] should contain the complete first link render array, which them could be used without invoking |render inside the actual component (instead of pre-rendering), or if pre-rendering is preferred? then it should be something like
embed 'radix:dropdown' with {
    dropdown_button_content: button.text|default()|render,
    dropdown_button_url: button.link['#url']|default()|render,
    dropdown_size: 'btn-sm',
    split_button: true,
    outline: true,
    items: links|slice(1)
  }

Remaining tasks

Ask the maintainer if this seems like a reasonable solution.

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Active

Version

6.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States diegopino

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @diegopino
  • πŸ‡ΊπŸ‡ΈUnited States danchadwick Boston

    @diegopino: thank you for the thorough report and suggested solution. I followed your ideas. Please re-open if you need further improvements (after adjusting your template to correspond to the one in the starter kit).

    This commit fixes a number of things:
    - The first link becomes the button. It retains any existing attributes.
    - The dropdown_button_attributes passed to the dropdown component are now actually used.
    - The preprocess function does not add classes. That's left to the template where it's easy to customize.
    - The first link, which becomes the button, is left as the first element in the links variable in case your subtheme needs it.
    - The link is now generated natively. This means that to add classes, the same care must be taken to avoid the core bug as happens with local tasks. A (ugh) global function was created to help with this.
    - The split variable is now calculated in the preprocess and passed to the dropdown component.
    - The menu block no longer needs to be passed to the dropdown component.

    NOTE TO EXISTING 6.0 RELEASE CANDIDATE USERS: You will need to copy a new links--dropdown.html.twig file from the starter kit to your subtheme and customize it to your liking.

  • πŸ‡ΊπŸ‡ΈUnited States danchadwick Boston
Production build 0.71.5 2024