lunedì 29 dicembre 2008

Protezione anti-spam con reCaptcha

Di librerie PHP per implementare una protezione anti-spam con l'uso di codici CAPTCHA ho già avuto modo di scrivere qualche tempo fa:

PHP: Proteggere un form da spam con codice captcha

Oggi voglio spendere qualche parola su reCaptcha un servizio che permette di realizzare una protezione basata su CAPTCHA in modo più semplice rispetto a quello visto nel post appena citato.

Il principale vantaggio di reCaptcha sta nel fatto che le immagini con i codici da decifrare sono generate da un server remoto, quindi il servizio può essere usato anche quando non si hanno a disposizione librerie grafiche installate sul proprio server.

Un altro aspetto interessante è che i codici captcha non sono generati casualmente, ma sono parole provenienti da libri di cui è in corso un processo di digitalizzazione: in particolare sono usate come captcha quelle parole che gli algoritmi di riconoscimento dei caratteri non sono riusciti a interpretare correttamente.

In questo modo mentre ci proteggiamo dallo spam aiutiamo (o meglio i visitatori del nostro sito che risolvono i CAPTCHA aiutano) la digitalizzazione di libri e documenti di interesse storico. Per chi fosse interessato tutti i dettagli di come questo avvenga sono sul sito (solo in inglese).

Vediamo come integrare la protezione reCaptcha su un form di un nostro sito.

Come prima cosa creiamo un account: scelto nome utente e password ci viene chiesto su quale dominio vogliamo utilizzare il servizio. In caso si voglia usarlo su molti domini conviene selezionare l'opzione per ricevere una chiave globale.

Completata la prima fase della registrazione, ci vengono comunicate una chiave pubblica e una chiave privata. Prendiamone nota.

Scarichiamo poi il pacchetto con la libreria. L'unico file che serve trasferire sul nostro server è recaptchalib.php e va messo nella stessa cartella dello script che si occupa della visualizzazione del form e dell'elaborazione dei risultati.

A questo punto si tratta di scriver il codice PHP necessario. Invece di postare un lungo blocco di codice ho creato una pagina dimostrativa ed un pacchetto scaricabile contenente sia recaptchalib.php che lo script di esempio usato nel post citato all'inizio modificato per funzionare con reCaptcha.

Nell'esempio lo stesso script (index.php) è usato per visualizzare il form e processare i risultati. Il file è commentato per cui non mi dilungo in dettagli.

Non dimenticate di modificare index.php in modo che le variabili $publickey e $privatekey contengano le chiavi pubblica e privata assegnate al vostro account e relative al vostro dominio.

Dai commenti dovrebbe risultare chiaro come usare le funzioni della libreria recaptcha_get_html() e recaptcha_check_answer() che servono rispettivamente a generare il codice HTML per il riquadro contenente il codice CAPTCHA e il campo per la risposta e a verificare la correttezza del codice inserito dall'utente.

Lo script serve solo a dimostrare il funzionamento della libreria: alla pressione del pulsante Invia se il codice è corretto vengono stampati a video i valori dei campi, altrimenti viene visualizzato un messaggio di errore.

Tutto qui. Quindi per l'uso su un sito reale dovrà ovviamente essere adattato alle vostre esigenze.

martedì 23 dicembre 2008

QContacts 1.0.5

Versione pre-natalizia del componente QContacts. Principalmente sono stati corretti alcuni bug e non ci sono grandi novità.

È ora possibile inserire la categoria del contatto e l'ID di Skype e Yahoo Messenger anche come colonne di una lista contatti e non solo nella pagina che mostra il singolo contatto.

Le liste contatti si possono ordinare in base a qualsiasi colonna mentre in precedenza si potevano ordinare solo in base a Nome e Ruolo del contatto. Per fare questo si deve impostare a il parametro ordinabile nei parametri del menu Aspetto Categoria Contatto.

Mi è stato fatto notare nel forum che era scomodo che quando si seleziona una colonna per ordinare la lista in base a quel campo, venisse allo stesso tempo invertita la direzione dell'ordinamento. Così funzionano le liste standard di Joomla, basta fare una prova su una lista articoli di una categoria. Comunque ho modificato questa parte e adesso si sceglie il campo di ordinamento con un click sull'intestazione della relativa colonna, mentre con un click sull'icona si passa da ordinamento ascendente a discendente e viceversa.

Vedere il log modifiche per ulteriori dettagli e la pagina di download per scaricare il componente, la stessa pagina contiene le istruzioni per l'aggiornamento.

Futuri sviluppi

Mi viene chiesto frequentemente di dare la possibilità di impostare una pagina dove reindirizzare l'utente una volta inviato il form. La soluzione di ricaricare la pagina del form con un messaggio di conferma mi sembra abbastanza frequente e a mio parere non così orrenda però vedrò di implementare questa funzione nella prossima versione. Credo che il vero problema sia che molti non vedono il messaggio di conferma per la ragione spiegata in questa faq.

Altre funzioni richieste spesso sono la possibilità di includere una Google Map sulla pagina del contatto e la visualizzazione dell'elenco dei contatti in un formato diverso da quello di una tabella, più "tipo blog". Anche queste richieste penso potranno essere soddisfatte dalla prossima versione.

Chi avesse altri suggerimenti può postarli come commento, ma anche nel forum.

Si avvicina la fine del supporto per Joomla 1.0

Un post di Steve Burge sul "Community Blog" del sito ufficiale di Joomla elenca tre date che porteranno alla fine del supporto per Joomla 1.0

  • 31 marzo 2009: estensioni compatibili solo con Joomla 1.0 non saranno più accettate nella directory ufficiale delle estensioni (JED)
  • 30 giugno 2009: le estensioni compatibili solo con Joomla 1.0 presenti nella directory saranno rimosse.
  • 22 luglio 2009: fine del ciclo di vita di Joomla 1.0

La terza data era stata già annunciata in precedenza, la novità riguarda quindi solo le disposizioni sulla directory delle estensioni.

Forse soluzioni meno drastiche della totale eliminazione dalla directory sarebbero state preferibili: ad esempio lasciare comunque un'opzione per includere nella ricerca le estensioni solo per Joomla 1.0.

Va anche detto che se un componente modulo o plugin non è ancora compatibile con la versione 1.5 e non lo sarà entro i prossimi sei mesi, si tratta di un prodotto probabilmente già abbandonato dallo sviluppatore e quindi avrebbe comunque poco senso continuare a presentarlo alla comunità degli utenti.

Quindi chi ha siti fatti con Joomla 1.0, a parte attaccarsi al tram, cosa fa?

1) Se li tiene così come sono. L'unico vero rischio di questa scelta è dato dalla scoperta di una grave vulnerabilità dopo il 22 luglio 2009. Senza più supporto ufficiale bisognerebbe sperare nel rilascio di una patch da parte della comunità, il che immagino potrebbe anche non essere tanto improbabile visto che qualcuno in giro che si ricorda come è fatto Joomla 1.0 ci sarà anche tra sei mesi.

Se si sceglie questa strada, oltre ovviamente ad avere un backup aggiornato, è bene fin da subito scaricare l'ultima versione dei pacchetti di tutte le estensioni che si usano sul sito nel caso si avesse bisogno in futuro di fare una reinstallazione.

2) Tenta il processo di migrazione. Io sinceramente non ho mai provato e non sono la persona adatta a cui chiedere delucidazioni. Da quello che si legge in giro la cosa è fattibile per i siti basati principalmente su contenuti standard (sezioni, categorie, articoli gestiti nativamente da Joomla), mentre appare più complicata per i siti con molti contenuti gestiti da estensioni di terze parti, riguardo ai quali bisognerà accertarsi se gli sviluppatori hanno messo a disposizione script di migrazione dei dati tra le versioni per Joomla 1.0 e Joomla 1.5 delle loro estensioni.

Considerazione finale. Visto che team di sviluppo di altri cms, per esempio Drupal per non fare nomi, sono in grado di supportare due versioni stabili del prodotto contemporaneamente, si poteva forse fare lo stesso: aspettare il rilascio di Joomla 1.6 stabile, che dubito avverrà prima di luglio prossimo, e solo a partire da quel momento mantenere Joomla 1.5 e 1.6 e "seppellire" Joomla 1.0.

Vabbè non facciamo polemiche che è troppo facile quando sono altri a spendere il tempo e a scrivere il codice necessario a far funzionare le cose, comunque credo che questa sarebbe stata una soluzione gradita a molti utenti.

venerdì 19 dicembre 2008

Guida Remository

Segnalo un articolo che ho scritto per HTML.it su come gestire un'area di download e upload di file sul proprio sito utilizzando il componente Remository. L'articolo tratta di tutte le funzioni del componente tranne quelle di utilizzo del tutto immediato ed intuitivo.

Remository è un buon componente open source, forse meno conosciuto di altri della sua categoria, come ad esempio Docman, rispetto al quale presenta però il vantaggio di poter funzionare in Joomla 1.5 senza legacy mode.

Qualche aspetto come ad esempio la gestione delle categorie potrebbe essere migliorato, ed è possibile che lo sia nelle prossime versioni visto che lo sviluppo del prodotto è abbastanza costante.

Spero che l'articolo sia utile, ecco il link: Gestire un'area download in Joomla

domenica 30 novembre 2008

Blog Joomla, link a categorie nella barra laterale

Dopo un po' di tempo proseguiamo lo sviluppo del blog "sperimentale" realizzato con Joomla. In un blog è frequente mettere a disposizione del visitatore una lista di link attraverso i quali si possono elencare i post catalogati sotto una determinata categoria (o etichetta come nel caso di Blogger).

Realizziamo quindi questa funzione anche nel nostro blog. Ricordo che tutti i post del blog sono inseriti nella sezione Post per cui il problema si risolve nel visualizzare in un modulo una lista di link a tutte le categorie di una determinata sezione.

Ci sono alcuni moduli di terze parti che consentono questo, ma per una ragione o per un'altra non mi soddisfacevano molto così ho seguito la filosofia del "chi fa da sè ..." e ne ho scritto uno io.

QCategories

Il modulo è, credo, di facile utilizzo. Una volta installato, dalla configurazione si possono impostare i seguenti parametri:

  • Sezione: si sceglie la sezione da cui estrarre le categorie.
  • Aspetto: si può scegliere l'aspetto (layout) della pagina che visualizza gli articoli della categoria: blog o tabella.
  • Mostra categorie vuote: si può scegliere di mostrare o nascondere le categorie senza articoli.
  • Mostra contatori: si può scegliere se visualizzare il numero degli articoli a fianco della categoria.
  • Ordina per: criteri di ordinamento della lista dei link. Scelta tra Titolo categoria, Ordine categoria (impostabile da Gestione categorie nel backend), Numero degli articoli

QCategories può essere scaricato qui. Il risultato è visibile sul blog dimostrativo.

Ho limitato le funzioni allo stretto indispensabile, se lo utilizzate e trovate qualche problema lasciate un commento.

giovedì 6 novembre 2008

