<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns="http://purl.org/rss/1.0/">




    



<channel rdf:about="http://blog.redturtle.it/prodotti-plone/RSS">
  <title>Prodotti Plone</title>
  <link>http://blog.redturtle.it</link>

  <description>
    
      
    
  </description>

  

  
            <syn:updatePeriod>daily</syn:updatePeriod>
            <syn:updateFrequency>1</syn:updateFrequency>
            <syn:updateBase>2012-05-08T16:02:35Z</syn:updateBase>
        

  

  <image rdf:resource="http://blog.redturtle.it/logo.png"/>

  <items>
    <rdf:Seq>
      
        <rdf:li rdf:resource="http://blog.redturtle.it/frontend-frameworks-interfacce-utente"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/come-gestire-l-iscrizione-alle-notifiche-di-un-sito-con-le-rule-di-plone"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/analisi-modifica-come-plone-genera-link-file-pt2"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/analisi-modifica-come-plone-genera-link-file-pt1"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/plog-2013-due-giorni-al-plone-open-garden-tra-idee-e-nuove-sfide"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/rt.atmigrator-pensioniamo-vecchi-tipi-con-un-click"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/quando-la-sicurezza-in-plone-e-importante-reindexobjectsecurity"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/salva-compilazione-form-contenuti-Plone-uwosh-pfg-d2c"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/come-utilizzare-online-id-login-plone"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/plone-i-bizzarri-comportamenti-di-tinymce-e-chrome"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/datatable.js-tabelle-per-tutti-i-gusti"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/wildcard-foldercontents-plugin-cartelle-plone"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/internazionalizzazione-javascript-plone"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/sviluppare-applicazioni-plone-interfaccia-web-plomino"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/gestire-la-modulistica-con-plone-parte-2"/>
      
    </rdf:Seq>
  </items>

</channel>


  <item rdf:about="http://blog.redturtle.it/frontend-frameworks-interfacce-utente">
    <title>Front-end frameworks, presente e futuro delle interfacce utente</title>
    <link>http://blog.redturtle.it/frontend-frameworks-interfacce-utente</link>
    <description>Una breve introduzione a questi nuovi strumenti per il web design agile e alla loro integrazione con il nostro amato cms Plone</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<blockquote class="pullquote">Spend your time innovating, not replicating (cit. Blueprint framework)<br /></blockquote>
