Gli argomenti trattati fanno riferimento alla versione 6.x di Drupal
I menu sono un particolare tipo di blocco.
La loro gestione è fornita dal modulo modules/menu.module e dalle funzioni contenute nel file includes/menu.inc.
menu_block($op = 'list', $delta = 0)
La funzione menu_block() legge il contenuto del menu individuato dal valore $delta. E' chiamata in fase di generazione dei blocchi dalla funzione block_list() con $op='view'.
Torna la seguente array:
$block['subject'] = titolo del bloccco
$block['content'] = stringa del contenuto del menu in formato HTML. [vedi menu_tree()]
L'array è usata in block.tpl.php.
menu_tree($delta)
La funzione menu_tree() ,chiamata da menu_block(), genera il codice HTML del menu individuato dal valore $delta.
Il valore di ritorno è una stringa.
Questa funzione chiama la menu_tree_page_data() per la lettura del contenuto del menu e la menu_tree_output() per la generazione del contenuto in codice HTML.
menu_tree_page_data($menu_name)
La funzione menu_tree_page_data() legge i contenuti dalle tabelle MENU_LINKS e MENU_ROUTER.
Ttornando un array associativa.
Vedere Il contenuto dei menu per una descrizione più dettagliata.
menu_tree_output($tree)
La funzione menu_tree_output() prende in ingresso l'array $tree prodotto da menu_tree_page_data() contenente tutte le informazioni sul menu da visualizzare e la converte in codice HTML .
Torna una stringa.
Questa funzione chiama le funzioni personalizzabili:
menu_primary_links()
La funziome menu_primary_links() torna un array $tree contenente titolo e riferimenti del menu di navigazione Primary links.
menu_secondary_links()
La funziome menu_secondary_links() torna un array $tree contenente titolo e riferimenti del menu di navigazione Secondary links.
theme_links($links,$attributes)
La funzione theme_links() genera il codice HTML dei menu di navigazione Primary links e Secondary links.
E' chiamata in page.tpl.php
menu_list_system_menus()
La funzione menu_list_system_menus() torna un array con i nomi dei menu di sistema:''navigation', 'primary-links', 'secondary-links';
menu_get_menus()
La funzione menu_get_menus() legge i nomi dei menu utente e di sistema dalla tabella MENU_CUSTOM.
Torna un array associativo con i nomi dei menu.
Esempio:
$menu[menu-mio] = "Menu mio"
$menu[navigation] = "Navigation"
$menu[primary-links] = "Primary links"
$menu[secondary-links] = "Secondary links"
menu_get_item($path=NULL, $router_item = NULL)
La funzione menu_get_item() legge i record dalla tabella MENU_ROUTER filtrando suii valori del campo "path" compatibili al percorso della pagina richiesta.
Ad esempio se il percorso della pagina richiesta è node/12345/edit, i possibili valori su cui sarà eseguito il filtro saranno:
7 node/12345/edit
6 node/12345/%
5 node/%/edit
4 node/%/%
3 node/12345
2 node/%
1 node
La funzione torna il primo record di MENU_ROUTER in cui il campo "path" è uguale ad uno dei valori suddetti.
La ricerca del valore di "path" che soddisfa ad uno dei valori suddetti è eseguita secondo il numero d'ordine discendente definito nel campo "FIT".
Abbiamo detto che un menu è un particolare tipo di blocco. Questo significa che le informazioni di selezione sono contenute nella tabella BLOCKS e seguono gli stessi criteri descritti per i blocchi. Quindi i menu selezionati saranno quelli che nella query di selezione dei blocchi hanno il nome modulo uguale a "menu".
Questo è vero per i menu generici.Per i menu primary-links e secondary-links la selezione avviene mediante le due funzion menu_primary_links() e menu_secondary_links() chiamate in template_preprocess_page() durante la generazione della pagina.
Rispetto ai blocchi, nei menu ciò che cambia è come leggere e visualizzare il contenuto e questo verrà descritto qui di seguito.
Il conenuto di un menu è letto dalla funzione menu_block(). All'interno di essa, la lettura e codifica del contenuto del menu viene eseguita, attraverso la funzione menu_tree($menu_name) , dalle due funzioni: menu_tree_page_data() e menu_tree_output().
- La prima , prende in input un nome di menu e in output fornisce un array ($tree) contenente tutte le informazioni lette dalle tabelle MENU_LINKS e MENU_ROUTER per il menu richiesto.
- La seconda, prende in input l'array $tree e genera in output il codice HTML del menu richiesto passandolo alla funzione menu_block().
<?php
function menu_tree($menu_name = 'navigation') {
static $menu_output = array();
if (!isset(
$menu_output[$menu_name])) {
$tree = menu_tree_page_data($menu_name);
$menu_output[$menu_name] = menu_tree_output($tree);
}
return $menu_output[$menu_name];
}
?>L'array $tree, contiene quindi tutte le informazioni delle singole voci appartenenti all'albero del menu corrente.
La singola voce del menu è individuata da una stringa costruita nel seguente modo:
$tree[<50000 + campo_weight> spazio <campo_title> spazio <campo_mlid>]
dove:
50000 è un valore fisso;
<campo_weight> è il peso (ordine) della voce nel menu;
<campo_title> è il titolo della voce corrente;
<campo_mlid> è l'identificativo univoco della voce in MENU_LINKS
Ad esempio per weight=-10 , title=Drupal mlid=96 la stringa che individua la voce è: $tree["49990 Drupal 96"]
Tutti i valori estratti per la singola voce del menu sono posti in $tree["49990 Drupal 96"][link].
Qui di seguito sono riportati i valori contenuti in $tree per ogni voce del menu:
(MR = da tabella MENU_ROUTER; ML= da tabella MENU_LINKS; AL=da altre fonti ) MR $tree[ 49990 Drupal 96][link][load_functions] MR $tree[ 49990 Drupal 96][link][to_arg_functions] MR $tree[ 49990 Drupal 96][link][access_callback] MR $tree[ 49990 Drupal 96][link][access_arguments] MR $tree[ 49990 Drupal 96][link][page_callback] MR $tree[ 49990 Drupal 96][link][page_arguments] MR $tree[ 49990 Drupal 96][link][title] = Drupal MR $tree[ 49990 Drupal 96][link][title_callback] MR $tree[ 49990 Drupal 96][link][type] MR $tree[ 49990 Drupal 96][link][description] ML $tree[ 49990 Drupal 96][link][menu_name] ML $tree[ 49990 Drupal 96][link][mlid] = 96 ML $tree[ 49990 Drupal 96][link][plid] ML $tree[ 49990 Drupal 96][link][link_path] = node/67 ML $tree[ 49990 Drupal 96][link][options] => array() ML $tree[ 49990 Drupal 96][link][module] ML $tree[ 49990 Drupal 96][link][hidden] ML $tree[ 49990 Drupal 96][link][has_children] ML $tree[ 49990 Drupal 96][link][expanded ] ML $tree[ 49990 Drupal 96][link][weight ] = -10 ML $tree[ 49990 Drupal 96][link][depth] ML $tree[ 49990 Drupal 96][link][customized] ML $tree[ 49990 Drupal 96][link][p1] = 96 ML $tree[ 49990 Drupal 96][link][p2] ML $tree[ 49990 Drupal 96][link][p3] ML $tree[ 49990 Drupal 96][link][p4] ML $tree[ 49990 Drupal 96][link][p5] ML $tree[ 49990 Drupal 96][link][p6] ML $tree[ 49990 Drupal 96][link][p7] ML $tree[ 49990 Drupal 96][link][p8] ML $tree[ 49990 Drupal 96][link][p9] ML $tree[ 49990 Drupal 96][link][updated ] AL $tree[ 49990 Drupal 96][link][in_active_trail] = FALSO/VERO AL $tree[ 49990 Drupal 96][link][access ] = VERO/FALSO AL $tree[ 49990 Drupal 96][link][href ] = node/67 AL $tree[ 49990 Drupal 96][link][localized_options] = array() AL $tree[ 49990 Drupal 96][link][below] = FALSO/VERO
Le prime componenti riguardano le funzioni e gli argomenti richiesti per visualizzare la voce del menu.
Poi ci sono alcune voci interessanti: il nome del menu [menu_name], se la voce è espansa o no [expanded], se ha figli [has_children], la pagina a cui punta [href ], il livello di profondità a cui appartiene la voce [depth], se la voce è quella selezionata [in_active_trail]. La componente [localized_options] può contenere un array caricato da funzioni di tematizzazione. Ad esempio la funzione theme_menu_item_link() la usa per inserite gli attributi per il tag HTML <a>.
Avendo il menu una struttura ad albero , l' eventuale identificativo della voce padre è posto in [plid], ed inoltre, per ogni ramo, sono indicati i nodi di diramazione <mlid> fino al nodo radice , attraverso i valori da [p1] (radice) a [p9].
Infine il valore [below] può contenere un array. Questa array è ancora di tipo $tree e rappresenta tutto il sotto albero che si sviluppa a partire dalla voce corrente.
Le due funzioni preposte alla lettura dei menu di navigazione sono la menu_primary_links() e menu_secondary_links(), chiamate all'interno della funzione template_preprocess_page(). Il codice HTML dei menu generato viene posto in $variables['primary_links'] e $variables['secondary_links'], per essere infine reso disponibile nel template page.tpl.php mediante le variabili $primary_links e $secondary_links.
Dalla funzione menu_primary_links() torna un array $links[] ad esempio formato nel seguente modo:
$links[menu-45 active-trail][] = array() eventuali attibuti $links[menu-45 active-trail][href] => node/18 $links[menu-45 active-trail][title] => LINK_1 $links[menu-48][] = array() eventuali attibuti $links[menu-48][href] => node/19 $links[menu-48][title] => LINK_2 $links[menu-46l][] = array() eventuali attibuti $links[menu-46][href] => node/17 $links[menu-46][title] => LINK_3
Nell'esempio il menu è formato da:
Questa array viene successivamente elaborata dalla funzione theme_links($primary_links,array('class' => 'links primary-links') ), chiamata nel file template page.tpl.php (tema garland), e che produce il codice HTML definitivo:.
<ul class="links primary-links"> <li class="first menu-45 active-trail"> <a href="/node/18" class="active">LINK1</a> </li> <li class="menu-48"> <a href="/node/19">LINK_2</a> </li> <li class="menu-46"> <a href="/node/17">LINK_3</a> </li> </ul>
Per la precisione in page.tpl.php viene chiamata la funzione theme('links',$primary_links,array('class' => 'links primary-links')) ma che sappiamo corrispondere alla theme_links(). Questa funzione peraltro può essere personalizzata generando in template.php la funzione miotema_links() o phptemplate_links().
Il codice generato , è infine incapsulato in page.tpl.php all'interno di un blocco <DIV> nel seguente modo:
<div class="links primary-links" >
codice HTML prodotto
</div>
Di seguito è riportato il codice della funzione theme_links() fornita con Drupal .
All'interno dell codice sono riportati alcuni commenti esplicativi.
<?php
// Parametri in ingresso
// $links contiene l'array prodotto da menu_primary_links()
// $attibutes è un array che conterrà il valore passato in page.tpl.php, in paticolare per il tema garland viene passata il // valore array('class' => 'links primary-links')
function theme_links($links, $attributes = array('class' => 'links')) {
$output = '';
// Qui vengono contati il numero di link del menu per definire la class 'first' e 'last'
if (count($links) > 0) {
// Inizio della lista con TAG <ul> l'attributo ID del tag corrisponde al valore 'class' passato in input
$output = '<ul'. drupal_attributes($attributes) .'>';
$num_links = count($links);
$i = 1;
// Inizio lettura LINK
foreach ($links as $key => $link) {
// Definizione dell' attributo 'class' per il tag <li>
// Il nome minimo sarà menu-xx. nel nostro esempio menu-45 menu-46 menu-48
$class = $key;
// Aggiunge 'first', 'last' e 'active' alla stringa della classe per meglio specificare l'elemento che si sta visualizzando.
if ($i == 1) {
$class .= ' first';
}
if ($i == $num_links) {
$class .= ' last';
}
if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))) {
$class .= ' active';
}
// Scittura del tag <li>
$output .= '<li'. drupal_attributes(array('class' => $class)) .'>';
// preparazione del tag anchor <a>
if (isset($link['href'])) {
// Pass in $link as $options, they share the same keys.
$output .= l($link['title'], $link['href'], $link);
}
else if (!empty($link['title'])) {
// Some links are actually not links, but we wrap these in <span> for adding title and class attributes
if (empty($link['html'])) {
$link['title'] = check_plain($link['title']);
}
$span_attributes = '';
if (isset($link['attributes'])) {
$span_attributes = drupal_attributes($link['attributes']);
}
$output .= '<span'. $span_attributes .'>'. $link['title'] .'</span>';
}
// fine primo link
$i++;
$output .= "</li>\n";
}
// fine lista
$output .= '</ul>';
}
// torna il codice prodotto
return $output;
}
?>Quanto detto per il menu Primary links vale per Il menu Secondary links.
E' utilizzata per la lettura dei contenuti la funzione: menu_secondary_links().
In page.tpl.php la variabile usata è la $secondary_links.
Il blocco <div> che coniene il codice HTML è il seguente:
<div class="links secondary-links" >
codice HTML prodotto
</div>