Joomla 1.5, personalizzare il template JA Purity

Sul sito ufficiale di Joomla è presente un tutorial che mostra come personalizzare il template JA Purity incluso nell'installazione base del cms. Non è molto dettagliato, ma abbastanza interessante specialmente per i principianti, per cui credo sia utile fare una sintesi in Italiano delle parti a mio parere più importanti.

Essendo JA Purity un template standard, può essere modificato da un aggiornamento di Joomla quindi è bene mantenere una copia della versione modificata.

Sostituire il logo

Il file del logo si chiama logo.png e si trova in

.../templates/ja_purity/images/

Per sostituirlo basta creare un'immagine con lo stesso nome e dimensioni (207 x 80 pixel) e trasferirla via FTP nella stessa cartella sovrascrivendo il file originale.

Modificare la posizione del logo

Logo come immagine

Occorre modificare il file template.css che si trova in

.../templates/ja_purity/css/

A partire dalla linea 957 questa è la parte da modificare

h1.logo a {
  width: 208px;
  display: block;
  background: url(../images/logo.png) no-repeat;
  height: 80px;
  position: absolute; /*Modificata da relative a absolute*/
  top: 10px;  /*Aggiunta*/
  left: 10px; /*Aggiunta*/
  z-index: 100;
}

Chiaramente top e left vanno modificati in base alla posizione che volete per il logo.

Logo come testo

Il file da modificare è sempre lo stesso template.css. A partire dalla riga 972 modificare

h1.logo-text a {
  color: #CCCCCC !important;
  text-decoration: none;
  outline: none;
  position: absolute;
  bottom: 40px; /*Modificare*/
  left: 5px; /*Modificare*/
}

p.site-slogan {
  margin: 0;
  padding: 0;
  padding: 2px 5px;
  color: #FFFFFF;
  background: #444444;
  font-size: 92%;
  position: absolute;
  bottom: 20px; /*Modificare*/
  left: 0; /*Modificare*/
}

Per questa modifica come per quella precedente è consigliabile l'uso di Firefox con il plugin Firebug per fare delle prove 'in diretta' e trovare i valori giusti per bottom e left.

Ridimensionare la testata

A partire dalla linea 921 di template.css trovate

/* HEADER
-------------------------------------- */
#ja-headerwrap {
  background: #333333;
  color: #CCCCCC;
  line-height: normal;
  height: 80px; /*Modificare*/
}

#ja-header {
  position: relative;
  height: 80px; /*Modificare*/
}

.ja-headermask {
  width: 602px;
  display: block;
  background: url(../images/header-mask.png) no-repeat top right;
  height: 80px; /*Modificare*/
  position: absolute;
  top: 0;
  right: -1px;
}

Modificare sulle linee indicate il valore 80px con quello della nuova altezza della testata.

Modificata l'altezza della testata potrebbe essere necessario modificare anche le dimensioni del logo. Effettuata la modifica al file immagine logo.png già visto in precedenza, va aggiustata questa parte di template.css dalla linea 957

h1.logo a {
  width: 208px; /*Larghezza del logo*/
  display: block;
  background: url(../images/logo.png) no-repeat;
  height: 80px; /*Altezza del logo*/
  position: relative;
  z-index: 100;
}

Se si modifica l'altezza della testata bisogna modificare anche l'altezza delle seguenti immagini

...\templates\ja_purity\images\header-mask.png
...\templates\ja_purity\styles\header\blue\images\header-mask.png
...\templates\ja_purity\styles\header\green\images\header-mask.png

Bisogna utilizzare un programma di grafica (Gimp, Photoshop, Paint.NET) per ricreare queste immagini della stessa altezza della testata, mantenendo il colore e il riempimento a gradiente.

Sostituire le immagini di testata

In ...\templates\ja_purity\images\ ci sono tre immagini: header1.jpg, header2.jpg, header3.jpg. Possono ovviamente essere sostituite con altre più in tema con l'argomento del vostro sito, basta creare tre immagini delle stesse dimensioni (600 x 80 pixel) e con lo stesso nome e rimpiazzare le immagini originali.

Va però tenuto presente che l'altezza delle immagini deve essere uguale a quella della testata. Se create immagini di altezza diversa da 80 pixel seguite le istruzioni sopra riportate per ridimensionare la testata.

È tutto. Spendere un po' di tempo a personalizzare JA Purity può essere una buona idea per differenziare il proprio sito da tutti gli altri che utilizzano questo popolare template.

sabato 1 novembre 2008

Drupal blog, captcha su modulo commenti

Continuando lo sviluppo del blog dimostrativo in Drupal (demo.latenight-coding.com/drupal-blog/) aggiungiamo un codice di verifica captcha al modulo per l'inserimento dei commenti. Abbiamo visto nel sito 'parallelo' in Joomla (demo.latenight-coding.com/joomla-blog/) che questa funzione è svolta dal componente installato per la gestione dei commenti, Chrono Comments.

In Drupal la possibilità di commentare i contenuti è disponibile nativamente, ma se si vuole utilizzare un codice captcha per prevenire l'inserimento di commenti spam è necessario ricorrere ad un modulo esterno.

Installazione captcha

Scaricato il modulo CAPTCHA dal sito ufficiale di Drupal, si deve decomprimere l'archivio in /sites/all/modules/ e attivare il modulo come al solito.

Amministra >> Struttura del sito >> Moduli

Ho attivato CAPTCHA e Image CAPTCHA nel riquadro Spam control.

Configurazione captcha

Amministra >> Gestione utente >> CAPTCHA

Vanno prima di tutto scelti i moduli da proteggere con il codice anti-spam: per il sito di esempio io ho scelto solo comment_form e image_captcha come tipo di captcha. Volendo si possono proteggere i moduli di login, registrazione e qualsiasi altro.

Amministra >> Gestione utente >> CAPTCHA >> Image CAPTCHA

Da questa schermata si può controllare l'aspetto del captcha.

1) Caratteri da utilizzare per il codice e lunghezza dello stesso. Per il sito ho scelto un codice di 5 caratteri composto da lettere maiuscole e numeri con esclusione dei numeri uno e zero e della lettera 'O' che si possono confondere facilmente.

2) Font. Nessun font è distribuito con il modulo bisogna inserire i font desiderati via FTP in

/sites/all/modules/captcha/image_captcha/fonts/

Io ho inserito arial.ttf preso direttamente da C:\Windows\fonts, si può utilizzare il font TrueType che si preferisce.

Tanto per non sbagliarsi tutte le altre impostazioni sono ai valori predefiniti. Volendo si possono sperimentare diversi colori, effetti di distorsione, ombreggiatura e linee di disturbo. È sempre visibile un'anteprima dell'aspetto del captcha in base alle impostazioni scelte per verificare se risulta troppo illeggibile.

Permessi captcha

Amministra >> Gestione utente >> Permessi

Sono disponibili i permessi administer CAPTCHA settings e Skip CAPTCHA che consentono rispettivamente l'amministrazione e configurazione del captcha ed evitano la visualizzazione del codice a certi ruoli: si può ad esempio richiedere il codice solo agli utenti anonimi, ma non ai registrati.

Con questo è tutto il risultato è visibile sul sito dimostrativo.

Cito per finire un mio post su oneCMS.it, "Drupal, prevenire lo spam con CAPTCHA" che contiene tra l'altro indicazioni su un modulo aggiuntivo per chi preferisse un captcha testuale invece che grafico.

mercoledì 29 ottobre 2008

Joomla 1.5, personalizzare il componente Weblinks

Ogni installazione di Joomla da sempre include un componente chiamato Weblinks che serve a mantenere una collezione di link a siti web suddivisi in categorie. È un componente semplice, ma che si presta a svariati usi come offrire risorse utili ai propri visitatori o scambiare link con altri siti.

Se si visualizza una categoria di Weblinks e si controlla la barra di stato del browser mentre il il puntatore del mouse è posizionato su uno dei link si vedrà qualcosa del tipo

index.php?view=weblink&catid=...&id=...&option=com_weblinks&Itemid=...

Al posto dei puntini vedrete ovviamente valori che variano a seconda del link.

Si vede chiaramente che il link non è diretto, non punta cioè al sito esterno, ma "passa" attraverso Joomla, più esattamente esegue il codice della view weblink del componente. È il codice della view che effettua un reindirizzamento al sito esterno.

Questo non è sempre l'ideale. Ad esempio se si scambiano link in genere si preferisce avere link diretti perché si ritiene che diano un maggior beneficio in termini di SEO.

Fortunatamente con semplici modifiche possiamo fare in modo che i link gestiti da Weblinks siano diretti. Prima di proseguire premetto che le indicazioni che seguono si applicano solo a Joomla 1.5 e raccomando di tenere copia dei file che andremo a modificare per poter facilmente annullare le modifiche in caso di problemi.

I numeri di riga dei file indicati per le modifiche fanno riferimento alla versione 1.57

Per prima cosa aggiungeremo un parametro alla configurazione di Weblinks modificando il file
.../administrator/components/com_weblinks/config.xml (da linea 32).

    <param name="link_icons" type="imagelist" 
directory="/images/M_images" default="" label="Icon" description="PARAMICONIMG" />
    <param name="direct_links" type="radio" default="0" label="Use Direct Links" description="">
    <option value="0">No</option>
    <option value="1">Yes</option>
    </param>
  </params>
</config>

Le righe in blu sono quelle da aggiungere, riporto quelle immediatemente precedenti e seguenti per facilitare l'individuazione del punto della modifica.

Poi in base all'impostazione del parametro visualizzeremo un link diretto o indiretto: modifichiamo il file
.../components/com_weblinks/views/category/view.html.php (da linea 116).

$item =& $items[$i];
if($params->get('direct_links',0) == 1) {
  $link = $item->url;
} else {
  $link=JRoute::_('index.php?view=weblink&catid='.
$category->slug . '&id='. $item->slug);
}
$menuclass = 'category'.$params->get( 'pageclass_sfx' );

A questo punto dal pulsante Preferenze sulla barra degli strumenti nella pagina di amministrazione del componente, possiamo impostare il parametro che abbiamo aggiunto e scegliere il tipo di link preferito.

Una conseguenza inevitabile della scelta dei link diretti è l'impossibilità di aggiornare il contatore delle visite. Il parametro per nascondere la relativa colonna è già presente nella configurazione.

Come tocco finale possiamo includere la traduzione in Italiano dell'etichetta per il parametro aggiunto. Inseriamo come ultima linea di
.../administrator/language/it-IT/it-IT.com_weblinks.ini

USE DIRECT LINKS=Utilizza link diretti

lunedì 13 ottobre 2008

Creare un blog con Drupal

Continuando l'esperimento, o caso di studio se preferite, della realizzazione di un blog in Joomla e Drupal veniamo alla configurazione necessaria per Drupal.

Premetto che per il sito di prova ho usato Drupal 6 con traduzione in Italiano. File della traduzione e istruzioni su come installarlo sono disponibili sul sito www.drupalitalia.org e relativo forum, vedere in particolare la sezione Traduzione italiana di Drupal.

