5 Aug.2016

Drupal 10: How to render any form in a Twig Template

Theme a form in drupal 8 and/or 9

Every form trying to use theme equals their machine name. You can find this template name in $form['#theme'] just by altering, it is always (or in most times) same as form id machine name. What you need to do is register a template for it. You need to implement hook_theme() You can write it in CUSTOMMODULE.module or in THEMENAME.theme. Theme key must be the same as in $form['#theme'], so it's automatically use it, otherwise you need to add the new one via form alter.

File
THEMENAME.theme
/**
 * Implements hook_theme().
 */
function easydrupal_theme($existing, $type, $theme, $path) {
  return [
    'contact_message_feedback_contact_form_form' => [
      'render element' => 'form',
    ],
  ];
}
 
/**
 * Implements hook_form_alter().
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param $form_id
 */
function THEMENAME_form_contact_message_feedback_contact_form_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
 
  // Checking field type because it is markup for logged user and we wan't any placeholder.
  if (isset($form['name']) && $form['name']['#type'] == 'textfield') {
    $form['name']['#attributes']['placeholder'][] = $form['name']['#title'] . ' *';
    unset($form['name']['#title']);
  }
 
  if (isset($form['mail']) && $form['mail']['#type'] == 'email') {
    $form['mail']['#attributes']['placeholder'][] = t('Your email') . ' *';
    unset($form['mail']['#title']);
  }
 
  if (isset($form['subject']['widget'])) {
    $form['subject']['widget'][0]['value']['#attributes']['placeholder'][] = $form['subject']['widget'][0]['#title'] . ' *';
    unset($form['subject']['widget'][0]['value']['#title']);
  }
 
  if (isset($form['message']['widget'])) {
    $form['message']['widget'][0]['value']['#attributes']['placeholder'][] = t('Message') . ' *';
    unset($form['message']['widget'][0]['value']['#title']);
  }
 
}
File
contact-message-feedback-contact-form-form.html.twig
<div class="row">
    <div class="col-sm-6">
        {{ form.name }}
        {{ form.mail }}
        {{ form.subject }}
    </div>
    <div class="col-sm-6">
        {{ form.message }}
    </div>
</div>
<div class="row">
    <div class="col-sm-12">
        {{ form.captcha }}
        {{ form.actions }}
        {# Renders the rest of the form #}
        {{ form|without('name', 'mail', 'subject', 'message', 'actions', 'captcha') }}
    </div>
</div>
Conclusion

As you can see, the implementation is very simple. In this way, you can do the theming for any form, for example, contact form of the site or Views Exposed Filters form with a custom twig file. You have the total control on rendering a form in a Twig template.

Ruslan Piskarov

Ukraine
PHP/WEB Developer / Drupal Expert. More than 11 years of experience delivering Drupal based General Purpose solutions for different sectors such as Job Boards, Product Portfolios, Geo Coding, Real Estate solutions, E-Commerce, Classifieds, Corporate and online Magazines/Newspapers.