form API: $form['#theme'] = 'function';

11 contenuti / 0 new
Ultimo contenuto
form API: $form['#theme'] = 'function';

Salve,

premessa: correggeti se erro se scrivo castronerie.

Come da oggetto, vorrei capire alcune cose circa l'utilizzo della proprietà #theme delle form API.
Ho già letto la doc a riguardo.

Mi piacerebbe passare alla funzione di theming ulteriori parametri utili, ma a quanto pare, se si implementa la funzione di theming via form API, è possibile passare solamente l'array $form in automatico, in quanto è possibile solamente dichiarare quale funzione chiamare.

Allora ho provato a passare degli elementi inserendoli $form, ma ho errori, in quanto tra la funzione che definisce il form (richiamato da drupal_get_form via id) e la rispettiva funzione di theming, c'è uno stadio intermezzo di building (che chiama una particolare funzione) che interpreta anche questi dati aggiuntivi e genera di conseguenza errori.
Non ho trovato un modo per escludere questi dati dal processo di building.

Momentaneamente ho risolto passando i dati con i campi hidden (serializzando in form e deserializzando in theme), i quali vengono interpretati e immessi nell'html finale.
Ma questa soluzione non mi piace molto, quindi chiedo a voi se esiste un metodo migliore.

Grazie.

Io la funzione che indichi l'ho utilizzata così:

<?php
//hook menu
function aziende_menu() {
 
$items = array();
  
$items['aziende/register'] = array(
   
'title' => t('Registrazione'),
   
'page callback' => 'drupal_get_form',
   
'page arguments' => array('aziende_register_form'),
   
'access arguments' => array('post aziende'),
   
'weight' => 21,
   
'type' => MENU_NORMAL_ITEM,
   );
  return
$items;
}
//hook form
function aziende_register_form() {
drupal_set_title(t("Registra la tua azienda"));
$form['etichetta_dati'] = array(
   
'#value' => t("DATI AZIENDALI"),
   
'#prefix' => '<div class="div-etichetta-info">',
   
'#suffix' => '</div>',
);
$form['etichetta_luogo'] = array(
   
'#value' => t("LUOGO"),
   
'#prefix' => '<div class="div-etichetta-info">',
   
'#suffix' => '</div>',
);
 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => t("Invia"),
  );
$form['#theme'] = 'aziende_register_form_draw';
return
$form;
}
//hook theme draw
function theme_aziende_register_form_draw($form) {
$rows[] = array(
 
drupal_render($form['etichetta_dati']),
 
drupal_render($form['etichetta_luogo']),
 
drupal_render($form['submit']),
);
   
$output .= drupal_render($form);
   
$output .= theme('table', array(), $rows);
    return
$output;
}
//hook theme
function aziende_theme($existing, $type, $theme, $path) {
  return array(
   
'aziende_register_form_draw' => array(
     
'arguments' => array('form' => NULL),
    ),
  );
}
?>

Sper ti possa essere utili anche se non ci sono molti commenti. CIAO!

Ciao,

grazie della risposta. Tranquillo, il codice è leggibile.
Dunque quando esegui $output .= drupal_render($form);, non renderizza nuovamente tutta la form, anche se parte di essa è stata già renderizzata quando allochi $rows?

A parte questo, è abbastanza simile a quanto ho fatto io, ma di fatto non ho ancora risolto il mio problema, a meno che non mi sfugge la soluzione...

@Felagund: come passi i parametri nel form?

<?php
$form
['#miei_settings'] = array(
 
'parametro1' => 'valore1',
 
'parametro2' => 'valore2',
 
'parametro3' => 'valore3',
);
?>

dovrebbe funzionare.

Attenzione che DEVE esserci il cancelletto all'inizio della chiave nel form (e non essere un valore già usato per altri scopi).

Ciao
Marco
--
My blog
Working at @agavee

Grazie mavimo, questa è una cosa che non sapevo!
Ma cosa serve passare alla funzione di theming ulteriori parametri utili? Cosa centra il codice sopra con (mio esempio) $form['#theme'] = 'aziende_register_form_draw'; ?