Preliminarmente attiviamo alcuni moduli base da Amministra >> Struttura del sito >> Moduli

  • Blog
  • Comment
  • Path
  • Taxonomy

Poi installiamo altri moduli che ci sono necessari

  • Pathauto per la generazione automatica di URL semplificate (o sef)
  • Token (perché richiesto da PathAuto)

I pacchetti scaricati da drupal.org vanno decompressi in .../sites/all/modules/ e poi attivati da Amministra >> Struttura del sito >> Moduli nel backend di Drupal.

Configurazione post e commenti

L'attivazione del modulo Blog rende disponibile una nuova tipologia di contenuto Intervento del blog (Blog entry). Da Amministra >> Gestione dei contenuti >> Tipi di contenuto con un click sulla voce Intervento del blog possiamo modificare una serie di parametri. Per quello che serve a noi in questo momento vanno bene quasi tutte le impostazioni predefinite.

Sotto Impostazioni del flusso di lavoro è bene spuntare Pubblicato e Promosso in prima pagina in modo che tutti i nuovi post siano pubblicati automaticamente e posti in prima pagina come è normale per un blog.

Sotto Impostazioni commento è bene impostare Anteprima commento su Richiesto. L'obbligo di visualizzare l'anteprima del commento prima di inviarlo è una forma, anche se limitata, di prevenzione contro gli spambot. Per ora ci accontentiamo di questa.

In Amministra >> Gestione utente >> Permessi attribuiamo all'utente anonimo i permessi accede ai commenti / inserisce commenti.

Creazione categorie

Per creare le categorie per i post dobbiamo utilizzare il modulo Taxonomy in Amministra >> Gestione dei contenuti >> Tassonomia.

Con Aggiungi vocabolario creiamo un vocabolario con queste impostazioni

  • Nome del vocabolario: Categoria
  • Tipi di contenuto: Intervento del blog
  • Impostazioni: Selezione multipla e Richiesto

Salvato il vocabolario, con Aggiungi termini aggiungiamo tre voci: Categoria 1, Categoria 2, Categoria 3 come Nome del termine e tutte le altre impostazioni lasciate ai valori predefiniti.

Impostazioni URL semplificate

Il modulo Pathauto ci consente di creare url semplificate o sef (search engine friendly) come si preferisce chiamarle. La configurazione è in Amministra >> Struttura del sito >> Alias URL, Impostazioni automatiche alias.

Sotto Impostazioni percorso del nodo impostiamo Modello per tutti i percorsi intervento del blog: blog/[yyyy]/[mm]/[title-raw].html

In questo modo ogni post del blog avrà come url

/blog/anno/mese/titolo_post.html

Creazione utente blogger

Credo sia preferibile non postare nel blog come utente amministratore, ma creare un ruolo apposito. In Amministra >> Gestione utente >> Ruoli creiamo un nuovo ruolo chiamato blogger con i seguenti permessi

  • crea contenuti di tipo blog
  • cancella i propri interventi nel blog
  • modifica i propri interventi nel blog
  • accede ai commenti
  • amministra commenti
  • inserisce commenti senza approvazione

Possiamo creare un utente di prova con questo ruolo e iniziare a scrivere.

Per ora è tutto. Ci sono molte funzionalità che possono essere aggiunte al blog e lo faremo presto. Quanto realizzato finora è visibile sul sito di prova

demo.latenight-coding.com/drupal-blog/

Chi volesse provare a sviluppare personalmente un blog in Drupal seguendo le indicazioni dell'articolo e incontrasse qualche difficoltà può lasciare un commento; ho cercato di entrare per quanto possibile nei dettagli, ma certo non sono proprio istruzioni passo-passo.

Chiaramente anche suggerimenti e proposte di soluzioni diverse sono graditi.

lunedì 6 ottobre 2008

Creare un blog con Joomla

Iniziamo in concreto lo sviluppo 'in parallelo' dei due blog realizzati con Joomla e Drupal (vedi post precedente). Le prime cose da fare sono l'organizzazione del contenuto e la gestione dei commenti. Parto con Joomla.

Sezioni e categorie

