3

I have a custom field with some radio inputs and the following (widget-)output right now:

<!-- BEGIN OUTPUT from 'core/themes/stable/templates/form/form-element.html.twig' -->
<div>
  <input />
  <label></label>
</div>
<!-- END OUTPUT from 'core/themes/stable/templates/form/form-element.html.twig' -->

For every radio single radio input(In my case 5 times - back 2 back). Can I remove the outer <div> without actually touching any themes (neither the stable theme nor my custom theme) ?

5

Got it working. First you have to copy the default form element template into your module's /templates folder. For example:

$ mkdir -p modules/custom/MYMODULE/templates 
$ cp core/themes/stable/templates/form/form-element.html.twig modules/custom/MYMODULE/templates/form-element.html.twig

Now rename it to something you want. For example:

$ mv modules/custom/MYMODULE/templates/form-element.html.twig modules/custom/MYMODULE/templates/form-element--foo.html.twig

Edit the file to match your needs. For example remove or change the <div></div> tags. Finally in your module's MYMODULE.module file add the following two hooks.

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 *
 * This hook adds a new theme suggestion for all radio form elements.
 */
function MYMODULE_theme_suggestions_form_element_alter(array &$suggestions, array $variables) {

  if ($variables['element']['#type'] == 'radio') {
    $suggestions[] = 'form_element__foo';
  }
}

/**
 * Implements hook_theme().
 *
 * This hook registers a new theme in your module. It will
 * automatically look for the template in your module's /templates folder.
 */
function MYMODULE_theme($existing, $type, $theme, $path) {

  return [
    'form_element__foo' => [
      // base_hook is important!
      // Otherwise your template won't know what to render.
      'base hook' => 'form_element',
    ],
  ];
}

Only thing left, I find, is to have the form ID added to the template suggestion as well, so that we could target only this one form's elements. As now this template will be taken into account for all radio form element wrappers. Independent from what form they are in. But unfortunately I couldn't find the form ID inside the form_element's $variables.


Hah, you simply could add a class to your radios and identify them by that later.

$form['radios'] = [
  '#type' => 'radios',
  // ...
  '#attributes' => ['class' => ['foo']],
];

And then the hook_theme_suggestions_HOOK_alter could look like that:

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function MYMOUDLE_theme_suggestions_form_element_alter(array &$suggestions, array $variables) {

  if ($variables['element']['#type'] == 'radio' && in_array('foo', $variables['element']['#attributes']['class'])) {
    $suggestions[] = 'form_element__foo';
  }
}

Now the custom template would only be taken into account for your specific radios.

  • 1
    If a parent theme hooks the "theme_hook_original", this wont work because your suggestion defined in a module wont be prioritized. In order to make it work, you need to add the hook in your .theme file. Function will then follow the same logic : MYTHEME_theme_suggestions_form_element_alter() – JF Kiwad Nov 14 at 1:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.