Create a Drupal8 custom TWIG template for a SELECT element

Create a Drupal8 custom TWIG template for a SELECT element

15 Jul 2017 |  drupal

Overriding a form element theme is simple in Drupal8. The following code is an example on how to do with the select field type but you can achieve the same with the field of your choice.

First create your new theme under your module directory template/select–awesome.html.twig.

{#
/**
 * @file
 * Theme override for a select_awesome element.
 *
 * Available variables:
 * - attributes: HTML attributes for the <select> tag.
 * - options: The <option> element children.
 *
 * @see template_preprocess_select_awesome()
 * @see template_preprocess_select()
 */
#}
{% spaceless %}
    <select{{ attributes }}>
        {% for option in options %}
            {% if option.type == 'optgroup' %}
                <optgroup label="{{ option.label }}">
                    {% for sub_option in option.options %}
                        <option value="{{ sub_option.value }}"{{ sub_option.selected ? ' selected="selected"' }}>{{ sub_option.label }}</option>
                    {% endfor %}
                </optgroup>
            {% elseif option.type == 'option' %}
                <option value="{{ option.value }}"{{ option.selected ? ' selected="selected"' }}>{{ option.label }}</option>
            {% endif %}
        {% endfor %}
    </select>
{% endspaceless %}
sandbox/template/select--awesome.html.twig

Then, add a new property #theme to the checkboxes element and set your template name as the value.

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['colors'] = [
      '#type' => 'select',
      '#title' => t('Color set'),
      '#options' => ['green', 'orange', 'red'],
      '#default_value' => 'green',
      '#theme' => 'select_awesome',
    ];
    return $form;
  }  
sandbox/src/form/your_form.php

Finally, implement the hook_theme() to declare your new theme template in your .module file.

    /**
     * Implements hook_theme().
     */
    function sandbox_theme($existing, $type, $theme, $path) {
      return [
        'select_awesome' => [
          'render element' => 'element',
          'preprocess functions' => [
            'template_preprocess_select_awesome',
            'template_preprocess_select',
          ],
        ],
      ];
    }
sandbox.module

Clear the cache, and you should see your new template.

Note, that I have declared a preprocess functions property to reuse the default template_preprocess_select function in order to avoid duplicating it.

Julien Dubreuil

Vous avez une idée, un projet web à réaliser ?

Ensemble, mettons en oeuvre sa réussite. Je vous accompagne dans vos projets, depuis l'élaboration du cahier des charges jusqu'à la mise en production. Pour plus d'information n'hésitez pas à me contacter.

Contactez-moi