In your yourTheme.theme
, you could do:
function yourTheme_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
foreach (\Drupal\Core\Render\Element::children($form) as $key) {
$form[$key]['#attributes']['data-twig-suggestion'] = $form['#id'];
}
$form['actions']['submit']['#attributes']['data-twig-suggestion'] = $form['#id'];
}
The function \Drupal\Core\Render\Element::children($form)
returns an array of all the children elements (for a form) for which the keys don't start with #
.
So, this array will have the field names as its elements. Then, you iterate over the array and add the attribute data-twig-suggestion
and its corresponding value. Note that the array will have some extra elements that aren't form fields, and those would also get the new attribute and its value. I don't think there is any collateral damage on that.
For the submit button ($form['actions']['submit']
) we are adding the attribute "manually", as the field element (submit
) is "nested" inside the actions
array, so our previous loop won't have added the attribute to the correct element in the array.
Then, you also add this function:
function yourTheme_theme_suggestions_input_alter(&$suggestions, array $variables) {
$element = $variables['element'];
if (isset($element['#attributes']['data-twig-suggestion'])) {
$suggestion_suffix = str_replace(['-'], '_', $element['#attributes']['data-twig-suggestion']);
$suggestions[] = 'input__' . $element['#type'] . '__' . $suggestion_suffix;
}
}
Here, each form input field is processed and a template suggestion is added based on the previously created attribute.
PS: this solution is based on this article: Getting granular with Drupal 8 forms.