Sei qui: Homefreccia in avantiTYPO3freccia in avantiSviluppo plugin di FE in TYPO3

SVILUPPO DI ESTENSIONI PER TYPO3: VISUALIZZAZIONE NEL FRONT-END

Concludiamo lo sviluppo dell'estensione per TYPO3 iniziata nell’articolo precedente con la scrittura codice necessario per la visualizzazione nel Front-End

Articoli, tutorial e news sul CMS TYPO3

Sviluppo plugin di FE in TYPO3
Sviluppo estensioni per TYPO3
Integrare template custom
Gestione utenti di BE

Scarica il materiale

listato1.txt

Il template HTML

1.2 K

listato2.txt

Il codice PHP dell’estensione

2.5 K

listato3.txt

Le label multilingua

724



Introduzione

Nell'articolo precedente abbiamo iniziato lo sviluppo di un'estensione per il CMS TYPO3 (un semplice libro dei visitatori). Abbiamo utilizzato l’extension Kickstarter come wizard per la creazione del database (la tabella dove salvare i messaggi) e di tutti i file necessari per integrare l’estensione col CMS e per gestire la parte di Back-End (BE). Come abbiamo visto, infatti, con l'utilizzo del Kickstarter otteniamo, senza bisogno di scrivere nemmeno una riga di codice, la form necessaria da BE per inserire nuovi record (nel nostro caso messaggi per il guestbook). Quello che però manca è la visualizzazione da FE. In questo articolo andremo a scrivere il codice necessario per visualizzare da FE la lista dei messaggi inseriti e un modulo di inserimento di nuovi messaggi. Inoltre andremo a scrivere il codice per il salvataggio dei nuovi messaggi inseriti.

La view dell'estensione - il template HTML

Prima ancora di mettere mani al codice, pensiamo a come vorremmo che fosse l’output del nostro plugin e disegnamolo su carta. A questo punto abbiamo due possibilità: la prima è di inserire il codice HTML all’interno del codice PHP, la seconda è di separare completamente il codice HTML dal codice PHP. Come ogni buon programmatore saprà, è sempre buona regola rispettare il pattern MVC (Model-View-Control). Nel nostro caso la parte Model è la tabella dei messaggi nel database. Per quanto riguarda View e Control dovremo quindi procedere alla loro separazione seguendo la seconda delle due strade sopra esposte, ovvero creando un file HTML (denominato template), per definire come deve essere l’output a video (View), e un file PHP, per integrare la visualizzazione con i dati (Control).

Il primo passo è quindi la stesura di un file HTML rappresentante l’output desiderato (Listato 1). Come si può vedere dal listato 1, sono stati rappresentati sia il modulo per l’inserimento di nuovi messaggi, sia una tabella in cui saranno elencati tutti i messaggi inseriti. Ciò che balza subito all’occhio sono dei commenti piuttosto strani e dei marcatori altrettanto strani. Proviamo a spiegarli:

Inizialmente il file HTML viene sviluppato senza tenere conto dei marcatori visti sopra. Solo dopo che si è soddisfatti della propria creazione si può andare a individuare i contenuti dinamici e sostituirli con dei marcatori. Inoltre è necessario definire l’area “interessante” (i tag <html>, <head>, <body> e così via, sono generati dal CMS e quindi non devono essere mandati in output dalla nostra estensione) e le eventuali porzioni di codice da ripetere (come la riga del singolo messaggio nel nostro caso), racchiudendole con commenti del formato sopra visto.

Scriviamo la logica dell'estensione

Passiamo ora a scrivere la logica PHP necessaria. Quando TYPO3, durante il parsing di una pagina, incontra un elemento di contenuto di tipo plugin richiama una particolare funzione del plugin in questione. Questa funzione deve restituire il codice HTML che deve essere visualizzato come output del plugin. Nel nostro caso la funzione richiamata è la funzione main($content, $conf) della classe class.user_guestbook_pi1. Se andiamo ad aprire questo file, vediamo come viene generato dal Kickstarter: una sola funzione (main) che restituisce un contenuto HTML d’esempio. Il nostro compito sarà quello di cancellare questa funzione e riscriverla ex-novo per gestire correttamente il guestbook. Nel listato 2 potete trovare la classe class.user_guestbook_pi1 così come si presenterà al termine di questo articolo. Ma procediamo per gradi.

