2

I'm looking to edit some Twig templates for certain form elements, but I need template suggestions only for certain form IDs. How do I go about that?

I currently have the following functions in my .theme file:

function exmaple_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_register_form') {
    // Something here to alter suggestions of form elements only for the form with the ID 'user_register_form'
  }
}

function example_theme_suggestions_form_element_alter(array &$suggestions, array $variables, $hook) {
  if (isset($variables['element']['#id'])) {
    $suggestions[] = $hook . '__' . str_replace('-','_', $variables['element']['#id']);
    // This works but returns global form element suggestions
    // For example 'form-element--edit-mail.html.twig' which affects all email edit form elements
    // I need suggestions like 'form-element--user-register-form--edit-mail.html.twig'
  }
}
1

1 Answer 1

5

This is kind of tricky as you'd have to write a lot of custom code to pass the form id to a form element as you stated above. Fortunately, there is a contrib module called "Themable forms" which does exactly that, both for form elements and form element labels.

So for example, if I am on the user login page, for the form elements, I see these default theme hooks for all individual form fields.

<!-- THEME HOOK: 'form_element' -->
<!-- BEGIN OUTPUT from 'themes/custom/mytheme/templates/form/form-element.html.twig' -->

<!-- THEME HOOK: 'form_element_label' -->
<!-- BEGIN OUTPUT from 'themes/custom/mytheme/templates/form/form-element-label.html.twig' -->

Note, there is no granularity at all for the above.

Now, after I enable Themable forms, I start to see very granular theme hook suggestions being output in the form of

  form-element--[form-id]--[element-type].html.twig
  form-element--form-id--[form-id].html.twig
  form-element--type--[element-type].html.twig
  form-element.html.twig

So for example, with the username field, I now see

<!-- THEME HOOK: 'form_element' -->
<!-- FILE NAME SUGGESTIONS:
   * form-element--user-login-form--textfield.html.twig
   * form-element--form-id--user-login-form.html.twig
   * form-element--type--textfield.html.twig
   x form-element.html.twig
-->

<!-- THEME HOOK: 'form_element_label' -->
<!-- FILE NAME SUGGESTIONS:
   * form-element-label--user-login-form--textfield.html.twig
   * form-element-label--form-id--user-login-form.html.twig
   * form-element-label--type--textfield.html.twig
   x form-element-label.html.twig
-->

You'll now note a few things, the form id in the form element suggestion as well as the name of the form element itself.

This should get you where you want to be according to your question above.

You can install the module with:

composer require drupal/themable_forms
1
  • 2
    For anyone curious, I've done a comparison of Formdazzle and Themable Forms modules here: drupal.org/i/3278319 Themable Forms is enough to address this specific Stack Exchange question, however you might as well go with Formdazzle which adds more, better suggestions for other elements like form.html.twig and input.html.twig Oct 18, 2022 at 22:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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