Per il nostro blog serve una sezione Post e un numero a scelta di categorie per (chi l'avrebbe detto) categorizzare i post. In uno sforzo di fantasia ho creato Categoria1, Categoria2 e Categoria3 ovviamente assegnando a ciascuna la sezione Post.

Per come funziona Joomla ogni post potrà essere assegnato ad una sola categoria, questo può non essere l'ideale in un blog, vedremo in seguito se e come si può ovviare almeno in parte al problema.

Prima pagina

In un blog, almeno secondo le mie preferenze, i post in prima pagina è meglio se sono disposti su una sola colonna.

Quindi nel backend di Joomla ho selezionato Menu >> Main Menu >> Home e nei Parametri Standard ho impostato #Principali: 5, #Intro: 0, #Link: 0. Avremo 5 post che occupano tutta la larghezza della pagina, nessun post in colonna (quindi il parametro Colonne è irrilevante) e nessun post come link in fondo alla pagina.

Commenti

Joomla non offre una gestione nativa dei commenti per cui dobbiamo ricorrere ad una estensione di terze parti. Ho scelto Chrono Comments perché è un componente nativo per Joomla 1.5 (non richiede l'attivazione del Legacy Mode) e gratuito (anche se non GPL).

Se si limita la scelta ai componenti per commenti nativi Joomla 1.5 e non commerciali, le possibilità non sono molte almeno a guardare la directory delle estensioni a extensions.joomla.org. Per quello che interessa in questo momento, il componente ha le funzionalità minime indispensabili ed è anche abbastanza semplice da configurare.

Una volta installati separatamente componente e plugin e attivato quest'ultimo da Gestione Plugin basta andare in Componenti >> Chrono Comments >> Comments Manager nel backend di Joomla, accedere alla pagina della configurazione tramite il pulsante Preferenze sulla toolbar e impostare i seguenti parametri.

Sections: Selezionare Post la nostra unica sezione, ma potremmo crearne altre e vogliamo che i commenti siano abilitati solo su questa.

Show Comments link in Blog view. Abilitato per mostrare un link ai commenti sulle viste blog inclusa la prima pagina.

Posting permissions. Tutti i gruppi selezionati.

Guests can post? Sì in modo che anche gli utenti che non hanno fatto il login possano commentare.

New Comments Default to. Non pubblicato per moderare tutti i commenti, ma è possibile scegliere di moderare solo i commenti degli utenti anonimi (guest, cioè che non hanno fatto il login) o pubblicare tutti i commenti senza moderazione. È chiaro che qualunque sia la scelta si possono comunque cancellare i commenti non desiderati dal backend.

Show Captcha. Abilitato.

Enable BBCode e Enable BBCode Panel. Sì per avere la toolbar per i BBCode sul form commenti.

Tutti gli altri parametri su impostazioni predefinite. Queste sono chiaramente le mie preferenze personali per il sito di prova.

Il risultato è visibile su demo.latenight-coding.com/joomla-blog/

Aggiustamenti estetici sono necessari e saranno fatti con calma.

martedì 30 settembre 2008

Joomla e Drupal a confronto. Creare un blog

Visto che Joomla e Drupal sono due cms tra i più conosciuti e sono spesso messi a confronto tra loro, voglio provare a condurre sul blog un piccolo esperimento: creare un sito di esempio con entrambi i prodotti e confrontare le diverse soluzioni offerte per realizzare funzionalità simili.

Il sito che creeremo sarà un blog. È vero che ci sono prodotti più specifici per creare blog, ma d'altra parte questa è una tipologia di sito conosciuta da tutti e non troppo complessa da sviluppare per cui penso sia l'ideale per questo tipo di esperimento.

Le funzionalità saranno quelle tipiche di un blog.

  • Post e commenti
  • Categorie
  • Pagina profilo utente
  • Feed

Vedremo se aggiungere altro strada facendo.

Saranno necessari diversi post per completare l'opera. Per il momento ho creato i due siti di prova

demo.latenight-coding.com/joomla-blog/
demo.latenight-coding.com/drupal-blog/

Le versioni dei due cms sono Joomla 1.57 e Drupal 6.4. I template scelti, rispettivamente, Siteground e Light Fantastic; l'aspetto grafico non è comunque quello che mi interessa di più in quanto entrambi i cms consentono di cambiare template con facilità. Di struttura e contenuto inizieremo a parlare dalla prossima volta.

Prima di concludere raccomando i seguenti articoli in tema con l'argomento in quanto trattano dell'utilizzo di Joomla e Drupal per sviluppare un blog.

Creare un vero e proprio blog con Joomla!
Usare Drupal per gestire un blog

Non è detto comunque che i siti sviluppati seguiranno la struttura e utilizzeranno tutti i componenti illustrati in questi articoli.

domenica 28 settembre 2008

Joomla 1.5, rimuovere Mootools dall'header

Chiunque abbia dato uno sguardo al sorgente html delle pagine di un sito realizzato con Joomla 1.5 avrà notato che la prima pagina e le pagine interne dei contenuti (sezioni, categorie, articoli) contengono nell'header queste righe

<script type="text/javascript" src="/media/system/js/mootools.js">
</script>
<script type="text/javascript" src="/media/system/js/caption.js">
</script>

Lo script caption.js serve alla visualizzazione automatica della didascalia (caption) delle immagini: per maggiori dettagli rimando al post che ho pubblicato su OneCms.it, Generare le didascalie delle immagini in Joomla.

Ora non dico che le didascalie delle immagini non siano utili, ma ci sono molti siti che ne fanno tranquillamente a meno o le gestiscono diversamente. Per cui, con tutto l'affetto per Mootools, forse è preferibile non includerlo nell'header, con i sui 70k e oltre, quando non serve.

La cosa si può fare commentando la riga 37 all'inizio della funzione display() in

.../components/com_content/controller.php

in modo che risulti così

//JHTML::_('behavior.caption');

In questo modo si evita il caricamento di caption.js e di conseguenza di mootools.js. Quel 'di conseguenza' forse non è immediatamente ovvio, i più curiosi potranno guardare il sorgente della funzione commentata sulla documentazione ufficiale. Ovviamente a questo punto non avremo più le didascalie alle immagini.

Si tratta di una modifica minima ad un file del core quindi affrontabile anche da parte dei più timorosi. D'altra parte annullare tutto e tornare alla situazione precedente non è certo difficile.

Dico subito, per fare risparmiare tempo a chi volesse provare, che se avete installato il template ja_purity (e, presumo, altri template di Joomlart) la cosa non funziona perché Mootools viene caricato comunque nel file index.php del template; si riesce invece a rimuovere da beez e da rhuk_milkyway, con altri template si tratta di provare.

Poi ci sono i moduli che necessitano di Mootools. Chiaro che se pubblicate uno di questi moduli su tutte le pagine del sito potete risparmiarvi la modifica perché il framework dovrà comunque essere sempre caricato.

Propongo questa cosa come semplice suggerimento. Soprattutto i fanatici dell'ottimizzazione ad ogni costo spero possano trovare spunti utili per qualche esperimento.

lunedì 8 settembre 2008

Mootools 1.2. Identificare browser e sistema operativo

Visto che Mootools 1.2 è stato rilasciato di recente, credo sia interessante iniziare a scrivere qualcosa su questa nuova versione del framework.

Per iniziare da qualcosa di semplice vediamo alcuni esempi di funzioni per determinare il nome, la versione e altre informazioni sul browser dell'utente. Visto che problemi di compatibilità fra browser sono sempre in agguato, spesso uno script deve essere in grado di compiere funzioni diverse a seconda del browser all'interno del quale viene eseguito.

Per fare questo si utilizzano alcuni metodi dell'oggetto Browser, inizializzato da Mootools e reso disponibile ai nostri script.

I browser vengono identificati in base al loro motore interno (rendering engine o layout engine). La funzione di un rendering engine è quella di visualizzare una pagina web così come la vediamo sullo schermo partendo dalle informazioni ricavate dal sorgente HTML (o XML) e dai fogli di stile CSS.

Si potrebbe dire che un'altra funzione non meno importante sia quella di rendere la vita dei web designer di tutto il mondo mai monotona e sempre ricca di sorprese grazie ai numerosi bachi e incompatibilità che fanno sì che lo stesso sorgente HTML mai produca lo stesso risultato visivo in tutti i browser.

Il nome del rendering engine in Mootools si ricava con

Browser.Engine.name

Esistono poi delle scorciatoie per individuare i diversi browser e relative versioni.

Identificare Internet Explorer

Il rendering engine di Internet Explorer è chiamato Trident.

if(Browser.Engine.trident) {
  alert('Internet Explorer');
  if(Browser.Engine.trident4) {
    alert('IE6');
  } else if(Browser.Engine.trident5) {
    alert('IE7');
  }
}

Identificare Mozilla o Firefox

Il rendering engine è chiamato Gecko

if(Browser.Engine.gecko) {
  alert('Mozilla / Firefox');
}

Identificare Opera

Il rendering engine è chiamato Presto

if(Browser.Engine.presto ) {
  alert('Opera');
  if(Browser.Engine.presto925 ) {
    alert('versione 9.25 o precedente');
  } else if(Browser.Engine.presto950 ) {
    alert('versione 9.50 o successiva');
  }
}

Identificare Safari o Google Chrome

Il rendering engine è chiamato Webkit

if(Browser.Engine.webkit ) {
  alert('Safari / Chrome / Webkit');
  if(Browser.Engine.webkit419) {
    alert('versione 419 o precedente');
  } else if(Browser.Engine.webkit420) {
    alert('versione 420 o successiva');
  }
}

Ricavare la versione del plugin Flash

Un'altra informazione che Mootools mette a disposizione è il numero di versione (major e build) del plugin Flash installato nel browesr.

alert(' Numero versione Flash: ' + 
Browser.Plugins.Flash.version);

alert('Numero build Flash: ' + 
Browser.Plugins.Flash.build);

Identificare il sistema operativo

Infine è possibile ricavare il sistema operativo dell'utente.

alert(Browser.Platform.name);
if(Browser.Platform.mac) {
  alert ('Mac');
} else if(Browser.Platform.win) {
  alert ('Windows');
} else if(Browser.Platform.linux) {
  alert ('Linux');
} else if(Browser.Platform.ipod) {
  alert ('Ipod');
} else if(Browser.Platform.other) {
  alert ('altro');
}

È tutto. Il sorgente completo dello script in un formato più adatto al copia e incolla lo trovate qui. Per testarlo è necessario anche scaricare Mootools 1.2 e includere lo script nell'header come nell'esempio.

sabato 16 agosto 2008

Mootools, effetti e transizioni

Il codice della classe QScroller offre un esempio di come realizzare una semplice animazione con Mootools.

var QScroller = new Class({
/* ... */
  show: function() { (1)
    var slide = this.slideIn.getElement('div');
    if(slide) {
      slide.replaceWith(this.curSlide);
    } else {
      this.curSlide.injectInside(this.slideIn);
    }
    this.doEffect();
  },
  doEffect: function() {
    this.fxOn = true;
    var d = this.isFirst ? 0:this.options.duration;
    var t = this.options.transition;
    
    var fxObj = this.slideIn.effects({ (2)
      duration:d,
      transition: t
    });
    /* ... */ (3)
    fxObj.start({ (4)
      top: [inY, 0],
      left: [inX, 0],
      opacity: [1, 1]
    });
    this.slideOut.effects({ (5)
      duration: d,
      transition: t
    }).start({
      top: [0, outY],
      left: [0, outX]
    });
    /* ... */
  },
});
QScroller.implement(new Options, new Events);

Per gestire l'effetto scrolling si utilizzano due elementi DIV generati dinamicamente e salvati negli attributi della classe slideIn e slideOut (vedi funzione initialize() in Mootools, creare elementi DOM).

Come già accennato gli elementi (slide) con il testo e/o le immagini da far scorrere sono contenuti in una serie di DIV la cui classe (default qslide, fare riferimento al sorgente html degli esempi) è passata alla classe QScroller attraverso il meccanismo delle options. L'insieme di queste slide è quindi memorizzato nell'attributo della classe slides (vedi ancora initialize() in Mootools. Ancora la classe QScroller).

(1) Il compito della funzione show() è quello di inserire in slideIn (con injectinside()) la prossima slide da visualizzare (curSlide vedi load() in Mootools. Ancora la classe QScroller), rimpiazzando (con replaceWith()) la slide precedente eventualmente presente . Poi viene invocata doEffect() che si occupa dell'effetto di scrolling vero e proprio.

(2) Si predispone un effetto da applicare all'elemento slideIn impostandone durata (in millisecondi) e transizione (per esempi sulle possibili transizioni supportate da Mootools vedi la documentazione).

(3) Il codice è omesso perché si tratta di semplici istruzioni per calcolare le posizioni iniziale e finale di slideIn e slideOut in base alla direzione del movimento.

(4) Il valore della proprietà top di slideIn passa da inY a zero, il valore della proprietà left da inX a zero, il tutto gradualmente per la durata e con l'effetto di transizione impostato in (2). Il valore di opacity resta costante a 1 (elemento visibile).

Se si considera che slideIn ha una posizione assoluta all'interno di un DIV contenitore (vedi inizializzazione dell'attributo wrapper in Mootools. Elementi ed eventi), il risultato finale è un effetto di scorrimento orizzontale o verticale di slideIn.

(5) Qualcosa di analogo a quanto visto sopra. Basta verificare nel codice omesso le posizioni iniziali e finali di left o top per slideIn e slideOut per capire il meccanismo: la slide corrente 'esce' come se fosse 'spinta fuori' dalla nuova che entra.

Si conclude qui questa serie di post sulla classe QScroller. Le funzioni rimanenti sono facilmente comprensibili, chi avesse bisogno di maggiori dettagli può lasciare un commento.

martedì 29 luglio 2008

QContacts 1.0.3

Dopo circa tre mesi dal rilascio della prima versione, è arrivato il momento di aggiungere qualche nuova funzionalità al componente per la gestione contatti QContacts.

Ecco le principali novità introdotte dalla versione 1.0.3 appena rilasciata.

Dalla configurazione del componente è possibile modificare praticamente ogni aspetto del codice captcha: dimensioni dell'immagine, numero dei caratteri del codice, font, colore di sfondo e del testo, presenza o meno delle linee verticali e curve.

Sono adesso disponibili fino a 6 campi personalizzati. Il tipo dei campi non è limitato a testo e textarea, ma sono possibili anche checkbox, radio e liste di selezione a discesa (drop down). La posizione sul modulo contatti e la larghezza di ogni campo sono configurabili. Alcuni utenti giustamente avevano richiesto di poter posizionare i campi personalizzati anche prima di quelli predefiniti, cosa che a questo punto è possibile fare.

L'elenco contatti visualizzato dai link Aspetto Categoria Contatto può includere molti più campi della scheda contatto, sono inoltre impostabili l'ordine e la larghezza delle singole colonne.

Un asterisco o altro simbolo a scelta può essere mostrato per segnalare un campo obbligatorio. Ho aggiunto inoltre un apposito selettore in qcontacts.css (label.required) per impostare lo stile dell'etichetta di un campo obbligatorio: l'impostazione predefinita è colore del testo rosso.

Il sito è aggiornato con la documentazione delle nuove funzioni.

www.latenight-coding.com/it/joomla-addons/qcontacts.html

I commenti degli utenti sulla prima versione sono stati in generale molto positivi, QContacts è al momento al primo posto su extensions.joomla.org nella sua categoria: Non è la più competitiva delle categorie, ma sono sempre soddisfazioni!

Spero che queste migliorie possano rendere il componente più utile e funzionale. Chi volesse dare un voto può farlo a questo link (è necessario registrarsi al sito).

Ringraziamenti

Voglio ringraziare tutti coloro che hanno inviato critiche e suggerimenti ed hanno contribuito a dare visibilità al componente. In modo particolare

Alex Red e lo staff di Joomla.it per l'ospitalità nella sezione download (download.joomla.it).

Vamba e lo staff di Joomlaitalia.com per l'inserimento nella sezione estensioni del sito (extensions.joomlaitalia.com).

Andrea di Joomlovers.net per la recensione e il supporto. Il blog di Andrea è aggiornato quotidianamente su tutte le novità del mondo Joomla! Raccomandato agli utenti e appassionati di questo cms.

Questo per ora è tutto. Nuovi sviluppi sono in preparazione :)

giovedì 24 luglio 2008

Mootools. Ancora la classe QScroller

Concludiamo l'esame della funzione initialize() della classe QScroller.

var QScroller = new Class({
  /*...*/
  initialize: function(wrapper,options) {
    /*...*/  
    this.slides = $$('.'+this.options.slides); (1)
    
    if($defined(this.options.buttons)) {
      if($defined(this.options.buttons.next)) {
        $(this.options.buttons.next).addEvent('click', 
        this.next.bind(this)); (2)
      }
      /*...*/ 
    }
    this.auto = this.options.auto;
    this.idxSlide = 0;
    this.step = 0;
    this.isFirst = true;
  },
  load: function() { (3)
    if(!this.isFirst) {
      this.idxSlide += this.step;
      if(this.idxSlide > this.slides.length-1) {
        this.idxSlide = 0;
      } else if(this.idxSlide < 0) {
        this.idxSlide = this.slides.length-1;
      }
    }
    this.curSlide = this.slides[this.idxSlide].clone();
    this.show();
  },
  /*...*/
});
QScroller.implement(new Options, new Events);

(1) La funzione $$ ritorna un array di elementi DOM selezionati, in questo caso, in base ad un selettore css che passiamo come argomento.

this.options.slides come abbiamo visto è un'opzione di configurazione della classe. Quindi ad esempio

this.slides = $$('.qslide');