La prima operazione che dobbiamo eseguire è l’inclusione del template HTML precedentemente creato. Per fare questo sfruttiamo l’oggetto cObj (ereditato dalla classe tslib_pibase e utilizzato per costruire i contenuti da visualizzare) e i metodi che ci mette a disposizione:

$content = $this->cObj->fileResource("EXT:".$this->extKey."/pi1/template.html");

$content = $this->cObj->getSubpart($content, '###TEMPLATE_GUESTBOOK###');

Con la prima riga andiamo a leggere il file template.html. Come vedete il path fornito è particolare: non viene fornito il path assoluto ma solo quello relativo all’estensione ($this->extKey contiene il nome dell’estensione che coincide con il nome della cartella che contiene il codice). La rimanente parte di path viene sostituita con la stringa “EXT”. Questa stringa verrà valutata dal metodo fileResource e sostituita con il path corretto dell’estensione (questo perchè, come spiegato nel precedente articolo, è possibile installare un’estensione in tre punti diversi).

Con la seconda riga di codice, invece, ci restringiamo alla sola porzione di template compresa fra i commenti <!-- ###TEMPLATE_GUESTBOOK### -->, escludendo quindi dall’output quanto esterno a questi. Se restituiamo il content fin qui generato e andiamo a vedere il risultato da FE, vedremo che viene visualizzato esattamente il codice HTML da noi scritto, compresi tutti i marcatori che, in effetti, non abbiamo ancora gestito.

Tralasciando per un attimo la lista dei messaggi, occupiamoci di tutti gli altri marcatori. Questi si dividono in due categorie: i marcatori delle label di testo e i marcatori di controllo. I primo sono quei marcatori del tipo ###LABEL_*### che, come introdotto sopra, servono ad identificare la posizione delle label testuali. Questi marcatori dovranno quindi essere sostituiti con del testo che dipenderà dalla lingua selezionata per la visualizzazione del FE (è anche possibile inserire direttamente le label nel codice HTML ma poi per ogni lingua disponibile da FE sarebbe necessario scrivere un codice HTML diverso e quindi gestirlo di conseguenza nell’estensione). Il codice necessario è il seguente:

$this->pi_loadLL();

$markerArray["###LABEL_NOME###"] = $this->pi_getLL("nome");

Con la prima riga diciamo a TYPO3 di caricare le definizioni delle label contenute nel file pi1/locallang.xml (listato 3). In questo file vengono fornite le traduzioni per le label in un numero arbitrario di lingue. Per poi visualizzare la label nella lingua corretta è sufficiente utilizzare una riga di codice come la seconda scritta sopra. TYPO3, attraverso una configurazione che viene fatta via TypoScript nel template, conosce la lingua corrente di visualizzazione da FE e, di conseguenza, attraverso la chiave “nome”, fornisce la label nella lingua corrente (se non esiste una traduzione fornisce la lingua di default). La seconda riga di codice deve essere ripetuta, con le dovute sostituzioni, per tutte le label necessarie, andando così a formare quello che viene detto l’array dei marcatori.

Per quanto riguarda gli altri marcatori (quelli definiti “di controllo”), le righe interessate sono le seguenti:

$markerArray["###GUESTBOOK_ACTION###"] = "index.php?id=".$GLOBALS['TSFE']->id;

$markerArray["###GUESTBOOK_PID###"] = $this->conf["pid"];

$markerArray["###GUESTBOOK_TSTAMP###"] = time();

