Personalizzazione dei form

Per personalizzare profondamente il markup di un form esistente si può usare una combinazione di hook_theme(), hook_form_alter() e un template Twig. Per modifiche semplici alla struttura o agli attributi del form può bastare un hook_form_alter() o, meglio, un hook_form_FORM_ID_alter().

Quando serve personalizzare il markup di un form

Modifiche semplici con form alter

Personalizzazione profonda con hook_theme()

Nel file .theme bisogna registrare il nuovo theme hook, cioè dire a Drupal che si vuole creare un nuovo template personalizzato per un determinato form :

<?php

use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_theme().
 */
function nome_tema_theme($existing, $type, $theme, $path) {
  return [
    'my_custom_user_login_form' => [ //questo è il nome dell'hook che verrà usato nell'hook_form_alter e verrà usato per il nome del template
      'render element' => 'form', //'form' indica il nome della variabile che dentro il Twig conterrà il form
    ],
  ];
}

/**
 * Implements hook_form_alter()
 */
function nome_tema_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id === 'user_login_form') { //il form che voglio modificare
    $form['#theme'] = 'my_custom_user_login_form'; //imposta la proprietà #theme sul template Twig denominato my-custom-user-login-form.html.twig
  }
}

//esempio con hook_form_FORM_ID_alter() dato che sappiamo già il form ID
function nome_tema_form_user_login_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
  $form['#theme'] = 'my_custom_user_login_form';
}


?>

Registrare un theme hook

Collegare il form al template con #theme

Creare il template Twig del form

Nel file my-custom-user-login-form.html.twig nella cartella templates/ del tema:

<div class="wrapper">
  <div class="left">
    {{ form.name }}
  </div>
  <div class="right">
    {{ form.pass }}
  </div>
  {# Stampa tutto il resto del form (bottoni, token nascosti, ecc.) #}
  {{ form | without('name', 'pass') }}
</div>

Stampare singoli elementi del form

Stampare il resto con without()

Attenzione a token, submit e campi nascosti