June09

Templating con javascript

Da sviluppatore (anche) JavaScript, una dei compiti che odio fare riguarda la definizione di template per l'inserimento in pagina di contenuti ottenuti successivamente rispetto al download della stessa grazie ad una richiesta AJAX a file JSON o XML. Odio fare questa attività perchè spesso viene realizzata con script incasinati che mischiano stringhe contenenti puro HTML a variabili contenenti dati. Un esempio di questo brutto approccio potrebbe essere:
var html = "<h1>"+data.title+"</h1>"
html += "<ul>"
for(var i=0; i<data.items.length; i++) {
    html += "<li><a href='supplies/"+data.items[i]+"'>"
    html += data.items[i]+"</a></li>"
}
html += "</ul>"
Non è per nulla un bel modo di lavorare giusto?

Per questo motivo credo che una bella analisi delle librerie presenti sul web che si occupano appunto di migliorare questo compito non può che far bene.

La prima libreria della quale parlerò è EJS (Embedded JavaScript embeddedjs.com) che sfrutta la sintassi di ERB (templating system per ruby). L'approccio di EJS è quello di utilizzare un file esterno che viene richiamato via AJAX per il template e che viene popolato a partire da un JSON (locale o scaricato a sua volta da remoto). L'aspetto della suddivisione delle componenti (grafica + dati) è sicuramente un aspetto positivo, ma personalmente non mi piace troppo è la necessità di effettuare richieste aggiuntive (anche se ottimamente cachate dalla libreria) per i vari template.

La seconda libreria analizzata si chiama JavaScriptTemplates (code.google.com/JavaScriptTemplates) ed è un modulo (comunque indipendente) di un framework MVC di nome TrimPath. Rispetto alla precedente, questa incapsula i template nella pagina dell'applicazione limitando quindi le richieste AJAX ai dati richiesti. I template possono essere inseriti nella pagina in due modi diversi. Il primo, forse più comodo ma un po' troppo invasivo nel markup, è quello di creare delle <textarea/> nascoste contenenti appunto il frammento HTML da popolare successivamente. Il secondo approccio, più pulito ma anche scomodo, è quello di utilizzare delle stringhe JavaScript che verranno compilate in HTML partendo sempre da un JSON contenendo il modello di dati da mostrare all'utente.

Oltre a queste librerie ne esistono altre, anche sviluppate sulla base di engine popolari come jQuery o MooTools, ma il loro comportamento può essere ricondotto a una di questi due approcci, ovvero l'utilizzo di file esterni con una richiesta AJAX in più per template oppure l'inserimento del template in pagina tramite <textarea/> o variabili JavaScript.

Nessuno dei due approcci mi appassiona molto tant'è che non riesco a eleggerne uno come migliore.

| 0 Comments/Trackbacks

May19

Upload di file con ajax

Uno dei difetti dei metodi comunicativi basati sulla tecnica AJAX è l'impossibilità di inviare file al server tramite JavaScript. Questa è una limitazione è imposta dalle policy di sicurezza relative alla sandbox all'interno della quale sono eseguiti gli script. Per ovviare a questo limite è disponibile un approccio che, grazie all'utilizzo di IFRAME facenti capo allo stesso dominio della pagina, permettono di effettuare upload di file senza ricaricare la pagina principale. L'implementazione di questo concetto nonostante possa sembrare abbastanza contorto, può essere riassunto in pochi punti:
  1. Inserire nell'html della pagina un elemento <form> contentente almeno un <input> di tipo file
  2. Inserire nell'html della pagina un <iframe> nascosto referenziato univocamente tramite id
  3. Valorizzare l'attributo target dell'elemento <form> creato in precedenza con l'id dell'<iframe>
In questo modo il submit della form sarà effettuato non nella pagina principale, ma nel <iframe> nascosto che accoglierà il risultato della chiamata HTTP senza però effettuare un redirect dalla pagina originale. Questa tecnica, fino a qua comunque funzionante, può essere ancora migliorata tramite alcune funzioni JavaScript che renderanno migliore l'usabilità della form. Innanzitutto grazie all'evento [i]onsubmit[/i] dell'oggetto <form> è possibile modificare il comportamento della pagina nel momento in cui l'utente preme sul tasto di invio dati, magari mostrando un indicatore dinamico di caricamento (la classica loading.gif). Assegnando un'ulteriore funzione all'evento [i]onload[/i] dell'oggetto <iframe> sarà inoltre possibile controllare quando il server avrà inviato la risposta relativa alla richiesta di upload. Ecco un breve esempio del funzionamento:
<form action="upload" method="post" target="iframe_01">
  <input type="file" name="upload_filename"/>
</form>
<iframe src="#" style="height: 0px; width: 0px; border-width: 0px" id="iframe_01" name="iframe_01">
</iframe>
$("form").bind("submit", function() {
  alert("Invio il file");
});
$("iframe").bind("load", function() {
  alert("File caricato con successo!");
});
E che nessuno dica che ajax è difficile!!

JavascriptWork | 0 Comments/Trackbacks

May06

I link-types e l'attributo rel