Anche in questo caso si va a riempire l’array dei marcatori con i valori necessari. La prima riga serve per sostituire il marcatore posizionato al posto dell’action della form con il link alla pagina corrente. Questo permette di inserire il plugin in una pagina qualsiasi, senza doversi preoccupare di aggiornare i link all’interno del codice HTML. Per ottenere l’id della pagina corrente viene sfruttato l’oggetto $GLOBALS[‘TSFE’], un oggetto con scope globale che contiene tutte le informazioni relative alla pagina corrente, all’utente che la sta visualizzando, al codice TypoScript e molto altro ancora (TSFE sta per TypoScript Front-End).

Con la seconda riga impostiamo il pid, ovvero diciamo dove dovranno essere salvati i messaggi inseriti. Il pid (ParentID) è una chiave esterna al campo uid della tabella pages e serve a specificare all’interno di quale pagina salvare un record. Il valore gli viene passato via TypoScript (questo aspetto lo approfondiremo in seguito).

A questo punto tutti i marcatori sono pronti per essere sostituiti. La sostituzione all’interno del codice HTML avviene con una semplice chiamata ad un’apposita funzione dell’oggetto cObj:

$content = $this->cObj->substituteMarkerArray($content, $markerArray);

Inserimento nel DB - salvataggio dei messaggi

Ora che la form di inserimento dei messaggi viene visualizzata correttamente e tutti i campi di controllo sono stati valorizzati, non ci resta che salvare i messaggi lasciati attraverso di essa. Il primo passo è quello di verificare se è stata fatta la submit della form:

$messaggio = t3lib_div::_POST($this->prefixId);

if (isset($messaggio["submit"]))

$this->salva($messaggio);

Con la prima riga andiamo a leggere la variabile user_guestbook_pi1 tra quelle passate in POST. Per farlo utilizziamo un metodo della classe statica t3lib_div anzichè leggere direttamente l’array $_POST fornito dal PHP. Il vantaggio di questa soluzione è che se in futuro il PHP modificherà il suo modo di accedere alle variabili passate in POST, sarà sufficiente aggiornare questa funzione di TYPO3 e tutte le estensioni che la utilizzano continueranno ad operare correttamente. Con le righe seguenti verifichiamo se è stata fatta la submit e, in caso positivo, richiamiamo la funzione salva con parametro i dati del messaggio (vedere Listato 2).

Poichè tutti i nomi dei parametri inseriti nella form corrispondono al nome del campo del database in cui dovranno essere scritti, la funzione salva è decisamente semplice:

unset($messaggio["submit"]);

$GLOBALS['TYPO3_DB']->exec_INSERTquery('user_guestbook_messaggi', $messaggio);

Con la prima riga si elimina il campo “submit” (che non ci interessa salvare), con la seconda, invece, si procede al vero e proprio inserimento del messaggio nel DB. Anche in questo caso non facciamo uso delle funzioni fornite dal PHP per la gestione dei DB MySQL ma sfruttiamo un oggetto fornito da TYPO3 e le sue funzioni. Il vantaggio di questa soluzione è che ci permette di astrarre le nostre query dal database sottostante: attraverso l’estensione DBAL (DataBase Abstraction Layer) la stessa query può essere eseguita su un gran numero di DBMS diversi. In questo caso stiamo eseguendo una insert e i parametri richiesti sono due: la tabella in cui inserire il record e un array nel formato campo => valore.

Output nel FE - lista dei messaggi

Siamo quasi giunti alla fine. L’ultimo passo è quello di mostrare la lista dei messaggi che sono stati inseriti. Per prima cosa dobbiamo costruire la query per estrarli dal database:

$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('nome, messaggio', 'user_guestbook_messaggi', 'pid="'.$this->conf["pid"].'" '.$this->cObj->enableFields('user_guestbook_messaggi'), '', 'crdate DESC');

Con questa riga di codice costruiamo la query per estrarre i campi nome e messaggio dalla tabella user_guestbook_messaggi relativamente ai messaggi contenuti in una determinata pagina (tramite il campo pid) e disponibili per essere visualizzati. Il risultato viene ordinato in base alla data di creazione (crdate) in ordine decrescente.