Seleziona e memorizza nell'attributo slides della classe tutti gli elementi di classe qslide. Controllando il sorgente html degli esempi è facile capire che questi elementi sono le div che contengono il testo o le immagini da far scorrere.

(2) Aggiunge un event listener per l'evento click ad ogni pulsante (next, prev, play, stop). AddEvent() l'abbiamo già incontrata (vedi questo post), per ulteriori dettagli rimando al sorgente degli esempi 2 e 3 (nel pacchetto di installazione) dove si vede come tramite il meccanismo delle options viene passato alla classe un oggetto buttons con gli ID dei link che servono per controllare lo scorrimento delle immagini.

Il codice rimanente serve solo ad inizializzare alcuni attributi il cui utilizzo sarà visto in seguito. Possiamo proseguire con le altre funzioni.

(3) il funzionamento di load() dovrebbe, almeno spero, essere del tutto intuitivo.

Come abbiamo detto sopra slides è un array con gli elementi (div) contenenti il testo e/o le immagini da far scorrere. La funzione memorizza in curSlide un clone del prossimo elemento da visualizzare in base alla direzione corrente dello scorrimento (step=1 avanti, step=-1 indietro).

È chiaro che devono esserci dei controlli per rendere ciclico il movimento. Se ci si sposta avanti quando siamo posizionati sull'ultimo elemento (idxSlide uguale a slides.length-1) si visualizza il primo, se ci si sposta indietro quando siamo posizionati sul primo elemento (idxSlide uguale a zero) si visualizza l'ultimo.

E anche per questa volta è tutto.

sabato 19 luglio 2008

PHP: Funzioni di ordinamento array

PHP possiede diverse funzioni dedicate all'ordinamento di array. Credo sia utile vedere alcuni esempi anche perché, a mio parere, quelli presenti sulla documentazione ufficiale non sono sempre lineari e facili da capire.

Inizieremo da esempi molto semplici potrei tranquillamente dire banali.

Ordinamento di array a una dimensione

Ordinamento degli elementi di un array

Consideriamo il seguente codice

$a = array(9,4,2,7,5);
sort($a);
print_r($a);

Il risultato di questo esempio è

Array
(
  [0] => 2
  [1] => 4
  [2] => 5
  [3] => 7
  [4] => 9
)

La funzione sort() ordina l'array in ordine crescente in base al valore degli elementi. Esiste anche una funzione rsort() che svolge un'operazione analoga, ma con ordinamento decrescente.

Altro esempio sempre utilizzando lo stesso array

$a = array(9,4,2,7,5);
asort($a);
print_r($a);
Il risultato è
Array
(
  [2] => 2
  [1] => 4
  [4] => 5
  [3] => 7
  [0] => 9
)

asort() ordina l'array in ordine crescente in base al valore degli elementi, ma, a differenza di sort(), mantiene l'associazione chiavi / valori dell'array originario. Per questo motivo è particolarmente utile quando si lavora con array associativi.

Nell'esempio seguente abbiamo un array associativo in cui ogni chiave è il nome di una squadra associato al rispettivo punteggio. Ecco come possiamo visualizzare una 'classifica'.

$a = array(
  'Fiorentina' => 66,
  'Inter' => 85,
  'Juventus' => 72,
  'Roma' => 82
);
arsort($a);
print_r($a);

Utilizziamo arsort(), l'omologa di asort() per l'ordinamento decrescente, perché vogliamo ordinare dal punteggio più alto al più basso ottenendo questo risultato

Array
(
  [Inter] => 85
  [Roma] => 82
  [Juventus] => 72
  [Fiorentina] => 66
)

Ordinamento delle chiavi di un array

Per ordinare un array in base al valore delle chiavi si utilizza ksort(). Ordiniamo l'array delle squadre visto in precedenza con questa funzione

ksort($a);

otteniamo

Array
(
  [Fiorentina] => 66
  [Inter] => 85
  [Juventus] => 72
  [Roma] => 82
)

La funzione krsort() è analoga, ma effettua un ordinamento decrescente delle chiavi.

Ordinamento naturale

La funzione natsort() ordina le stringhe contenenti valori numerici in modo più 'naturale', cioè più simile a quanto farebbe un essere umano, rispetto agli algoritmi usati dalle altre funzioni di ordinamento.

Vediamo un esempio. Questo è l'array da ordinare

$a=array('A4','A11','B6','A2','B400','B3','B31');

ordinamento con sort()

sort($a);
print_r($a);

Risultato

Array
(
  [0] => A11
  [1] => A2
  [2] => A4
  [3] => B3
  [4] => B31
  [5] => B400
  [6] => B6
)

Ordinamento con natsort()

natsort($a);
print_r($a);

Risultato

Array
(
  [3] => A2
  [0] => A4
  [1] => A11
  [5] => B3
  [2] => B6
  [6] => B31
  [4] => B400
)

Confrontando i due risultati si nota come natsort() ordini numericamente la parte numerica delle stringhe. Inoltre le associazioni chiavi valori sono preservate analogamente a quanto accade con asort().

La funzione natcasesort() è del tutto analoga tranne per il fatto che l'ordinamento non è sensibile alle maiuscole e minuscole.

Ordinamento di array multidimensionali

Tra le funzioni per l'ordinamento di array, array_multisort() è forse la più complessa. Serve ad ordinare più array insieme o un array multidimensionale, rispetto a una o più delle sue dimensioni: è di questo secondo utilizzo che vedremo un esempio.

Consideriamo il seguente codice

$a = array(
  array(5, 7, 8, 5),
  array(1, 2, 6, 4)
);
array_multisort($a[0], SORT_ASC, $a[1], SORT_DESC);

$a è un array a più dimensioni (o array di array se si preferisce). Il risultato dell'ordinamento è

Array
(
  [0] => Array
    (
      [0] => 5
      [1] => 5
      [2] => 7
      [3] => 8
    )

  [1] => Array
   (
     [0] => 4
     [1] => 1
     [2] => 2
     [3] => 6
   )
)

Il funzionamento può non essere facile da capire a prima vista. Il tutto però risulta più chiaro se rappresentiamo come tabella l'array multidimensionale da ordinare (i numeri in grassetto sono gli indici).

Array di partenza,

  | 0 | 1 | 2 | 3 |
0 | 5 | 7 | 8 | 5 |
1 | 1 | 2 | 6 | 4 |

Array risultante dopo l'esecuzione di array_multisort().

  | 0 | 1 | 2 | 3 |
0 | 5 | 5 | 7 | 8 |
1 | 4 | 1 | 2 | 6 |

L'array è stato ordinato in ordine crescente (SORT_ASC) in base al valore degli elementi della prima dimensione (la prima riga); quando due di questi elementi hanno lo stesso valore (nell'esempio 5), l'ordinamento è stato fatto in base agli elementi corrispondenti della seconda dimensione (la seconda riga) e questa volta l'ordine è decrescente (SORT_DESC): la colonna contenente i valori 5-4 è posta prima di quella contenente 5-1.

L'ordine degli argomenti passati ad array_multisort() detta la priorità dei criteri di ordinamento. Chi ha familiarità con il linguaggio SQL riconoscerà che la situazione è del tutto analoga a quella che si verifica quando si specificano più campi di ordinamento in una clausola ORDER BY.

Spero che questa breve panoramica delle funzioni PHP per l'ordinamento di array sia stata utile. Non è certo mia intenzione duplicare la documentazione ufficiale del PHP a cui consiglio di fare riferimento per numerosi dettagli che ho necessariamente omesso e per esempi di codice più complessi di quelli sopra presentati.

venerdì 27 giugno 2008

Mootools. Creare elementi DOM

L'esame del sorgente della classe QScroller ci porta a spendere qualche parola sulle funzioni di Mootools dedicate alla creazione di elementi DOM.

Riporto di seguito solo le parti di sorgente di cui parleremo

var QScroller = new Class({
  /* ... */
  initialize: function(wrapper,options) {
    /* ... */     
    this.slideOut = new Element('div').setStyles({ (1)
      position: 'absolute',
      overflow: 'hidden',
      top: 0,
      left: 0,
      width: this.wrapper.getStyle('width'),
      height: this.wrapper.getStyle('height')
    }).injectInside(this.wrapper);

    this.slideIn = this.slideOut.clone(); (2)
    this.slideIn.injectInside(this.wrapper);        
    /* ... */
  },
  /* ... */
});
QScroller.implement(new Options, new Events);

(1) Con questa istruzione creiamo un nuovo elemento div, ne impostiamo alcuni attributi con la funzione setStyles() (già incontrata nell'articolo precedente) e lo aggiungiamo come figlio di this.wrapper (l'elemento contenitore anch'esso visto in precedenza) con la funzione injectInside().

Come si vede, una volta che un elemento è stato creato è necessario inserirlo nel documento. Inserire l'elemento in un altro preesistente con la funzione injectInside() è uno dei modi per farlo, ma non l'unico: esistono infatti anche le funzioni injectBefore() e injectAfter() di cui vediamo subito un esempio.

Consideriamo questa porzione di documento html

<div id="elemento0"></div>

Dopo l'esecuzione di questo codice Javascript

<script type="text/javascript">
<!--
window.addEvent('domready', function() {
  var el = $('elemento0');
  var e = new Element('div', {id: 'elemento1'});
  e.injectInside(el);
  var e = new Element('div', {id: 'elemento2'});
  e.injectBefore(el);
  var e = new Element('div', {id: 'elemento3'});
  e.injectAfter(el);
});
//-->
</script>

ecco la struttura del documento visualizzata dal Dom Inspector di Firefox che rende bene l'idea del risultato prodotto dallo script.

Continuiamo con il sorgente di QScroller

(2) L'istruzione clone(), come il nome suggerisce, crea una copia identica di un elemento. I due attributi della classe slideIn e slideOut funzioneranno come elementi di 'transito' per il contenuto delle slide che saranno animate con effetto di scorrimento.

I dettagli devono essere rimandati a quando passeremo dal codice di inizializzazione alle funzioni che svolgono i compiti effettivi per cui è stata sviluppata la classe.

Avevo detto che non sarebbe stata una cosa tanto veloce! I più impazienti hanno già a disposizione il sorgente completo da esaminare.

venerdì 20 giugno 2008

Mootools. Elementi ed eventi

Prima di proseguire con l'esame della classe QScroller ecco il link per scaricare il pacchetto completo con gli esempi. Decomprimete l'archivio in una cartella del vostro sito web (o localhost) e aprite index.html con il browser. Tenendo a portata di mano il sorgente della classe (file qscroller.js) sarà più facile seguire il discorso.

Continuiamo la spiegazione della funzione initialize() che, ricordo, viene invocata automaticamente alla creazione di un'istanza della classe.

var QScroller = new Class({
  options: { 
    slides: 'qslide',
    direction: 'h',
    duration: 3000,
    auto: false,
    delay: 1000,
    transition: Fx.Transitions.linear
  },
  initialize: function(wrapper,options) { 
    this.setOptions(options); 
    this.wrapper = $(wrapper); (1)
    this.wrapper.setStyles({ (3)
      position: 'relative',
      overflow: 'hidden'
    });
    this.wrapper.addEvent('mouseenter', (4)
      this.fireEvent.pass('onMouseEnter',this));

    this.wrapper.addEvent('mouseleave', 
      this.fireEvent.pass('onMouseLeave',this));
    /* ... */
  },
  /* ... */
});
QScroller.implement(new Options, new Events);

var opt = { 
  auto:true,
  onMouseEnter: function(){this.stop();}, (5)
  onMouseLeave: function(){this.play();}
}
var scroller = new QScroller('qscroller1',opt); (2)

Uno dei maggiori punti di forza di Mootools è la facilità con cui consente di accedere e modificare gli elementi DOM o crearne nuovi dinamicamente. Le funzioni dedicate a questo scopo sono molte, vedremo solo quelle che sono utilizzate nel codice della classe.

La prima che incontriamo è la funzione $ (l'hanno chiamata semplicemente così) che ritorna un elemento DOM il cui ID passiamo come argomento. Nel nostro caso

(1) Salviamo come proprietà wrapper della classe QScroller l'elemento DOM di ID qscroller1 (vedi (2) )

Fatto questo possiamo modificare gli attributi dell'elemento (che come vedremo è il contenitore della nostra animazione)

(3) Impostiamo gli attributi position ed overflow. La funzione setStyle() riceve come argomento un oggetto letterale che contiene le coppie attributo/valore che dobbiamo impostare ( {attributo1: 'valore1', attributo2: 'valore2', ... } ).

Anche solo da queste poche righe penso si possa intuire la facilità con cui Mootools permette di modificare dinamicamente con Javascript il contenuto o l'aspetto di una pagina web.

(4) Come spesso succede in Mootools una sola riga di codice si traduce in una lunga spiegazione.

a) con addEvent() aggiungiamo a this.wrapper (ricordo, l'elemento di ID qscroller1) un event listener per l'evento mouseenter.

b) quando il puntatore del mouse entra (mouseenter appunto) nell'area dell'elemento attiveremo (con fireEvent()) l'evento onMouseEnter della classe QScroller.

c) il che significa che sarà eseguito il codice della funzione onMouseEnter() che abbiamo passato in options (5).

