Thème un formulaire de contact

11

Je voudrais thème un formulaire de contact dans Drupal 8. Je voudrais mettre divs autour des éléments de formulaire (en utilisant bootstrap).

Je veux aussi mettre quelques classes sur certains éléments (bouton soumettre, le formulaire lui-même).

Johan Haest
la source
2
Je suggère de décrire votre problème plus en détail et de dire ce que vous avez déjà essayé. Cela montrera une certaine initiative et aidera les autres à vous donner une meilleure réponse.
Aram Boyajyan

Réponses:

16

Ouvrez votre fichier YOURTHEMENAME.theme et ajoutez le code suivant:

function YOURTHEMENAME_form_contact_message_feedback_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  // Name
  $form['name']['#prefix'] = '<div class="row"><div class="col-md-6"><div class="form-group">';
  $form['name']['#suffix'] = '</div>';
  $form['name']['#attributes']['placeholder'][] = $form['name']['#title'].'*';
  $form['name']['#attributes']['class'][] = 'form-control';
  unset($form['name']['#title']);

  // Mail
  $form['mail']['#prefix'] = '<div class="form-group">';
  $form['mail']['#suffix'] = '</div>';
  $form['mail']['#attributes']['placeholder'][] = $form['mail']['#title'].'*';
  $form['mail']['#attributes']['class'][] = 'form-control';
  unset($form['mail']['#title']);


  // Subject
  $form['subject']['widget'][0]['value']['#attributes']['class'][] = 'form-control';
  $form['subject']['widget'][0]['value']['#attributes']['placeholder'][] = $form['subject']['widget'][0]['#title'].'*';
  $form['subject']['widget'][0]['#title'] = '';
  unset($form['subject']['widget'][0]['value']['#title']);
  $form['subject']['widget'][0]['#prefix'] = '<div class="form-group">';
  $form['subject']['widget'][0]['#suffix'] = '</div></div>';

  // Message
  $form['message']['widget'][0]['value']['#attributes']['class'][] = 'form-control';
  $form['message']['widget'][0]['value']['#attributes']['placeholder'][] = $form['message']['widget'][0]['#title'].'*';
  $form['message']['widget'][0]['#title'] = '';
  unset($form['message']['widget'][0]['value']['#title']);
  $form['message']['widget'][0]['#prefix'] = '<div class="col-md-6"><div class="form-group">';
  $form['message']['widget'][0]['#suffix'] = '</div></div></div>';

  // Submit
  $form['actions']['#prefix'] = '<div class="clearfix">';
  $form['actions']['#suffix'] = '</div>';
  $form['actions']['submit']['#attributes']['class'][] = 'btn';
  $form['actions']['submit']['#attributes']['class'][] = 'btn-success';
  $form['actions']['submit']['#attributes']['class'][] = 'pull-right';

}

Et voici votre résultat: entrez la description de l'image ici

N'oubliez pas de vider vos caches;)

rpayanm
la source
1
Si mon thème s'appelle 'abc' et mon formulaire est nommé 'contactez-nous', comment nommer la fonction?
Daniel Dewhurst
3
{themename} _form_contact_message_ {formname} _form_alter
Johan Haest
C'est tellement génial !!!
ipwa
20

Vous pouvez simplement thème chaque forme comme vous le souhaitez. Je n'aime pas la méthode de @rpayanm, car elle est difficile à maintenir et difficile à lire, avec de grandes formes, ce n'est pas le cas, juste un emballage simple et une structure simple.

Chaque formulaire essayant d'utiliser le thème est égal à leur nom de machine. Vous pouvez trouver ce nom de modèle $form['#theme']simplement en le modifiant, il est toujours (ou dans la plupart des cas) identique au nom de la machine id du formulaire. Ce que vous devez faire, c'est d'enregistrer un modèle. Vous devez mettre en œuvre hook_theme(). Vous pouvez l'écrire dans CUSTOMMODULE.module ou dans THEMENAME.theme. La clé de thème doit être la même que dans $form['#theme'], donc elle l'utilise automatiquement, sinon vous devez en ajouter une nouvelle via le formulaire.

