Playing With Input Templates In Drupal 8

Tags: Drupal 8


Ever wanted to have a nice and clean <button></button> element for your Form buttons instead of the age old <input type=’submit>? (You will be lying if you say no!) One of the challenges until Drupal 7 was the granularity to which you could play with form templates; for instance, you could certainly modify form wrappers and elements. But anything beyond that was still out of reach and default.

With Drupal 8, we have attempted to solve this problem using input.html.twig. This Twig file is the base for every input type you see on a Drupal form. However, the theme suggestions are still lacking, you could for example use input--submit.html.twig to modify all the submit type buttons. But this may feel like overkill when you need something for just a single form.

Thankfully this is not a big issue. We can easily add specific template suggestions using HOOK_theme_suggestions_input_alter.

An example

In the example below, we will see how we can use input.html.twig that ships with D8 core to modify the markup for our input elements. In this case, we will consider a simple example of transforming the add_to_cart button of our product_add_to_cart_form to <button></button>.

How to do it

First we will have to do little bit of prep work. The code below needs to be where you are generating your form or in a hook_form_alter for the form.

// We need to change the markup for submit button.

// @see mycustomtheme_theme_suggestions_input_alter().

$form['add_to_cart']['#attributes']['data-twig-suggestion'] = 'addtocart';

We will check for the above attribute in our mycustomtheme_theme_suggestions_input_alter in the  mycustomtheme.theme file.

/**

* Implements hook_theme_suggestions_input_alter().

*/

function mycustomtheme_theme_suggestions_input_alter(&$suggestions, array $variables) {

$element = $variables['element'];

if (isset($element['#attributes']['data-twig-suggestion'])) {

  if ($element['#attributes']['data-twig-suggestion'] == 'addtocart') {

    $suggestions[] = 'input__add_to_cart';

  }

}

}

TIP: You could also make the above code generic to have additional theme suggestions and get rid of the if conditions. That way, every input.html.twig will have an additional suggestion named input--<type>--<form--id>.html.twig available.

Now copy the input.html.twig and place it in your theme’s templates directory, and rename it to input--add-to-cart.html.twig.

Change the content of the file from

<input />

to

<button></button>

That is it! Rebuild cache and behold your creation.

Bonus

If you want to pass custom variables to such Twig templates, you can use

THEMENAME_preprocess_input().


/**

* Implements THEMENAME_preprocess_input().

*/

function mycustomtheme_preprocess_input(&$variables) {

$element = $variables['element'];

if (isset($element['#attributes']['data-twig-suggestion'])) {

  if ($element['#attributes']['data-twig-suggestion'] == 'addtocart') {

    // Get tooltip content from config.

    $tooltip = \Drupal::config('myform.settings')

      ->get('tooltip.value');

    $variables['tooltip'] = $tooltip;

  }

}

}

This way you can pass any variable to the Twig template and print it using

Find this post helpful (or not)? Tell us so below.

Swarad Mokal, Technical Architect
Posted by

Swarad Mokal, Technical Architect

Big time Manchester United fan, avid gamer, web series binge watcher, and handy auto mechanic.