Con questo meccanismo consentiamo agli utenti della classe di personalizzare il codice eseguito al verificarsi di un determinato evento senza dover intervenire sul codice della classe stessa.

Resterebbe da vedere l'uso di pass() e soprattutto perché sia necessario in questo caso, ma spero non si offenda nessuno, rimando la spiegazione ad un'altra volta! L'argomento è complesso e questa breve serie di articoli non vuole certo essere una guida completa a Mootools.

mercoledì 11 giugno 2008

Joomla 1.5. Tabs in contenuti e moduli

L'uso di tabs (o linguette, tipo schedario o rubrica telefonica) come strumento per consentire all'utente di navigare facilmente tra diverse 'pagine' di informazioni è un modello di interfaccia che si riscontra frequentemente su molti siti web.

Posto che ce ne sia bisogno, ecco un esempio dall'home page di Yahoo.

In Joomla 1.5 le tabs si possono facilmente creare con apposite funzioni del framework. L'unico problema è che le tabs sono di solito utilizzate nel backend, per averle nel frontend è necessario un po' di lavoro. Spiego il procedimento passo passo, stile ricetta della nonna.

Per prima cosa installare il plugin Jumi che ci servirà per facilitare l'inserimento di codice html e php in un contenuto. Il plugin va attivato da Gestione plugin.

Creare con un programma FTP una cartella jumi_includes all'interno della stessa cartella dove è installato Joomla.

Poi creare un file tabs.css. Siccome è difficoltoso fare il copia e incolla dal testo, ho voluto provare pastebin.com: fate click sui nomi dei file che saranno via via citati nell'articolo per vederne una versione con sintassi evidenziata scaricabile o copiabile facilmente.

dl.tabs {
float:left;
margin:10px 0pt -1px;
z-index:50;
}
dl.tabs dt {
background:#F0F0F0 none repeat scroll 0%;
border-left:1px solid #CCCCCC;
border-right:1px solid #CCCCCC;
border-top:1px solid #CCCCCC;
color:#666666;
float:left;
margin-left:3px;
padding:4px 10px;
}
dl.tabs dt.open {
background:#F9F9F9 none repeat scroll 0%;
border-bottom:1px solid #F9F9F9;
color:#000000;
z-index:100;
}
div.current {
border:1px solid #CCCCCC;
clear:both;
padding:10px;
}
div.current dd {
margin:0pt;
padding:0pt;
}

Questi attributi sono copiati dal foglio di stile del template predefinito del backend e servono a determinare l'aspetto delle tabs. Fare l'upload di tabs.css in jumi_includes.

Creare un file tabs.php con questo contenuto

<?php
JHTML::stylesheet('tabs.css','jumi_includes/');

Questa istruzione serve ad includere nell'intestazione del documento html il file css creato in precedenza. Il percorso del file css è relativo alla cartella di Joomla. Per esempio supponendo che la pagina principale del vostro sito sia raggiungibile con

http://www.example.com/joomla

come risultato della esecuzione di JHTML::stylesheet() con gli argomenti visti sopra, tra <HEAD> e </HEAD> della pagina trovereste

<link rel="stylesheet" href="/joomla/jumi_includes/tabs.css" 
type="text/css" />

È una funzione da tenere a mente perché utilissima quando si sviluppano moduli e componenti che necessitano di inserire propri fogli di stile nell'intestazione del documento html.

Continuiamo con il codice

jimport('joomla.html.pane');

Include la definizione della classe JPane che utilizzeremo subito e inserisce (sempre tra <HEAD> e </HEAD>) il codice Javascript necessario al funzionamento delle tabs. Non vedremo questo codice in dettaglio, fa parte di Joomla e funziona e questa è l'unica cosa che ci interessa.

$tabs = &JPane::getInstance('tabs');
echo $tabs->startPane('test-tabs');

Otteniamo un'istanza dell'oggetto che ci serve e iniziamo il gruppo di tabs con ID test-tabs. Potete scegliere l'ID che preferite, ma se si vogliono creare più gruppi di tabs sulla stessa pagina è importante che ognuno abbia un ID differente.

echo $tabs->startPanel('Tab1', 'test-tab1');
?>
<p>Contenuto tab1</p>
<p>qwerty</p>
<?php
echo $tabs->endPanel();

Contenuto della prima tab. Mi sembra abbastanza intuitivo: inseriamo il codice html che vogliamo tra startPanel() e endPanel(). Gli argomenti da passare al primo metodo sono il titolo visibile della tab e un ID che anche in questo caso deve essere univoco.

echo $tabs->startPanel('Tab2', 'test-tab2');
?>
<p>Contenuto tab2</p>
<?php
echo $tabs->endPanel();
echo $tabs->startPanel('Tab3', 'test-tab3');
?>
<p>Contenuto tab3</p>
<?php
echo $tabs->endPanel();
echo $tabs->endPane();
?>

Allo stesso modo si creano la seconda e la terza tab e si chiude il gruppo con endPane()

Fare l'upload di tabs.php in jumi_includes.

A questo punto create un articolo e nel contenuto inserite il comando Jumi

{jumi [jumi_includes/tabs.php]}

Pubblicate e visualizzate l'articolo nel frontend. Il risultato dovrebbe essere questo.

Considerando che possiamo inserire codice html come contenuto dei tabs penso sia chiaro che si possono ottenere effetti interessanti.

Ma potrebbe essere anche più interessante visualizzare dei moduli a nostra scelta in un gruppo di tabs. Si può fare, ecco la seconda ricetta.

Per prima cosa aprire con un editor di testi il file templateDetails.xml nella cartella del proprio template. Aggiungere una nuova posizione tabs nella sezione positions

<positions>
...  
<position>tabs</position>
</positions>

Al posto dei puntini avete le altre posizioni previste dal template: quelle non vanno toccate (precisazione forse inutile).

Poi effettuare il login al backend di Joomla! ed entrare in Gestione moduli. Aprire mod_latestnews (modulo Ultime Notizie), se non è nella lista dei moduli crearlo con Nuovo. Nella schermata di modifica del modulo impostare

  • Posizione: tabs
  • Assegnazione Menu: Tutti

Questo non significa che il modulo sarà visibile su tutte le pagine perché la posizione tabs che abbiamo aggiunto non è richiamata nel codice del template. Caricheremo il contenuto del modulo da codice (vedremo subito come).

Ripetere le stesse identiche operazioni per il modulo mod_mostread (Articoli più letti). Potete ovviamente scegliere due (o più) moduli diversi.

Creare un file tabs_moduli.php con questo contenuto

<?php
JHTML::stylesheet('tabs.css','jumi_includes/');
jimport('joomla.html.pane');
$tabs = &JPane::getInstance('tabs');
echo $tabs->startPane('moduli-tabs');

$document = &JFactory::getDocument();
$renderer = $document->loadRenderer('module');

La prima parte è identica al primo esempio. Le ultime due righe servono ad ottenere un'istanza dell'oggetto renderer per la visualizzazione del contenuto dei moduli. Non mi dilungo in troppi dettagli.

$i = 1;
foreach (JModuleHelper::getModules('tabs') as $mod)  {

Per ogni modulo assegnato alla posizione tabs

 echo $tabs->startPanel($mod->title, 'mod'.$i);

si crea un tab che ha per titolo il titolo del modulo

 echo $renderer->render($mod);
 echo $tabs->endPanel();

come contenuto del tab si inserisce il contenuto del modulo ottenuto utilizzando l'oggetto renderer e si chiude il tab

 $i++;
}
echo $tabs->endPane();
?>

Effettuare l'upload di tabs_moduli.php nella cartella jumi_includes usata in precedenza.

Creare un articolo, ma va bene anche quello creato in precedenza, e inserire nel contenuto il comando Jumi

{jumi [jumi_includes/tabs_moduli.php]}

Salvare e visualizzare l'articolo nel frontend. Il risultato dovrebbe essere di questo tipo

Mi sembra una buona soluzione salva spazio: si possono pubblicare più moduli nello spazio occupato da uno e lasciare che sia l'utente a scegliersi le informazioni da visualizzare selezionando le tabs.

Oltre al plugin esiste un modulo Jumi. Negli esempi abbiamo sempre utilizzato le tabs nel contenuto di un articolo, con il modulo Jumi possiamo utilizzarle allo stesso modo in una posizione modulo del template.

Per modificare l'aspetto e i colori delle tabs ed adattarli al template è necessario agire sul file tabs.css.

Questo è un post da smanettoni. Può darsi, sinceramente non mi sono messo a spulciare la directory delle estensioni su joomla.org, che ci siano moduli già pronti che fanno questo genere di cose. Però scriversi il codice a mano ci ha consentito di conoscere alcune funzioni del framework che possono sempre tornare utili.

Alla prossima.

martedì 10 giugno 2008

