A Ovest Di Paperino

Welcome to the dark side.

Commenti

[pippone semi-tecnico che un giorno ospiterò su un altro blog]

I commenti sono la parte più delicata ed importante di un blog. Importante perché un blog senza commenti è come il sale senza la pasta; delicata perché si può finire vittima di attacchi XSS: non che per me sia importante, ma visto che ho colto l’occasione per imparare a sviluppare un CMS quasi da zero tanto vale cercare di essere quanto più diligente possibile.

Nelle passate due settimane ho speso un sacco di tempo nel cercare una soluzione bilanciata per l’editing dei commenti: mi sono sempre meravigliato perché piattaforme di blogging importanti anche come Wordpress non supportassero l’editing in modalità Rich Text in maniera nativa anche se supportano un set limitato di tag HTML in maniera egregia. Pensavo, a dir la verità in maniera piuttosto naive, che bastasse includere un JavaScript (TinyMCE, FCKEditor o qualsiasi altro) per rendere la textarea magicamente user friedly. Fino a quando non ho provato l’esperimento in maniera diretta. Lo scopo di tutto questo spremermi di meningi era volto non solo nel rendere il sistema di commenti pratico e semplice, ma anche ridurre al minimo i miei interventi di post-editing necessari per un tag non chiuso o una sostituzione andata a male (:) –> ).

Un commento dal momento in cui viene premuto il tasto pubblica, al momento in cui viene “rivisualizzato indietro” subisce così tanti passaggi che alla fine la questione cresce di complessità in maniera geometrica: supporto degli smiley, supporto della creazione/accorciamento automatico dei link, supporto per alcuni tag (grassetto, corsivo, sottolineato e barrato; citazione e link), lettere accentate, varie ed eventuali.

Pensare che un search/replace/regex possa sistemare tutto tutto tutto si è dimostrato totalmente scorretto. Ad esempio l’accorciamento delle URL va fatto nel testo “normale” ma non all’interno di <A href>; la sostituzione degli smiley va fatta fuori dai tag; i tag invalidi vanno eliminati anziché essere HTML-codificati.

In seguito mi è venuto anche il pallino di rendere l’editor RichText configurabile come opzionale e supportare quello che io chiamo il semi HTML, ovvero l’ibrido tra HTML e plain text che quasi tutte le piattaforme supportano. Esempio:

Se l’input è HTML full il seguente HTML <b> &amp; </b> deve essere la rappresentazione di ciò che va renderizzato come &; se l’input è in semi HTML lo stesso diventa la rappresentazione di &amp; i line break (\r\n) vanno convertiti in <p> e <br/>, ecc. Ovvero tutto quello che c’è all’interno dei tag HTML va considerato plain text e come tale va passato attraverso un bel HTMLEncode/LineBrake.Convert. Ho considerato che tale pallino avesse costo limitato in quanto questo era esattamente il modo in cui operava la TextArea prima del lifting. Visto che c’ero ho voluto pure fare in modo che il backend fosse aware se il plugin Javascript fosse stato lanciato con successo o meno (JS magari disabilitato o altro): se il plugin non risulta inizializzato il backend tratterà l’input come semi-HTML anziché HTML full.

Infine ho anche cercato di evitare che il copia-incolla desse la falsa illusione di supportare anche tag non supportati, tipo le immagini. Il primo tentativo è stato quello di abilitare il cut-paste in modalità plain-text only. Con FCKEditor la cosa è supportata out-of-the-box, con TinyMCE ho dovuto fare qualche giro di troppo alla fine mi sono arreso.

Nel provare TinyMCE e FCKEditor mi sono reso conto dei limiti dell’uno e dell’altro. FCKEditor – prima che mi si accendesse la lampadina del distinguere completamente il semi-HTML dall’HTML full – era stato problematico per la sua estrema fedeltà all’HTML. Se si digitano due spazi consecutivi il secondo verrà giustamente e automaticamente convertito in &nbsp;. E questo creava non pochi grattacapi nella gestione degli smiley (o delle URL) che per essere interpretati correttamente hanno bisogno di essere “staccati” dal testo tramite uno spazio o equivalente (inizio riga, fine riga). TinyMCE invece mi ha dato non pochi problemi con il cut&paste, ma in compenso è stato abbastanza semplice fare in modo che prima di “pubblica” l’editor ci prefissasse una stringa nota per segnalare al backend che il JS era stato inizializzato correttamente. Tornando ad FCKEditor ho avuto molte difficoltà nell’editare il contenuto del testo e alla fine ho cercato una soluzione altrettanto pratica.

Alla fine il risultato è sintetizzabile nei seguenti passaggi:

  • filtrare tutti i tag HTML non presenti nella whitelist
  • iterare su tutto il contenuto che non è un tag HTML e fare le sostituzioni del caso (in realtà alcune sostituzioni sono applicabili anche all’interno di alcuni tag)

Questi due compiti non sono così semplici come si può immaginare, basta un esempio più banale per rendersi conto di quanti trabocchetti ci sono per la via. Io mi sono affidato a buona parte del codice di gestione dei commenti di DasBlog, anche se date le drastiche modifiche richieste sono in preda ad una tentazione di refactoring.

Se occorre ampi pezzi di codice C# sono a disposizione. Oltre al classico feedback per critiche, osservazioni, ecc.

Il prossimo post sull’argomento riguarderà i pericoli intrinseci del fare caching dei risultati.

-quack