Oggi ho letto un interessante articolo riguardo al prossimo standard HTML 5 e vorrei riproporlo, sintetizzato, su queste pagine.
L'articolo riguardava l'attributo rel disponibile per i tag <link>, <a> e <area> e il concetto di link-types.
Questa precisazione serve a definire dal punto di vista semantico il perchè stiamo mettendo in relazione con la pagina corrente. Questo perchè viene rappresentato grazie appunto all'attributo rel.
Da un punto di vista generale i link-types possono essere catalogati in due macro-gruppi: i link a risorse esterne da includere nella pagina corrente (css, favicon) e i link che puntano verso un altro documento.
Entrando nello specifico invece, per adesso sono state definiti ben 18 valori possibili per l'attributo rel.

Analizziamoli brevemente:

  • rel=alternate: permette di proporre all'utente una pagina alternativa che presenta in qualche modo gli stessi contenuti della pagina corrente
  • rel=archives: permette di relazionare alla pagina un archivio di documenti, immagini, records disponibili per essere scaricato
  • rel=author: permettere di referenziare il realizzatore della pagina corrente (può essere utilizzato anche per un link del tipo mailto)
  • rel=external: definisce un collegamento come esterno alla pagina corrente e in nessun modo imputabile al realizzatore della pagina (viene spesso utilizzato da WordPress per i link all'interno di commenti scritti da visitatori)
  • rel=feed: relaziona un feed rss o atom alla pagina corrente
  • rel=first, last, prev, next, and up: permettono di relazionare la pagina corrente con altre pagine dello stesso tipo in una sorta di paginazione o di gerarchia
  • rel=icon: assegna alla pagina corrente un'icona (la famosa favicon)
  • rel=license: permette di impostare una particolare licenza ai contenuti presenti nella pagina
  • rel=nofollow: indica che il link non è stato inserito intenzionalmente dall'autore della pagina ma deriva da azioni commerciali come per esempio banner o adv di vario genere (grazie a questo attributo gli spider non gestiscono il link per il calcolo del PageRank)
  • rel=noreferrer: indica allo user-agent di non comunicare il referrer quando scarica il documento relazionato
  • rel=prefetch: forza lo user-agent a ottenere la risorsa in anticipo prima dell'effettiva richiesta dell'utente per velocizzare poi la navigazione
  • rel=search: indica che il documento relazionato permette di effettuare ricerche relative alla pagina corrente
  • rel=sidebar: indica che il documento relazionato dovrebbe essere aperto in un contesto differente dalla finestra principale (per esempio in una sidebar)
  • rel=tag: permette di relazionare altre pagine "taggate" come la pagina corrente
Nonostante questa distizione potrebbe sembrare fin troppo precisa e ridondante, credo invece che sia un ottimo punto di partenza per arrivare ad un vero web semantico dove non solo il contenuto di un documento sia auto-esplicativo, ma lo siano anche i link tra esso e le altre risorse.
Questa specificazione sembrerebbe essere quella ufficiale, ma questo non è ancora certo in quanto le specifiche HTML 5 sono tutt'ora in fase di sviluppo.

Web Standard | 0 Comments/Trackbacks

May03

Aggiornamento per jQuery.callback

Ho aggiornato il plugin jQuery.callback inserendo la possibilità di sovrascrivere completamente i parametri di default della callback utilizzando unicamente quelli definiti dallo sviluppatore. La versione corrente è la 1.1 ed è completamente retrocompatibile con la precedente. Il plugin è hostato presso Google Code.

Javascript | 2 Comments/Trackbacks

April28

I context processor

I context processor rappresentano in Django quello che sono i listener nello stack J2EE. Grazie ad essi è possibile popolare l'oggetto context utilizzato per il rendering delle varie pagine. I context processor vengono utilizzati per rendere disponibili alcune variabili ai template senza doverlo ripetere per ciascuna view. Dal punto di vista implementativo essi non sono nient'altro che particolari metodi che accettano come parametro l'oggetto request e ritornano una mappa di valori che verranno "appesi" al contesto.
Il framework presenta di default 5 processor; essi sono:
  • django.core.context_processors.auth definisce tre variabili utilizzate per modificare la pagina in base allo stato dell'utente corrente: user rappresenta un istanza dell'utente correntemente loggato, messages contiene un elenco di messaggi destinati all'utente corrente e perms rappresenta un istanza dell'oggetto PermWrapper che permette di identificare i permessi;
  • django.core.context_processors.debug permette di effettuare debug direttamente dal livello template. Definisce le variabili debug, un booleano che identifica se è attivato o meno il debug per la sessione corrente e sql_queries che contiene la lista delle query effettuate per generare la pagina;
  • django.core.context_processors.i18n facilita l'internazionalizzazione dei template includendo LANGUAGES e LANGUAGE_CODE come definiti all'interno di settings.py;
  • django.core.context_processors.media permette di avere un riferimento alla cartella contentente i file media includendo la variabile MEDIA_URL;
  • django.core.context_processors.request permette di avere un riferimento alla richiesta corrente includendo la variabile request. Rispetto ai precedenti processor, questo non è attivato di default.
Ovviamente oltre a queste funzioni già presenti nel framework è possibile definirne di proprie in base alle proprie esigenze. Per farlo basta definire una funzione che accetti l'oggetto request come parametro e ritorni un dizionario di valori e inserire il riferimento ad essa all'interno della variabile TEMPLATE_CONTEXT_PROCESSORS.

Django | 0 Comments/Trackbacks