web-dev-qa-db-fra.com

Comment utiliser un fichier modèle pour thème un formulaire?

Alors que les nœuds, les commentaires, les blocs et bien d'autres choses dans Drupal sont à thème en utilisant des fichiers de modèle de thème (comme node.tpl.php), les formulaires sont une histoire différente. Il n'y a pas de fichiers de modèle de thème pour les formulaires Comment puis-je obtenir un formulaire particulier pour utiliser un modèle de thème personnalisé?

49
Chaulky

Il est tout à fait raisonnable de vouloir utiliser un fichier tpl pour afficher un formulaire. Vous pouvez utiliser beaucoup de CSS et #prefix/#suffix propriétés pour obtenir des résultats similaires, mais en utilisant tpl, vous n'avez pas à encombrer la séparation de vos couches logique et de présentation et vous n'avez pas à cibler de vilains sélecteurs CSS comme #user-login label. Voici un exemple dans Drupal 7 ...

mytheme/template.php:

function mytheme_theme($existing, $type, $theme, $path) {
    // Ex 1: the "story" node edit form.
    $items['story_node_form'] = array(
        'render element' => 'form',
        'template' => 'node-edit--story',
        'path' => drupal_get_path('theme', 'mytheme') . '/template/form',
    );

    // Ex 2: a custom form that comes from a custom module's "custom_donate_form()" function.
    $items['custom_donate_form'] = array(
        'render element' => 'form',
        'template' => 'donate',
        'path' => drupal_get_path('theme', 'mytheme') . '/template/form',
    );

    return $items;
}

custom_donate_form ():

function custom_donate_form($form, &$form_state) {
    $form['first_name'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('First name')),
    );
    $form['last_name'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Last name')),
    );
    $form['address'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Address')),
    );
    $form['city'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('City')),
    );
    $form['state'] = array(
        '#type' => 'select',
        '#options' => array(
            'default' => 'State',
            '...' => '...',
        ),
    );
    $form['Zip'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Zip')),
    );
    $form['email'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Email')),
    );
    $form['phone'] = array(
        '#type' => 'textfield',
        '#attributes' => array('placeholder' => t('Phone')),
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Submit',
    );

    return $form;
}

mytheme/template/form/donate.tpl.php:

<div class="row">
    <div class="small-12 medium-12 large-8 columns">

        <div class="row">
            <div class="small-12 columns">
                <h5>Contact Information</h5>
            </div>
        </div>

        <div class="row">
            <div class="small-12 large-6 medium-6 columns">
                <?php print render($form['first_name']); ?>
            </div>
            <div class="small-12 large-6 medium-6 columns">
                <?php print render($form['last_name']); ?>
            </div>
        </div>

        <div class="row">
            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['address']); ?>
            </div>

            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['city']); ?>
            </div>
        </div>

        <div class="row">
            <div class="small-12 medium-3 large-3 columns">
                <?php print render($form['state']); ?>
            </div>

            <div class="small-12 medium-3 large-3 columns">
                <?php print render($form['Zip']); ?>
            </div>

            <div class="medium-6 large-6 columns"></div>
        </div>

        <div class="row">
            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['email']); ?>
            </div>

            <div class="small-12 medium-6 large-6 columns">
                <?php print render($form['phone']); ?>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="small-12 medium-12 large-8 large-offset-2 columns">
            <?php print render($form['submit']); ?>
        </div>
    </div>
</div>

<!-- Render any remaining elements, such as hidden inputs (token, form_id, etc). -->
<?php print drupal_render_children($form); ?>

Cela utilise Foundation , ce qui nous donne un formulaire comme celui-ci:

enter image description here

73
Charlie Schliesser

Vous devez implémenter hook_form_alter () dans un module ou template.php et définir la propriété # theme du formulaire:

/**
 * Implements hook_form_alter().
 */
function hook_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login') {
    $form['#theme'] = array('overwrite_user_login');
  }
}

Ensuite, implémentez un nouveau thème:

/**
 * Implements hook_theme().
 */
function hook_theme($existing, $type, $theme, $path){
  return array(
    'overwrite_user_login' => array(
      'render element' => 'form',
      'template' => 'form--user_login',
      'path' => $path . '/templates',
    ),
  );
}

Et puis ajoutez le formulaire - modèle user_login.tpl.php avec le code suivant pour rendre le formulaire:

<?php print drupal_render_children($form) ?> 
17
mrded

Même si vous pouvez utiliser la solution de kiamlaluno, je ne le ferais pas personnellement.

Quelle est la raison pour laquelle vous avez besoin d'un fichier modèle pour un formulaire? Si c'est parce que vous voulez un balisage légèrement différent pour un formulaire existant? Si tel est le cas, vous pouvez utiliser hook_form_alter() pour modifier le formulaire avant son rendu. En utilisant l'API Form, vous pouvez modifier tous les champs du formulaire, injecter des éléments html, etc.

Voici un exemple de hook_form_alter() que j'ai créé qui modifie le bloc de formulaire de connexion standard drupal:

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {

  switch ($form_id) {
    case 'user_login_block':

      // Form modification code goes here.
            $form['divstart'] = array(
                '#value' => '<div style="background-color: red;">',
                '#weight' => -1,
            );

            $form['instruct'] = array(
                '#value' => '<p>Enter your username and password to login</p>',
                '#weight' => 0,
            );          

            $form['divend'] = array(
                '#value' => '</div>',
                '#weight' => 4,             
            );
      break;
  }
}

L'exemple ci-dessus enveloppe tout le formulaire dans un DIV qui a un style en ligne pour transformer la couleur d'arrière-plan en rouge. Il ajoute également un paragraphe de texte d'aide au début du formulaire.

Voici à quoi ressemble mon formulaire de connexion utilisateur une fois le code ci-dessus chargé:

Customised login form

Voir la référence de l'API de formulaire pour plus d'informations: Référence de l'API de formulaire

13
Camsoft

Je n'ai en fait jamais eu besoin d'utiliser un fichier modèle pour un formulaire.
Pour autant que je puisse voir, Drupal le code principal utilise des fonctions de thème, lorsqu'un formulaire ou une partie d'un formulaire doit être rendu d'une manière particulière; une fonction de thème qui appelle drupal_render () est normalement suffisante pour n'importe quel usage.

Pour répondre à la question, la création d'un fichier modèle pour un formulaire n'est pas différente de la création d'un fichier modèle qui n'est pas pour un formulaire.

Définissez une fonction de thème en utilisant comme fonction de thème le nom du rappel du générateur de formulaire. Le code doit être similaire au suivant:

/**
 * Implementation of hook_theme().
 */

 function mymodule_theme() {
   return array(
     'mymodule_form' => array(
       'template' => 'mymodule-form',
       'file' => 'mymodule.admin.inc',
       'arguments' => array('form' => NULL),
     ),
   );
 }

Si le formulaire contient la valeur $form['field_1'], Sa valeur sera disponible dans le fichier modèle sous la forme $field_1. Le fichier modèle pourra également utiliser toutes les valeurs transmises par template_preprocess_mymodule_form().

12
kiamlaluno

Je styliserais toujours en ajoutant à mon fichier CSS en utilisant des sélecteurs pour identifier l'élément à coiffer comme suit pour le formulaire de connexion principal

#user-login
{
   border:1px solid #888;
   padding-left:10px;
   padding-right:10px;
   background-image: url(http://www.zaretto.com/images/zlogo_s.png);
   background-repeat:no-repeat;
   background-position:right;
}

#user-login label
{
    display: inline-block;
}

Ce que j'ajoute simplement à sites/all/themes/theme-name/css/theme-name.css

Si ce dont vous avez besoin pour le style n'a pas d'ID ou de sélecteur suffisamment précis, il est nécessaire d'utiliser l'approche hook pour modifier le HTML et ajouter des identificateurs.

L'OMI utilisant le style en ligne sur les éléments est une très mauvaise pratique qui devrait être déconseillée et remplacée par l'utilisation de class et id

1
Richard Harrison

Pour thème un formulaire, vous pouvez utiliser un CSS personnalisé, comme expliqué dans Thème Drupal 7 formulaires (y compris CSS et JS)).

Fondamentalement, vous devez effectuer ces étapes:

  1. Enregistrez un chemin d'accès au formulaire à l'aide de hook_menu ()
  2. Définissez le formulaire
  3. Enregistrer une fonction de thème avec hook_theme ()
  4. Écrivez la fonction de thème
  5. Créez les fichiers CSS et JavaScript
0
shasi kanth