<p>Per chiarire cosa sia il front-end development si potrebbe usare una <strong>metafora automobilistica</strong> (come nella migliore tradizione dei venditori): costruire una web app è come costruire una macchina, il front-end developer è chi si occupa di montare i sedili in pelle, le finiture in radica, il volante, i pedali ecc., mentre il back-end developer è chi si occupa di montare il motore, i freni e la trasmissione. Quindi il <strong>front-end development è tutta la parte di sviluppo che, una volta piazzati i componenti strutturali, si occupa di rendere il prodotto davvero utilizzabile e più confortevole</strong>.</p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p>Il front-end development coinvolge principalmente 3 tecnologie: <strong>html</strong>, <strong>css</strong> e <strong>javascript</strong>. Negli anni queste tre tecnologie hanno mostrato i loro difetti: l'html e il javascript sono vecchi e "brutti" e, anche se il css non è brutto di per sé, è totalmente anti-DRY (don't repeat yourself!). Per contro, il web di oggi impone <strong>design ogni giorno più complessi</strong> e richiede la <strong>compatibilità non solo con tutti i possibili browser, ma anche con un numero sempre maggiore di dispositivi hardware</strong> come smartphone, tablet, desktop, ecc.</p>
<p>Per affrontare queste nuove sfide, il front-end design ha fatto balzi in avanti come pochi altri rami dell'informatica ed è nata una miriade di nuovi strumenti, come appunto i front-end framework. Oggi non si parla più solo di fogli di stile css "artigianali" e di qualche pezzo di codice javascript qua e là, ma di veri e propri framework per il design di user interface sempre più accattivanti.<br />Alcuni di questi framework si limitano a fornire le fondamenta, come ad esempio Skeleton, mentre altri arrivano a coprire ogni aspetto di un'interfaccia utente come ad esempio Bootstrap.</p>
<h2>Pro e contro dei framework</h2>
<p>Come sempre sulle scelte tecnologiche, sul web si aprono crociate e contro-crociate (certa gente ha troppo tempo libero) quindi ecco la mia <strong>personale e per niente esaustiva lista di pro e contro</strong> all'utilizzo dei front-end frameworks.</p>
<p>Contro:</p>
<ul>
<li>codice non scritto da noi, quindi bisogna imparare a conoscerlo</li>
<li>rischio di design simili fra loro (ormai i siti "bootstrap" si riconoscono a colpo d'occhio)</li>
<li>si rischia di aggiungere un nuovo livello di complessità e astrazione.</li>
</ul>
<p>Pro:</p>
<ul>
<li>design più veloce e agile, non c'è bisogno di partire da zero</li>
<li>la web app è già pronta per il mobile</li>
<li>l'organizzazione dei file e del codice è ben studiata e "ingegnerizzata".</li>
</ul>
<h2>Frameworks a confronto</h2>
<p>Dei tanti front-end framework disponibili ho deciso di portare i due esempi di maggior successo con due brevi schede tecniche: Bootstrap by Twitter e Foundation by Zurb.</p>
<h3><i><strong>Twitter Bootstrap</strong></i></h3>
<p><i>Sleek, intuitive, and powerful front-end framework for faster and easier web development.</i></p>
<p><img src="http://blog.redturtle.it/uploads/bootstrap.jpg/@@images/2317e08f-bc8a-4b13-a372-a84020da0067.jpeg" alt="Twitter Bootstrap" class="image-inline" title="Twitter Bootstrap" /></p>
<p> </p>
<p>- sviluppato da: <strong>Twitter</strong><br />- primo rilascio: <strong>Agosto 2011</strong><br />- licenza: <strong>Apache v2.0</strong><br />- supportato da tutti i maggiori browser (IE&gt;7)<br />- scritto in <strong>less</strong> (the dynamic stylesheet language)<br />- supporto al mobile: <strong>desktop, tablet e smartphone</strong><br />- Il <strong>progetto più popolare su github.</strong></p>
<h3><i><strong>Zurb Foundation</strong></i></h3>
<p><i>The most advanced responsive front-end framework in the world.</i></p>
<p><strong><img src="http://blog.redturtle.it/uploads/foundationframework.jpg/@@images/73c2c0ee-5f1c-4cb3-95d2-25473ca5020f.jpeg" alt="Foundation framework" class="image-inline" title="Foundation framework" /></strong><br />- sviluppato da: <strong>Zurb</strong>, azienda attiva nel web design<br />- primo rilascio: <strong>Settembre 2011</strong><br />- licenza: <strong>MIT Licence</strong><br />- scritto in <strong>sass</strong><br />- <strong>16esimo progetto più popolare su github</strong><br />- supporto al mobile: <strong>desktop, tablet e smartphone.</strong></p>
<p>Per un confronto più puntuale sulle caratteristiche, consiglio queste due ottime fonti:</p>
<ul>
<li><a class="external-link" href="http://responsive.vermilion.com/compare.php">http://responsive.vermilion.com/compare.php</a></li>
<li><a class="external-link" href="http://usablica.github.io/front-end-frameworks/compare.html">http://usablica.github.io/front-end-frameworks/compare.html</a></li>
</ul>
<h2><strong>And the winner is...?</strong></h2>
<p>Tra i tanti framework open source disponibili, la mia scelta è al momento per <strong>Twitter Bootstrap</strong> per l'eccellente qualità e la quantità di features, e secondariamente per un fenomeno detto <a class="external-link" href="http://it.wikipedia.org/wiki/Economie_di_rete">esternalità di rete</a>.</p>
<h2>Integrazioni con Plone</h2>
<p>Vediamo ora come la comunità Plone ha integrato questi front-end framework (per ora solo Bootstrap) nel nostro cms.</p>
<p><strong>plonetheme.bootstrap</strong>:</p>
<p>Questo prodotto è un tema "vecchio stile" iniziato da <span>Nathan van Gheem e Mikel Larreategi. L'approccio di questo tema è quello di riscrivere molti template di Plone per aderire alle specifiche di Bootstrap. L'effetto, come potete vedere dall'immagine, è notevole e l'integrazione è quasi perfetta. L'unico dubbio che rimane è sulla velocità di customizzazione di questa soluzione.<br /></span></p>
<ul>
<li><a class="external-link" href="http://pypi.python.org/pypi/plonetheme.bootstrap">http://pypi.python.org/pypi/plonetheme.bootstrap</a></li>
<li><a class="external-link" href="http://github.com/collective/plonetheme.bootstrap">http://github.com/collective/plonetheme.bootstrap</a></li>
</ul>
<p> </p>
<p><img src="http://blog.redturtle.it/uploads/pbootstrap.png/@@images/006e1906-0f6a-41ce-9a89-48bb3bae52b1.png" alt="plonetheme.bootstrap" class="image-inline" title="plonetheme.bootstrap" /></p>
<p><strong>diazotheme.bootstrap</strong>:</p>
<p>Un'altra ottima integrazione di Bootstrap in Plone è fatta da Izhar Firdaus di Inigo Consulting. Questo tema è basato sulla nuova tecnologia per la scrittura dei temi di Plone, cioè Diazo. L'integrazione del framework è per forza di cose meno spinta della soluzione precedente, ma l'effetto finale è comunque notevole. Al contrario del precedente tema, qui non ci sono dubbi sulla velocità di customizzazione che è sicuramente più agile.</p>
<ul>
<li><a class="external-link" href="http://plone.org/products/diazotheme.bootstrap">http://plone.org/products/diazotheme.bootstrap</a></li>
<li><a class="external-link" href="http://github.com/kagesenshi/diazotheme.bootstrap">http://github.com/kagesenshi/diazotheme.bootstrap</a></li>
</ul>
<p><img src="http://blog.redturtle.it/uploads/dbootstrap.png/@@images/eb83ffad-67a7-47be-9d45-a8e06c3463c7.png" alt="diazotheme.bootstrap" class="image-inline" title="diazotheme.bootstrap" /></p>
<h2><i>"This is the end..."</i> ♫</h2>
<blockquote class="pullquote">Hold your hats and stay tuned!</blockquote>
<p>Nonostante il primo prodotto abbia un ottimo livello qualitativo, la mia scelta al momento va sul secondo per la maggiore agiltià e facilità di customizzazione. In ottica futura questa soluzione permetterà anche a designer agnostici di Plone di entrare nei progetti con pochissimo overhead e di trovarsi a loro agio con gli strumenti che già utilizzano (ad es. Node.js + Plone mockups + bootstrap). Ma di questo parleremo più approfonditamente nelle prossime puntate.</p>
<ul>
</ul>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Giacomo Spettoli</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>front-end</dc:subject>
    
    
      <dc:subject>web</dc:subject>
    
    
      <dc:subject>twitter</dc:subject>
    
    
      <dc:subject>bootstrap</dc:subject>
    
    
      <dc:subject>HTML5</dc:subject>
    
    
      <dc:subject>Diazo</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>css</dc:subject>
    
    <dc:date>2013-06-04T09:15:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/come-gestire-l-iscrizione-alle-notifiche-di-un-sito-con-le-rule-di-plone">
    <title>Come gestire l'iscrizione alle notifiche di un sito con le rule di Plone</title>
    <link>http://blog.redturtle.it/come-gestire-l-iscrizione-alle-notifiche-di-un-sito-con-le-rule-di-plone</link>
    <description>E' possibile permettere agli utenti di restare sempre informati sulle novità di un sito? Certo, con le contentrules e l'invio delle notifiche via mail</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Lo ammetto, quando si avvicina il momento di scrivere un nuovo post del blog mi sembra sempre di non avere argomenti interessanti o di approfondire argomenti già raccontati (vedi i miei <a href="http://blog.redturtle.it/content-type-products-contentmigration" class="internal-link">innumerevoli</a> <a href="http://blog.redturtle.it/migrazione-plone-4-tips-and-tricks" class="internal-link">post</a> sulle <a href="http://blog.redturtle.it/rt.atmigrator-pensioniamo-vecchi-tipi-con-un-click" class="internal-link">migrazioni</a>, per esempio).</p>
<p>Poi, però, capita che un paio di giorni prima della scadenza (argomento già trattato da Ale in un <a href="http://blog.redturtle.it/mi-piacciono-le-bagigie" class="internal-link">post precedente</a>) arrivi una richiesta di un cliente che mi accende la lampadina e mi da il <strong>LA</strong> per scrivere il mio prossimo articolo.</p>
<p>Il caso di studio che vi racconto è partito da una semplice richiesta:</p>
<p class="callout">Sarebbe possibile permettere agli utenti del sito di rimanere sempre aggiornati con i nuovi contenuti del sito?</p>
<blockquote class="pullquote">Usiamo le contenrules! Un gioco da ragazzi!</blockquote>
<a name="anchor-breaktext"></a><div class="breakText">Il mio primo pensiero è andato subito alle <strong>regole</strong>: una funzionalità nativa di Plone che permette di definire una (o più di una) certa azione da fare al verificarsi di un (o più di uno) determinato evento. Per esempio, in questo caso mi sarebbe bastato creare una regola che si attivava alla creazione di determinati contenuti, e come azione inizialmente pensavo di spedire una mail agli utenti utilizzando <a class="external-link" href="https://pypi.python.org/pypi/collective.contentrules.mailtogroup">collective.contentrules.mailtogroup</a> per gestire la lista di indirizzi. Non c'era da sviluppare nulla di nuovo e in due minuti impostavo il tutto. Più facile di così, si muore.</div>
<p><img src="http://blog.redturtle.it/topic_images/data.jpg/@@images/dfaa0819-f5fb-4bd7-812f-a87c3f1fc3a8.jpeg" alt="" class="image-right" title="" /></p>
<p>Ma la domanda nascondeva qualche trabocchetto (o come direbbe Data, un tracobbetto): infatti gli "<i>utenti</i>" potevano anche essere utenti <i>anonimi</i>, e gli utenti stessi dovevano potersi iscrivere liberamente alle notifiche, senza passare per un gestore intermedio (ingenuamente mi ero illuso di poter creare un form di richiesta con <a class="external-link" href="https://pypi.python.org/pypi/Products.PloneFormGen">Products.PloneFormGen</a> in modo che poi i gestori potessero raccogliere le iscrizioni e gestire le liste di notifiche direttamente nella regola).</p>
<p>A questo punto, dopo alcune ricerche, era chiaro che nessuno dei prodotti disponibili faceva al caso mio.<br />Dovevo quindi studiare un modo per soddisfare questa richiesta e donare alla comunità un nuova utile funzionalità. Per questo è nato <strong>collective.contentrules.subscription</strong>.</p>
<p>E' un prodotto molto semplice che ha due componenti principali: una nuova azione per le regole e un tool che memorizza le varie sottoscrizioni.</p>
<p>Nell'azione da associare alle regole si possono inserire il soggetto e il testo della mail che verrà poi spedita, e quando viene scatenata questa azione, la lista di email a cui spedire la notifica è presa interrogando il tool e recuperando la lista di indirizzi a lei associata.</p>
<p>Lato utente, è presente una vista che mostra tutte le possibili regole disponibili (ovviamente solo quelle che hanno la nostra nuova azione impostata), da cui può scegliere a quali iscriversi. E' previsto anche un controllo di prevenzione per lo spam sfruttando <a class="external-link" href="https://pypi.python.org/pypi/collective.z3cform.norobots">collective.z3cform.norobots</a>.</p>
<p><img src="http://blog.redturtle.it/topic_images/iscrizione_rules.png" alt="Iscrizione notifiche" class="image-inline" title="Iscrizione notifiche" /></p>
<p>Esiste poi anche un pannello di controllo per i gestori del sito, che permette di avere una panoramica sullo stato delle iscrizioni ed eventualmente intervenire per rimuoverne.</p>
<p><img src="http://blog.redturtle.it/topic_images/controlpanel_rules.png/@@images/be49399f-16c3-43fd-9e15-7a55c802dbe1.png" alt="Controlpanel rules" class="image-inline" title="Controlpanel rules" /></p>
<p>Il tutto ovviamente è versionato e disponibile su <a class="external-link" href="https://github.com/RedTurtle/collective.contentrules.subscription">github</a>, quindi se vi piace l'idea e volete contribuire a migliorarlo, siete i benvenuti :)</p>
<p><br />Questa è una versione di partenza e mancano diverse funzionalità utili che potrebbero essere introdotte nelle prossime versioni, come per esempio la possibilità da parte degli utenti di visualizzare le proprie iscrizioni ed eventualmente cancellarsi, e anche un maggior livello di sicurezza nella gestione delle sottoscrizioni (ad esempio con un passaggio di validazione e conferma dell'indirizzo inserito).</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Cecchi</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>python</dc:subject>
    
    
      <dc:subject>mail</dc:subject>
    
    
      <dc:subject>products</dc:subject>
    
    
      <dc:subject>release</dc:subject>
    
    <dc:date>2013-05-09T12:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/analisi-modifica-come-plone-genera-link-file-pt2">
    <title>Analisi (e modifica) di come Plone genera link ai File - seconda parte</title>
    <link>http://blog.redturtle.it/analisi-modifica-come-plone-genera-link-file-pt2</link>
    <description>Continua il viaggio e l'analisi dei prodotti per rendere Plone compatibile con software di statistiche</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Nella <a class="external-link" href="http://blog.redturtle.it/2013/05/03/analisi-modifica-come-plone-genera-link-file-pt1">prima parte dell'articolo</a> abbiamo risolto solo una parte del problema per rendere gli URL di Plone più "parlanti".</p>
<p>Vediamo ora come affrontare i problemi restanti.</p>
<h2>Fase 2: come trattare il pregresso</h2>
<p>Infatti è solo ora che le cose si fanno interessanti...</p>
<p>Ci siamo trovati di fronte a un grosso problema: come "bonificare" la situazione creatasi negli anni precedenti alle modifiche sopra descritte?</p>
<p>Sarebbe stato possibile scrivere una procedura automatica che sistemasse automaticamente tutti i link generati tramite TinyMCE dalla forma canonica alla forma di download modificata?<br />La risposta per noi è stata "forse... ma meglio di no". Si parlava di centinaia (migliaia) di link, per decine di siti Plone.</p>
<p>L'eventualità di eseguire qualcosa senza un intervento umano era a dir poco terrificante, col rischio di trovare contenuti rovinati dall'operazione dopo mesi.<br />Molto meglio aiutare l'utente a sistemare il problema, cercando per lui i potenziali link da sistemare ma chiedendo conferma dell'operazione: un lavoro di certo più lungo ma che dà la sicurezza del risultato.</p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p>Il primo passo è stato quindi quello di riprendere uno spike, un prodotto mai rilasciato che si occupava di ricerca all'interno del testo Plone usando espressioni regolari, e renderlo qualcosa di utilizzabile da interfaccia Plone: <a class="external-link" href="https://plone.org/products/rt.bulkmodify">rt.bulkmodify</a>.</p>
<p>Il prodotto presenta un'interfaccia Plone che permette di <strong>cercare testo all'interno dei contenuti del sito</strong>. Quando il testo viene trovato, una tabella viene popolata con i risultati.</p>
<p>Visto che questo tipo di operazione richiede il risveglio dei contenuti Plone, il tempo richiesto per completarsi su un sito molto popolato potrebbe essere tanto lungo da mandare in timeout la richiesta, quindi la scelta presa è stata quella di fornire un'<strong>interfaccia JavaScript reattiva, completamente basata su chiamate AJAX</strong>.<br />Se tutta l'operazione dovesse durare anche 20 minuti, questa viene spezzata in tante piccole chiamate che terminano velocemente.</p>
<p>Oltre alla ricerca è poi possibile eseguire la <strong>sostituzione del testo trovato</strong>, sempre sfruttando le espressioni regolari.</p>
<p>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="700" width="100%">
<param name="src" value="uploads/rt.bulkmodify-demo.swf"><embed height="700" width="100%" src="uploads/rt.bulkmodify-demo.swf" type="application/x-shockwave-flash"></embed>
</object>
</p>
<p>C'è un problema: una semplice espressione regolare con sostituzione testuale non può sistemare il problema perché non c'è modo di sapere, senza un'analisi del contenuto Plone, il nome reale del file caricato.</p>
<p>Il prodotto doveva quindi essere <strong>estendibile</strong>, permettendo di lanciare speciali operazioni lato server di sostituzione del testo, per individuare i link interni ai file e trasformarli nella forma voluta. Tutto questo è stato di nuovo inserito nel prodotto specifico del Cliente ma senza tradire l'idea iniziale: sarà una persona in carne e ossa che supervisionerà e deciderà cosa sostituire e cosa no.</p>
<h2>Link a file... esterni!</h2>
<p>L'ultimo pezzo del puzzle riguarda i link tra siti diversi.<br />Il Cliente ha un grande numero di siti Plone che, per fortuna, condividono il 90% dei prodotti installati.</p>
<p>La necessità di sistemare le statistiche era quindi valida anche per link ad altri siti del Cliente.<br />Se quindi un sito nel dominio "http://sub1.vostro-host.com/" conteneva un link a un file in un altro sito "http://sub2.vostro-host.com/", questo link al file avrebbe dovuto rispettare la regola di essere comprensibile al software di raccolta statistiche.</p>
<p>Nel caso di nuovi link, tutto ciò diventa lavoro del redattore: è lui che deve fornire il link corretto per il download (copiandolo dalla vista di downalod del file, che ora monta rer.downloadurl)...</p>
<p>...ma ancora una volta: come sistemare il pregresso??</p>
<p>La soluzione è stata quella di scrivere un nuovo plugin che sfruttasse le caratteristiche di Plone scoperte per capire se i link, anche quando esterni, fossero link a file Plone.</p>
<p>Per fare questo occorre:</p>
<ul>
<li>cercare gli URL nel testo</li>
<li>per ogni URL, tentare di scaricare lo stesso aggiungendovi in fondo "/at_download/file" (se ok: probabilmente è Plone!)</li>
<li>se si ottiene una risposta con un header che identifica il nome reale del file, salvare questo nome</li>
<li>generare l'URL aggiungendovi "/at_download/file" e il nome del file.</li>
</ul>
<p>Il Cliente era interessato a sistemare solo i propri link interni (intesi come: link ad altri siti dell'organizzione) e quindi l'espressione regolare di ricerca è stata limitata agli URL contenenti il nome host corretto, anche perché aprire connessioni a URL esterni a un sito può (ulteriormente) rallentare la procedura.</p>
<h2>Conclusione</h2>
<p>La Storia ha avuto un lieto fine, anche grazie a una serie di prodotti con compiti ben separati.</p>
<p>Ma probabilmente varrebbe la pena sistemare tutto questo direttamente alla fonte: tra i tanti pregi di Plone c'è sempre stato quello di avere gli "URL parlanti", quindi credo valga la pena rendere gli URL ai file già <strong>leggibili dagli HTTP log</strong>.</p>
<p class="callout">Non ha senso (e confonde) avere più modi per accedere alla stessa informazioni in modi "simili".</p>
<p>Che ne dite?</p>
<p><span class="discreet">L'immagine in testata è di <a class="external-link" href="http://www.flickr.com/photos/8741037@N08/">mothemagicdragon</a>.</span></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Fabbri</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>products</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2013-05-07T09:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/analisi-modifica-come-plone-genera-link-file-pt1">
    <title>Analisi (e modifica) di come Plone genera link ai File: una storia vera (parte 1)</title>
    <link>http://blog.redturtle.it/analisi-modifica-come-plone-genera-link-file-pt1</link>
    <description>L'esigenza: rendere i link ai file generati in Plone compatibili con software di statistiche e come una serie di prodotti riutilizzabili abbiamo risolto il problema</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<h2>C'era una volta il File in Plone</h2>
<p>Questa Storia parte da un Cliente non molto contento del modo in cui Plone gestisce i file.<br />Nel caso non lo sappiate, c'è una certa confusione a riguardo.</p>
<p>Se nel vostro sito Plone vi collegate all'indirizzo diretto a un file, nella forma...</p>
<p style="padding-left: 30px; ">http://vostro-host.com/percorso/al/file.pdf</p>
<p>...il file in questione viene "aperto direttamente": gli header inviati da Plone scatenano l'apertura del file "<i>inline</i>", quindi sfruttando eventuali plugin del browser, se presenti.<br />Questo tipo di comportamento ha<strong> problemi di usabilità</strong>: utenti che non capiscono di essere ancora "<i>dentro al browser</i>" potrebbero chiudere il browser pensando che si tratti di un programma esterno. Se l'utente poi vuole scaricare il file dal plugin, deve trovarne la funzione all'interno dello stesso.</p>
<p>Eppure se arrivate allo stesso file dall'interfaccia Plone (dal navigatore del sito, da una delle viste, ...) vi troverete a un URL diverso:</p>
<p style="padding-left: 30px; ">http://vostro-host.com/percorso/al/file.pdf/view</p>
<p>Questo è l'indirizzo della vista del contenuto file (<strong>file_view</strong>) da cui potete vedere alcune informazioni sul file e da dove viene mostrato il link per scaricarlo, che assume invece questa forma:</p>
<p style="padding-left: 30px; ">http://vostro-host.com/percorso/al/file.pdf/at_download/file</p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p><strong>NB</strong>: per alcuni, passare prima dalla vista del contenuto file è solo una perdita di tempo... e un click inutile. Per altri, se il navigatore facesse scaricare direttamente il file (funzionalità semplice da ottenere con Plone), sarebbe inconcepibile: capirete quindi che non esiste una soluzione universale.</p>
<h2>La Storia si complica</h2>
<p>Il <strong>contenuto File</strong> in Plone è uno di quei pochi tipi dove il <strong>campo titolo non è obbligatorio</strong>.</p>
<p>Partendo da Plone 4 (con l'inclusione di <i>plone.app.blob</i> nel core Plone) è stata introdotta un'altra grossa differenza: prima di Plone 4, caricare un file con e senza titolo non aveva differenze sull'URL generato: l'id del file (che determinava anche l'URL) era sempre lo stesso: il nome del file caricato.<br />Con Plone 4 il campo titolo è rimasto opzionale ma, se venisse fornito, questo verrà utilizzato per generare l'id del contenuto (come per tutti gli altri tipo Plone).<br />Se dovessimo quindi caricare lo stesso "<i>file.pdf</i>" con il titolo "<i>Il mio file PDF</i>", otterremmo in realtà questo URL:</p>
<p style="padding-left: 30px; ">http://vostro-host.com/percorso/al/il-mio-file-pdf</p>
<h2>TinyMCE (la Storia diventa un gran caos)</h2>
<p>Avete mai fatto caso <strong>al modo in cui TinyMCE genera link ai file</strong>? Li tratta in modo diverso dagli altri contenuti?<br />No!</p>
<p>Usando il comodo plugin per i link interni, TinyMCE genera un semplice <i>link diretto al file</i>, che per quanto visto sopra è il link che determina l'apertura del file <i>inline</i>.</p>
<p>Vediamo di ricapitolare; la situazione è la seguente:</p>
<ul>
<li>dai navigatori Plone arrivo alla vista dei file ("/view")</li>
<li>da questa vista ho disponibile il link per scaricare il file ("/at_download/file")</li>
<li>usando link generati dall'editor ottengo l'apertura diretta del file <i>inline</i>.</li>
</ul>
<h2>...ed infine le statistiche</h2>
<p>Il colpo di grazia ci viene dato dai <strong>sistemi di statistiche che analizzano i log</strong>. Esistono infatti software che, analizzando i log degli accessi HTTP, sono in grado di individuare se la risorsa scaricata è un file, e di quale tipo.</p>
<p>Il problema di questo approccio è che nel log HTTP non ci sono molte informazioni se non l'URL (questo è un limite universale dell'approccio... Plone e altri CMS non potrebbero fare nulla per evitarlo); per capire quindi se un dato URL si riferisce ad un file PDF, l'unico modo è sperare che l'URL stesso finisca con "<i>.pdf</i>". Nessun header può fare la differenza qui...</p>
<p>Se torniamo ai file di Plone, avrete notato come da quasi nessuno di questi si capisca che si sta per accedere ad un file PDF:</p>
<ul>
<li>http://vostro-host.com/percorso/al/il-mio-file-pdf<br />non finisce con ".pdf"</li>
<li>http://vostro-host.com/percorso/al/il-mio-file-pdf/view<br />non finisce con "<i>.pdf</i>" ma almeno non mente! Non è un link al file, ma solo una vista</li>
<li>http://vostro-host.com/percorso/al/il-mio-file-pdf/at_download/file<br />non finisce con "<i>.pdf</i>"</li>
<li>http://vostro-host.com/percorso/al/file.pdf<br />questo andrebbe bene... peccato che l'unico caso in cui potremmo ottenere questo URL è non fornendo un titolo al file (potreste aggiungere il titolo dopo ma sarebbe troppo scomodo, e dovremmo essere certi che nessuno lo rinomini).</li>
</ul>
<p>Tanto per essere chiari: il Cliente utilizza uno di questi sistemi di statistiche e si è trovato (giustamente) scontento della grande varietà di URL presenti.</p>
<p>Ci è quindi giusta questa richiesta:</p>
<ul>
<li>"niente attivazione di plugin, i file vanno scaricati"</li>
<li>"voglio che gli URL dei file Plone indichino il formato del file".</li>
</ul>
<h2>Fase 1: fermare il problema</h2>
<p>Analizzando la situazione, ci siamo resi conto che il comportamento corretto per scaricare file lo abbiamo solo tramite la chiamata a "<strong>/at_download/file</strong>", che però ha comunque dei problemi:</p>
<ul>
<li>non finisce col nome reale del file</li>
<li>non è utilizzata da TinyMCE.</li>
</ul>
<p>La fortuna ha voluto che il Cliente utilizzasse già da tempo (e con soddisfazione) una variante del plugin dei link a file in Plone: <a class="external-link" href="http://plone.org/products/collective.tinymceplugins.advfilelinks">collective.tinymceplugins.advfilelinks</a>.<br />Se fino ad allora questo plugin si era sempre limitato ad accorgimenti grafici atti ad aumentare l'<strong>usabilità dei link</strong> (in primis: <strong>fornire la dimensione del file che si sta per scaricare</strong>), ora poteva tornarci utile per sistemare una delle funzionalità che TinyMCE non offre: scegliere il <i>tipo</i> di link al file.</p>
<p>Abbiamo quindi rilasciato una nuova versione del prodotto che portasse una nuova funzionalità: poter scegliere se avere un link diretto al file (<i>inline</i>), un link alla vista (<i>preview</i>) del file o un link per scaricare il file - tramite un nuovo menù a tendina.</p>
<p><img src="http://blog.redturtle.it/pypi-images/collective.tinymceplugins.advfilelinks/collective.tinymceplugins.advfilelinks-1.1.0-03.png" /></p>
<p>Per questioni di correttezza verso la comunità che già utilizza questo prodotto non sarebbe stato giusto scegliere un valore di default diverso da quello predefinito di TinyMCE, quindi è stato tenuto come valore predefinito il "<i>link diretto al contenuto</i>".<br />Ma non era nemmeno pensabile che gli utenti del Cliente cambiassero ogni volta quel menù a tendina... è stato quindi usato un prodotto aggiuntivo che "sistemasse" il valore predefinito (funzionalità nativa, prevista dalla nuova versione di <i>collective.tinymceplugins.advfilelinks</i>).</p>
<p>Bene! Ora i link ai file fatti tramite TinyMCE hanno iniziato ad essere link al download reale, tagliando fuori gli eventuali plugin.</p>
<h2>at_download, Quel Permissivo</h2>
<p>Ma rimane il problema cruciale delle statistiche.</p>
<p>Dopo aver eseguito qualche test ci siamo accorti che <strong>la chiamata a "at_download/file" può ricevere altri elementi di percorso senza inficiarne il comportamento</strong>.</p>
<p>La cosa forse è un po' strana, ma richiamando un URL Plone in questo modo...</p>
<p style="padding-left: 30px; ">http://vostro-host.com/percorso/al/il-mio-file-pdf/at_download/file/fasullo.doc</p>
<p>... non ottenete errori: L'URL scatena comunque il download del file (e negli header inviati c'è il vero nome "<i>file.pdf</i>"... non preoccupatevi).<br />Il sistema di statistiche però in questo caso avrebbe (erroneamente) capito che la risorsa scaricata era un file di Word (.doc).</p>
<p>Sfruttando questa "<i>funzionalità</i>" abbiamo reso <i>collective.tinymceplugins.advfilelinks</i> ancora più flessibile, rendendo possibile indicare, tramite un prodotto di terze parti, come generare gli URL nel caso di "<i>URL alla preview</i>" o "<i>URL al download</i>".<br />Nello stesso prodotto di cui sopra è stato quindi cambiato il valore per il download del file da "<i>/at_download/file</i>" a "<i>/at_download/file/nome reale del file</i>".</p>
<p>Infine, la cosa più semplice: cambiare la vista <i>file_view</i> perché mostrasse lo stesso URL di download modificato. Per fare questo è stato rilasciato un micro-pacchetto: <a class="external-link" href="http://plone.org/products/rer.downloadurl">rer.downloadurl</a>.</p>
<p>Ok, missione compiuta: da ora in poi i link ai file saranno amichevoli con il software di statistiche!</p>
<p>... ma i vecchi link?!</p>
<p>Siete curiosi di sapere come finisce? Per ora ho già scritto troppo; per il resto della Storia ci rivediamo martedì prossimo!</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Fabbri</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>products</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2013-05-03T12:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/plog-2013-due-giorni-al-plone-open-garden-tra-idee-e-nuove-sfide">
    <title>Plog 2013, due giorni al Plone Open Garden tra idee e nuove sfide</title>
    <link>http://blog.redturtle.it/plog-2013-due-giorni-al-plone-open-garden-tra-idee-e-nuove-sfide</link>
    <description>Dal 3 al 7 di Aprile si è svolto nella magnifica Sorrento uno degli eventi "must have" italiani su Plone, il Plone Open Garden. Ecco la nostra esperienza</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Come già annunciato nelle ultime news di Plone.it, dal 3 al 7 di Aprile si è svolto nella magnifica <b>Sorrento</b> uno degli eventi "must have" italiani su Plone, il <b>Plone Open Garden</b>. <br />In rappresentanza delle tartarughe, <b>Massimo Azzolini e io</b> siamo arrivati in città il giorno prima dell'inizio ufficiale. Il nostro timore era di essere i soli plonisti in città quella sera, ma appena arrivati in hotel abbiamo avuto la piacevole sorpresa di non essere arrivati tra i primi, bensì tra gli ultimi!</p>
<p>Così l'evento è iniziato già la sera del 2, durante l'aperitivo dell'hotel.</p>
<blockquote class="pullquote">In eventi come il Plog, la comunità Plone mostra le sue qualità migliori: giovialità e socievolezza.</blockquote>
<p>Eventi come il Plog servono anche a stringere nuove amicizie, nuove collaborazioni o semplicemente ritrovare persone che vivono dalla parte opposta del globo e con cui magari si collabora giornalmente a rendere il nostro amato cms sempre più "cool".</p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<h2>Day 1... si aprano le danze!</h2>
<p>Mercoledì 3, di buonora, sono iniziati i lavori dell'evento. Date le condizioni atmosferiche non ottime, tra i partecipanti si è subito diffusa la gag di rinominare l'evento in "<b>Plone Open Hall</b>" o "<b>Plone Open Basement</b>", per la location scelta per i talk.</p>
<p>Ad aprire le danze sono stati due famosi plonisti francesi, Thomas Desvain e Cédric Messiant. <a class="external-link" href="http://www.slideshare.net/ThomasDesvenain/collectivelocal-plog2013-v2">Thomas ha presentato</a> una suite di prodotti molto interessanti per la <b>delega di permessi agli utenti limitatamente ad un certo contesto </b>di un sito Plone. Tra i prodotti presentati spiccano <b>collective.local.adduser</b> per delegare la creazione di utenti locali; <b>collective.local.addgroup</b> per la delega di creazione dei gruppi; infine <b>collective.local.sendto</b> per la delega di invio di email agli utenti. Tutti i prodotti di questa suite sono disponibili su github:<a class="external-link" href="https://github.com/tdesvenain"> https://github.com/tdesvenain</a>.</p>
<p>Il collega <a class="external-link" href="http://www.slideshare.net/cedricmessiant/collectivecontact-plog2013">Cédric ha presentato</a> un'altra suite di <b>prodotti per la gestione di una rete di contatti/esperti all'interno di un'azienda</b>. La soluzione prevede di poter definire dei gruppi, dei ruoli nei gruppi e degli esperti per i ruoli. La metafora usata durante il talk rappresenta i gruppi con i raggruppamenti gerarchici di un esercito (armata, reggimento); i ruoli sono il corrispondente dei gradi dell'esercito (generale, comandante) e gli esperti sono i singoli soldati. La suite di prodotti è disponibile come al solito su github:</p>
<ul>
<li><a class="external-link" href="https://github.com/collective/collective.contact.plonegroup">https://github.com/collective/collective.contact.plonegroup</a></li>
<li><a class="external-link" href="https://github.com/vincentfretin/collective.contact.core">https://github.com/vincentfretin/collective.contact.core</a></li>
<li><a class="external-link" href="https://github.com/vincentfretin/collective.contact.widget">https://github.com/vincentfretin/collective.contact.widget</a>.</li>
</ul>
<p>Dopo i colleghi francesi è stato il turno di quelli olandesi, con <b>Guido Stevens</b> che ha <a class="external-link" href="http://www.slideshare.net/GuidoStevens/plonesocial-roadmap">presentato</a> la sua soluzione social per Plone, <b>PloneSocial</b>. La chiarezza della visione di cosa c'è nel futuro social di Plone ha lasciato molti piacevolmente impressionati. Il cuore del talk, più che l'insieme dei dettagli tecnici, è stata la presentazione di una roadmap per il completamento del social networking in Plone.</p>
<blockquote class="pullquote">Studi di settore hanno dimostrato che le interazioni lavorative di tipo social all'interno di un'azienda aumentano la produttività dei dipendenti del 20-25%!</blockquote>
<p>La suite di prodotti copre per ora le funzionalità di microblogging, activity stream, follow di utenti o di aree di contenuti e aree di team working. Più di un partecipante al talk era interessato a come avesse affrontato il problema delle performance e Guido ha dimostrato che, attraverso ingegnose soluzioni tecniche, è possibile assicurare la scalabilità sia in alto sia in basso del sistema.<br />Dopo una breve pausa, <b>ha preso la parola il nostro Massimo per <a class="external-link" href="http://www.slideshare.net/massimo.azzolini/agile-values-methods-and-software">presentare l'esperienza di RedTurtle</a> nel mondo del software agile, i problemi comuni e le soluzioni aziendali adottate, sia di tipo organizzativo interno sia come strumenti sviluppati, tra cui Penelope</b>. Il nostro approccio e le nostre soluzioni hanno attirato l'interesse e le domande di molti colleghi Plonisti che si trovano ad affrontare tutti i giorni gli stessi problemi.</p>
<h2><img src="http://blog.redturtle.it/uploads/image.jpeg" title="plog2013-banner" height="286" width="224" alt="plog2013-banner" class="image-left" /></h2>
<p>L'ultimo <a class="external-link" href="http://www.slideshare.net/gborelli/plog2013-lets-get-a-better-collectivegeo-and-improve-plone-for-georeferenced-content">talk</a> della mattinata è stato di <b>Giorgio Borelli</b>, collega plonista italiano, che ha raccontato l'ormai noto e apprezzato prodotto Plone per la geolocalizzazione, <b>collective.geo</b> e la sua roadmap per l'evento.</p>
<p>Nel pomeriggio i lavori sono ripresi con degli sprint su vari argomenti. Lo sprint in assoluto più partecipato è stato incentrato su una <b>discussione sullo stato dell'universo dei prodotti Plone e su come migliorarne sempre più la qualità e la tracciabilità</b>. Dalla discussione è nata l'idea di istituire un concorso annuale per i "migliori 50 prodotti di Plone", in modo da sfruttare questa piccola competizione per spingere la comunità a curare sempre più i propri prodotti.</p>
<p>Nel resto del pomeriggio ho partecipato al gruppo della documentazione, mentre Massimo a quello del Marketing. Nel nostro gruppo ci siamo occupati di trascrivere nero su bianco il processo di rilascio di una nuova release di Plone, le persone coinvolte e gli step da seguire. Abbiamo proseguito con la stesura della documentazione sul processo di installazione passo passo di Plone sui più diffusi sistemi operativi.</p>
<h2>Day 2... the show must go on!</h2>
<p>Il secondo giorno di conferenza si è aperto con un talk di <b>Antonio De Marinis dell'Agenzia Europea per l'Ambiente</b> (eea.europa.eu).</p>
<p>Lo scopo del <a class="external-link" href="http://www.slideshare.net/demarant/visualize-open-data-with-plone-da-viz-plog-2013">talk</a> è stato quello di presentare i lavori dell'Agenzia, fare una panoramica su cosa sia l'Open Data e presentare uno prodotti sviluppati, <a class="external-link" href="http://plone.org/products/eea.daviz">eea.daviz</a>. Questo prodotto permette di visualizzare di dati provenienti dai dataset mondiali in forma di grafici. <br />A seguire ha preso la parola l'attuale presidente della Plone Foundation, <b>Paul Roeland</b><b>, </b>che ha fatto un report sullo stato della fondazione, sui progetti aperti e sulle sovvenzioni per l'organizzazione di nuovi eventi. <br />Dopo una breve pausa ha preso la parola <b>Érico Andrei</b> di Simples Consultoria, l'azienda che quest'anno ha ricevuto l'incarico di organizzare l'annuale conferenza mondiale di Plone.</p>
<blockquote class="pullquote">"...siamo qui per farvi vedere come spendiamo i soldi dell'Agenzia, che  in fin dei conti, sono anche i vostri soldi!" (cit. A. De Marinis)</blockquote>
<p>Come da previsioni, il talk è iniziato con un resoconto dello stato dei lavori dell'organizzazione dell'evento e delle location identificate. <b>Dall'entusiasmo mostrato da <span>É</span>rico ci si aspetta che la Plone Conference 2013 sarà un evento da non perdere</b>. Nella seconda parte del suo talk, Andrei è passato a presentare lo stato di avanzamento di un prodotto presentato in anteprima all'ultima PloneConf, <a class="external-link" href="https://github.com/collective/collective.cover">collective.cover.</a> Questo prodotto, molto interessante, ha lo scopo di <b>fornire alle nostre redazioni uno strumento per la costruzione di homepage in maniera facile, veloce e estremamente flessibile</b>. L'idea di base del prodotto non è nuova, esistevano già vari prodotti per questo scopo - come il più vecchio e famoso <a class="external-link" href="http://plone.org/products/collective.portletpage">collective.portletpage</a> -, ma collective.cover sembra un passo avanti per la flessibilità e per l'utilizzo di tecnologie all'avanguardia che entreranno in Plone nelle prossime release.</p>
<p>Nel pomeriggio, come il giorno precedente, sono ripresi gli sprint. Massimo ed io abbiamo continuato a partecipare ai gruppi del giorno precedente. I lavori della documentazione si sono concentrati sulla preparazione di uno script per l'installazione guidata di tutte le dipendenze di Plone. Lo script, grazie a una grafica minimale, guida l'utente nell'altrimenti delicato compito di preparare il sistema ad ospitare Plone. Il gruppo del Marketing si è concentrato invece sull'identificazione della lista di 50 prodotti "consigliati" di Plone.</p>
<h2>Day 3... leaving Sorrento is never easy, I saw the light fading out!</h2>
<p>Il dovere purtroppo non guarda in faccia nessuno. Il terzo giorno, infatti, la sveglia ci ha riportato alla realtà alle 5 am per prendere il treno che da Napoli ci avrebbe riportato a Ferrara. Dopo 7 ore di viaggio siamo tornati alla nostra città, con un carico di <b>nuovi spunti di approfondimento su soluzioni e prodotti basati sul nostro amato cms Plone</b>.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Giacomo Spettoli</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>conference</dc:subject>
    
    
      <dc:subject>eventi</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    
      <dc:subject>community</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2013-04-12T10:20:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/rt.atmigrator-pensioniamo-vecchi-tipi-con-un-click">
    <title>rt.atmigrator: pensioniamo i vecchi tipi con un click</title>
    <link>http://blog.redturtle.it/rt.atmigrator-pensioniamo-vecchi-tipi-con-un-click</link>
    <description>Archetype che non servono più e contenuti da migrare in un altro tipo? Un prodotto ci può aiutare a concedere loro il meritato riposo in modo facile ed intuitivo</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<blockquote class="pullquote">Di cosa potrei parlare? Cosa ho fatto ultimamente di interessante da poter condividere?</blockquote>
<p>Quando sto per scrivere un nuovo post per il blog, il problema è sempre il solito: trovare un argomento interessante da proporre.</p>
<p>Sfortunatamente per voi, la risposta è sempre la stessa: <strong>migrazioni!</strong></p>
<a name="anchor-breaktext"></a><div class="breakText">Ormai le migrazioni sono diventate il mio pane quotidiano. Il lavoro dell'ultimo anno è stato prevalentemente quello di prendere per mano <strong>vecchi e appesantiti portali Plone</strong> e dargli nuova vita <strong>migrandoli alla versione più aggiornata</strong>.</div>
<p>Come già detto in un precedente <a href="http://blog.redturtle.it/content-type-products-contentmigration" class="internal-link">articolo</a>, spesso le migrazioni sono anche il momento ideale in cui fare un'analisi del portale e individuare eventuali <strong>archetypes creati ad hoc</strong> che, col tempo, sono <strong>diventati inutili o addirittura da eliminare</strong>, perché mai utilizzati correttamente.</p>
<p><img src="http://blog.redturtle.it/topic_images/recycle_logo.gif/@@images/dfcdee5f-a6c5-429b-979c-93a4cf9672dd.jpeg" alt="recycle" class="image-right" title="recycle" />Se quei contenuti li vogliamo proprio eliminare, li cancelliamo direttamente dal portale e non ci si pensa più.<br />Discorso diverso, invece, se questi vanno <strong>mantenuti e</strong> magari <strong>"<i>convertiti</i>" in qualcosa di più standard</strong>, come ad esempio i contenuti base di Plone.</p>
<p>Ultimamente ho dovuto pensare proprio a come migrare 4-5 vecchi Archetypes ormai inutilizzati e farli diventare dei tipi base di Plone (Cartelle, Pagine ed Eventi).</p>
<p>La prima idea è stata quella di creare una serie di procedure come descritto nell'articolo di cui parlavo prima, ma poi mi sono chiesto se non esistesse un modo per rendere parametrizzabile questa operazione senza dover scrivere ogni volta 200 metodi uguali.</p>
<p>Visto che la migrazione che mi interessava era molto base e non avevo bisogno di eseguire nessuna operazione intermedia, ho deciso di creare un piccolo prodottino che mi aiutasse: <a class="external-link" href="https://pypi.python.org/pypi/rt.atmigrator">rt.atmigrator</a>.</p>
<p>Si tratta di un pacchetto che <strong>va inserito nel buildout e non ha bisogno di essere installato</strong>.</p>
<p>Fornisce una semplice vista (<i>http://url-del-sito/@@migrate-types</i>) che non fa altro che chiedere all'utente 2 cose:</p>
<ul>
<li>Il <strong>tipo di partenza</strong> (selezionabile tra i tipi aggiungibili nel portale)</li>
<li>Il <strong>tipo di destinazione</strong> (selezionabile tra i tipi aggiungibili nel portale).</li>
</ul>
<p><img src="http://blog.redturtle.it/topic_images/atmigrator.png" alt="atmigrator" class="image-inline" title="atmigrator" /></p>
<p>Una volta confermato, viene lanciato un metodo come quelli già descritti, che esegue la migrazione con <a class="external-link" href="https://pypi.python.org/pypi/Products.contentmigration">Products.contentmigration</a> utilizzando come parametri i 2 tipi impostati nel form.</p>
<p>Completata la migrazione, <strong>nel log c'è una descrizione completa delle operazioni svolte</strong> (ed eventualmente il traceback degli errori) e l'utente viene informato di quanti elementi sono stati aggiornati.</p>
<p>Il prodotto di per sé è molto semplice, dato che esegue una migrazione base da un tipo ad un altro.<br />Nulla vieta però di prevedere, in futuro, anche delle evoluzioni e supportare, ad esempio, una gestione di filtri per determinare i contenuti da migrare (oltre al solo tipo, magari anche un percorso o lo stato di pubblicazione), oppure delle operazioni pre e post migrazione per determinati tipi.</p>
<p>Il sorgente è disponibile su <a class="external-link" href="https://github.com/RedTurtle/rt.atmigrator">github</a>, quindi si può consultare ed eventualmente modificare in un attimo.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Cecchi</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>migration</dc:subject>
    
    
      <dc:subject>Archetypes</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2013-03-20T08:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/quando-la-sicurezza-in-plone-e-importante-reindexobjectsecurity">
    <title>Quando la sicurezza in Plone è importante: reindexObjectSecurity</title>
    <link>http://blog.redturtle.it/quando-la-sicurezza-in-plone-e-importante-reindexobjectsecurity</link>
    <description>Quando gli indici introdotti da prodotti aggiuntivi hanno a che fare con la sicurezza del sito, è meglio prendere alcune precauzioni per evitare problemi</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Per chiunque sviluppi con Plone, diventa presto chiara l'importanza del catalogo e, contemporaneamente, la necessità di <strong>mantenere il catalogo del sito aggiornato</strong>.</p>
<p>L'API principale a cui si fa riferimento per aggiornare lo stato di un contenuto nel catalogo Plone è la chiamata a <strong>reindexObject</strong>:</p>
<pre>&gt;&gt;&gt; context.setTitle('Nuovo titolo')<br />&gt;&gt;&gt; context.reindexObject()<br />&gt;&gt;&gt; context.title()<br />'Nuovo titolo'</pre>
<p>Fin qui, nulla di nuovo.</p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p>In alcuni casi è possibile limitare gli indici aggiornati a un sottoinsieme di quelli esistenti.</p>
<pre>&gt;&gt;&gt; context.setTitle('Nuovo titolo')<br />&gt;&gt;&gt; context.reindexObject(idxs['Title', 'sortable_title', 'SearchableText'])<br />&gt;&gt;&gt; context.title()<br />'Nuovo titolo'</pre>
<p>In base all'attributo modificato, vale la pena aggiornare tutti gli indici che lo riguardano.</p>
<h2>Quando la sicurezza incontra la ricerca</h2>
<p><img src="http://blog.redturtle.it/topic_images/MorePaperPeople.jpg/@@images/118a359e-7d62-465d-9cec-9f5f418c1cf4.jpeg" alt="Meeting" class="image-right" title="Meeting" />Un fatto meno noto: <strong>il catalogo di Plone è usato anche nella gestione della sicurezza</strong>.<br />In particolare esiste un indice dal nome <strong>allowedRolesAndUsers</strong> esplicitamente usato per una verifica di sicurezza: capire se un utente ha accesso a un contenuto (in pratica viene memorizzato nel catalogo se gli utenti hanno il permesso di "<strong>View</strong>" sul contenuto).</p>
<p>Perché tutto questo? L'alternativa sarebbe disastrosa in termini di prestazioni: caricare tutti i documenti risultanti dalla ricerca e verificare il controllo di sicurezza direttamente su questi.<br />Tale operazione può diventare molto lenta e dispendiosa, se pensiamo che una semplice ricerca testuale può portare a migliaia di risultati in un sito mediamente popolato.</p>
<p>E' quindi importante che <strong>questo indice sia sempre aggiornato</strong>. Per questo motivo, ogni volta che viene effettuata un'operazione che comporta un cambio di sicurezza di un contenuto (principalmente modifiche nella pagina di condivisione), l'indice viene aggiornato automaticamente.</p>
<p>Dato che una semplice chiamata al metodo <i>reindexObject</i> può essere relativamente dispendiosa (tenete sempre presente che Plone potrebbe indicizzare anche i file allegati e che l'operazione di re-indicizzazione di un file può essere piuttosto lenta), esiste un altro metodo che viene utilizzata al suo posto: <strong>reindexObjectSecurity</strong>.<br />Nel funzionamento base di Plone, questa chiamata si occupa di aggiornare solo l'indice <i>allowedRolesAndUsers</i> introdotto sopra.</p>
<h2>Sicurezze alternative</h2>
<p><img src="http://blog.redturtle.it/topic_images/5894290438_493dd4802c_o.jpg/@@images/81948fc8-a18a-43f3-8235-cc9a7468adf6.jpeg" alt="Security cams" class="image-right" title="Security cams" />Ma è vero che l'unico indice legato alla sicurezza sia allowedRolesAndUsers?<br />Nell'uso quotidiano di Plone sì, ma esistono alternative.</p>
<p>Vi porto due esempi.</p>
<h3>collective.portlet.truereview</h3>
<p>Sto parlando di un prodotto poco noto e di qualche anno fa: <a class="external-link" href="https://pypi.python.org/pypi/collective.portlet.truereview/">collective.portlet.truereview</a>.</p>
<p>Questo prodotto applica lo stesso principio utilizzato col permesso "<i>View</i>" dall'indice <i>allowedRolesAndUsers</i> per un nuovo permesso legato all'attività di revisione dei contenuti: "<i>Review portal content</i>".<br />Per fare questo viene creato un nuovo indice: <i>reviewerRolesAndUsers</i>.</p>
<p>Lo scopo del prodotto è fornire una portlet di revisione alternativa per Plone che, a differenza di quella ufficiale, non richieda il caricamento del contenuto.<br /><i>NB</i>: il prodotto è fermo dal 2009, non sono certo che funzioni ancora ma lo trovo piuttosto didattico.</p>
<h3>collective.localrolesdatatables</h3>
<p>Il secondo esempio è legato al più recente <a class="external-link" href="http://plone.org/products/collective.localrolesdatatables/">collective.localrolesdatatables</a>.</p>
<p>Questo prodotto vuole fornire una vista che permetta di ispezionare lo stato della sicurezza e delle condivisioni in un sito Plone.<br />Per fare questo è necessario capire su quali contenuti ci siano effettivamente delle personalizzazioni locali della sicurezza, ovviamente senza caricare i contenuti per non ricadere nel solito problema di prestazioni (ormai ci siamo capiti, vero?!).<br />L'approccio usato è quello di creare un nuovo indice "<strong>hasLocalRoles</strong>", un valore booleano che indica se un contenuto ha ruoli locali impostati o meno.</p>
<h2>Espandere il funzionamento di reindexObjectSecurity</h2>
<p><img src="http://blog.redturtle.it/topic_images/bingbang.jpg/@@images/35839ef6-0211-4940-b28f-61007cbbed77.jpeg" alt="Universe expanding" class="image-left" title="Universe expanding" />E' stato proprio utilizzando di recente <i>collective.localrolesdatatables</i> che mi sono imbattuto in un bug (di cui sono certo soffra anche <i>collective.portlet.truereview</i>):<br />il prodotto funziona a dovere, ma se la sicurezza di un contenuto viene aggiornata, l'indice "hasLocalRoles" non viene modificato a sua volta, almeno non fin quando l'intero documento verrà modificato (e quindi completamente reindicizzato).</p>
<p>Qual è il problema? Il metodo <strong><i>reindexObjectSecurity</i> "non sa" che anche questo indice fa parte della sicurezza del sito</strong>.</p>
<p>Come risolvere?</p>
<p>Se andiamo ad analizzare l'implementazione di <i>reindexObjectSecurity</i>, troviamo questa riga di codice:</p>
<pre>catalog.reindexObject(ob, idxs=self._cmf_security_indexes,<br />                      update_metadata=0, uid=brain_path)</pre>
<p>Viene quindi chiesto di reindicizzare nel catalogo il documento (<i>ob</i>) e di limitarsi agli indici definiti nella tupla <i>self._cmf_security_indexes</i> (quindi non tutti gli indici).<strong> </strong></p>
<p><strong>_cmf_security_indexes</strong> è un attributo di classe definito per <strong>CatalogAware</strong>, nel pacchetto <i>Products.CMFCore</i>. La sua definizione è la seguente:</p>
<pre>_cmf_security_indexes = ('allowedRolesAndUsers',)</pre>
<p>La soluzione è molto semplice: estendere la lista di indici registrati in questo attributo (<a class="external-link" href="https://github.com/collective/collective.localrolesdatatables/blob/8319deb4aef3d8db1803f1823071052130b28ce4/collective/localrolesdatatables/__init__.py">qui</a> come ho modificato <i>collective.localrolesdatatables</i>):</p>
<pre>from Products.CMFCore.CMFCatalogAware import CatalogAware<br /><br />CatalogAware._cmf_security_indexes += ('mioNuovoSecurityIndex',)</pre>
<h3>Problemi?</h3>
<p>Questo tipo di intervento ha un effetto collaterale: modifica l'attributo <strong>a livello di classe</strong> e si rispecchia quindi su <i>tutti</i> i siti Plone presenti nell'installazione. Potreste anche trovarvi nella situazione in cui il prodotto che necessita di questa modifica sia installato su un solo sito Plone, quindi il nuovo indice non sia presente in altri, eppure la modifica sia comunque applicata.</p>
<p>E' un problema? Per fortuna no!<br />Il catalogo Plone è molto tollerante: se viene chiesta la reindicizzazione di un indice non esistente, questo fallisce l'operazione senza sollevare eccezioni.</p>
<p><span class="discreet">L'immagine di testata è di <a class="external-link" href="http://www.flickr.com/photos/adulau/">Alexandre Dulaunoy</a>.</span></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Fabbri</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>products</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>Archetypes</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2013-03-12T08:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/salva-compilazione-form-contenuti-Plone-uwosh-pfg-d2c">
    <title>Salva la compilazione dei form in contenuti Plone con uwosh.pfg.d2c</title>
    <link>http://blog.redturtle.it/salva-compilazione-form-contenuti-Plone-uwosh-pfg-d2c</link>
    <description>Panoramica sul prodotto Plone uwosh.pfg.d2c, un utile adattatore per PloneFormGen che memorizza in contenuti i form compilati</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Il prodotto <a class="external-link" href="https://pypi.python.org/pypi/uwosh.pfg.d2c">uwosh.pfg.(d)ata(2)(c)ontent</a> <strong>implementa un adattatore</strong> per <a class="external-link" href="http://plone.org/products/ploneformgen">PloneFormGen</a> (un generatore di form per Plone) che <strong>salva i dati del form in un'istanza di un determinato tipo di contenuto</strong>.<br /><br />Il prodotto fornisce appunto un tipo di <strong>contenuto</strong> <i>dinamico</i> e <i>universale</i> per memorizzare i dati sottomessi attraverso un modulo PloneFormGen. Si tratta di una vera e propria <strong>copia persistente</strong> del modulo compilato dall'utente, che potrai gestire come un qualsiasi oggetto Plone.</p>
<blockquote class="pullquote"><strong>I campi del contenuto generato saranno esattamente i campi del modulo che hai configurato!</strong></blockquote>
<p>Inoltre, una volta generato il contenuto a seguito della sottomissione del form, potrai controllare la sua visibilità e il suo accesso applicando su di esso un <strong>specifico workflow</strong> come per un normale tipo di contenuto.</p>
<p>I campi del modulo diventeranno i campi dell'oggetto creato: potrai quindi modificare il loro valore. Questa funzionalità è realizzata mediante <a class="external-link" href="https://pypi.python.org/pypi/archetypes.schemaextender">schemaextender</a>, che è stato usato nel prodotto uwosh.pfg.d2c per aggiungere i <strong>campi extra</strong> del modulo al tipo di contenuto.</p>
<p>Ora vediamo come applicare l'adattatore ai form in tre mosse e come configurare i campi principali che lo caratterizzano.</p>
<div class="visualClear"></div>
<a name="anchor-breaktext"></a><div class="breakText">
<h2>Uso dell'adattatore</h2>
</div>
<p><img src="http://blog.redturtle.it/uploads/savedatatocontentadapter.png/@@images/77c4146a-abfe-4ae0-a7cb-70de46e51597.png" alt="" class="image-right" title="" />Il prodotto uwosh.pfg.d2c aggiunge un elemento <i>"Save Data to Content Adapter"</i> al menù a discesa "Aggiungi nuovo..." per un form di PloneFormGen.</p>
<p>Una volta abilitato l'adattatore, quando un utente invia un modulo verrà creato un nuovo contenuto con i dati inseriti nel form.</p>
<p>Vediamo in dettaglio come applicare l'adattatore:</p>
<ol>
<li>aggiungi il form, e con "QuickEdit" inserisci tutti i campi di interesse</li>
<li>aggiungi l'adattatore al form</li>
<li>attiva l'adattatore: scegli "QuickEdit" sul form e, nella lista delle azioni, seleziona l'adattatore appena aggiunto.</li>
</ol>
<p><img src="http://blog.redturtle.it/uploads/aggiungiadattatore.png/@@images/8a8c2846-9fe0-4625-b99b-560b94e3eb25.png" alt="" class="image-left" title="" /></p>
<p><img src="http://blog.redturtle.it/uploads/attivaadattatore.png/@@images/e2bc8128-b7b4-4664-b09a-aee9ba09eb94.png" alt="" class="image-left" title="" /></p>
<p>Troverai i contenuti generati dopo la compilazione del form nella cartella dell'adattatore.</p>
<div class="visualClear"></div>
<h2>Campi di configurazione dell'adattatore</h2>
<h3>Il tipo di contenuto dell'oggetto generato</h3>
<p>Il campo <i>"Saved entry content type"</i> si riferisce al <strong>portal type</strong> dell'oggetto usato per il salvataggio dei dati all'invio dei moduli.<br /><br />A questo scopo il prodotto fornisce un nuovo tipo di contenuto <i>"FormSaveData2ContentEntry"</i>, ma è possibile <strong>clonare</strong> <i>"FormSaveData2ContentEntry</i>", per usare un proprio tipo personalizzato, in tre modi:<img src="http://blog.redturtle.it/uploads/addcontenttype.png/@@images/cdc16110-1cb3-43f1-a72f-a827ddce71a8.png" alt="" title="" class="image-right" id="__mce_tmp" /></p>
<ul>
<li>tramite l'interfaccia fornita dal prodotto, alla creazione/modifica dell'adattatore, facendo click sul bottone <i>"Add new type"</i></li>
<li>copiando manualmente il tipo "<i>FormSaveData2ContentEntry"</i> nel portal_types tool (via ZMI) e poi rinominarlo in modo appropriato</li>
<li>aggiungendo il clone del tipo "<i>FormSaveData2ContentEntry</i>" al types tool via codice genericsetup profile.</li>
</ul>
<p>Una volta creato, il nostro nuovo tipo di contenuto sarà presente tra le opzioni del save data adapter; è necessario selezionarlo esplicitamente e quindi tornare in modifica dell'adattatore se lo abbiamo creato con gli utimi due metodi; altrimenti verrà applicato il valore di default <i>FormSaveData2ContentEntry</i>.</p>
<h3>I campi relativi al titolo</h3>
<p>Il campo <i>"Title Field"</i> ti permette di <strong>scegliere tra i vari campi del form</strong> quale sarà il campo da cui verrà preso il titolo dell'oggetto generato.</p>
<p>Se per il titolo del futuro oggetto non vuoi usare nessuno dei campi  del form, puoi utilizzare un'altra funzionalità dell'adattatore: <i>"Dynamic title override"</i>, che ti permette di inserire un'espressione TALES valutata al momento della generazione dell'oggetto per <strong>determinare dinamicamente</strong> il titolo. In questo modo puoi attribuire al contenuto titoli più  complessi, come ad esempio il nome del form (risalendo all'oggetto padre)  seguito dalla data di creazione.</p>
<pre><br />python:'%s %s' % (here.aq_inner.aq_parent.aq_parent.Title(),here.created().strftime('%d/%m/%Y'))</pre>
<p>Come ultimo, il campo dell'adattatore <i>"Nice Ids"</i> ti consente di generare per l'oggetto un nome breve partendo dal titolo del form.</p>
<h3>Permessi e sicurezza</h3>
<p>La compilazione di un form può essere effettuata anche da un utente <strong>anonimo</strong>, se tale modulo è pubblico.</p>
<p>Tuttavia, se l'invio del form è seguito dalla creazione dell'oggetto  corrispondente, come nel nostro caso, l'anonimo non ha i permessi  sufficienti per creare un oggetto e di conseguenza per compilare il  form.</p>
<p>Perciò l'adattatore prevede un campo <i>"Avoid Security Checks"</i> per evitare i controlli di sicurezza nella creazione di un oggetto,  consentendo quindi anche agli utenti anonimi di completare il form.<br /><br />Un  altro modo per fornire questa possibilità senza evitare i controlli di  sicurezza, è modificare il workflow e i permessi del tipo di contenuto  generato a favore dell'utente anonimo.</p>
<h3>In conclusione</h3>
<p>Il prodotto ti fornisce un adattatore per PloneFormGen e un nuovo tipo di contenuto che sarà quello generato una volta sottomesso il form su cui hai applicato l'adattotore. Puoi decidere di utilizzare quel tipo oppure puoi personalizzarlo clonandolo.</p>
<p>Puoi inoltre configurare il punto da cui verrà preso il titolo e permettere anche agli utenti anonimi di usare il tuo form, senza che la creazione del contenuto fallisca per permessi insufficienti.</p>
<p>Personalmente ho trovato molto utile <a class="external-link" href="https://pypi.python.org/pypi/uwosh.pfg.d2c">uwosh.pfg.d2c</a> e ringrazio l'autore del prodotto Nathan Van Gheem e i contributori Author T. Kim Nguyen, Lurker Petri Savolainen, che mi hanno fornito molte delle funzionalità di cui avevo bisogno. Se vi sembra che faccia anche al caso vostro, potete appronfondire con altra <a class="external-link" href="http://pythonhosted.org/uwosh.pfg.d2c/">documentazione</a>.</p>
<p><span style="text-align: start; float: none; ">Anche se il prodotto è legato ad <a class="external-link" href="http://plone.org/products/archetypes">Archetypes</a>, il framework che</span><span style="text-align: start; float: none; "> Plone sta lentamente sostituendo con <a class="external-link" href="http://plone.org/products/dexterity">Dexterity</a> e in futuro è</span><span style="text-align: start; float: none; "> possibile che prodotti come questo non servano più, al momento è</span><span style="text-align: start; float: none; "> ancora un'ottima risorsa!</span><br /><br /><br /><span class="discreet">La foto in testata è di <a class="external-link" href="http://www.flickr.com/photos/59937401@N07/">Images_of_Money</a></span></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Federica D'Elia</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>products</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2013-03-04T10:45:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/come-utilizzare-online-id-login-plone">
    <title>Come utilizzare gli Online ID per il login Plone</title>
    <link>http://blog.redturtle.it/come-utilizzare-online-id-login-plone</link>
    <description>Facebook, Twitter, Google. Ma anche OpenID, Foursquare, LinkedIN e molti altri. Vediamo come sfruttare il servizio di RPX/Janrain per autenticarsi in Plone</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Oggi giorno se un sito istituzionale, un portale web o anche il più semplice dei siti richiede una registrazione con utente e password che poi dovranno essere in qualche modo memorizzati, le persone mal volentieri compileranno il form in questione.</p>
<p>Il perché è ovvio: ogni persona ha come minimo 50 registrazioni a siti vari e, soprattutto, ogni <i>internauta</i> di oggi ha un profilo su più <strong>social network</strong>.<br />Da qui la brillante idea di permettere di accedere ai siti direttamente con un altro account che fornisca l'identità.</p>
<p class="breakText">Plone non poteva certo rimanere indietro su questo fronte e quindi ecco <strong><a class="external-link" href="http://pypi.python.org/pypi/plonesocial.auth.rpx/0.815">plonesocial.auth.rpx</a></strong>: un pacchetto che utilizza i servizi di autenticazione <strong>RPX</strong> offerti <strong>Janrain</strong>.</p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<h3>Una nostra personalizzazione</h3>
<p>Il plugin di <a class="external-link" href="http://comlounge.net/">COM.lounge</a> non rispondeva però appieno alle necessità di un nostro cliente, il quale non voleva l'autenticazione automatica indiscriminata da parte di tutti ma un secondo step di registrazione in cui richiedere alcuni dati aggiuntivi.<br />Abbiamo quindi deciso di estendere il prodotto originale sviluppandone una <a class="external-link" href="https://github.com/RedTurtle/plonesocial.auth.rpx/tree/plone4_compatible">nostra versione</a> in cui:</p>
<ul>
<li>abbiamo aggiunto un campo <i>"telefono"</i> al profilo utente</li>
<li>abbiamo aggiunto un form obbligatorio per effettuare la registrazione al portale</li>
<li>abbiamo modificato il plugin di autenticazione in modo da lasciare anonimi tutti gli utenti che non hanno completato il form.</li>
</ul>
<p class="breakText"> </p>
<h2>Configuriamo il sistema</h2>
<p> </p>
<p><img alt="RPX sing-up" class="image-right" src="http://blog.redturtle.it/uploads/RPX_singup.png/@@images/cad635c6-6223-47f3-b923-26bf8fd11c23.png" style="text-align: center; " title="RPX sing-up" /></p>
<p> </p>
<p> </p>
<p> </p>
<p>La prima cosa da configurare è <a class="external-link" href="https://rpxnow.com">Janrain</a> stesso che, in linea con la politica di questo sistema, non fornisce la possibilità di una registrazione diretta al sistema ma solo tramite un account preesistente.</p>
<p style="text-align: center; "> </p>
<p style="text-align: center; "> </p>
<p style="text-align: center; "> </p>
<div><img alt="RPX create application" class="image-left" src="http://blog.redturtle.it/uploads/RPX_createapplication.png/@@images/e3d502bd-627b-407f-b114-bd46d65ba31b.png" title="RPX create application" />
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>Dopo aver confermato le informazioni del proprio account, bisogna scegliere un nome per la propria applicazione.</p>
<p style="text-align: center; "> </p>
<p style="text-align: center; "> </p>
<p style="text-align: center; "> </p>
<p> </p>
<p><img alt="RPX plone conf" class="image-right" src="http://blog.redturtle.it/uploads/RPX_PloneConf.png/@@images/a7a6cf20-0664-42df-8489-5a7d72a9e042.png" title="RPX plone conf" /></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>Il dominio RPX, basato sul nome che avete scelto per la vostra applicazione, insieme ad alcune altre chiavi vanno a comporre le informazioni di configurazione. Queste sono necessarie a configurare il nostro pacchetto Plone.</p>
<p style="text-align: center; "> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>A questo punto la configurazione <i>“Plone to RPX”</i> è completa, ma ora bisogna configurare RPX perché si colleghi ai vari provider di Online ID per i quali si vuole garantire l’accesso sul nostro portale Plone.</p>
<p>La home dell’applicazione presenta alcune informazioni sugli accessi, limitate se si sta utilizzando la versione gratuita, molto più complete se avete acquistato una versione plus, pro o enterprise. <br />Dei vari menù e quick links disponibili quello che ci interessa è il menu <i>“Development -&gt; Provider Configuration”</i>.</p>
<p style="text-align: center; "><img alt="RPX global configuration" class="image-inline" src="http://blog.redturtle.it/uploads/RPX_configureprovider.png/@@images/6f5acd0c-7b72-472e-b71a-13344f67d430.png" title="RPX global configuration" /></p>
<p>Nell’immagine qui sopra si può vedere che, al momento, la mia applicazione è configurata per gestire l’accesso tramite Facebook e Google; l’altro dettaglio visibile è che molte delle opzioni sono disponibili solo per le versioni a pagamento.</p>
<p> </p>
<p>Ora vediamo come configurare RPX per connettersi ad uno degli <strong>Online ID </strong>disponibili e prendiamo come esempio la configurazione per <a class="external-link" href="http://twitter.com/">Twitter</a>.</p>
<p>Cliccando sul pulsante <i>“Configure”</i> parte un <strong>wizard</strong> che fa compiere tutti i passi necessari.</p>
<p style="text-align: center; "><img alt="RPX wizard twitter" class="image-inline" src="http://blog.redturtle.it/uploads/RPX_wizardtwitter.png/@@images/8ebcbad8-5bd6-4bd7-b530-f0c0abd16737.png" title="RPX wizard twitter" /></p>
<p>Per collegare Twitter, ma anche Facebook tra quelli che ho avuto modo di provare, occorre attivare il proprio account come <strong>“Developers”</strong>. Nulla di particolarmente difficile, sul web si trovano tutte le informazioni necessarie, ma è un’ulteriore passaggio da fare.</p>
<p>Una volta effettuato l’accesso, bisogna creare la propria applicazione tramite la compilazione di un semplice form dove è necessario inserire i parametri indicati nella seconda schermata del wizard.</p>
<p style="text-align: center; "><img alt="RPX twitter create application" class="image-inline" src="http://blog.redturtle.it/uploads/RPX_twitterapp.png/@@images/3baabc82-6ce9-48b1-b6b0-a2737f0addff.png" title="RPX twitter create application" /></p>
<p>La terza schermata dice di impostare il permesso di “lettura e scrittura” da parte della vostra applicazione su Twitter, mentre l’ultimo passaggio da fare è impostare in <i>RPX</i> i parametri di <i>“customer Key”</i> e <i>“Customer Secret”</i> per effettuare il collegamento tra i due sistemi.</p>
<p>I <i>wizard</i> di configurazione non sono tutti uguali, perché ogni provider necessita di configurazioni particolari, ma si concludono tutti con la richiesta dei parametri per il collegamento tra i sistemi.</p>
<p>Per concludere la configurazione di RPX, bisogna andare a impostare il <strong>widget di Sign-in</strong> che verrà mostrato nel proprio sito scegliendo i tipi di account che sono stati precedentemente configurati.</p>
<p style="text-align: center; "><img alt="RPX widget di sing-in" class="image-inline" src="http://blog.redturtle.it/uploads/RPX_widgetsingin.png/@@images/27366202-b281-4b91-9b65-b928d50bfa33.png" style="text-align: center; " title="RPX widget di sing-in" /></p>
<p> </p>
<p>A questo punto tutto è pronto per effettuare l’accesso con Online ID in Plone; buon login!</p>
<p style="text-align: center; "><img alt="RPX login plone" class="image-inline" src="http://blog.redturtle.it/uploads/RPX_logininplone.png/@@images/9c061453-8468-479b-9fbc-d1e2836487d3.png" title="RPX login plone" /></p>
</div>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Mirco Angelini</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    
      <dc:subject>products</dc:subject>
    
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>Facebook</dc:subject>
    
    
      <dc:subject>login</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2013-02-01T09:15:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/plone-i-bizzarri-comportamenti-di-tinymce-e-chrome">
    <title>Plone: i bizzarri comportamenti di TinyMCE e Chrome</title>
    <link>http://blog.redturtle.it/plone-i-bizzarri-comportamenti-di-tinymce-e-chrome</link>
    <description>Una soluzione all'espansione dell'area di testo TinyMCE attraverso le colonne laterali, che si verifica in Chrome</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Nelle ultime installazioni di <strong>Plone 4</strong> è emerso un bug molto fastidioso. Di tanto in tanto accade che, aprendo un contenuto in modifica, utilizzando il browser <strong>Chrome</strong>, la pagina si apra sbordando sul lato destro e uscendo completamente dal contenuto principale.</p>
<p><img src="http://blog.redturtle.it/uploads/tiny_bug.png/@@images/19a82d81-4ce6-4a28-b8c4-369cecc804d1.png" alt="" class="image-left" title="" /></p>
<p>L'effetto è spiacevole, perché parte dei campi di input <strong>invadono i riquadri della colonna destra</strong>.</p>
<div>Ho potuto riscontrare lo stesso problema in una qualsiasi installazione di Plone 4, con il semplice utilizzo del tema Sunburst e nessun add-on.<br /><br />Se l'utente ricarica la pagina, il contenuto centrale si ridimensiona tornando al proprio posto.<br /><br />Il metodo per replicare il problema, con assoluta certezza che riaccada, è quello di aprire una pagina in modifica e spostarsi dal tab "<i>Default</i>" nel tab "<i>Impostazioni</i>" e poi tornare al tab "<i>Default</i>". Tutto questo succede usando Chrome.<br /><br />Attraverso un serie di test ho potuto osservare che tale comportamento è dovuto alla presenza di almeno un campo con editor di testo TinyMCE.</div>
<p> </p>
<p><img src="http://blog.redturtle.it/uploads/tiny_settings.png/@@images/6dbe9e2a-538f-4f68-a95c-9f6256e0044c.png" alt="" class="image-right" title="" /></p>
<a name="anchor-breaktext"></a><div class="breakText">Purtroppo non è servito giocare con le impostazioni di TinyMCE relative al ridimensionamento automatico, come mi aveva gentilmente <a class="external-link" href="http://plone-regional-forums.221720.n2.nabble.com/Problema-con-Tinymce-in-un-Plone-4-x-con-un-tema-a-layout-fisso-td7581791.html">suggerito Vito Falco nella lista italiana di Plone</a>.</div>
<p> </p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p class="callout" style="text-align: left; ">Dopo varie ricerche ho trovato il <a class="external-link" href="https://dev.plone.org/ticket/11217">bug ufficiale</a>: <i>"Sunburst Theme: Expanding textarea's right portlets bleed through".</i></p>
<div>Indagando meglio, ho scoperto che il bug è causato dalla <strong>toolbar di TinyMCE</strong> e molto probabilmente è imputabile al tipo di struttura utilizzata, ovvero una serie di tabelle nidificate. Le icone nella toolbar sono raggruppate in tabelle che si trovano in <i>float</i> <i>left</i>, a loro volta inserite in un elemento HTML <i>td</i> di un'altra tabella. Al caricamento della pagina, queste tabelle ignorano la dimensione del contenuto e si posizionano su una medesima riga, causando lo spiacevole effetto che vi ho descritto.</div>
<div class="visualClear"></div>
<p> </p>
<h3>Una soluzione</h3>
<div><a class="external-link" href="https://dev.plone.org/ticket/11217#comment:5">maartenkling</a> ha proposto un semplice e funzionante <i>workaround</i>: rimuovere il floating sulle tabelle che raggruppano le icone.</div>
<pre>span.ploneSkin table.mceToolbar {<br />     float: none;<br />}</pre>
<div><img src="http://blog.redturtle.it/uploads/tinymce_resolve_1.png/@@images/4c28504c-42ad-4d5b-bbd9-47d2cad1a033.png" alt="" class="image-right" title="" /></div>
<div></div>
<div>Purtroppo con questa modifica le icone non occupano tutto lo spazio orizzontale disponibile: gruppi di icone vengono mostrati su più linee anche se esiste lo spazio sufficiente per mostrarle tutte su una singola linea, ad esempio nel caso in cui non vi siano colonne laterali.</div>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<div class="visualClear"></div>
<h3>La mia soluzione</h3>
<div>In attesa che la struttura di TinyMCE venga migliorata, un altro modo per risolvere il problema è quello di <strong>specificare la larghezza del contenuto sull'elemento HTML td contenitore delle tabelle di icone</strong>, recuperando tale larghezza dalla <i>table</i> principale. In questo modo la larghezza non viene più ignorata e, se non è sufficiente per mostrare tutte le icone su una singola linea, i gruppi si posizionano uno sotto l'altro.<br /><br />In pratica, all'inizializzazione dell'editor dobbiamo ottenere le dimensioni riguardanti la larghezza dalla tabella che ha la classe <i>"mceLayout"</i>, poiché questo è l'elemento HTML padre più prossimo su cui sono definite dimensioni relative all'editor. Presa la larghezza, la dobbiamo impostare sull'elemento HTML <i>td</i> che contiene le varie toolbar.<br /><br />La funzione da eseguire è questa:</div>
<pre>function myCustomInitInstance(inst) {<br />    <br />    // tabella contenitore che possiede le dimesioni<br />    var tinytable = $("table.mceLayout");<br /><br />    // elemento td che contiene le toolbar<br />    var tinytoolbar = tinytable.find("tr.mceFirst td.mceToolbar");<br /><br />    // fissiamo le dimensioni sul contenitore delle toolbar<br />    $(tinytoolbar).css("width",$(tinytable).css("width"));<br />}</pre>
<div>Rimane da trovare il punto esatto in cui agganciare questa funzione. <strong>Essa deve essere eseguita dopo l'inizializzazione di TinyMCE</strong>.<br /><br />Per questo scopo ho deciso di utilizzare <a class="external-link" href="http://www.tinymce.com/wiki.php/Configuration:init_instance_callback"><i>"init_instance_callback"</i></a>, un'opzione di configurazione di TinyMCE. Questa opzione deve contenere il nome di una funzione che verrà eseguita ogni volta che sarà inizializzata un'istanza dell'editor. Essa deve essere specifica nell'inizializzazione di TinyMCE (<i>"tinyMCE.init"</i>).</div>
<div></div>
<pre>tinyMCE.init({<br />    ...<br />    init_instance_callback : "myCustomInitInstance"
});</pre>
<div></div>
<pre>function myCustomInitInstance(inst) {<br />    alert("Editor: " + inst.editorId + " is now initialized.");<br />}</pre>
<blockquote class="pullquote">Il formato della funzione è: <i>InitInstance (inst)</i>, dove <i>inst</i> è l'istanza dell'oggetto editor.</blockquote>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="visualClear">Ricapitolando, ho personalizzato il file <i>tiny_mce_init.js</i>, dove viene inizializzato l'oggetto TinyMCE, assegnando all'opzione <i>"init_instance_callback"</i> la mia funzione <i>"myCustomInitInstance</i>".</div>
<pre><br />...<br />var init_dict = {<br />    ...<br />    init_instance_callback : "myCustomInitInstance"<br />}<br />...</pre>
<div>Quindi <i>"myCustomInitInstance"</i> verrà eseguita all'inizializzazione dell'editor e servirà per impostare la larghezza disponibile alla toolbar, prendendo tale larghezza dall'elemento padre più prossimo.<br /><br />L'ultima modifica da fare è cambiare la proprietà <i>display</i> del contenitore HTML <i>td</i>, altrimenti la <i>table</i> innestata ignorerà la larghezza dell'elemento padre appena fissata.</div>
<pre>td.mceToolbar {<br />     display:block;<br />}</pre>
<p>Con queste brevi linee di codice possiamo evitare che l'editor invada la colonna laterale destra. Il passo successivo sarà quello di investigare su come questa soluzione diventi definitiva per il bug. Altri suggerimenti per risolvere il problema sono ben accetti!</p>
<p><span class="discreet">La foto in testata è di <a class="external-link" href="http://www.flickr.com/photos/bowena/">bowenmurphy</a>.</span></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Federica D'Elia</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>TinyMCE</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2013-01-24T08:15:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/datatable.js-tabelle-per-tutti-i-gusti">
    <title>jQuery.DataTables.js: tabelle per tutti i gusti</title>
    <link>http://blog.redturtle.it/datatable.js-tabelle-per-tutti-i-gusti</link>
    <description>Se una semplice tabella non rende merito ai dati mostrati, ci si rivolge a Javascript/css per avere di più. Vediamo come usare DataTables per avere molto di più!</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Tante volte abbiamo il compito di mettere in mostra tramite tabelle una serie di dati e le (più che giustificate) richieste sono sempre le stesse: fare batching dei dati visualizzati; permettere l'ordinamento delle singole colonne; poter fare ricerca sulle righe della tabella filtrandone il testo.</p>
<p>Cercando sul web, vi renderete conto che i plugin Javascript disponibili sono molti, ma uno mi ha colpito in particolare: <a class="external-link" href="http://www.datatables.net/index">jQuery.DataTables.js</a>. Semplice da usare, funzionalità di base estese, molti plugin aggiuntivi e, non da ultimo per un plonista, esiste una versione già "pacchettizzata" per Plone su pypi.</p>
<a name="anchor-breaktext"></a><div class="breakText">Vediamo quali sono le sue caratteristiche principali.</div>
<h3>Introduzione del plugin nelle pagine HTML</h3>
<p>Per utilizzare questo plugin, tutto quello che bisogna fare è inserire nella pagina jquery.dataTables.css e jquery.dataTables.js.</p>
<p>Come detto esiste anche la versione pacchettizzata di questa libreria: è un porting realizzato registrando le risorse javascript e css per poterle inserire nel portal_javascript e nel portal_css e utilizzarle all'interno di Plone; chi volesse più informazioni le può cercare su pypi: <a class="external-link" href="http://pypi.python.org/pypi/collective.js.datatables">collective.js.datatables</a>.</p>
<h3>Utilizzo base del plugin</h3>
<p>Una volta introdotte le risorse Javascript e css nella pagina, per cominciare a utilizzare DataTables è sufficiente avere una tabella e inizializzarla tramite il costruttore del plugin:</p>
<pre><br />  jq('#table_id').dataTable()<br /> </pre>
<p>Facendo questo, si passa da una tabella come questa:</p>
<p><img src="http://blog.redturtle.it/topic_images/base1.JPG" alt="Tabella base" class="image-inline" title="Tabella base" /></p>
<p>a una tabella come questa:</p>
<p><img src="http://blog.redturtle.it/topic_images/tabella-css-js" alt="Tabella css js" class="image-inline" title="Tabella css js" /></p>
<p>Come si può vedere, con una riga di Javascript nella tabella abbiamo già aggiunto:</p>
<ul>
<li>batching e navigazione delle pagine della tabella;</li>
<li>ordinamento delle colonne;</li>
<li>filtro sul testo della tabella.</li>
</ul>
<h3>Altre funzionalità</h3>
<p>Questo plugin, come si può vedere dalla <a class="external-link" href="http://www.datatables.net/examples/">documentazione</a> sul sito, presenta molte altre funzionalità; ma ce ne sono alcune molto utili su cui spenderò qualche parola.</p>
<h4>Traduzioni</h4>
<p>Il plugin è traducibile in ogni sua label. Per farlo, si può procedere tramite un vocabolario di traduzioni durante l'inizializzazione del plugin in questo modo:</p>
<pre><br /> jq(document).ready(function(){<br />   jq('#table_id').dataTable({<br />     "oLanguage":{<br />         "sLengthMenu": "Visualizza _MENU_ elementi per pagina",<br />         "sZeroRecords": "Nessun elemento trovato",<br />         "sInfo": "Visualizzati da _START_ a _END_ di _TOTAL_ elementi",<br />         "sInfoEmpty": "Visualizzati da 0 a 0 di 0 elementi", <br />         ....<br />         }<br />      });<br />    });<br /> </pre>
<p>Un approccio alternativo può essere quello di usare l'attributo oLanguage passando il path di un oggetto "callable" del server che ritorni le informazioni relative alle traduzioni. Questo è molto comodo quando si lavora con il pacchetto per Plone, perché nelle ultime versioni è stata introdotta una vista che, una volta chiamata dal plugin, tornerà il vocabolario con le traduzioni:</p>
<pre>  <br />  jq(document).ready(function(){<br />     jq('#table_id').dataTable({<br />        "oLanguage":{<br />           "sUrl": "@@collective.js.datatables.translation",<br />         }<br />      });<br />   });<br /> </pre>
<p>In questo modo il plugin verrà visualizzato nella stessa lingua del browser, se la traduzione lato Plone esiste.</p>
<h4>Ordinamento: quando l'alfabeto non basta!</h4>
<p>L'ordinamento di base di DataTables è quello alfabetico e tiene in considerazione caratteri e numeri, ma non è inusuale che venga chiesto di ordinare le colonne della tabella anche in base ad altri criteri. Vediamo cosa si può fare, ad esempio, se viene chiesto di ordinare una colonna in base alla stringa scritta al suo interno, sapendo che quella stringa è una data nel formato gg/mm/aaaa.</p>
<p>Il plugin è scritto in jQuery, per cui sfruttiamo lo stile usato da jQuery per estendere i plugin. Guardando codice ed esempi, si può vedere che DataTables usa 3 funzioni per fare l'ordinamento di una colonna: una funzione prepara i dati per il confronto fra loro e le altre due fanno i confronti per l'ordinamento crescente e decrescente.</p>
<p>Potremo quindi scrivere codice come questo:</p>
<pre>  <br />  jq(document).ready(function(){<br />     jq.extend(jq.fn.dataTableExt.oSort,<br />           {<br />           "date-ita-pre": function(a){<br />               // ci aspettiamo date nel formato DD/MM/YYYY<br />               // se le trasformiamo nel formato inglese sono ordinabili<br />               var itaDate = a.split('/');<br />               if (itaDate == "")<br />                   return 0;<br />               return (itaDate[2] + itaDate[1] + itaDate[0]) * 1;<br />               },<br /><pre>           "date-ita-asc": function(a,b){<br />               return ((a&lt;b)? -1 : ((a&gt;b) ? 1: 0));<br />               },</pre>
<pre>           "date-ita-desc": function(a,b){<br />               return ((a&lt;b)? -1 : ((a&gt;b) ? 1: 0));<br />               }</pre>
...<br /> });<br /><br /> jq('#table_id').dataTable({<br /> "aoColumn": [null, ... , ..., {"sType": "date-ita"}]<br /> });<br /> });</pre>
<p>Analizziamo il codice qui sopra partendo... dalla fine! Nelle ultime righe, inizializziamo il plugin impostando l'ordinamento delle colonne tramite una lista: ogni elemento della lista corrisponde a una colonna. Se si usa null, si utilizza l'ordinamento standard. Per l'ultima colonna della tabella, stiamo dicendo di utilizzare l'ordinamento "date-ita". Tramite questa stringa, il plugin sa che esistono 3 funzioni Javascript, precedentemente dichiarate, che permetteranno di preparare il dato e confrontarlo per ordinarlo rispetto agli altri dati.</p>
<p>Subito sopra, infatti, possiamo vedere che, mentre le ultime due funzioni si occupano di fare il confronto fra due valori per ordinarli fra loro, la prima prende in ingresso una stringa, la spezza in corrispondenza della '/' e la ricompone secondo l'ordine inglese (anno, mese, giorno), che è l'ideale per ordinare una data. La moltiplicazione per 1 viene fatta per fare casting della stringa a intero e poter fare così dei confronti fra interi. Allora sarà facile per le altre funzioni decidere se 20130102 è maggiore o minore di 20130103 e così via.</p>
<h4>Navigazione alternativa nella paginazione</h4>
<p>Questa in realtà è una finezza ma, personalmente, più che una navigazione che permette di muoversi solo tra le pagine "precedente" e "successiva", preferisco una paginazione più completa che mi permetta di saltare anche alcune pagine.</p>
<pre>  <br />  jq(document).ready(function(){<br />     jq('#table_id').dataTable({<br />           "sPaginationType": "full_numbers",<br />           ...<br />      });<br />   });<br /> </pre>
<p>Questo ci permette di avere una navigazione come quella mostrata nella figura che segue:</p>
<p><img src="http://blog.redturtle.it/topic_images/tabellanavigatore" alt="Tabellanavigatore" class="image-inline" title="Tabellanavigatore" /></p>
<h4>Conclusioni</h4>
<p>La lunghezza del post non rende onore alla semplicità d'uso del plugin: una volta aggiunto a una pagina, bastano 5 minuti di orologio per poter avere tabelle con tutte le funzionalità necessarie a mostrare e elaborare grosse moli di dati. Ho provato il plugin anche utilizzando tabelle con circa un migliaio di elementi, e i tempi di risposta sono rapidissimi.</p>
<p>Inoltre, guardando la documentazione, ci si può rendere conto che ci sono ancora molte funzionalità da poter sfruttare. Per me, ad oggi, è sicuramente il primo plugin da tenere in considerazione quando si devono mostrare dati tabellari.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Bellenghi</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>jQuery</dc:subject>
    
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>javascript</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2013-01-22T10:05:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/wildcard-foldercontents-plugin-cartelle-plone">
    <title>wildcard.foldercontents: le cartelle con una marcia in più</title>
    <link>http://blog.redturtle.it/wildcard-foldercontents-plugin-cartelle-plone</link>
    <description>La solita vista contenuti vi ha stancato? Proviamo a sostituirla con una nuova versione rivista e "potenziata" che aggiunge diverse nuove funzionalità</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Il tab "contenuti" di Plone, è una comoda vista delle cartelle (o contenuti "cartellosi") che permette di avere una visione generale degli elementi contenuti al suo interno.</p>
<p><img src="http://blog.redturtle.it/topic_images/foldercontents.png" alt="foldercontents" class="image-inline" title="foldercontents" /></p>
<p>Con questa vista si possono anche fare alcune operazioni come il copia/incolla di contenuti, il riordino di elementi trascinandoli e cambiare il criterio di ordinamento dei contenuti visualizzati a seconda di alcuni indici come il titolo o la data di modifica.</p>
<p class="callout">E se noi volessimo uno strumento più completo, e fare operazioni più complesse?</p>
<a name="anchor-breaktext"></a><div class="breakText">Questa vista è molto utile per i gestori dei siti, ma ha diverse limitazioni, perché non permette di invertire l'ordinamento scelto precedentemente (per esempio se si vuole ordinare alfabeticamente dalla Z alla A) o di forzare l'ordine di tutti gli elementi della cartella in modo permanente senza doverli spostare uno ad uno (e quando gli elementi sono più di 20 e quindi sono paginati, è un bel problema).</div>
<p>Per risolvere queste "mancanze", esiste un prodotto che ci può aiutare: <a class="external-link" href="http://pypi.python.org/pypi/wildcard.foldercontents">wildcard.foldercontents</a>.<br />E' un plugin per Plone sviluppato da <strong>Nathan Van Gheem</strong> che riprende il lavoro iniziato dal nostro<strong> Luca Fabbri</strong> con <a class="external-link" href="http://pypi.python.org/pypi/collective.sortmyfolder">collective.sortmyfolder</a> e aggiunge altre interessanti funzionalità.</p>
<p><img src="http://blog.redturtle.it/topic_images/wilcard_foldercontents.png" alt="wildcard foldercontents" class="image-inline" title="wildcard foldercontents" /></p>
<p>In sostanza sostituisce la vecchia vista contenuti con un nuovo template. Come si può notare (a parte la grafica leggermente modificata) le funzionalità di base sono rimaste tutte, con in più alcune aggiunte:</p>
<ol>
<li>Possibilità di modificare il criterio di ordinamento degli elementi in base a diversi indici (ordine cartella, titolo, data di modifica, data di creazione), sia in ordine crescente che decrescente</li>
<li>Supporto alla selezione multipla con shift+click</li>
<li>Possibilità di spostare un elemento singolo in cima o in fondo</li>
<li>Possibilità di effettuare un upload di file multiplo</li>
<li>Possibilità di riordinare gli elementi della cartella in base a un determinato indice.</li>
</ol>
<p>Il prodotto funziona decisamente bene e soprattutto è un ottimo strumento a disposizione dei gestori del sito che, in questo modo, possono avere un controllo più completo dei contenuti delle cartelle.</p>
<p>E poi è completamente tradotto in italiano!, dunque perché non provarlo?</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Cecchi</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>products</dc:subject>
    
    
      <dc:subject>integration</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2012-12-11T14:35:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/internazionalizzazione-javascript-plone">
    <title>Internazionalizzazione e javascript a braccetto in Plone</title>
    <link>http://blog.redturtle.it/internazionalizzazione-javascript-plone</link>
    <description>Ci sono un italiano, uno spagnolo, un francese e un inglese che... vogliono visitare il nostro sito multilingua in Plone. Come trattiamo le traduzioni se c'è tanto javascript?</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Capita di dover sviluppare siti che sfruttano javascript per presentare  dati e testi. Se il sito è multilingua, anche questi dati e questi testi dovranno essere tradotti coerentemente con la lingua in cui si sta visualizzando il sito.</p>
<div class="pageBreak">Se le parole e le frasi da tradurre sono poche, questo compito può essere portato a termine tramite un dizionario. Supponiamo infatti di dover aprire un alert con un messaggio. Sarà sufficiente avere qualcosa di questo tipo:</div>
<pre><br /> // Tramite jQuery si prende la lingua corrente dall'attributo del tag html <br /> var lang = jq('html').attr('lang');<br /><br /> // si dichiara il vocabolario con le traduzioni nelle varie lingue
 var messages = {'it': 'Benvenuti',<br />                 'en': 'Wellcome',<br />                 'es': 'Bienvenido',<br />                 'fr': 'Bienvenue'};<br /><br /> // apriamo l'alert scegliendo la traduzione opportuna.
 alert(messages[lang]);</pre>
<p>Se la pagina web che stiamo creando ha molte parti caricate via javascript, e quindi molti testi e parole da presentare tradotte, questo approccio è scomodo; innanzitutto perché si rischia di dover mantere molto codice solo per le traduzioni.<br />Se siamo in un caso come questo, il sito sviluppato probabilmente è già multilingua e i dati verranno presentati correttamente. Per quanto riguarda i testi da mostrare in javascript, è meglio sfruttare un motore di traduzioni, e in Plone, grazie alla community, un'utility di questo tipo esiste già: <strong>jarn.jsi18n</strong>. Grazie a questo prodotto, infatti, è possibile sfruttare appieno il message factory di plone e tutti i suoi file di traduzioni.</p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<h3>Come usarlo</h3>
<p>Il funzionamento è semplice. Una volta installato il prodotto nel sito, tutto quello che dobbiamo fare è caricare un catalogo e creare un message factory nel javascript che scriviamo:</p>
<pre><pre><br /> // Tramite jQuery si ottiene la lingua corrente dall'attributo del tag html<br /> var lang = jq('html').attr('lang');<span style="text-align: start; float: none; "><br />  <br /> // Dato un dominio di traduzioni e una lingua si ottiene un catalogo dal server;<br /> // questo restituirà al browser un vocabolario tipo<br /> // {...</span><code class="focusRow wrappedText">"from_date": "Dal"</code><span style="text-align: start; float: none; ">, "to_date": "Al", ...}<br /> jarn.i18n.loadCatalog('fta.at', lang);</span><br /> <br /> // Creiamo un message factory javascript che sfrutta il catalogo restituito dal server<br /> mf = jarn.i18n.MessageFactory('fta.at');</pre>
<span style="text-align: start; float: none; "> <br /></span></pre>
<p><span style="text-align: start; float: none; ">Da qui in poi si potrà procedere utilizzando il message factory in modo molto 'plonish':</span><span class="source-code console-message-text"> </span></p>
<pre><span class="source-code console-message-text"><br /> // Si può iniziare a tradurre stringhe<br /> &gt; mf('How to get here')</span><span class="source-code console-message-text"><span><span class="source-code">:<br /> "<span class="source-code console-formatted-string">Come arrivare</span>"<br /><br /></span></span></span></pre>
<p>E se abbiamo dei testi da costruire dinamicamente: <span class="source-code console-message-text"> </span></p>
<pre><span class="console-message-text source-code"> <br /> // Si possono tradurre anche stringhe in modo più dinamico, esattamente come in plone.<br /> &gt; mf('other_results')</span><span class="console-message-text source-code"><span><span class="source-code">;<br /> "<span class="console-formatted-string source-code">... e altre ${results} voci</span>"</span></span></span><span class="source-code console-message-text"><br /><br /> &gt; mf('other_results', {'results': 10})</span><span class="source-code console-message-text"><span><span class="source-code">;<br /> "<span class="source-code console-formatted-string">... e altre 10 voci</span>"<br /><br /></span></span></span></pre>
<h3><br />Under the hood</h3>
<p>Come funziona tutto questo? Guardando il codice, ci si può rendere conto di come cose utili e funzionali possano essere create in modo semplice. Il pacchetto si compone di una vista e di un javascript. La vista è una classica BrowserView Plone che restituirà una stringa json con i dati richiesti:</p>
<pre> <br /> def __call__(self, domain, language):<br />     ...<br /><br />     # Si ottiene l'utility plone per le traduzioni<br />     td = queryUtility(ITranslationDomain, domain)<br />     if td is None or language not in td._catalogs:<br />         return<br /><br />     # Si ottiene il catalogo per il dominio nella lingua richiesta<br />     mo_path = td._catalogs[language][0]<br />     catalog = td._data[mo_path]._catalog<br />     if catalog is None:<br />         td._data[mo_path].reload()<br />         catalog = td._data[mo_path]._catalog<br />     ...<br /><br />     # si restituisce il catalogo in formato json. <br />     # Qualcosa del tipo: '<span style="text-align: start; float: none; ">{...</span><code class="wrappedText focusRow">"from_date": "Dal"</code><span style="text-align: start; float: none; ">, "to_date": "Al", ...}'</span><br />     response.setBody(json.dumps(catalog))<br />     return response</pre>
<p>Il javascript si occupa della chiamata al server per ottenere il catalogo che verrà gestito interamente lato client: una cosa molto interessante in questa gestione è, nei browser che lo consentono, l'uso dello <a class="external-link" href="http://en.wikipedia.org/wiki/Web_storage">storage del browser</a>, tramite cui si riesce a fare caching di questo catalogo e non ricaricarlo ogni volta che si chiama una pagina:</p>
<pre> <br /> // si salva il catalog nello storage con una chiave associata<br /> var key = domain + '-' + language;<br /><br /> // se abbiamo già quella chiave nello storage verificheremo se il catalogo è ancora valido.<br /> if (key in localstorage) {<br />     if ((Date.now() - parseInt(localstorage.getItem(key + '-updated'), 10)) &lt; ttl) {<br />         var catalog = JSON.parse(localstorage.getItem(key));<br />         jarn.i18n._setCatalog(domain, language, catalog);<br />         return;<br />         }<br />     }</pre>
<p>Come sempre, conoscere bene l'architettura e i componenti di Plone permette di svolgere lavori più o meno complicati in modo semplice, ma soprattutto pulito.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Bellenghi</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>javascript</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2012-11-21T13:40:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/sviluppare-applicazioni-plone-interfaccia-web-plomino">
    <title>Sviluppare applicazioni Plone direttamente da interfaccia web con Plomino </title>
    <link>http://blog.redturtle.it/sviluppare-applicazioni-plone-interfaccia-web-plomino</link>
    <description>Breve test di valutazione su Plomino, un pacchetto Plone per la creazione di applicazioni web in stile Lotus ® Notes direttamente da intefaccia grafica WYSIWYG</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><span>E' pratica comune fare test su estensione e prodotti Plone a scopo conoscitivo o per studio. Generalmente si esplorano pacchetti alla ricerca di soluzioni applicabili al lavoro di tutti i giorni, ma non di rado capita di soddisfare semplici curiosità.</span></p>
<p><span> </span><img alt="logo_plomino" class="image-left" src="http://blog.redturtle.it/uploads/copy_of_logo.jpg/@@images/793027f6-f7f6-4b1f-a6ea-572468173265.jpeg" title="logo_plomino" />Recentemente, grazie alla mia doppia partecipazione nei team <strong>Lotus <span>®</span> Notes <span>/ Plone</span></strong>, mi è stato proposto di fare alcuni test su <a class="external-link" href="http://www.plomino.net/">Plomino</a>.</p>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText">Non ho mai avuto l'occasione di usare questo prodotto prima d'ora, nonostante sia disponibile già dalla versione Plone 2.1; il primo passo, quindi, è stato ricercare in rete di documentazione - compito facile, visto che è disponibile un <a class="external-link" href="http://www.plomino.net/">sito</a> web dedicato, ricco di esempi e how-to.</div>
<h3>Installazione</h3>
<p>L'installazione è piuttosto semplice, se si ha dimestichezza con i <strong>buildout</strong>; è già tutto pronto, bastano pochi comandi:<br />(potete trovare i sorgenti <a class="external-link" href="https://github.com/plomino/Plomino">qui</a>)</p>
<pre>io@dev:~$ git clone https://github.com/plomino/Plomino my_app<br />io@dev:~$ cd my_app<br />io@dev:~$ virtualenv .<br />io@dev:~$ . bin/activate<br />io@dev:~$ ./bin/python bootstrap.py<br />io@dev:~$ ./bin/buildout<br />io@dev:~$ ./bin/instance fg </pre>
<p>Fatto!</p>
<p>Come dice <a class="external-link" href="http://http//www.linkedin.com/profile/view?id=3001479&amp;locale=en_US&amp;trk=tyah2">Eric Bréhault</a> (p<span style="text-align: center; ">roject owner),</span> Plomino si propone come “web application builder”, e nella semplicità ha il suo punto di forza.<br />Non a caso, in alcune <a class="external-link" href="http://www.slideshare.net/makinacorpus/plomino">slide</a> proposte da Eric, viene fatto riferimento alla lenta curva di apprendimento di <strong>Plone</strong> e quindi alle difficoltà incontrate dai programmatori meno esperti, per mettere in risalto le doti di Plomino.</p>
<p>A questo scopo il team di sviluppo si è concentrato nel fornire semplici funzioni per la creazione di applicazioni web direttamente da interfaccia grafica, realizzate partendo da concetti facili presi in prestito dal noto e glorioso <strong>Lotus Notes ®</strong>, rendendo Plomino un prodotto che offre l'opportunità di cimentarsi nella creazione di applicazioni relativamente complesse anche ai meno esperti.</p>
<p>Ricca la "dotazione di serie", Plomino di base implementa:</p>
<ul>
<li>Form di inserimento direttamente realizzabili in WYSIWYG, comportamenti hide-when, subform, validazione campi personalizzabile<br /><i>(In Plone potrebbe essere paragonato a</i><i> un content-type dinamico)</i></li>
<li>Tool di generazione chart e mappe</li>
<li>Viste indicizzate e categorizzate<br /><i>(Le viste Lotus corrispondo alle collezioni in Plone, sono praticamente query su database in base al tipo di documento. Una particolarità delle viste Lotus consiste nella possibiltà di raggruppare i risultati per categorie visualizzabili in una vista in sezioni espandibili)</i></li>
<li>ACL/ruoli</li>
<li>Azioni. <br /><i>(Sono molto simili alle action in Plone quindi associabili a pulsanti o link)</i></li>
<li>Form di ricerca <br /><i>(Ricerca personalizzabile)</i></li>
<li>Replica server-to server<br /><i>(Permette di trasferire contenuti e quindi replicare i dati da server a server su database differenti)</i></li>
<li>Agenti schedulati<br /><i>(Programmi che posso essere lanciati a comando o programmati per essere eseguiti in stile cron)</i></li>
<li>Tool di migrazione automatica da Lotus Domino (plomino.dominoimport).<br /><br /> </li>
</ul>
<blockquote class="pullquote"><span style="text-align: center; ">"Solid as Zope, clean as Plone, easier than Django. Plomino"</span></blockquote>
<p>Un'applicazione "tipo" realizzabile in Plomino corrisponde a grandi linee a un'applicazione <strong>Lotus <span>®</span> Notes</strong> client side stile 6.5 (quindi prima dell'introduzione delle Xpages), composta da alcuni form di inserimento e varie viste per raggruppamento e/o filtro dei documenti. Il vantaggio offerto è dato dalla semplicità di realizzazione, interamente da web e con pochi click.</p>
<p><span><span style="text-align: center; "> </span></span>Approfondendo alcuni aspetti tecnici, posso dire che ho trovato molto semplice lavorare con le formulas, perché i metodi messi a disposizione nelle classi rispecchiano molto i metodi noti nell'ambiente di casa <strong><a class="external-link" href="http://en.wikipedia.org/wiki/IBM">IBM</a></strong>, come per esempio:</p>
<ul>
<li><strong>createDocument(self)<br /></strong><i><span>Returns a new empty document</span></i></li>
<li><strong><span class="pre">deleteDocuments(self,</span> <span class="pre">ids=None,</span> <span class="pre">massive=True)<br /></span></strong><i>Batch delete documents from database. If massive is True, the onDelete formula and index updating are not performed</i></li>
<li><strong>getAllDocuments(self)<br /></strong><i>Returns catalog brains for all the PlominoDocument objects stored in the database</i></li>
<li><strong>getCurrentUserRights(self)<br /></strong><i>Returns the current user’s access rights</i></li>
<li><strong><span class="pre">getDocument(self,</span> <span class="pre">docid)<br /></span></strong><i>Returns the PlominoDocument object corresponding to the identifier, or none</i></li>
<li><strong><span class="pre">getForm(self,</span> <span class="pre">formname)<br /></span></strong><i>Returns the PlominoForm object corresponding to the identifier</i></li>
<li><strong>getUserRoles(self)<br /></strong><i>Returns all the roles declared in the database</i></li>
<li><strong>getViews(self)<br /></strong><i>Returns all the PlominoView objects stored in the database</i></li>
<li><strong><span class="pre">isCurrentUserAuthor(self,</span> <span class="pre">doc)<br /></span></strong><i>Returns True if the current user is author of the given document or has the PlominoAuthor right</i></li>
<li><strong>refreshDB(self)<br /></strong>...</li>
</ul>
<p>L'unico linguaggio per interagire con il database in <a class="external-link" href="http://www.plomino.net/">Plomino </a>è Python, diversamente da Lotus che invece ha a sua disposizione LotusScript, Javascript, Java e Formulas, ma onestamente a mio avviso quest'ultimo approccio tende a confondere più che facilitare (+1 per Plomino).</p>
<p>Comoda la possibilità di importare ed esportare le applicazione via XML; gli esempi pubblicati sul sito sono installabili direttamente da interfaccia web.<br /> Non mi piace, invece, l'implementazione del comportamento hide-when, troppo articolata; risulta più pratica nel client di sviluppo Lotus <span>®</span> Notes.</p>
<p>Una cosa che mi ha fatto sorridere è la possibilità di fare quello che tecnicamente corrisponde a una <i>@dblookup</i> in Lotus (<i>in pratica una </i>query su database), anche nelle colonne di visualizzazione all'interno di una vista, ahimè uno dei limiti di Lotus mai superato in 20 anni...</p>
<p>Per iniziare, consiglio la visione di questo semplice tutorial online:</p>
<p><iframe frameborder="0" height="315" src="http://www.youtube.com/embed/GLC-4XFi5XI" width="560"></iframe></p>
<h3>Conlusioni</h3>
<p>In conclusione il mio giudizio è positivo; in genere non amo l'approccio WYSIWYG, però le circostanze assumono un ruolo importante: molto dipende, infatti, dal tipo di applicazione che si vuole sviluppare.<br />Forse Plomino è più adatto a chi non ha modo di approfondire <strong>Plone </strong>o per chi è, semplicemente, alle prime armi.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Nicola Senno</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>python</dc:subject>
    
    
      <dc:subject>Domino</dc:subject>
    
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>TinyMCE</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2012-11-16T10:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/gestire-la-modulistica-con-plone-parte-2">
    <title>Plone: dalla semplice modulistica e carta stampata, alla modulistica on-line  - parte 2</title>
    <link>http://blog.redturtle.it/gestire-la-modulistica-con-plone-parte-2</link>
    <description>Continuiamo la nostra esplorazione di auslfe.formonline.pfgadapter mostrando ora alcuni esempi passo passo ed esplorando le altre funzionalità fornite</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Nel <a href="http://blog.redturtle.it/gestire-la-modulistica-con-plone-parte-1" class="internal-link">precedente articolo</a> abbiamo parlato della <strong>generazione di modulistica online con Plone</strong>; ora andiamo avanti proponendo qualche esempio di implementazione.</p>
<h3>Si comincia</h3>
<p>Il nostro Ente fittizio ha una regola: ogni nuovo dipendente, se necessita di una connessione Internet dal proprio computer, deve richiedere l'attivazione della stessa tramite un modulo (ah... la cara vecchia burocrazia).</p>
<p>Il form di generazione di questo documento si trova in un'area della nostra intranet, una sezione dell'ufficio IT pubblica ed accessibile a tutti.<br />Il form è stato generato dall'ufficio IT stesso chiedendo i pochi dati necessari.</p>
<p><img src="http://blog.redturtle.it/topic_images/auslfe.formonline.pfgadapter/compilazione-modulo/@@images/27d0ac30-e16b-45af-8ef1-5c4a308e0f7a.png" alt="Compilazione modulo" class="image-inline" title="Compilazione modulo" /></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p>Questo PloneFormGen usa il nostro adattatore, configurato per salvare i dati in una cartella della sezione ("<i>Archivio richieste</i>") e per "leggere" l'e-mail del responsabile dell'utente che fa la richiesta dal campo "Indirizzo e-mail del mio responsabile".</p>
<p><img src="http://blog.redturtle.it/topic_images/auslfe.formonline.pfgadapter/adattatore-modulistica-online-compilato/@@images/f466c0fe-8fbb-4c29-828e-4e10369ad238.png" alt="Adattatore modulistica online (compilato)" class="image-inline" title="Adattatore modulistica online (compilato)" /></p>
<p>Sì, avete capito bene!<br />L'integrazione di Plone con un organigramma aziendale è fattibile in vari modi ma la soluzione più semplice (che ha suggerito il cliente stesso) è che <i>sia l'utente richiedente a indicare il proprio responsabile</i>.<br />Questa è ovviamente una delle prima cose che potrebbe non piacervi del prodotto e che qualcuno potrebbe voler personalizzare; che possiamo dire… siete i benvenuti!<br />Ma lasciatemi dire che finora questo approccio ha funzionato molto bene (ora vedremo perché).</p>
<p>Questo stesso prodotto può essere usato (con form completamente diversi) per altre attività: richiesta delle ferie, prenotazione risorse, ...</p>
<h3>Workflow e sicurezza</h3>
<p>Cosa succede dopo?</p>
<p>Al salvataggio del form viene generato un nuovo tipo di contenuto di tipo "<i>Modulistica Online</i>", che non è altro che una copia della pagina Plone.<br />Da qui nasce il motivo per cui è lasciata libertà di selezionare che cosa generare: l'unico limite imposto è che il tipo di destinazione sia una qualche forma di documento (tecnicamente parlando: abbia il campo di testo "text").</p>
<p><img src="http://blog.redturtle.it/topic_images/auslfe.formonline.pfgadapter/condivisione/@@images/8a0e968c-2b5f-4a18-b3fe-88242919d25c.png" alt="Condivisione" class="image-right" title="Condivisione" />L'utente che compila il form deve poi avere i diritti per generare quel contenuto all'interno della cartella di destinazione (nella quotidianità di Plone: deve essere "<i>Contributore</i>" nella cartella).</p>
<p>I dati inseriti nel form vengono quindi raccolti e riversati nel nuovo documento.<br />Il documento rispetta un workfklow specifico del prodotto ed è in uno stato privato, visibile solo all'autore della richiesta, e attende di essere inviato per l'approvazione (l'utente ha la libertà di modificare la richiesta, accedendo al campo di testo).</p>
<p><img src="http://blog.redturtle.it/topic_images/auslfe.formonline.pfgadapter/modulo-completato/@@images/3a0f0378-9c67-4033-ad62-57375f403a4a.png" alt="Modulo completato" class="image-inline" title="Modulo completato" /></p>
<p>Il nostro adattatore ha però intrapreso un'ultima azione prima di abbandonare definitivamente il campo: cercare l'utente con l'e-mail segnalata nel campo del proprio responsabile.<br />Se lo trova: assegna a quell'utente il ruolo di "<i>Editor</i>" nello specifico contesto del contenuto generato. Se non lo trova: riporta un errore e non permette di salvare il modulo.</p>
<p><img src="http://blog.redturtle.it/topic_images/auslfe.formonline.pfgadapter/adattatore-modulistica-online-notifiche/@@images/1ac32e4c-1e46-49e3-b8c3-c427a7ba431f.png" alt="Adattatore modulistica online: notifiche" class="image-right" title="Adattatore modulistica online: notifiche" />Il responsabile riceve un'email (il cui testo è personalizzabile dalla configurazione dell'adattatore) che lo informa della presenza di un documento che attende la sua approvazione e il link per raggiungerlo in un click.</p>
<p>Il responsabile può modificare il contenuto, poi può approvare o rifiutare. Nel primo caso la palla passa all'<strong>evasore</strong> finale, nel secondo caso l'utente viene avvertito del rifiuto.</p>
<p>Chi è l'evasore finale?<br /> E' la persona incaricata della chiusura della richiesta, in questo esempio è il membro dell'IT che si occupa di abilitare l'utente; anche lui può rifiutare o approvare la richiesta (con mail di notifica).<br />Come viene identificato?<br /> L'evasore finale non è (obbligatoriamente) una singola persona ma spesso è un gruppo, e non è responsabile solo della richiesta specifica ma di tutte le richieste di attivazione Internet.<br /> Per questo motivo usiamo semplicemente i ruoli locali di Plone, assegnando il ruolo di "<i>Revisore</i>" al gruppo interessato sulla cartella archivio.</p>
<p>La sicurezza del sistema è data dall'evasore finale. Se un utente tentasse di "fare il furbo" e auto-referenziarsi come responsabile di se stesso avrebbe due problemi:</p>
<ul>
<li>il tutto viene tracciato dal sistema di wokflow di Plone (e questo spesso basta da sé)</li>
<li>l'approvatore finale avrebbe sotto gli occhi che chi ha approvato la richiesta è la persona stessa che l'ha fatta (o comunque un utente non qualificato).</li>
</ul>
<p>Ovviamente tutto questo funziona perché il target del prodotto sono le aziende e gli enti di piccole o medie dimensioni.</p>
<p>Bye bye carta stampata.</p>
<h3>Varianti</h3>
<p>Il prodotto ha poi subìto un paio di evoluzioni che voglio solo accennare.</p>
<p>La prima (e più complessa): tramite il prodotto aggiuntivo <a class="external-link" href="http://pypi.python.org/pypi/auslfe.formonline.tokenaccess">auslfe.formonline.tokenaccess</a> è possibile configurare il form in modo tale che</p>
<ul>
<li>l'utente che effettua la richiesta possa essere un utente anonimo</li>
<li>l'approvatore della richiesta sia esso stesso un utente anonimo</li>
</ul>
<p>Questo viene ottenuto inserendo nella mail inviata al responsabile uno speciale <strong>token segreto</strong> che fornisce temporaneamente i poteri di revisore all'utente.<br />Il token porta l'utente ad un form che permette di eseguire le azioni bi base sul modulo: approvare o rifiutare (magari con un commento alla modifica di workflow).</p>
<p><img src="http://blog.redturtle.it/topic_images/auslfe.formonline.pfgadapter/form-di-approvazione-anonima/@@images/9b421c66-2c0d-47c6-be93-23859dbcceba.png" alt="Form di approvazione anonima" class="image-inline" title="Form di approvazione anonima" /></p>
<p>Tutto questo è possibile perché vengono sfruttate le funzionalità date da <a class="external-link" href="http://pypi.python.org/pypi/collective.powertoken.core/">collective.powertoken</a>.</p>
<p>La seconda variante è una semplificazione del workflow a tre stadi descritto sopra. Ci possono essere alcune procedure aziendali molto semplici dove non è richiesto che un proprio responsabile approvi la richiesta prima di sottoporla all'evasore finale.</p>
<p>I due workflow (standard e semplice) possono coesistere installando in Plone il <i>supporto per le politiche di workflow (CMFPlacefulWorkflow)</i>.</p>
<h3>Conclusione</h3>
<p>Che sia questo prodotto o un altro, ci tenevo a mostrare come con Plone è possibile semplificare i flussi documentali del vostro Ente o della vostra Azienda.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Fabbri</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>plonegov</dc:subject>
    
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2012-10-24T07:40:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>





</rdf:RDF>