Mootools. Funzione initialize e options

Continuiamo lo sviluppo della classe QScroller. Partiamo dal codice includendo questa volta le istruzioni per la creazione di un'istanza scroller.

var QScroller = new Class({
  options: { (1)
    slides: 'qslide',
    direction: 'h',
    duration: 3000,
    auto: false,
    delay: 1000,
    transition: Fx.Transitions.linear
  },
  initialize: function(wrapper,options) { (2)
    this.setOptions(options); (5)
    /* ... */
  },
  /* ... */
});
QScroller.implement(new Options, new Events);

var opt = { (4)
  auto:true,
  onMouseEnter: function(){this.stop();},
  onMouseLeave: function(){this.play();}
}
var scroller = new QScroller('qscroller1',opt); (3)

(1) options è una proprietà standard, come si vede è un oggetto le cui proprietà sono inizializzate con valori predefiniti. Ne vedremo tra poco l'utilizzo.
(2) se una classe possiede una funzione initialize() questa sarà eseguita ogni volta che un'istanza viene creata e riceverà gli argomenti che abbiamo passato al costruttore.
(3) In questo esempio passiamo al costruttore 2 argomenti.
(4) Per il momento concentriamoci sul secondo, l'oggetto opt.
(5) Questo oggetto viene utilizzato in initialize() dalla funzione setOptions() (che la nostra classe eredita da Options per effetto di implement):

  • quando è definita una proprietà in opt presente anche nell'oggetto options di cui al punto (1), il valore in opt sovrascrive quello in options.
  • quando è definita una proprietà in opt non presente nell'oggetto options, la proprietà in opt viene aggiunta ad options.
  • le proprietà in options non definite in opt mantengono ovviamente il valore preimpostato.

Detto questo dopo l'esecuzione del codice sopra riportato i valori della proprietà options di scroller saranno i seguenti

scroller.options.slides -> 'qslide'
scroller.options.direction -> 'h'
scroller.options.duration -> 3000
scroller.options.auto -> true
scroller.options.delay -> 1000
scroller.options.transition -> Fx.Transitions.linear
scroller.options.onMouseEnter -> function(){this.stop();}
scroller.options.onMouseLeave -> function(){this.play();}

A cosa servono tutte queste opzioni ancora non si è visto!

Penso che l'utilità di questo meccanismo fornito da Options e setOptions() sia chiara: predefinendo i valori di una serie di opzioni possiamo in molti casi ridurre il numero di argomenti da passare al costruttore, semplificando così l'utilizzo della classe.

Anche questo è un post breve. Continueremo l'esame della funzione initialize() la prossima volta.

venerdì 6 giugno 2008

Mootools. Struttura di una classe

Di Mootools ho già avuto modo parlare, ma essendomi divertito abbastanza con questo framework ultimamente, mi è venuta voglia di approfondire il discorso.

Come al solito, per evitare noiose spiegazioni teoriche partiremo da un esempio concreto e mostreremo (più o meno) passo passo come si crea una (più o meno) semplice classe Mootools.

Prima di proseguire è ben ricordare che le classi Mootools sono molto diverse concettualmente dalle classi a cui siamo abituati in altri linguaggi di programmazione orientati agli oggetti. Una classe Mootools è essa stessa un oggetto (cosa che risulta palese dal semplice fatto che si usa l'istruzione new per crearla), un oggetto che viene utilizzato come prototipo per la creazione di altri oggetti.

Detto questo, da ora in poi parlerò tranquillamente di classi ed istanze nella stessa accezione che questi termini hanno in linguaggi quali C++ o Java. Trattandosi di Javascript, la terminologia non sarà del tutto corretta, ma sarà più facile capirsi.

Anche se si tratta di un esempio, è opportuno cercare di sviluppare qualcosa che abbia una utilità pratica: la classe servirà a presentare sul nostro sito delle informazioni (testo ed eventualmente immagini) con un effetto di scorrimento orizzontale o verticale. Si vedrà come con Mootools sia possibile ottenere degli effetti gradevoli scrivendo relativamente poco codice.

Vediamo innanzi tutto la struttura della classe (i puntini di sospensione racchiusi tra commenti servono da segnaposto per il codice che dovrà essere scritto in seguito)

var QScroller = new Class({
  options: {/* ... */},
  initialize: function(wrapper,options) {
    /* ... */
  },
  load: function() {
    /* ... */
  },
  show: function() {
    /* ... */
  },
  doEffect: function() {
    /* ... */
  },
  stop: function(){
    /* ... */
  },
  play: function() {
    /* ... */
  },
  next: function() {
    /* ... */
  },
  prev: function() {
    /* ... */
  },
  swapSlides: function() {
    /* ... */
  }
});
QScroller.implement(new Options, new Events);

Sono molte righe, ma in realtà si tratta solo di due istruzioni!

Cercare di spiegare esattamente cosa succede a livello di framework sarebbe troppo complesso, accontentiamoci del risultato finale. Una volta eseguito il blocco di codice riportato sopra abbiamo a disposizione una classe QScroller. Le istanze di QScroller possiederanno le proprietà e i metodi definiti nell'oggetto (un oggetto letterale, notate le graffe) che passiamo come argomento alla funzione Class.

Con implement aggiungiamo a QScroller le funzionalità delle classi Options ed Events definite nel framework. In altre parole tutte le proprietà e i metodi di Options ed Events saranno copiati in QScroller che potrà utilizzarli come propri. Cosa questo comporti si vedrà in seguito.

A questo punto tutto quello che abbiamo è uno scheletro vuoto. La prossima volta inizieremo a scrivere il codice dei metodi a partire dalla importante funzione initialize().

L'argomento richiederà alcune 'puntate'. Aggiungo un'etichetta Mootools per dare modo a chi arrivi a metà del discorso di recuperare facilmente tutti gli articoli.

domenica 1 giugno 2008

Joomla 1.5: Inserire HTML, Javascript o PHP in un articolo

Tutti coloro che hanno avuto la necessità di inserire codice HTML o Javascript in contenuti Joomla! si saranno resi conto di quanto effettuare questa operazione con un editor WYSIWYG sia difficoltoso o quantomeno scomodo.

Ogni editor ha un funzione per visualizzare e modificare direttamente il sorgente html del contenuto e questo sembrerebbe risolvere il problema, ma non è così: infatti se utilizziamo questa funzione per inserire codice html o Javascript, al momento di salvare il contenuto ci accorgeremo che parte (molto spesso gran parte) del codice che abbiamo inserito è stato rimosso.

Questo accade perché di solito gli editor sono configurati per accettare solo un insieme limitato di tag html, e rimuovere automaticamente tutti gli altri. Questa non deve considerarsi una limitazione quanto piuttosto una misura di sicurezza importante soprattutto per i siti che consentono l'inserimento di contenuti da parte dei visitatori e che devono cautelarsi contro l'inserimento di codice o script potenzialmente pericolosi.

Detto questo resta il problema.

Una possibile soluzione consiste nel disabilitare l'editor WYSIWYG. In questo modo possiamo inserire html e Javascript nel contenuto senza alcun tipo di filtro e, terminata l'operazione e salvato il contenuto, riabilitare l'editor WYSIWYG. Questa soluzione non è ideale: infatti se a distanza di tempo abbiamo bisogno di apportare modifiche al contenuto è facile dimenticarsi che questo contiene codice inserito direttamente ed effettuare le modifiche con l'editor WYSIWYG abilitato. In questo modo al momento del salvataggio i filtri 'mutileranno' il codice inserito in precedenza con le conseguenze che è facile immaginare.

Un'altra possibilità è l'utilizzo di apposite estensioni di terze parti. Ce ne sono diverse, a mio parere, una delle migliori per questo tipo di situazioni è Jumi.

Il funzionamento di Jumi è semplicissimo: per prima cosa inseriremo il codice html e/o Javascript che si desidera in un file e ne faremo l'upload sul nostro sito (meglio se in un cartella apposita).

Poi utilizzeremo un semplice comando plugin per passare a Jumi il percorso del file che sarà incorporato nel nostro contenuto.

Esempio di utilizzo di Jumi

Installate Jumi come qualsiasi plugin Joomla! Attivatelo da Gestore plugin. Create poi un semplice file di testo salve.html con questo contenuto

<p>Salve da <b>Jumi</b></p>
<script type="text/javascript">
<!--
document.write('Un saluto a tutti!');
//-->
</script>

Via FTP create una cartella jumi_includes all'interno della stessa cartella dove è installato Joomla! e inseritevi il file salve.html

Create un nuovo articolo e inserite nel contenuto questo comando

{jumi [jumi_includes/salve.html]}

Salvate, pubblicate l'articolo e visualizzatelo nel frontend (non con la funzione anteprima articolo presente nel backend). Vedrete che il codice html e lo script sono stati inclusi nel contenuto. Lo script ovviamente è stato eseguito dal browser e quindi è visibile l'output dell'istruzione document.write()

Il percorso del file da includere da passare a Jumi è sempre relativo alla cartella in cui è installato Joomla! a meno che non si specifichi un diverso percorso di base nella configurazione del plugin.

Includere codice PHP in un articolo

E se volessimo includere codice PHP in un articolo? Gli script PHP, come si sa, non sono eseguiti nel browser, ma dal server per cui il metodo che abbiamo visto all'inizio, cioè l'inclusione diretta nel contenuto previa disabilitazione dell'editor WYSIWYG, non funziona.

Anche in questa situazione Jumi ci viene in aiuto. Create con un normale editor di testo un file di nome salve.php con questo contenuto (un classico)

<?php
echo 'Salve Mondo!';
?>

Inseritelo via FTP nella stessa cartella utilizzata in precedenza jumi_includes. A questo punto il comando da inserire nell'articolo è semplicemente

{jumi [jumi_includes/salve.php]}

Salvate e visualizzate l'articolo come in precedenza: la scritta di saluto apparirà nel vostro contenuto nella posizione dove avete inserito la stringa di comando.

Oltre al plugin, esiste anche un modulo Jumi che vi consente di inserire html, javascript, php in una qualsiasi posizione modulo del vostro template.

Sul sito dello sviluppatore trovate maggiori dettagli ed esempi.

mercoledì 14 maggio 2008

Joomla 1.5: Inserire video YouTube in un modulo

Mi è stato fatto notare che QTube, il plugin per inserire video YouTube in articoli Joomla! di cui ho parlato un po' di tempo fa, non funziona nei moduli HTML personalizzati (quelli che si creano in Gestione moduli -> Nuovo -> HTML personalizzato).

Questo non è un problema o una limitazione specifica del plugin, ma il modo normale di funzionamento di Joomla 1.5 che non processa i comandi dei content plugin inseriti nel contenuto di moduli HTML.

La possibilità di attivare i mambot su questo tipo di moduli era presente nella versione 1.0 di Joomla, ma questa caratteristica è stata rimossa nella versione 1.5.

Quindi ho creato anche un modulo QTube che può essere utilizzato da chi voglia inserire facilmente un video YouTube in una posizione modulo prevista nel template del proprio sito Joomla.

Il modulo e il plugin funzionano con gli stessi parametri di configurazione (rimando alla documentazione sul sito per i dettagli), ma sono indipendenti e installabili separatamente. Come è ovvio il modulo si configura da Gestione moduli nel backend.

Il tutto, come al solito, lo trovate qui

www.latenight-coding.com/it/joomla-addons/qtube.html

Il plugin è stato anche approvato nella directory delle estensioni del sito ufficiale joomla.org

Ecco il Link

Da questa pagina potete anche votare l'estensione. Se l'avete trovata utile e vi va di spendere qualche secondo, questo è un buon modo per supportarla ed aiutarmi a 'passare parola'.

Già che sono in argomento, colgo l'occassione per fare alcune precisazioni che possono sembrare inutili, ma, a giudicare da alcune richieste di supporto che ho ricevuto, non lo sono. Tutte cose in gran parte scritte nella documentazione del plugin e modulo, ma voglio ripeterle.

1) Il plugin (come tutti i plugin) deve essere attivato da Estensioni -> Gestore plugin nel backend. Se vi ritrovate il comando inserito tra parentesi graffe tale e quale (cioè non rimpiazzato dal video) nel testo dell'articolo, la mancata attivazione del plugin è la causa più probabile del problema.