/**
 * Implements hook_theme().
 */
function MODULENAME_theme($existing, $type, $theme, $path) {
  return [
    'FORM_ID_THEME' => [
      'template' => 'custom-form-template-name',
      'render element' => 'form',
    ]
  ];
}

Drupal passe la variable $ form avec le formulaire.

Ensuite, vous devez créer custom-form-template-name.html.twig(avec le nom de votre modèle à partir de hook_theme ()).

Le modèle minimal est

{{ form }}

Vous pouvez également imprimer chaque champ du formulaire où vous le souhaitez

{{ form.field_name }}

Ici, vous pouvez faire ce que vous voulez avec le balisage.

Vous pouvez également transmettre des données supplémentaires au modèle en implémentant template_preprocess_TEMPALTENAME

function template_preprocess_FORM_ID_THEME(&$variables) {
  $variables['example'] = 'This is added via preprocess';
}

Et puis utiliser dans le modèle

{{ example }}
<div class="first-field">
  {{ form.first_field }}
</div>

<div class="second-field">
  {{ form.second_field }}
</div>

<div class="buttons">
  {{ form.submit }}
  {{ form.preview }}
</div>
{#
Don't forget to add printing form special info at the end.
Without this data form will not working propertly.
#}
{{ form.form_build_id }}
{{ form.form_token }}
{{ form.form_id }}

Je pense que cette méthode est plus flexible, propre et puissante.

Ps désolé pour mon anglais, j'espère que quelqu'un modifiera et corrigera mes erreurs :)

Exemple de formulaire complexe utilisant cette méthode.

entrez la description de l'image ici

Niklan
la source
2
Notez que pour moi, je devais changer {{ form.submit }}pour{{ form.actions.submit }}
mikeDOTexe
@Niklan: J'ai suivi le même code ci-dessus pour mon formulaire de groupe d'entités personnalisé. Si j'utilise {{ form }}, il imprime tout le formulaire, mais si j'utilise un champ spécifique comme {{ form.my_field }}, rien ne s'affiche. Une idée comment pouvons-nous afficher chaque champ du formulaire de groupe d'entités personnalisé?
kalidasan
@kalidasan essaie d'imprimer chaque champ sans imprimer {{ form }}. Je suggère qu'après l'impression, {{ form }}tous les éléments du formulaire seront marqués comme '#rendered' => TRUEet ne seront pas rendus bientôt. Si vous ne souhaitez pas utiliser cette méthode de formulaire de thème, vous devez imprimer chaque champ individuellement. Il n'y drupal_render_children()en a pas dans Drupal 8, sauf si vous l'écrivez par vous-même. Quoi qu'il en soit par défaut, cela provoquera des doublons, essayez donc d'imprimer chaque champ manuellement.
Niklan
@Niklan: Je n'ai pas utilisé {{ form }} & {{ form.my_field }}ensemble. D'abord essayé avec seulement {{ form }}, ici je peux voir la forme entière. Ensuite, retiré {{ form }}du modèle, puis essayé séparément pour chacun des champs du formulaire, comme ceci {{ form.my_field }}, etc , mais il ne faut pas en sortir. Rien affiché.
kalidasan
1
@kalidasan, vous pouvez désactiver les titres template_preprocess_FORM_ID_THEME(&$variables). Dans ce prétraitement, vous pouvez ajouter de nouvelles variables, modifier les éléments de formulaire existants, y compris. Je n'ai jamais vu ça {{ form.field_name.widget }}et je thématise souvent les formulaires. Il semble que ce champ soit créé ou ajouté par un module tiers? Je pense que c'est permis, mais pas de règle pour les autres. Je vous recommande de commencer par le crochet de prétraitement et de regarder $variables['form']ce qu'il contient à l'intérieur.
Niklan