Template multipli di Joomla! e Virtuemart
Chi ha provato ad usare più di un template per Joomla!, in abbinamento con Virtuemart, ha scoperto che determinate operazioni nell'ecommerce 'rompono' l'assegnazione dei template alle pagine, rendendo sgradevole la navigazione. Vediamo da dove ha origine il problema e come risolverlo.
(Questo articolo è relativo alla versione 1.1 di virtuemart, sarà aggiornato alla versione 2 non appena questa avrà raggiunto un certo livello di stabilità)
Può capitare di dover usare templates diversi su un medesimo sito; personalmente non amo la cosa, mi ricorda la tecnica costruttiva degli anni sessanta/settanta in cui ogni locale aveva un pavimento diverso, con uno spiacevole "effetto arlecchino".
Tuttavia, se i templates sono progettati con coerenza, in siti di discreta ampiezza, intesa sia come numero di pagine sia come eterogeneità tra le sezioni, questa tecnica agevola la navigazione ed aiuta l'utente ad orientarsi.
Tipicamente, nei siti più semplici, l'applicazione della tecnica si limita ad un template per la sola home page ed un altro per tutte le altre sezioni del sito. E qui cominciano i problemi.
Template multipli
Chi ha provato ad assegnare i template sarà andato tranquillamente in 'Estensioni -> Gestione Template' ed avrà selezionato un template di defaul per l'intero sito; dopo di che avrà editato la sezione 'Assegnazione al menu' e selezionato l'home page.
Tutto a posto? Sì, finché non si tenta di cancellare un prodotto dal carrello, di modificarne la quantità di inserire un codice coupon.... insomma tutte operazione non proprio infrequenti.
In questi casi l'operazione impedisce al selettore di template di riconoscere correttamente la pagina e appare il template sceltoper la home page.
Le operazioni che cambiano i template
Quando avviene il cambio di template? Se analizziamo le situazioni in cui avviene l'errore di selezione del template ci accorgiamo che in tutti questi casi abbiamo un modulo form che trasferisce i dati in modalità POST; i parametri per la selezione del componente e per la gestione di questo sono inseriti in campi di tipo hidden, ma la action indica, correttamente, solo la pagina cui inviare i dati, senza alcuna query string nell'url.
Joomla! effetta correttamente il dispatch della richiesta per quanto riguarda la selezione del componente e dei moduli pubblicati nella pagina, non altrettanto bene si comporta nella selezione del template.
La selezione del template
La selezione del template ed il suo rendering avviene abbastanza tardi nel processo di esecuzione del codice di risposta ad una richiesta (sezione Rendering in http://docs.joomla.org/API_Execution_Order) perchè l'errore?
il template viene selezionato tramite il metodo getTemplate() della classe JSite (/includes/application.php).
Inizializzazione di JMenu
All'interno della funzione sopra citata, il medoto getMenu() è usato per ottenere il menù del sito e quindi la voce attiva. getMenu() è eseguito nella classe parent di JSite, ovvero JApplication (/libraries/joomla/application/application.php) tramite la chiamata a JMenu::getInstance() che restituisce l'istanza esitente del menù.
Nota:
a questo livello esistono solo due menù: site e system. Il primo contiene le voci di front end, il secondo quelle di back end.
Il metodo JMenu->getActive() restituisce la voce attiva; ma chi si andrà a vedere la classe scoprirà che il metodo citato è in realtà la lettura di una proprietà che non viene impostata da nessun metodo interno alla classe!
Inizializzazione della voce attiva in JURI
In realtà la voce di menù attiva viene impostata tramite il metodo privato JRouterSite->_parseRawRoute() della classe JRouterSite (/includes/router.php)
if(!$uri->getVar('Itemid') && !$uri->getVar('option'))
{
$item = $menu->getDefault();
// ... omissis
}
$uri è una istanza della classe JURI (/libraries/joomla/environment/uri.php ) ed il metodo JURI->getVar() restituisce le variabili ottenute dal parsing della query string.
Se non è presente né la variabile ItemId (voce di menù attiva) né option (il componente), allora è impostata come voce attiva la pagina di default; e proprio qui sta il problema. Virtuemart trasmette questi dati con il metodo POST e non li riporta nella query string quindi quando si effettuano le operazioni sopra indicate immancabilmente cambia il template che diventa quello della pagina di default, in altri termini quello della home.
JURI viene inizializzato durante la fase "Routing and Authorisation" del citato flusso di esecuzione.
La soluzione per l'uso di template multipli con virtuemart
Le soluzioni disponibili
Qua e la si trovano diversi post (di forum) in cui si suggerisce di modificare questo o quel file di Joomla! (raro) o di Virtuemart (frequente) per inserire la query string in questione in ogni possibile form. Il risultato è un susseguirsi di utenti che tentano di raccapezzarsi tra i vari files delle diverse versioni dei programmi in oggetto. Infatti il punto dolente di queste soluzioni 'hack' sono:
- le istruzioni debbono essere modificate qualora sia modificato il codice originario (files aggiunti, rimossi, modificati tra le versioni);
- l'aggiornamento dei programmi spesso cancella le modifiche effettuate.
Trattandosi di un sistema e-commerce è evidente quanto l'ultimo punto sia problematico: la scelta è tra aggiornare il codice correndo il rischio di far saltare l'impostazione grafica e non effettuare l'aggiornamento correndo il rischio che qualcuno faccia saltare il sito.
La soluzione corretta
La soluzione corretta è ovviamente quella che non richiede la modifica di codice di terze parti, se poi è rispettosa delle specifiche di programmazione di Joomla! ed è funzionale allora è la soluzione ottima.
L'inizializzazione e creazione delle istanze di JURI avviene dopo il lancio dei trigger relativi agli eventi registrati per "onAfterInitialise" (si veda il già più volte citato schema di esecuzione), è pertanto possibile scrivere un plugin di tipo system che, in presenza di determinate condizioni, istanzi JURI e provveda ad impostare le opportune variabili che sono necessarie per la scelta del template corretto, ma che non vengono gestite non essendo presente una query string.
Quali sono le 'determinate condizioni'? Ovviamente la presenza in $_POST dei due valori itemID ed option, e che quest'ultimo sia equale a 'com_virtuemart'. In questo caso i due valori andranno letti da $_POST ed impostati come query string dell'istanza di JURI.
if ( (JRequest::getVar('option', 'POST') == 'com_virtuemart') && (JRequest::getVar('Itemid', 'POST') != '') ){
$uri = &JURI::getInstance();
$qs = $uri->getQuery(true);
$qs['Itemid'] = JRequest::getVar('Itemid', 'POST');
$qs['option'] = 'com_virtuemart';
$uri->setQuery($qs);
}
In questo modo la determinazione della voce di menù attiva funzionerà correttamente e non vi sarà più la sgradita commutazione di template.
Conclusioni
Ancora una volta voglio mettere in guardia il lettore riguardo l'inopportunità di modificare i files del sistema Joomla! e dei componenti scritti da terzi, soprattutto se parliamo di VirtueMart e quindi di un sistema e-commerce.
Sono superficialità che nel tempo si pagano molto care; nel caso si tratti della realizzazione di un sito aziendale è sempre doveroso rivolgersi ad un esperto professionista e non all'improvvisato di turno, non so se in futuro sarete felici di averlo fatto: so che non ne sarete pentiti. al sito non è successo niente? no news, good news!
Per chi non ha voglia di cimentarsi con la programmazione è disponibile il plugin pacchettizzato per Joomla! 1.5. Ricordatevi che, una volta installato, il plugi deve essere attivato.
Commenti
volevo solo sapere se il plug-in funziona anche con Virtuemart 2 ed in caso negativo se ci sarà un aggiornamento. Grazie.
Saluti, Giuseppe
===Risposta
verifichi che il plugin sia attivato, comunque nella pagina di dettaglio prodotto di solito non ci si arriva con un submit di dati post. verifichi anche la flypage.
RSS feed dei commenti di questo post.