Come utilizzare un file modello per creare un tema di un modulo?


50

Mentre i nodi, i commenti, i blocchi e molte altre cose in Drupal sono tematici usando file di modelli di temi (come node.tpl.php), i moduli sono una storia diversa. Non ci sono file modello di tema per i moduli. Come posso ottenere un modulo particolare per utilizzare un modello di tema personalizzato?

Risposte:


73

È del tutto ragionevole voler utilizzare un file tpl per visualizzare un modulo. Puoi usare un sacco di CSS e #prefix/ #suffixproprietà estranee per ottenere risultati simili, ma usando tpl non devi ingombrare la separazione dei tuoi livelli logici e di presentazione e non devi mirare a brutti selettori CSS come #user-login label. Ecco un esempio in 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); ?>

Questo sta usando Foundation , che ci dà un modulo come questo:

inserisci qui la descrizione dell'immagine


sembra che tu abbia dimenticato uno stato di ritorno sulla funzione mytheme_theme ()
sel_space

Hai ragione, l'ho aggiunto.
Charlie Schliesser,

5
Nota molto importante è che, in fondo allo snippet di codice, è ciò print drupal_render_children($form)che rende il modulo effettivamente fare cose :).
Chris Rockwell,

Buona risposta. Posso aggiungere che è necessario specificare ulteriormente engine, se si utilizza qualcosa di non predefinito. Es 'engine' => 'twig'.
milkovsky,

1
Bella risposta. Ricorda se vuoi creare un tema per un modulo di amministrazione come user_profile_formo user_register_form. In quello scenario dovrai o a) fare il tuo tema nel tema admin (o sottotitolarlo se non puoi cambiare il tema admin di base) oppure b) mettere il tuo tema in un modulo personalizzato. Altrimenti il ​​tuo tema non sarà visto.
therobyouknow

18

Devi implementare hook_form_alter () in un modulo o template.php e impostare la proprietà #theme del form :

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

Quindi implementare un nuovo tema:

/**
 * 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',
    ),
  );
}

E poi aggiungi il modulo - template user_login.tpl.php con il seguente codice per renderizzare il modulo:

<?php print drupal_render_children($form) ?> 

1
La #themeproprietà è molto semplice ed è menzionata per la prima volta molto in basso nelle risposte, super strano. Questo è sicuramente il mio metodo preferito.
Matt Fletcher,

1
Ho testato questo codice e funziona come previsto.
VladSavitsky,

14

Anche se potresti essere in grado di utilizzare la soluzione di Kiamlaluno, personalmente non lo farei.

Qual è il motivo per cui hai bisogno di un file modello per un modulo? Se è perché desideri un markup leggermente diverso per un modulo esistente? In tal caso, è possibile utilizzare hook_form_alter()per modificare il modulo prima che venga visualizzato. Utilizzando l'API del modulo è possibile modificare tutti i campi del modulo iniettando elementi HTML ecc.

Ecco un esempio di hook_form_alter()quello che ho creato che modifica il blocco del modulo di accesso drupal standard:

/**
 * 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'esempio sopra avvolge l'intero modulo in un DIV che ha uno stile in linea per trasformare il colore di sfondo in rosso. Aggiunge inoltre un paragrafo di testo di aiuto all'inizio del modulo.

Ecco come appare il mio modulo di login utente ora che viene caricato il codice sopra:

Modulo di accesso personalizzato

Vedere il riferimento API del modulo per ulteriori informazioni: Riferimento API del modulo


1
Solo per chiarire l'uso degli stili incorporati in questo esempio è solo per semplificare l'esempio. Non consiglio di usare gli stili incorporati e dovresti usare le classi.
Camsoft

Non sto supportando l'utilizzo di un file modello per il rendering di un modulo; in effetti, ho anche detto che non ho mai usato un file modello per eseguire il rendering di un modulo (ho effettivamente cambiato il codice di un modulo che utilizzava un file modello per un modulo) e che Drupal non usa il modello file per il rendering dei moduli.
kiamlaluno

5
Cosa succede se si desidera modificare radicalmente il markup? A volte un file modello è un'opzione migliore.
cossovich,

6
Markup in un builder di logici di forma odori.
Charlie Schliesser,

1
Sebbene questa soluzione funzioni nella maggior parte dei casi, potrebbe effettivamente interrompersi quando il rendering del modulo viene aggiornato in un callback ajax
PatrickS

13

In realtà non ho mai avuto bisogno di usare un file modello per un modulo.
Per quanto posso vedere, il codice di base di Drupal utilizza le funzioni del tema, quando un modulo o parte di un modulo deve essere reso in un modo particolare; una funzione tema che chiama drupal_render () è normalmente sufficiente per qualsiasi scopo.

Per rispondere alla domanda, la creazione di un file modello per un modulo non è diversa dalla creazione di un file modello che non è per un modulo.

Definire una funzione tema, usando come funzione tema il nome del callback del form builder. Il codice dovrebbe essere simile al seguente:

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

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

Se il modulo contiene il valore $form['field_1'], il suo valore sarà disponibile nel file modello come $field_1. Il file modello sarà anche in grado di utilizzare qualsiasi valore passato da template_preprocess_mymodule_form().


Come posso suggerire un modulo definito da alcuni altri moduli, possibilmente moduli di base per utilizzare la mia funzione / modello di tema?
Shafiul

Set $form['#theme'].
kiamlaluno

1
Non funzionante, quando invio il modulo, non andrà alla funzione
form_submit

1

Vorrei sempre lo stile aggiungendo al mio file CSS utilizzando i selettori per identificare l'elemento da definire come segue per il modulo di accesso principale

#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;
}

Quanto sopra aggiungo semplicemente a sites/all/themes/theme-name/css/theme-name.css

Se ciò che è necessario per lo stile non ha un ID o un selettore sufficientemente accurato, è necessario utilizzare l' hookapproccio per modificare l'HTML e aggiungere identificatori.

L'IMO usando lo stile inline sugli elementi è una brutta pratica che dovrebbe essere deprecata e sostituita con l'uso di classeid


0

Per creare un tema di un modulo, puoi usare un css personalizzato, come spiegato in Temi Drupal 7 Forms (compresi CSS e JS) .

Fondamentalmente è necessario eseguire questi passaggi:

  1. Registrare un percorso per il modulo utilizzando hook_menu ()
  2. Definisci il modulo
  3. Registra una funzione tema con hook_theme ()
  4. Scrivi la funzione tema
  5. Crea i file CSS e JavaScript

-2

Sono abbastanza sicuro che sei in grado di utilizzare un modello per i moduli, ma devi utilizzare hook_theme per registrare il modello in primo luogo. Ho avuto una situazione in cui il modulo doveva davvero essere basato su tabelle anziché su div e le semplici modifiche di #prefix e #suffix non lo tagliavano davvero. Se interessati potrei probabilmente provare a trovare un esempio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.