2) I comandi plugin devono essere inseriti in un articolo. Per inserire un video in una posizione modulo potete usare il modulo QTube di cui ho parlato all'inizio, ma ci sono in ogni caso altri 'posti' dove i plugin non funzionano come i testi descrittivi delle sezioni/categorie ed i componenti: ad esempio non si può utilizzare il plugin per inserire un video in una descrizione prodotto di Virtuemart.

3) Per fare le parentesi graffe che racchiudono il comando (almeno su PC Windows) si usano i tasti AltGr+Maiusc+è e AltGr+Maiusc+* c'è chi ha chiesto anche questo per cui vale la pena rendere l'informazione pubblica se dovesse servire anche ad altri :)

Chiudo qui. Alla prossima.

mercoledì 30 aprile 2008

Javascript: Mootools e classi

Per chi non lo conoscesse Mootools è un framework Javascript creato per facilitare la scrittura di codice orientato agli oggetti garantendo altresì la compatibilità con i diversi browser.

Chi ha avuto la voglia (e la pazienza perché gli articoli erano piuttosto lunghi) di leggere quanto scritto un po' di tempo fa a proposito di programmazione a oggetti in Javascript (Javascript: Esempi di Programmazione a Oggetti, Javascript: Oggetto prototype ed ereditarietà) ricorderà come le differenze in questo campo tra Javascript e i più tradizionali linguaggi orientati agli oggetti siano notevoli.

Uno degli scopi di Mootools è proprio quello di facilitare la vita agli sviluppatori con esperienza in linguaggi quali C++, Java o PHP5 consentendo loro di programmare a oggetti in Javascript con una metodologia di lavoro ed una terminologia più familiare.

Detto così, il tutto può risultare abbastanza generico, per cui è bene passare ad un esempio concreto.

Ereditarietà in Javascript puro

Riciclo un esempio già visto nell'articolo su Javascript, prototype ed ereditarietà citato sopra

function Veicolo(passeggeri) {
 this.velocita = 0;
 this.passeggeri = 0;
 this.carica = function(passeggeri) {
   if(passeggeri > 0) {
     this.passeggeri += passeggeri;
   }
 }
 this.carica(passeggeri);
}
function Aereo(passeggeri) {
 this.carica(passeggeri);
 this.altitudine = 0;
 this.decolla = function() {
   this.velocita = 100;
   this.altitudine = 10;
 }
}
Aereo.prototype = new Veicolo();
Aereo.prototype.constructor = Aereo;

Ereditarietà con 'classi' Mootools

L'equivalente utilizzando le classi MooTools

var Veicolo = new Class({
 initialize: function(options) {
   this.options = options;
   this.passeggeri = 0;
   this.velocita = 0;
   if(this.options.passeggeri) {
     this.carica(this.options.passeggeri);
   }
 },
 carica: function(passeggeri) {
   if(passeggeri > 0) {
     this.passeggeri += passeggeri;
   }
 }
})

var Aereo = Veicolo.extend({
 initialize: function(options) {
   this.parent(options);
   this.altitudine = 0;
 },
 decolla: function() {
   this.velocita = 100;
   this.altitudine = 10;
 }
})
Fare click qui per eseguire l'esempio.

L'esempio non sfrutta che in minima parte le potenzialità del framework, però credo possa servire a vedere che aspetto ha una 'classe' Mootools.

Chiaramente si tratta di una sovrastruttura, 'sotto' c'è sempre l'ereditarietà prototipale di Javascript e non potrebbe essere diversamente. L'equivalente di ciò che in Javascript otteniamo riassegnando l'oggetto prototype, utilizzando MooTools lo si fa tramite l'oggetto Class e .extend.

Questo è solo un primo contatto avremo modo di parlare ancora di MooTools.

sabato 26 aprile 2008

Joomla 1.5: Componente per la gestione dei contatti

Joomla! da sempre include nell'installazione base un componente per la gestione dei contatti (com_contact). Il componente fa il suo onesto lavoro consentendoci di creare un numero a piacere di categorie di contatti ed inserire per ogni contatto indirizzo, numero di telefono, di cellulare, di fax e altre informazioni che possono essere pubblicate sul sito o rese consultabili solo dal backend di Joomla! Oltre a questo possiamo visualizzare un modulo che consente ai visitatori l'invio di una email al contatto direttamente dal sito web.

Può capitare (ed in effetti mi è capitato recentemente) di avere bisogno di qualche funzione in più. In questo caso si potrebbe decidere di fare delle modifiche direttamente al codice di com_contact. Così facendo si corre però il rischio di perdere tutte le modifiche fatte nell'eventualità (non tanto remota) che alcuni file del componente standard contatti siano sovrascritti da un successivo aggiornamento di Joomla!

Una strada sicuramente migliore è quella di creare un nuovo componente, derivato da com_contact. La licenze GNU/GPL di Joomla! ce lo permette purché anche il componente derivato sia rilasciato sotto licenza GNU/GPL o compatibile.

Tutto questo preambolo per presentare QContacts un componente per la gestione dei contatti alternativo a quello incluso in Joomla! e rispetto al quale presenta questi miglioramenti (almeno io li reputo tali!)

  • alcuni campi informativi aggiunti alla scheda contatto: Skype e Yahoo Messenger
  • possibilità di proteggere con un codice captcha anti-spam il modulo per l'invio dell'e-mail
  • possibilità di aggiungere campi personalizzati (massimo 3) al suddetto modulo

Non sono molte modifiche, ma erano quelle che servivano a me e spero siano utili anche ad altri, nuove funzioni potranno essere aggiunte in future versioni.

QContacts è un componente che funziona in modalità nativa in Joomla! 1.5 (quindi non potete utilizzarlo in Joomla! 1.0)

Per il codice anti-spam ho utilizzato Securimage (www.phpcaptcha.org) una libreria open source per la generazione di immagini captcha, che richiede che siano installate sul server le librerie grafiche GD2 con il supporto per i font TrueType.

Ecco il link per scaricare il componente, sul sito trovate anche le istruzioni e la documentazione

QContacts

Se ci sono problemi o suggerimenti potete lasciare un commento o contattarmi tramite il modulo contatti del sito (fatto con QContacts chiaramente).

lunedì 31 marzo 2008

Joomla 1.5: Inserire video YouTube in un articolo

Il titolo spiega già il problema. Abbiamo inserito un nostro video su YouTube (o trovato il video di qualcun altro che ci piace) e vogliamo includerlo in un articolo del nostro sito realizzato con Joomla.

Non è una cosa difficle da fare, ma esistono più modi per farla.

Inserire il codice direttamente nell'editor

YouTube fornisce il codice html necessario per includere un video in una pagina web (riquadro Informazioni su questo video, nella pagina da cui il video viene riprodotto, vedi figura)

Il codice si può inserire in un articolo utilizzando il pulsante html dell'editor WYSIWYG standard di Joomla che consente di lavorare sul codice html grezzo del contenuto che si sta scrivendo.

L'inserimento di codice html con l'editor di Joomla non è un'operazione che riesce sempre in quanto alcuni editor filtrano determinati tag o attributi quando il contenuto viene salvato. Per cui bisogna sempre controllare se il video si visualizza correttamente. In caso contrario conviene aprire il sorgente html della pagina e verificare che il codice inserito sia stato salvato correttamente.

Dalle impostazioni dell'editor è di solito possibile disabilitare questo filtro (cosa però pericolosa per la sicurezza del sito se si consente l'inserimento di articoli agli utenti non amministratori) o aggiungere i tag che ci servono alla lista di quelli consentiti.

È difficile fare una casistica precisa dato il numero di editor esistenti e le diverse versioni di Joomla, ma per quello che ho potuto verificare, l'inserimento manuale del codice fornito da YouTube con il metodo spiegato sopra funziona di sicuro con TinyMCE e Joomla 1.5.

Problemi di validazione

C'è però un problema. Se una volta inserito il codice provate a validare la pagina contenente il video con il W3C validator, con ogni probabilità otterrete una serie di errori di validazione. Infatti il codice fornito da YouTube non è valido XHTML Transitional che è il DocType comunemente usato nei template di Joomla.

Ora a molti questa cosa potrà non fare nè caldo nè freddo, ma come si sa, il mondo è pieno di gente strana, e ci sono anche quelli che alla validità del codice sui propri siti ci tengono.

Quindi che si fa?

QTube

Per evitare operazioni di copia e incolla e correzioni a mano del codice mi sono scritto un plugin che rende molto semplice inserire un video YouTube in un qualsiasi contenuto Joomla.

Il plugin, oltre a risolvere il problema della validazione del codice, ovvia anche agli inconvenienti dovuti ad eventuali filtri dei tag html impostati nell'editor, è semplice da utilizzare e consente le stesse opzioni di personalizzazione del codice che sono disponibili sul sito di YouTube.

Plugin con questo tipo di funzionalità ne esistono già e alcuni consentono di inserire video da fonti diverse da YouTube. Se però tutti i video che vi interessa includere nel vostro sito sono su YouTube, questa può essere una soluzione più 'leggera' rispetto a plugin molto più complessi.

Il plugin è scritto per Joomla 1.5 (e versioni successive) in modalità nativa, quindi non serve attivare Legacy Mode. La licenza è open source e questo è il link da cui potete scaricare il pacchetto di installazione: QTube.

Il sito come potrete vedere non è il solito: mi sembrava strano continuare a parlare di Joomla senza avere un sito personale realizzato con questo cms, per cui l'ho fatto, o meglio iniziato, in quanto l'unica cosa che ci trovate per ora è il plugin in questione. Altro è in cantiere, non solo relativo a Joomla, ma si avrà modo di parlarne.

Se trovate errori o problemi d'uso lasciate un commento.