Skip to content
Field note

Playing With Input Templates In Drupal 8

Introduction

August 28, 2017·2 min read·Swarad Mokal, Technical Program Manager/ Field correspondent
Playing With Input Templates In Drupal 8

Introduction

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{{ attributes }} />{{ children }}

to

<button{{ attributes }}>{{ "add to cart" | t }}{{ children }}</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

{{ tooltip|raw }}

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

Companion brief

Bring this dispatch into a working session - one page in, scoping memo out.

Brief Foyer
Pressure-test "Field note" with a partner

If this dispatch landed, bring it into a room with us.

The argument in "Playing With Input Templates In Drupal 8" is ours - but every situation breaks the argument differently. Send the situation in one page and a named partner will reply inside one business day with a scoping memo: where the argument holds for you, where it bends, and what we'd actually do in the first two weeks.

One-pager · Field note

By submitting this form you acknowledge that you have read Axelerant's Privacy Policy and agree to its terms.

Replied to by a named partner within one business day.