@danzise: ipotizza che in fase di elaborazione del form devi determinare una serie di parametri che poi in fase id theming generano form con strutture di output differenti, è giusto che queste considerazioni siano nella generazione del form, mentre in fase di "resa grafica" i dati pre-processati cambino l'output..

Ciao
Marco
--
My blog
Working at @agavee

mavimo wrote:
@Felagund: come passi i parametri nel form?
via input type hidden... ma una soluzione sinceramente brutta.
mavimo wrote:

<?php
$form
['#miei_settings'] = array(
 
'parametro1' => 'valore1',
 
'parametro2' => 'valore2',
 
'parametro3' => 'valore3',
);
?>

dovrebbe funzionare.

Attenzione che DEVE esserci il cancelletto all'inizio della chiave nel form (e non essere un valore già usato per altri scopi).


ok, e se volessi invece dare alla funzione di theming n parametri formali, oltre a $form, poi, dal form, come faccio a passare questi parametri?

grazie.

Temo che non sia prevista questa possibilità, almeno guardando quanto riportato in:

questo perché si ha:

<?php
$content
= theme($elements['#theme'], $elements);
?>

e da theme:

<?php
$args
= func_get_args();
// ...
$content = theme($elements['#theme'], $elements);
?>

quindi per fare quello che richiedi ci sarebbe da mettere mano al core delle funzionalità di theming (cosa che io EVITO COME LA PESTE).

Sicuro di avere questa necessità REALE e non poter procedere in altro modo? Mi sembrerebbe una soluzione più semplice, oppure avere due funzioni di theming, una con solo $form che poi chiama l'altra con i parametri formali (soluzione non bellissima, ma potrebbe risolvere il tuo problema).

Ciao
Marco
--
My blog
Working at @agavee

No, mai toccare il core... :P Mai fatto né mai lo farò :O

In effetti leggendo il tuo post, potrei optare per la tua soluzione, anche se non bellissima: creo una funzione di theming un po' più generica richiamata da un'altra funzione che magari preleva i parametri dal form e li passa alla suddetta funzione di theming generica...

O ancora, direttamente nella mia funzione di theming, potrei sempre inizializzare i parametri formali e poi fare un check del tipo:

Quote:
Se ha passato solamente il form, allora cerca nel form i parametri
Esplico meglio con un esempio:
<?php
 
function theme_my_function(array $form = array(), $par1 = "", array $par2 = array()) {
    if (
$par1 == "" && $form['#miei_parametri']['par1'] != "") {
     
$par1 = $form['#miei_parametri']['par1'];
    }
    if (
count($par2) == 0 && count($form['#miei_parametri']['par2']) != 0) {
     
$par2 = $form['#miei_parametri']['par2'];
    }
  }
?>

Che intendi per:

mavimo wrote:
Sicuro di avere questa necessità REALE e non poter procedere in altro modo? Mi sembrerebbe una soluzione più semplice...

Peccato però: potevano strutturare in #theme un array con il passaggio di parametri, così come implementato in altri contesti... :O

Grazie.

@Felagund: hai veramente necessità di usare parametri formali e non poter prendere le informazioni dal form?

Un codice più pulito, compresso e facilmente estendibile potrebbe diventare:

<?php
 
function theme_my_function($form, $par1 = NULL, $par2 = NULL, ...) {
   
$params = array('par1', 'par2', ...);
    foreach (
$params as $param) {
     $
$param = is_null($$param)) ? $form['#miei_parametri'][$$param] : $$param;
     }
    }
  }
?>

(nonostante Aborri l'uso del $$VAR in questo caso può essere utile, per nona vere n.mila IF)

Ciao
Marco
--
My blog
Working at @agavee

Beh si, il $$var è utile in questo caso, io ho postato un esempio ingenuo.

Vera necessità? BOH non saprei, però mi è scattato questo ragionamento che va a prescindere da Drupal e da questo contesto: posso passare una funzione, e ad una funzione potrei passare tutti i parametri che voglio...

Alla fine i parametri da passare sono 3: due inizializzati ad inizio funzione in una variabile, e il terzo usato in un if e fine della storia.

Grazie dell'aiuto :)