3

In D8 I created a custom input twig file (based on input.html.twig) :

{{ icon }}

<input{{ attributes }} />{{ children }}

Then I created a new entry in hook_theme() :

function my_module_theme() {
 return [
   'input_custom' => [
     'render element' => 'form',
     'variables' => [
       'icon' => NULL,
     ],
     'template' => 'input-custom',
   ],
 ];
}

Then I'm loaded the template in my form element :

$form['my_field'] = [
        '#type' => 'textfield',
        '#theme' => 'input_custom',
        '#icon' => 'my_icon',
        '#title' => $this->t('My title'),
      ];

My custom variable is sent to the template but I lost all html attributes on the input. If I remove variables from my_module_theme() all html attributes are back, but I'm losing my custom variable.

How can I send custom variables in custom input template ?

  • 1
    Possible duplicate of Use a (twig) template for a custom module configuration page – leymannx Jul 5 '18 at 11:02
  • If render element is wrong what am i suppose to use ? It's not a duplicate question, here it's about a specific element. Your link is about the template of the form (i'm already using this and it's working :)) – Promo Jul 5 '18 at 11:23
  • You are supposed to use 'render element' => 'input'. – leymannx Jul 5 '18 at 11:25
  • it's not working... – Promo Jul 5 '18 at 11:41
  • 2
    If you want to define a custom template for an input element use a double underscore '#theme' => 'input__custom'. No need to redeclare this template in hook_theme() then. You can prepare additional variables in a preprocess hook. – 4k4 Jul 5 '18 at 11:58
3

Declare a #theme starting with the base hook of the input element and a double underscore:

  $form['my_field'] = [
    '#type' => 'textfield',
    '#theme' => 'input__custom',
    '#icon' => 'my_icon',
    '#title' => $this->t('My title'),
  ];

Prepare additional variables in a preprocess hook:

function mytheme/mymodule_preprocess_input(&$variables) {
  if ($variables['theme_hook_original'] == 'input__custom') {
    $variables['icon'] = $variables['element']['#icon'];
  }
}

Then you can use the added variables in the input template:

{{ icon }}
0

Update : this solution is not working because the form element becomes a theme element.

I just realize that I'm taking the problem in the wrong way... I should use a custom template where I will load my input and not the opposite.

Like this I don't need to override a core element.

Twig file :

{{ icon }}

{{ input }}

Hook_theme :

function my_module_theme() {
  return [
    'input_custom' => [
      'variables' => [
        'icon' => null,
        'input' => null,
      ],
      'template' => 'input-custom',
    ],
  ];
}

My form element :

 $form['my_field'] = [
    '#theme' => 'input_custom',
    '#icon' => $labels['icon'],
    '#input' => [
      '#type' => 'textfield',
      '#title' => $this->t('My title'), 
    ],
  ];

Notice : for this solution, I changed my point of view on the issue to make it easier to solve. Technically even if this is working, as @4k4 said this is not answering totally the beginning question.

  • 2
    Not exactly the answer to the question for a custom input twig file (based on input.html.twig), which you can do, by the way. – 4k4 Jul 5 '18 at 12:17
  • Indeed, can you post your solution as an answer please ? – Promo Jul 5 '18 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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