Un messaggio è “disponibile per essere visualizzato” quando non è stato cancellato e quando non è stato nascosto. Per effettuare questi controlli è sufficiente richiamare la funzione enableFields() con parametro la tabella del db interessata. L’output di tale funzione è una porzione di SQL che permette di estrarre solamente i record che risultano attivi e si basa sul file ext_tables.php per determinare quali campi concorrono alla definizione di “attivo”. Nel nostro caso tali campi sono solamente il campo deleted e hidden ma potrebbero essere presenti anche i campi starttime (data di inizio pubblicazione), endtime (data di fine pubblicazione) e fe_group (gruppi di accesso) nel qual caso la query da costruire sarebbe veramente ostica.

Una volta ottenuti i messaggi da visualizzare si procede nel modo seguente (vedere la funzione listaMessaggi() nel listato 2):

Se ricarichiamo la pagina dovremmo vedere la form di inserimento e sotto ad essa i messaggi già inseriti.

Configurazione TypoScript dell'estensione

Avevamo lasciato in sospeso la configurazione del pid da TypoScript. Lo abbiamo incontrato nella seguente riga di codice:

$markerArray["###GUESTBOOK_PID###"] = $this->conf["pid"];

L’intenzione è quella di permettere di configurare via TypoScript la pagina in cui devono essere salvati tutti i messaggi. Pertanto nel nostro template TypoScript ci sarà una riga come segue:

plugin.user_guestbook_pi1.pid = 22

dove 22 è l’uid della pagina che conterrà i messaggi. Tutta la configurazione fatta via TypoScript nel formato sopra visto (plugin.chiaveestensione_piX.chiave = valore) viene passata al plugin sottoforma di array (chiave => valore) come parametro della funzione main (più precisamente come parametro $conf). Con la riga di codice $this->conf=$conf; si copia la configurazione in una variabile di classe per renderla accessibile a tutti i metodi della classe. Per accedere ad un parametro passato via TypoScript è quindi sufficiente accedere all’array $this->conf con chiave il nome del parametro (ad es. $this->conf[‘pid’]).

È sempre una buona regola prevedere il maggior numero di parametri possibili via TypoScript per permettere a chi utilizzerà l’estensione di poterla configurare senza la necessità di modificare i codici sorgenti. Nel nostro guestbook, ad esempio, sarebbe conveniente permettere la configurazione via TypoScript di quale template HTML si vuole utilizzare

Conclusioni

In questi articoli non sono stati trattati molti argomenti (record multilingua, versioning, FlexForm, e molto altro ancora) in quanto lo spazio non ce lo consentiva ma quanto visto è comunque sufficiente per iniziare. L’estensione creata in questo articolo e nel precedente è molto semplice ed ha come unico scopo quello di dare una base da cui poi iniziare a lavorare per la realizzazione di un’estensione molto più complessa.

Non mi rimane quindi che auguravi buon lavoro!

Bibliografia

[1] W. Altmann, R. Fritz, D. Hinderink, “TYPO3, Enterprise Content Management”, 2005 Packt Publishing, Birmingham (UK).

[2] Kasper Skårhøj, “Backend Programming”, http://typo3.org/documentation/document-library/tutorials/doc_tut_backend/current/view/

[3] Kasper Skårhøj, “TYPO3 Coding Guidelines”, http://typo3.org/documentation/document-library/core-documentation/doc_core_cgl/current/view/

[4] Kasper Skårhøj, “TYPO3 Core APIs”, http://typo3.org/documentation/document-library/core-documentation/doc_core_api/current/view/

[5] Oliver Hofmann, “Basic extension tutorial”, http://typo3.org/documentation/document-library/tutorials/player_profile_basic/current/view/

[6] Il sito di riferimento degli sviluppatori: http://www.typo3.org

Commenti all'articolo

Nessun elemento
Nessun elemento trovato nel Guestbook