<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jblog</title>
	<atom:link href="http://jblog.it/feed" rel="self" type="application/rss+xml" />
	<link>http://jblog.it</link>
	<description>News e appunti per webmaster</description>
	<lastBuildDate>Thu, 14 Jan 2010 19:23:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Google Docs permette l&#8217;upload di file&#8230; di qualsiasi tipo!</title>
		<link>http://jblog.it/2010/01/13/google-docs-upload-storage-file-qualsiasi-tipo_829.html</link>
		<comments>http://jblog.it/2010/01/13/google-docs-upload-storage-file-qualsiasi-tipo_829.html#comments</comments>
		<pubDate>Wed, 13 Jan 2010 04:00:34 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Internet news]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[google docs]]></category>
		<category><![CDATA[online storage]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=829</guid>
		<description><![CDATA[Google fa un grosso passo avanti con Docs: 1 gigabyte di spazio e upload di file di qualsiasi tipo, non solo di documenti. Finalmente tutti i documenti a portata di mano, senza più pendrive, memory card e documenti dimenticati chissà dove!]]></description>
			<content:encoded><![CDATA[<p><a title="Google Docs permette l’upload di file… di qualsiasi tipo!" href="http://jblog.it/2010/01/13/google-docs-upload-storage-file-qualsiasi-tipo_829.html"><img class="alignnone size-full wp-image-830" title="Google Docs - Upload di file e 1 gigabyte di spazio gratuito" src="http://jblog.it/wp-content/uploads/2010/01/docs_new_upload1.gif" alt="Google Docs - Upload di file e 1 gigabyte di spazio gratuito" width="540" height="104" /></a></p>
<p>Google fa un grosso passo avanti con Docs: 1 gigabyte di spazio e upload di file di qualsiasi tipo, non solo di documenti.</p>
<p>Beh&#8230; finalmente! Io, che uso sempre Google Docs per appuntarmi idee e articoli per questo blog, ne sentivo l&#8217;esigenza. Perché? Semplicemente per avere tutto in un posto ed evitare di aprire più siti o utilizzare pendrive che spesso si dimenticano. <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' title="Google Docs permette lupload di file... di qualsiasi tipo!" /> </p>
<h3>Alcuni dettagli</h3>
<p><strong>Per tutti gli utenti.</strong> Oltre al servizio online, l&#8217;upload è stato implementato anche sulla suite stand-alone.</p>
<p><strong>Estensione dello spazio.</strong> Lo spazio fornito gratuitamente è pari a <strong>1 gigabyte</strong>. Tuttavia è possibile esternderlo alla modica cifra di $0,25 <em>all&#8217;anno</em> per gigabyte.</p>
<p><strong>Dimensione dei file</strong>. Potranno essere caricati solo file inferiori <strong>a 250 mebagbyte</strong>.</p>
<p><span id="more-829"></span></p>
<p><img class="alignnone size-full wp-image-831" title="Uploading di file | by ReadWriteWeb" src="http://jblog.it/wp-content/uploads/2010/01/docs_uploading.gif" alt="Uploading di file | by ReadWriteWeb" width="540" height="240" /></p>
<p><strong>Condivisione.</strong> Così come succede già per i documenti, i file potranno essere condivisi con tutti gli utenti di Docs. Invece non è ancora presente una funzionalità per condividere documenti e altri file su siti di terze parti, ma il responsabile precisa che questa possibilità non è stata scartata del tutto.</p>
<p><strong>Lavorare con i file.</strong> Naturalmente non sarà possibile lavorare su tutti i tipi di file caricati con Docs. Questo attualmente è possibile solo con i PDF, i file della suite Microsoft Office e i formati nativi di Docs. Per tutti gli altri tipi di file sarà necessario scaricarli sul proprio pc e lavorarci su con l&#8217;applicazione necessaria.</p>
<p><strong>Niente &#8220;cloud&#8221;.</strong> Il responsabile del progetto avverte che non è un disco virtuale, in quanto non c&#8217;é un client con il compito di aiutarti a sincronizzare i terabyte. <em>A questo proposito invito a cercare i rumori e le indiscrezioni sul progetto di Google chiamato <strong>GDrive</strong></em>.</p>
<p><!--adv300--></p>
<h3>Vijay Bangaru, Google Docs product manager</h3>
<blockquote><p>this is a natural extension and progression of what we&#8217;ve been doing with Google Docs</p></blockquote>
<blockquote><p>the idea behind this feature is that it&#8217;s really an opportunity for Google to invest in cloud storage and provide value added services to its users around sharing files, uploading files and being able to collaborate and search on all of that content</p></blockquote>
<p><small>&#8220;Questa è una naturale estensione e miglioramento a dimostrare quanto è stato fatto con Google Docs. L&#8217;idea dietro a questa funzionalità consiste nel fatto che per Google è una grossa opportunità investire nel cloud storage fornendo ricchi servizi riguardo la condivisione e l&#8217;upload di file, per incentivare la collaborazione e la ricerca su questi contenuti.&#8221;</small></p>
<h5>Fonti</h5>
<p><a title="Google Docs to Allow Storage of Any Type of File" href="http://www.pcworld.com/article/186738/google_docs_to_allow_storage_of_any_type_of_file.html" target="_blank">http://www.pcworld.com/article/186738/google_docs_to_allow_storage_of_any_type_of_file.html</a></p>
<p><a title="Google Docs: Now for Storage as much as Collaboration" href="http://www.readwriteweb.com/enterprise/2010/01/google-docs-now-for-storage-as.php" target="_blank">http://www.readwriteweb.com/enterprise/2010/01/google-docs-now-for-storage-as.php</a></p>
<p><span class="highlight_green">Per me questa è una bella novità&#8230; Credo che mi aiuterà molto e migliorerà la mia esperienza con Google Docs. <strong>Tu che ne pensi?</strong></span></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=829&type=feed" alt=" Google Docs permette lupload di file... di qualsiasi tipo!"  title="Google Docs permette lupload di file... di qualsiasi tipo!" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2010/01/13/google-docs-upload-storage-file-qualsiasi-tipo_829.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Autenticazione HTTP &#8220;basic&#8221; su server Apache</title>
		<link>http://jblog.it/2010/01/11/autenticazione-http-basic-server-apache-mod_auth-htaccess-htpasswd-proteggere-file-directory_818.html</link>
		<comments>http://jblog.it/2010/01/11/autenticazione-http-basic-server-apache-mod_auth-htaccess-htpasswd-proteggere-file-directory_818.html#comments</comments>
		<pubDate>Mon, 11 Jan 2010 05:00:01 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Sicurezza]]></category>
		<category><![CDATA[mod_auth]]></category>
		<category><![CDATA[proteggere directory]]></category>
		<category><![CDATA[proteggere file]]></category>
		<category><![CDATA[proteggere login]]></category>
		<category><![CDATA[sicurezza apache]]></category>
		<category><![CDATA[sicurezza directory]]></category>
		<category><![CDATA[sicurezza file]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=818</guid>
		<description><![CDATA[L'autenticazione HTTP permette di implementare un controllo degli accessi basato su username e password, semplice da realizzare, stabile e sicuro. In questo articolo: come proteggere file e directory con username e password. Infine, come personalizzare la pagina di errore 401.]]></description>
			<content:encoded><![CDATA[<p><a title="Autenticazione HTTP “basic” su server Apache" href="http://jblog.it/2010/01/11/autenticazione-http-basic-server-apache-mod_auth-htaccess-htpasswd-proteggere-file-directory_818.html"><img src="http://jblog.it/wp-content/uploads/2010/01/apachesecurity_bouncer.jpg" alt="apachesecurity bouncer Autenticazione HTTP basic su server Apache" width="540" height="322" title="Autenticazione HTTP basic su server Apache" /></a></p>
<p>Ogni applicazione viene progettata e sviluppata con uno o più sistemi di autenticazione e sicurezza. Pensiamo al login di un sito web, al controllo degli utenti o alla gestione dei permessi.</p>
<p>L&#8217;autenticazione HTTP permette di implementare un controllo degli accessi basato su username e password, semplice da realizzare, stabile e sicuro.</p>
<p><strong class="highlight_green">PRO.</strong> Questo tipo di autenticazione offre un più rigido controllo sugli utenti e una maggiore stabilità rispetto al classico login. Il controllo degli utenti è <strong>molto rigido</strong> in quanto è l&#8217;amministratore a inserire nuove coppie di username e password, al contrario della procedura di registrazione durante la quale sono gli utenti a inserire i dati. Riguardo la <strong>stabilità</strong>, il discorso è molto simile a quello che si fa con i cms: un modulo Apache scritto e controllato da centinaia di sviluppatori è assai meno probabile che fallisca rispetto alle procedure di login scritte da un team ristretto di programmatori.</p>
<p><span id="more-818"></span><strong class="highlight_red">CONTRO.</strong> Il primo limite sta proprio nel fatto che per inserire un nuovo utente bisogna andare a scrivere &#8220;a mano&#8221; i dati per l&#8217;autenticazione, problema comunque risolvibile con uno script che accede al file dei dati per l&#8217;autenticazione, nel caso si voglia una procedura di registrazione automatizzata. Un altro limite è la difficoltà di gestire l&#8217;utente connesso, ad esempio, per avere un&#8217;area personale o per memorizzare i prodotti del carrello, tutte cose facilmente realizzabili nel caso di un login con database.</p>
<p><strong>AUTENTICAZIONE HTTP con PHP » <a href="http://php.net/manual/en/features.http-auth.php" target="_blank">http://php.net/manual/en/features.http-auth.php</a></strong></p>
<p><span class="highlight_orange"><strong>ATTENZIONE.</strong> Potrebbe succedere che <strong>in locale</strong> l&#8217;autenticazione HTTP non funzioni. Invece di perdere tempo inutilmente provala direttamente sul tuo spazio web, magari in una directory di test. A me è successo così! Per saperne di più segui <a href="http://forum.html.it/forum/showthread.php?s=&amp;threadid=1376669" target="_blank">questa discussione sul forum di html.it</a> che, tutt&#8217;ora non ha risposte <img src='http://jblog.it/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' title="Autenticazione HTTP basic su server Apache" /> .</span></p>
<h4>SOMMARIO</h4>
<dl>
<dt><strong><a href="#buon-motivo-autenticazione-http">Un buon motivo per l’autenticazione HTTP</a></strong></dt>
<dd><small>Una delle tante situazioni che ti dovrebbe far capire il senso dell&#8217;autenticazione HTTP.</small></dd>
<dt><strong><a href="#diverse-autenticazioni-http">Le diverse autenticazioni HTTP</a></strong></dt>
<dd><small>La differenza fra le diverse autenticazioni.</small></dd>
<dt><strong><a href="#esempio-veloce">Un esempio veloce</a></strong></dt>
<dd><small>Esempio facile da capire per introdurre l&#8217;argomento.</small></dd>
<dt><strong><a href="#direttive-apache">Le direttive Apache</a></strong></dt>
<dd><small>Una panoramica sulle direttive Apache che servono per implementare l&#8217;autenticazione HTTP, in modo da comprendere meglio cosa stiamo facendo.</small></dd>
<dt><strong><a href="#ottenere-percorso-assoluto">Ottenere il percorso assoluto</a></strong></dt>
<dd><small>Conoscere il percorso assoluto del server è necessario per impostare correttamente il file .htaccess.</small></dd>
<dt><strong><a href="#file-htpasswd">Il file delle password: .htpasswd</a></strong></dt>
<dd><small>Il file che contiene le coppie &#8220;username:password&#8221;.</small></dd>
<dt><strong><a href="#file-htgroup">Il file dei gruppi di utenti: .htgroup</a></strong></dt>
<dd><small>Il file (opzionale) in cui impostare i gruppi di utenti.</small></dd>
<dt><strong><a href="#autenticazione-http-in-pratica">Autenticazione HTTP in pratica</a></strong></dt>
<dd>
<div style="padding-left: 10px;"><small><a href="#proteggere-file">Come proteggere i file</a><br />
<a href="#proteggere-directory">Come proteggere una directory</a><br />
<a href="#nota-prestazioni">Una nota sulle prestazioni</a><br />
<a href="#creare-eccezioni">Creare eccezioni</a></small></div>
</dd>
<dt><strong><a href="#pagina-errore-401">Personalizza la pagina di errore “401 Authorization Required”</a></strong></dt>
<dd><small>Come personalizzare la pagina di errore che appare quando non si inseriscono i dati corretti.</small></dd>
</dl>
<h5>Note sull&#8217;articolo</h5>
<p>Data la complessità degli argomenti trattati cerco di dare il giusto supporto anche agli sviluppatori che si sono avvicinati da poco all&#8217;uso del server Apache. Infatti per buona parte dell&#8217;articolo vengono fornite tutte quelle conoscenze di base richieste per una buona comprensione dell&#8217;autenticazione HTTP al fine di <strong>evitare un semplice copia-incolla</strong> che difficilmente porterà ai risultati sperati.</p>
<p><strong>Se le direttive e il funzionamento del server Apache ti sono familiari</strong> puoi benissimo andare direttamente a vedere come implementare l&#8217;autenticazione HTTP iniziando a leggere dal paragrafo &#8220;<a title="Autenticazione HTTP in pratica" href="#autenticazione-http-in-pratica">Autenticazione HTTP in pratica</a>&#8220;.</p>
<h2 id="buon-motivo-autenticazione-http">Un buon motivo per l&#8217;autenticazione HTTP</h2>
<p>Pensa a un grosso sito ecommerce. Questo sarà diviso almeno in 4 aree: publica, utenti, gestione, amministrazione.</p>
<p>Nell&#8217;area <em>pubblica</em> potranno accedervi tutti, nell&#8217;area <em>utenti</em> solo gli utenti registrati, nell&#8217;area <em>gestione</em> solo gli addetti alle normali mansioni, come la moderazione dei commenti sui prodotti, e nell&#8217;area <em>amministrazione</em> solo pochi amministratori che, tra gli altri, avranno il compito di aggiungere nuovi amministratori e gestirne i permessi. Data la delicatezza dell&#8217;area <em>amministrazione</em> è necessario proteggerla il più possibile.</p>
<p>Ed è qui che entra in gioco l&#8217;autenticazione HTTP, che verrà implementata per creare una <strong>ulteriore barriera</strong> prima di accedere alla pagina <em>login</em>. In questo modo per accedere all&#8217;area <em>amministrazione</em> sarà necessario inserire due <strong>diverse</strong> coppie di username e password, con il conseguente rafforzamento della sicurezza.</p>
<p><img class="alignnone size-full wp-image-820" title="esempio ecommerce autenticazione http" src="http://jblog.it/wp-content/uploads/2010/01/example_http_sitemap.jpg" alt="example http sitemap Autenticazione HTTP basic su server Apache" width="540" height="276" /></p>
<p>Naturalmente, questo è solo uno dei tanti motivi per sfruttare l&#8217;autenticazione HTTP per rendere più sicuro il proprio sito.</p>
<h2 id="diverse-autenticazioni-http">Le diverse autenticazioni HTTP</h2>
<p>Su un server Apache si possono implementare almeno 3 tipi di autenticazione HTTP.</p>
<p><strong>Base.</strong> Utilizza dei file di testo per l&#8217;autenticazione. Il modulo necessario è <strong>mod_auth.c</strong>, ed è considerato uno dei moduli di base. In ogni caso dai un&#8217;occhiata ai servizi del tuo provider oppure alle informazioni php, con la funzione <em>phpinfo()</em>.</p>
<p><strong>DBM.</strong> Utilizza dei file di tipo DBM per l&#8217;elenco di username e password. Il modulo necessario è <strong>mod_auth_dbm.c</strong>.</p>
<p><strong>Digest.</strong> Basata sull&#8217;algoritmo di hashing md5.  Il modulo necessario è <strong>mod_auth_digest.c</strong>. Questo modulo  è ancora in fase di test e alcune funzioni non sono ancora correttamente implementate.</p>
<h2 id="esempio-veloce">Un esempio veloce</h2>
<p>Per darti l&#8217;idea di quello che dobbiamo fare ti faccio un esempio veloce.</p>
<h5 id="httpauthbase_ex1">File .htaccess</h5>
<pre>AuthType Basic
AuthName "Restricted Files" #messaggio personalizzato
AuthUserFile /percorso-assoluto/.htpasswd
Require valid-user</pre>
<p><small>N.B. non ho scritto il vero percorso assoluto per questioni di sicurezza. Credo che il mio provider non vorrebbe che lo sventolassi in giro! <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' title="Autenticazione HTTP basic su server Apache" />  </small></p>
<h5 id="httpauthbase_ex2">File .htpasswd</h5>
<pre>admin:86dGPOHvD26i2
admin2:165491czyZTp2
admin3:29p7hc19vPpm6</pre>
<p>dove username e password della prima riga sono &#8220;admin&#8221;.</p>
<h5>Demo</h5>
<p>Se non ti basta lo screenshot puoi provarlo andando su <a href="http://test.jblog.it/http_auth_base/" target="_blank">http://test.jblog.it/http_auth_base/</a> (username e password sono entrambe &#8220;admin&#8221;).</p>
<p><img class="alignnone size-full wp-image-821" title="richiesta dati autenticazione http" src="http://jblog.it/wp-content/uploads/2010/01/screenshot_httpauth.jpg" alt="screenshot httpauth Autenticazione HTTP basic su server Apache" width="540" height="275" /></p>
<h2 id="direttive-apache">Le direttive Apache</h2>
<p>Le direttive principali per implementare l&#8217;autenticazione HTTP.</p>
<p><strong>AuthType.</strong> Imposta il tipo di autenticazione: basic o digest.</p>
<p><strong>AuthName.</strong> Messaggio o descrizione personalizzata; utile per dare indicazioni.</p>
<p><strong>AuthUserFile.</strong> File degli username e delle password, generalmente chiamato .htpasswd.</p>
<p><strong>AuthGroupFile.</strong> File dei gruppi di utenti.</p>
<p><strong>Require.</strong> Filtra gli utenti abilitati all&#8217;accesso. Generalmente si utilizza <em>valid-user</em> per indicare che l&#8217;accesso è permesso a tutti gli utenti validi, ad esempio quelli che inseriscono credenziali valide. Alternativamente si possono utilizzare <em>user</em> e <em>group</em> seguiti rispettivamente da una lista di utenti o di gruppi, separati da spazi.</p>
<p><strong>Satisfy.</strong> Gestisce la politica degli accessi. Funziona solo se sono utilizzate contemporaneamente le direttive <em>Allow</em> e <em>Require</em>. Con <em>All</em> fa in modo che entrambe le condizioni siano verificate per convalidare l&#8217;accesso, invece con <em>Any</em> basta che sia verificata solo una delle condizioni.</p>
<h2 id="ottenere-percorso-assoluto">Ottenere il percorso assoluto</h2>
<p>Per collegare il file delle password (.htpasswd) e dei gruppi al file .htaccess non ci si può limitare al percorso relativo, ma è necessario il <strong>percorso assoluto</strong>. Per internderci, il percorso assoluto è quello che sul nostro pc inizia con &#8220;C:/&#8230;&#8221;.</p>
<p>Uno dei modi per ottenere il percorso assoluto del server è quello di creare ed eseguire il seguente <strong>script php</strong>:</p>
<pre>&lt;?php
   echo $_SERVER['DOCUMENT_ROOT'];
?&gt;</pre>
<p>dove la variabile <code>$_SERVER['DOCUMENT_ROOT']</code> contiene il percorso assoluto della directory in cui si trovano i file del tuo sito.</p>
<h4>Se non sei pratico/a di php segui queste istruzioni</h4>
<ol>
<li>Rinomina lo script in &#8220;doc_root.php&#8221;</li>
<li>Caricalo nella directory principale del tuo sito</li>
<li>Eseguilo scrivendo http://www.tuosito.com/doc_root.php</li>
<li> Copia e conserva il testo fornito in output, cioè il percorso assoluto</li>
</ol>
<p><img class="alignnone size-full wp-image-825" title="percorso assoluto | document root" src="http://jblog.it/wp-content/uploads/2010/01/doc_root.jpg" alt="doc root Autenticazione HTTP basic su server Apache" width="540" height="161" /></p>
<p><strong>ATTENZIONE.</strong> Ti accorgerai anche tu che il percorso ottenuto dallo script php <strong>non è completo</strong>. Basterà guardare alla fine per osservare l&#8217;assenza del nome della directory in cui si trova il file .htpasswd. Quasi sempre è necessario <strong>completare il percorso assoluto</strong> scrivendo manualmente la directory in cui si trova il file .htpasswd. Un po&#8217; di pazienza e tutto funzionerà a dovere! <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' title="Autenticazione HTTP basic su server Apache" /> </p>
<h2 id="file-htpasswd">Il file delle password: .htpasswd</h2>
<p>Il  file .htpasswd deve contenere la lista di username e password che verranno utilizzati per l&#8217;autenticazione (vedi l&#8217;esempio in basso).</p>
<p><strong>Il nome del file.</strong> Il file dei dati di autenticazione puoi rinominarlo a tuo piacimento; non è obbligatorio chiamarlo &#8220;.htpasswd&#8221;. Tuttavia è consigliabile rispettare il modello &#8220;.htxxxxxx&#8221;, cioè farlo iniziare sempre con &#8220;.ht&#8221; cambiando solo il resto. Esempi validi: &#8220;.htpassword&#8221;, &#8220;.ht_dati_accesso&#8221;.</p>
<p><strong>Criptare le password.</strong> Al contrario dell&#8217;username, che viene scritto &#8220;in chiaro&#8221;, la password deve essere criptata. Fortunatamente su internet si possono trovare molti siti che si occupano non solo di criptare la password ma anche di impostare il file .htpasswd.</p>
<h5>Strumenti utili per .htpasswd</h5>
<p><a href="http://www.htaccesstools.com/htpasswd-generator/" target="_blank">http://www.htaccesstools.com/htpasswd-generator/</a><br />
<a href="http://www.wmtips.com/tools/htpasswd-generator/" target="_blank">http://www.wmtips.com/tools/htpasswd-generator/</a><br />
<a href="http://www.4webhelp.net/us/password.php" target="_blank">http://www.4webhelp.net/us/password.php</a><br />
<a href="http://www.clockwatchers.com/htaccess_tool.html" target="_blank">http://www.clockwatchers.com/htaccess_tool.html</a><br />
<a href="http://htmlfixit.com/cgi-bin/tools/htaccess/index.pl" target="_blank">http://htmlfixit.com/cgi-bin/tools/htaccess/index.pl</a><br />
<a href="http://tools.dynamicdrive.com/password/" target="_blank">http://tools.dynamicdrive.com/password/</a><br />
<a href="http://www.softspecialist.com/i/htaccess-password-generator-htpasswd-encryption-tool.htm" target="_blank">http://www.softspecialist.com/i/htaccess-password-generator-htpasswd-encryption-tool.htm</a></p>
<p><strong>Per iniziare.</strong> Se non ti va o non riesci a  utilizzare questi tools puoi iniziare subito con questi dati: <span style="font-family: Courier New;">admin:86dGPOHvD26i2</span>, dove username e password sono entrambi admin.</p>
<p><strong>Scrivere il file .htpasswd. </strong>Per creare un file .htpasswd è necessario seguire solo <strong>2 semplici regole</strong>:</p>
<ol>
<li> username e password devono essere separate dai due punti &#8220;:&#8221;</li>
<li>inserire una coppia <code>&lt;username&gt;:&lt;password&gt;</code> per riga</li>
</ol>
<h5>Esempio di file .htpasswd</h5>
<pre>admin:86dGPOHvD26i2
admin2:165491czyZTp2
admin3:29p7hc19vPpm6</pre>
<p><span class="highlight_red"><strong>Per una maggior sicurezza</strong> sulla documentazione Apache viene consigliato di inserire i file .htpasswd all&#8217;esterno della directory principale del sito in modo da renderli totalmente inaccessibili dall&#8217;esterno, ad esempio tramite browser. Purtroppo non sempre è possibile inserire dei file all&#8217;esterno della directory principale, soprattutto se hai un hosting di base.</span></p>
<h2 id="file-htgroup">Il file dei gruppi di utenti: .htgroup</h2>
<p>Il  file dei gruppi di utenti deve contenere l&#8217;elenco dei gruppi in corrispondenza dei quali si scrive la lista di username appartenenti (vedi l&#8217;esempio in basso). Questo file è <strong>direttamente collegato al file .htpasswd</strong> in quanto gli username appartenenti a ciascun gruppo sono proprio quelli scritti nel file .htpasswd.</p>
<p><strong>Il nome del file.</strong> Il file dei dati di autenticazione puoi rinominarlo a tuo piacimento. Tuttavia è consigliabile rispettare il modello &#8220;.htxxxxxx&#8221;, cioè farlo iniziare sempre con &#8220;.ht&#8221; cambiando solo il resto. Esempi validi: &#8220;.htgruppi&#8221;, &#8220;.ht_lista_gruppi&#8221;. Ho preferito chiamarlo &#8220;.htgroup&#8221; per avere una maggior chiarezza nella scrittura dell&#8217;articolo.</p>
<p><strong>A cosa serve?</strong> Dividere gli utenti per gruppi è necessario, ad esempio, nel caso in cui si hanno diverse aree alle quali devono accedere diversi gruppi di utenti. Inoltre è anche comodo per la direttiva <em>Require </em>perché invece di inserire tutti gli username si evita di &#8220;sporcare&#8221; eccessivamente il file .htaccess limitandosi a scrivere pochi gruppi.</p>
<p><img class="alignnone size-full wp-image-822" title="relazioni e flusso htaccess htpasswd htgroup" src="http://jblog.it/wp-content/uploads/2010/01/http_auth_flow.jpg" alt="http auth flow Autenticazione HTTP basic su server Apache" width="540" height="211" /></p>
<h4>Esempio</h4>
<p>Nota la &#8220;pulizia&#8221; della <em>versione 2</em> del file .htaccess rispetto alla <em>versione 1</em>. Probabilmente non ti sembrerà niente di così rivoluzionario&#8230; Pensa in grande! Pensa a una lista di 30 username per ogni gruppo!</p>
<h5>File .htpasswd (valido per le due versioni del file .htaccess)</h5>
<pre>admin:86dGPOHvD26i2
admin2:165491czyZTp2
admin3:29p7hc19vPpm6
admin4:86dGPOHvD26i2
admin5:165491czyZTp2
admin6:29p7hc19vPpm6
admin7:86dGPOHvD26i2
admin8:165491czyZTp2
admin9:29p7hc19vPpm6</pre>
<h5>File .htaccess [versione 1] (senza dividere gli utenti in gruppi)</h5>
<pre>&lt;Files index_gruppo1.php&gt;
   AuthType Basic
   AuthName "Fai parte del gruppo 1?"
   AuthUserFile /percorso_assoluto/.htpasswd
   AuthGroupFile /percorso_assoluto/.htgroup
   Require user admin admin2 admin3 admin4 admin5
&lt;/Files&gt;

&lt;Files index_gruppo2.php&gt;
   AuthType Basic
   AuthName "Fai parte del gruppo 2?"
   AuthUserFile /percorso_assoluto/.htpasswd
   AuthGroupFile /percorso_assoluto/.htgroup
   Require user admin6 admin7 admin8 admin9
&lt;/Files&gt;</pre>
<h5>File .htaccess [versione 2] (utenti suddivisi in gruppi)</h5>
<pre>&lt;Files index_gruppo1.php&gt;
   AuthType Basic
   AuthName "Fai parte del gruppo 1?"
   AuthUserFile /percorso_assoluto/.htpasswd
   AuthGroupFile /percorso_assoluto/.htgroup
   Require group gruppo1
&lt;/Files&gt;

&lt;Files index_gruppo2.php&gt;
   AuthType Basic
   AuthName "Fai parte del gruppo 2?"
   AuthUserFile /percorso_assoluto/.htpasswd
   AuthGroupFile /percorso_assoluto/.htgroup
   Require group gruppo2
&lt;/Files&gt;</pre>
<h5>.htgroup (per il file .htaccess versione 2)</h5>
<pre>gruppo1: admin admin2 admin3 admin4 admin5
gruppo2: admin6 admin7 admin8 admin9</pre>
<p><span class="highlight_green"><strong>Demo.</strong> Per farti capire meglio di cosa sto parlando vai su <a href="http://test.jblog.it/http_auth_group/" target="_blank">http://test.jblog.it/http_auth_group/</a>.</span></p>
<p><span class="highlight_red"><strong>Per una maggior sicurezza</strong> sulla documentazione Apache viene consigliato di inserire i file .htgroup all&#8217;esterno della directory principale del sito in modo da renderli totalmente inaccessibili dall&#8217;esterno, ad esempio tramite browser. Purtroppo non sempre è possibile inserire dei file all&#8217;esterno della directory principale, soprattutto se hai un hosting di base.</span></p>
<h2 id="autenticazione-http-in-pratica">Autenticazione HTTP in pratica</h2>
<p><!--adv300--></p>
<h3 id="proteggere-file">Come proteggere i file</h3>
<p>Per proteggere uno o più file si possono utilizzare le direttive <code>&lt;Files&gt;</code> o <code>&lt;FilesMatch&gt;</code>.</p>
<p>La seconda è da preferire quando i file da proteggere si devono riconoscere tramite regex. In pratica, la <strong>direttiva <code>&lt;FilesMatch&gt;</code></strong> deve essere utilizzata quando  si devono proteggere più file con gli stessi criteri oppure quando non si è sicuri del nome, ad esempio quando non si sa se l&#8217;estensione è scritta in minuscolo o in maiuscolo.</p>
<p>La <strong>direttiva <code>&lt;Files&gt;</code></strong> è da preferire solo quando il file è uno solo e si è sicuri del nome.</p>
<h5>Uso della direttiva &lt;FilesMatch&gt;</h5>
<pre># 1) protegge i file secret1.php e secret2.php
# 2) [pP][hH][pP] perchè non si è sicuri di come è scritta l'estensione
&lt;FilesMatch "(secret1|secret2)\.[pP][hH][pP]"&gt;
   AuthType Basic
   AuthName "Accesso alle pagine segrete..."
   AuthUserFile /percorso_assoluto/.htpasswd
   Require valid-user
&lt;/FilesMatch&gt;</pre>
<h5>Uso della direttiva &lt;Files&gt;</h5>
<pre>&lt;Files secret1.php&gt;
   AuthType Basic
   AuthName "Accesso alla pagina segreta..."
   AuthUserFile /percorso_assoluto/.htpasswd
   Require valid-user
&lt;/Files&gt;

&lt;Files secret2.php&gt;
   AuthType Basic
   AuthName "Accesso alla pagina segreta..."
   AuthUserFile /percorso_assoluto/.htpasswd
   Require valid-user
&lt;/Files&gt;</pre>
<h3 id="proteggere-directory">Come proteggere una directory</h3>
<p>Teoricamente si dovrebbe agire come per i file, utilizzando però le direttive <code>&lt;Directory&gt;</code> e <code>&lt;DirectoryMatch&gt;</code>.</p>
<p><strong>Problema. </strong>A meno che tu non abbia accesso al file di configurazione del server o del virtual host, non è possibile farlo in quanto le direttive <code>&lt;Directory&gt;</code> e <code>&lt;DirectoryMatch&gt;</code> <strong>NON possono essere utilizzate nel file .htaccess</strong>. A questo proposito vorrei ringraziare Enoa del <a title="Come utilizzare le direttive &lt;Directory&gt; e &lt;DirectoryMatch&gt;?" href="http://forum.html.it/forum/showthread.php?s=&amp;threadid=1376012" target="_blank">forum di html.it</a>.</p>
<p><strong>Soluzione. </strong>Inserire un file .htaccess direttamente nelle directory da proteggere. Tutto qui! <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' title="Autenticazione HTTP basic su server Apache" />  Ricordati di non inserire i file .htpasswd e .htgroup nella directory da proteggere.</p>
<h5>Esempio di file .htaccess da inserire nella directory da proteggere</h5>
<pre>AuthType Basic
AuthName "Accesso alla Directory XXX..."
AuthUserFile /percorso_assoluto/.htpasswd
Require valid-user</pre>
<h3 id="nota-prestazioni">Una nota sulle prestazioni</h3>
<p>Per sua natura l&#8217;implementazione dell&#8217;autenticazione HTTP comporta un <strong>leggero peggioramento delle prestazioni</strong>. In pratica, ogni volta che si accede a dei file protetti direttamente o indirettamente (cioè all&#8217;interno di una directory protetta) il server controlla se la richiesta HTTP è autorizzata ad essere soddisfatta. In altre parole, ogni &#8211; e sottolineo ogni &#8211; richiesta HTTP è soggetta a un controllo da parte del server per verificare se questa possiede le autorizzazioni necessarie.</p>
<p>Quindi, prima di implementare un&#8217;autenticazione HTTP chiediti quanto influirà questo, seppur leggero, abbassamento di prestazioni.</p>
<h3 id="creare-eccezioni">Creare eccezioni</h3>
<p>Nonostante ci si autentichi con successo potrebbero sorgere altri problemi. Gli script utilizzati con <strong>tecniche Ajax</strong> oppure i file <strong>XML</strong> richiamati da animazioni Flash potrebbero non essere letti in quanto la richiesta di questi file non proverrebbe dal browser con cui ci si è autenticati e il server Apache potrebbe considerarla come una <strong>richiesta non autorizzata</strong>.</p>
<p>Un&#8217;altra situazione per la quale è necessario creare delle eccezioni si ha quando ci sono dei <strong>file o sottodirectory ad accesso libero in una directory protetta</strong>.</p>
<h4><strong>Soluzione veloce</strong></h4>
<p>Se il sito è stato <strong>sviluppato completamente da te</strong>, non avrai grosse difficoltà ad applicare questa soluzione: ti basterà solo modificare qualche riga di codice.</p>
<p>Inserire i file ad accesso libero in una <strong>sottodirectory da &#8220;liberare&#8221;</strong> dalla protezione dell&#8217;autenticazione HTTP.</p>
<ol>
<li>Crea una sottodirectory</li>
<li>Inserisci tutti i file e le directory da &#8220;liberare&#8221;</li>
<li>Inserisci in questa sottodirectory un nuovo file .htaccess con il seguente codice</li>
</ol>
<pre>Allow from All
Satisfy Any</pre>
<p>Queste due righe disattivano l&#8217;inserimento dei dati per l&#8217;autenticazione. Con <code>Satisfy Any</code> si stabilisce che è sufficiente verificare una delle due condizioni tra <code>Require</code> (che si trova nel file .htaccess della directory superiore) e <code>Allow</code>. Quindi, poiché con <code>Allow from All</code> diciamo ad server che l&#8217;accesso è &#8220;permesso a tutti&#8221; una delle due direttive è sempre verificata.</p>
<h4>Soluzione complessa</h4>
<p>Se il sito è <strong>basato su un CMS</strong> o comunque <strong>non è stato sviluppato da te</strong> non è possibile spostare file e directory in quanto non sapremmo dove effettuare le modifiche al codice. Questa soluzione infatti permette di &#8220;liberare&#8221; file e directory lasciandoli tutti al loro posto.</p>
<p><strong>Liberare una directory</strong>. Come per la soluzione veloce,  basta inserire al suo interno un nuovo file .htaccess con il seguente codice:</p>
<pre>Allow from All
Satisfy Any</pre>
<p><strong>Liberare uno o più file. </strong>Utilizzando le direttive <code>&lt;Files&gt;</code> o <code>&lt;FilesMatch&gt;</code> è possibile liberare rispettivamente uno o più files. Utilizzare <code>&lt;Files&gt;</code> per liberare dei file in base al <strong>nome esatto</strong> mentre<code> &lt;FilesMatch&gt;</code> per liberare dei file riconoscendoli tramite espressioni regolari.</p>
<p><strong>Il file index.php.</strong> Generalmente se si accede a una directory senza specificare un file verremo portati sul file index.php o index.html. Se liberiamo il file index.php della directory contenente il file .htaccess principale (con le varie istruzioni per l&#8217;autenticazione HTTP) questo è soggetto a un doppio comportamento. Se accediamo alla directory (senza specificare nessun file), cioè scrivendo nel browser &#8220;http://miosito.com/directory_protetta/&#8221; ci verranno chiesti i dati per l&#8217;autenticazione. Invece se accediamo al file index.php (specificandolo nell&#8217;indirizzo), cioè scrivendo nel browser &#8220;http://miosito.com/directory_protetta/index.php&#8221; non ci vengono chiesti i dati per l&#8217;autenticazione. Non credo sia possibile risolvere questo problema.</p>
<p><strong>Demo.</strong> Prova le eccezioni create per index.php e free_access.php con questo script: <a href="http://test.jblog.it/http_auth_exception/index.php" target="_blank">http://test.jblog.it/http_auth_exception/index.php</a>. Prova anche ad accedere a <a href="http://test.jblog.it/http_auth_exception/" target="_blank">http://test.jblog.it/http_auth_exception/</a> in cui, a differenza del primo indirizzo, ti verranno chiesti i dati per l&#8217;autenticazione.</p>
<h5>Esempio</h5>
<pre>AuthType Basic
AuthName "Accesso alla Directory..."
AuthUserFile /percorso_assoluto/.htpasswd
Require valid-user

# Libera il file index.php
&lt;Files index.php&gt;
   Allow from All
   Satisfy Any
&lt;/Files&gt;

# Libera il file free_access.php
&lt;Files free_access.php&gt;
   Allow from All
   Satisfy Any
&lt;/Files&gt;
# Libera tutti i file .xml, .css e .js
&lt;FilesMatch "\.(xml|css|js)$"&gt;
   Allow from All
   Satisfy Any
&lt;/FilesMatch&gt;

# Libera i file "page1.php" e "page2.php"
&lt;FilesMatch "^(page1\.php|page2\.php)$"&gt;
   Allow from All
   Satisfy Any
&lt;/FilesMatch&gt;</pre>
<h2 id="pagina-errore-401">Personalizza la pagina di errore &#8220;401 Authorization Required&#8221;</h2>
<p>Come ciliegina sulla torta <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' title="Autenticazione HTTP basic su server Apache" />  impostiamo una <strong>pagina personalizzata</strong> per l&#8217;errore 401 che si verifica quando non si inseriscono dei dati di autenticazione corretti.</p>
<h5>Pagina 401 di default</h5>
<p><img class="alignnone size-full wp-image-823" title="pagina errore 401 default | authentication required" src="http://jblog.it/wp-content/uploads/2010/01/http_auth_401default.jpg" alt="http auth 401default Autenticazione HTTP basic su server Apache" width="540" height="236" /></p>
<h5>Codice da inserire nel file .htaccess principale</h5>
<pre>ErrorDocument 401 /my_401.html</pre>
<h5>La mia pagina 401 personalizzata</h5>
<p><img class="alignnone size-full wp-image-824" title="pagina errore 401 personalizzata | authentication required" src="http://jblog.it/wp-content/uploads/2010/01/http_auth_401custom.jpg" alt="http auth 401custom Autenticazione HTTP basic su server Apache" width="540" height="236" /></p>
<p><strong>Demo.</strong> Prova la pagina personalizzata su <a href="http://test.jblog.it/http_auth_errordoc/" target="_blank">http://test.jblog.it/http_auth_errordoc/</a> (clicca su &#8220;annulla&#8221;).</p>
<h2>Suggerimenti? Bisogno d&#8217;aiuto?</h2>
<p>Sto imparando a mie spese che su Apache anche le cose più semplici non sono così immediate, ma bisogna sempre sbatterci un po&#8217; la testa!</p>
<p>Se hai dei suggerimenti per una miglior comprensione dell&#8217;articolo, ti serve qualche chiarimento o non riesci a venire a capo di un particolare problema non esitare a contattarmi. Sarà l&#8217;occasione per imparare qualcosa di nuovo!</p>
<h2>Crediti</h2>
<p>Apache HTTP Server &#8211; Core » <a href="http://httpd.apache.org/docs/2.0/mod/core.html" target="_blank">http://httpd.apache.org/docs/2.0/mod/core.html</a></p>
<p>Apache HTTP Server &#8211; mod_auth » <a href="http://httpd.apache.org/docs/2.0/mod/mod_auth.html" target="_blank">http://httpd.apache.org/docs/2.0/mod/mod_auth.html</a></p>
<p>Apache HTTP Server &#8211; Authentication, Authorization and Access Control » <a href="http://httpd.apache.org/docs/2.0/howto/auth.html" target="_blank">http://httpd.apache.org/docs/2.0/howto/auth.html</a></p>
<p>Foto | NYkette » <a href="http://newyorkette.com/2006/03/08/a-bouncer-on-bouncers/" target="_blank">http://newyorkette.com/2006/03/08/a-bouncer-on-bouncers/</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=818&type=feed" alt=" Autenticazione HTTP basic su server Apache"  title="Autenticazione HTTP basic su server Apache" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2010/01/11/autenticazione-http-basic-server-apache-mod_auth-htaccess-htpasswd-proteggere-file-directory_818.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Twitter parla italiano! &#8220;Che c&#8217;è di nuovo?&#8221;</title>
		<link>http://jblog.it/2009/12/11/twitter-parla-italiano-twitter-supporta-lingua-italiana_808.html</link>
		<comments>http://jblog.it/2009/12/11/twitter-parla-italiano-twitter-supporta-lingua-italiana_808.html#comments</comments>
		<pubDate>Thu, 10 Dec 2009 23:30:14 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Internet news]]></category>
		<category><![CDATA[Social network]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[microblogging]]></category>
		<category><![CDATA[social networking]]></category>
		<category><![CDATA[tweet]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=808</guid>
		<description><![CDATA[Dal blog ufficiale di Twitter arriva una bella notizia: da oggi Twitter supporta la lingua italiana! Gli autori del blog: "siamo emozionati perché oggi con il lancio della versione italiana del nostro sito diventiamo ancora di più una piattaforma di comunicazione globale. Come sempre, desideriamo ringraziare tutti i traduttori che hanno partecipato al progetto e che ci hanno mostrato la loro bravura".]]></description>
			<content:encoded><![CDATA[<p><a title="Twitter parla italiano! 'Che c'è di nuovo?'" href="http://jblog.it/2009/12/11/twitter-parla-italiano-twitter-supporta-lingua-italiana_808.html"><img class="alignnone size-full wp-image-809" title="Twitter: che c'è di nuovo?" src="http://jblog.it/wp-content/uploads/2009/12/twitter_italian_photo.jpg" alt="Twitter: che c'è di nuovo?" width="540" height="243" /></a></p>
<p>Dal <a title="Ed ecco l'italiano! " href="http://blog.twitter.com/2009/12/ed-ecco-litaliano.html" target="_blank">blog ufficiale di Twitter</a> arriva una bella notizia: da oggi <strong>Twitter supporta la lingua italiana!</strong> Gli autori del blog:</p>
<blockquote><p>siamo emozionati perché oggi con il lancio della versione italiana del nostro sito diventiamo ancora di più una piattaforma di comunicazione globale. Come sempre, desideriamo ringraziare tutti i traduttori che hanno partecipato al progetto e che ci hanno mostrato la loro bravura.</p></blockquote>
<p><span id="more-808"></span></p>
<p><!--adv300--></p>
<p><img class="alignnone size-full wp-image-810" style="border:1px solid #EEEEEE;" title="Twitter: seleziona lingua (italiano)" src="http://jblog.it/wp-content/uploads/2009/12/twitter_select_language.jpg" alt="Twitter: seleziona lingua (italiano)" width="540" height="160" /></p>
<blockquote><p>Ora che le conversazioni su Twitter si arricchiscono di punti di vista sempre più diversificati a livello globale, il network di informazioni continuerà a crescere in ogni angolo e fessura del pianeta. Più eventi saranno condivisi, più conoscenza e consapevolezza si diffonderà e i milioni di persone che alimentano Twitter influenzeranno altri milioni di persone con i loro tweet.</p></blockquote>
<p><img class="alignnone size-full wp-image-811" style="border:1px solid #EEEEEE;" title="twitter_what_happening" src="http://jblog.it/wp-content/uploads/2009/12/twitter_what_happening.jpg" alt="twitter what happening Twitter parla italiano! Che cè di nuovo?" width="540" height="140" /></p>
<h4>Hai mai consigliato a qualcuno di iscriversi su Twitter?</h4>
<p>Io si, e le risposte più comuni sono &#8220;eh&#8230;ma è tutto in inglese, non lo capisco&#8221; oppure &#8220;su Twitter parlano tutti in inglese!&#8221;. Risposte di questo tipo le ho avute soprattutto da amici che non conoscono bene l&#8217;inglese oppure che non hanno un blog e, probabilmente, non ne sentono (ancora) l&#8217;esigenza.</p>
<h4>Il 2010 sarà l&#8217;anno di Twitter?</h4>
<p>Sono convinto che gli italiani non abbiano ancora capito il <em>senso </em>di Twitter e la differenza dai comuni social network. Negli ultimi mesi di quest&#8217;anno ci si attendeva un&#8217;esplosione di Twitter che non c&#8217;è stata, forse proprio a causa del mancato supporto alla lingua italiana. (In effetti <strong>Facebook </strong>esplose proprio quando venne tradotto in italiano&#8230;)</p>
<p>Twitter mi piace. Mi è sempre piaciuto, fin dall’inizio. Speriamo che la lingua italiana favorisca l’iscrizione degli utenti italiani e i tweet in italiano.</p>
<p>Altrimenti ci toccherà tweettare in inglese&#8230;tra italiani!</p>
<img src="http://jblog.it/?ak_action=api_record_view&id=808&type=feed" alt=" Twitter parla italiano! Che cè di nuovo?"  title="Twitter parla italiano! Che cè di nuovo?" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/12/11/twitter-parla-italiano-twitter-supporta-lingua-italiana_808.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Google lancia la ricerca Real-Time e aggiorna l&#8217;interfaccia di AdSense</title>
		<link>http://jblog.it/2009/12/07/google-ricerca-real-time-aggiorna-interfaccia-adsense-real-time-search_799.html</link>
		<comments>http://jblog.it/2009/12/07/google-ricerca-real-time-aggiorna-interfaccia-adsense-real-time-search_799.html#comments</comments>
		<pubDate>Mon, 07 Dec 2009 21:03:14 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Internet news]]></category>
		<category><![CDATA[adsense]]></category>
		<category><![CDATA[caffeine]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[real-time]]></category>
		<category><![CDATA[ricerca]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=799</guid>
		<description><![CDATA[Google ha pubblicato un video intitolato "Real Time Search" in cui vengono illustrati i significativi cambiamenti del motore di ricerca. In adsense sono state aggiornate grafica e interfaccia. Inoltre sono state modificate e migliorate alcune pagine fondamentali con grafici e informazioni aggiuntive.]]></description>
			<content:encoded><![CDATA[<p><a title="Google lancia la ricerca real-time e aggiorna l'interfaccia adsense" href="http://jblog.it/2009/12/07/google-ricerca-real-time-aggiorna-interfaccia-adsense-real-time-search_799.html"><img class="alignnone size-full wp-image-804" title="google real time search adsense new interface" src="http://jblog.it/wp-content/uploads/2009/12/search_adsense__top.jpg" alt="google real time search adsense new interface" width="540" height="186" /></a></p>
<p>E da un po&#8217; di tempo che si sente parlare di aggiornamenti di interfaccia da parte di Google, e ancora di più dei suoi interventi riguardo la ricerca real-time (hai presente il progetto &#8220;Google Caffeine&#8221;?).</p>
<p>Beh&#8230; tutto ciò si sta concretizzando!<span id="more-799"></span></p>
<h2>Real-Time Search</h2>
<p><img class="alignnone size-full wp-image-801" title="google real time search" src="http://jblog.it/wp-content/uploads/2009/12/search.jpg" alt="google real time search" width="540" height="300" /></p>
<p>Google, sul <a title="Youtube - Google channel" href="http://www.youtube.com/user/Google" target="_blank">proprio canale Youtube</a>, ha pubblicato un video intitolato &#8220;Real Time Search&#8221; in cui vengono illustrati i significativi cambiamenti del motore di ricerca.</p>
<p>Il modo in cui Google supporterà la ricerca in tempo reale consiste nel fatto che nelle <acronym title="Search Engine Result Page">SERP</acronym>, oltre ai consueti risultati, vedremo una <strong>piccola area &#8220;animata&#8221;</strong> in cui ci verranno forniti dei link in tempo reale pescati da Twitter, Yahoo answers, siti di news, servizi web, ecc.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="540" height="328" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/WRkYmx4A9Do&amp;hl=it_IT&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="540" height="328" src="http://www.youtube.com/v/WRkYmx4A9Do&amp;hl=it_IT&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h2>Google Adsense: nuova interfaccia</h2>
<p><img class="alignnone size-full wp-image-802" title="google adsense new interface" src="http://jblog.it/wp-content/uploads/2009/12/adsense.gif" alt="google adsense new interface" width="540" height="300" /></p>
<p>Questa sera mi è arrivata un&#8217;email:</p>
<blockquote><p>Nuova interfaccia disponibile per il suo account AdSense</p></blockquote>
<p>Sono stato scelto come beta-tester per la nuova interfaccia di adsense! Certo, se hanno scelto me chissà quanti ne avranno scelti: diciamo che, per ovvi motivi, non entro spesso nel mio account&#8230; <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' title="Google lancia la ricerca Real Time e aggiorna linterfaccia di AdSense" /> </p>
<p>I cambiamenti di grafica da parte di Google erano nell&#8217;aria. Riguardo adsense parlare solo di grafica è riduttivo; infatti sono state apportate delle modifiche anche all&#8217;interfaccia. Non sono un esperto di adsense e non lo conosco a fondo, quindi ho notato solo le modifiche nelle pagine più classiche: home, unità pubblicitarie, creazione di una nuova unità pubblicitaria.<br />
<!--adv300--></p>
<h3>Home » panoramica</h3>
<p><strong></strong>Sono stati aggiunti dei grafici simili a quelli di Google Analytics, vengono fornite ulteriori informazioni e in maniera più chiara.</p>
<h3>I nuovi grafici</h3>
<p>Ecco i nuovi grafici al lavoro nella pagina &#8220;rapporti sul rendimento&#8221;:</p>
<p><img class="alignnone size-full wp-image-807" title="nuovi grafici adsense - adsense charts" src="http://jblog.it/wp-content/uploads/2009/12/adsense_charts.jpg" alt="nuovi grafici adsense - adsense charts" width="540" height="224" /></p>
<h3>Creazione di una nuova unità pubblicitaria</h3>
<p><strong></strong>Il processo di creazione di una nuova unità pubblicitaria è stato ridotto a 2 fasi anziché 3: prima bisognava selezionare il tipo di annuncio e in seguito impostarne l&#8217;aspetto, mentre ora il tipo di annuncio è selezionabile nella stessa pagina in cui si imposta l&#8217;aspetto. Inoltre, l&#8217;anteprima è stata spostata lateralmente riducendo l&#8217;altezza della pagina. Devo dire che ho particolarmente apprezzato le modifiche apportate a questa pagina.</p>
<p><img class="alignnone size-full wp-image-803" title="google adsense new interface" src="http://jblog.it/wp-content/uploads/2009/12/adsense-max.gif" alt="google adsense new interface" width="540" height="533" /></p>
<h3>Per sapere di più</h3>
<p>Sul blog ufficiale di Google AdSense: <a title="Una nuova interfaccia di AdSense: ora in versione beta" href="http://it-adsense.blogspot.com/2009/11/una-nuova-interfaccia-di-adsense-ora-in.html" target="_blank">http://it-adsense.blogspot.com/2009/11/una-nuova-interfaccia-di-adsense-ora-in.html</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=799&type=feed" alt=" Google lancia la ricerca Real Time e aggiorna linterfaccia di AdSense"  title="Google lancia la ricerca Real Time e aggiorna linterfaccia di AdSense" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/12/07/google-ricerca-real-time-aggiorna-interfaccia-adsense-real-time-search_799.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>19 pacchetti di icone completi e definitivi</title>
		<link>http://jblog.it/2009/12/07/pacchetti-icone-definitivi-completi-icons-set-social-emoticons_774.html</link>
		<comments>http://jblog.it/2009/12/07/pacchetti-icone-definitivi-completi-icons-set-social-emoticons_774.html#comments</comments>
		<pubDate>Mon, 07 Dec 2009 05:20:24 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Grafica]]></category>
		<category><![CDATA[Web design]]></category>
		<category><![CDATA[bandiere]]></category>
		<category><![CDATA[emoticons]]></category>
		<category><![CDATA[icone]]></category>
		<category><![CDATA[mini icone]]></category>
		<category><![CDATA[pacchetti icone]]></category>
		<category><![CDATA[smilies]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[social bookmarking]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=774</guid>
		<description><![CDATA[Durante la realizzazione di un sito arriva sempre il momento in cui è necessario utilizzare dei pacchetti di icone, ad esempio per linkare il profilo sui vari social network o per elencare i metodi di pagamento accettati. Se stai realizzando un cms la scelta del giusto pacchetto di icone può addirittura diventare un problema.]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><a title="19 pacchetti di icone completi e definitivi" href="http://jblog.it/2009/12/07/pacchetti-icone-definitivi-completi-icons-set-social-emoticons_774.html"><img class="alignnone size-full wp-image-795" title="19 pacchetti di icone completi e definitivi" src="http://jblog.it/wp-content/uploads/2009/12/19_pacchetti_icone.jpg" alt="19 pacchetti di icone completi e definitivi" width="540" height="100" /></a></p>
<p style="text-align: left;">Durante la realizzazione di un sito arriva sempre il momento in cui è necessario utilizzare dei pacchetti di icone, ad esempio per linkare il profilo sui vari social network o per elencare i metodi di pagamento accettati.</p>
<p style="text-align: left;">Se stai realizzando un cms la scelta del giusto pacchetto di icone può addirittura diventare un <strong>problema</strong>. Infatti, poiché un generico cms ha molte funzioni alle quali associare l&#8217;icona adatta, a meno che tu non voglia prenderle a caso da <em>google immagini</em>, hai bisogno di <strong>pacchetti completi in grado di soddisfare le esigenze attuali (e future) del tuo cms</strong>.</p>
<p style="text-align: left;">Il fatto è che non sempre hai il tempo e la voglia di correre su internet per cercare l&#8217;icona adatta, anche perché sarebbe difficile trovarne una allineata allo stile di quelle che stai già utilizzando.</p>
<p style="text-align: left;">Quindi per non avere più preoccupazioni dai uno sguardo ai seguenti pacchetti di icone e scegli quelli più adatti alle tue esigenze!</p>
<p><span id="more-774"></span></p>
<h2 style="text-align: left;">Una panoramica dei pacchetti</h2>
<p><!--adv300--></p>
<p style="text-align: left;">I pacchetti veramente completi che <strong>ti eviteranno tutte le preoccupazioni</strong> sono:</p>
<ul style="text-align: left;">
<li><a href="#fugueicons">Fugue Icons</a>, pacchetto completissimo</li>
<li><a href="#famfamfamsilk">FamFamFam Silk Icons</a>, pacchetto completo anche se le icone sono meno della metà di quello precedente</li>
<li><a href="#snpack">Social Network Icon Pack</a>, icone di vari social network (alcuni non molto conosciuti)</li>
<li><a href="#famfamfamflag">FamFamFam Flag Icons</a>, le bandiere di tutti gli stati del mondo</li>
<li><a href="#chalkwork">Chalkwork Payments</a>, icone di varie carte di credito e metodi di pagamento</li>
</ul>
<p style="text-align: left;">Per siti graficamente leggeri i 3 pacchetti seguenti hanno <strong>icone in bianco e nero (o scala di grigi)</strong>, secondo me molto delicate e gradevoli:</p>
<ul style="text-align: left;">
<li><a href="#bwpx">bwpx.icns</a></li>
<li><a href="#mini2">Mini Icons 2</a></li>
<li><a href="#mini12">Mini Pixel Icon Set v.1.2</a></li>
</ul>
<p style="text-align: left;">Gli altri pacchetti per un motivo o per l&#8217;altro meritavano di essere segnalati.</p>
<p style="text-align: left;"><img class="alignnone size-full wp-image-796" title="tabella comparativa 19 pacchetti icone" src="http://jblog.it/wp-content/uploads/2009/12/19_table.png" alt="tabella comparativa 19 pacchetti icone" width="540" height="610" /></p>
<h2 id="fugueicons" style="text-align: left;">Fugue Icons</h2>
<p style="text-align: left;"><a href="http://www.pinvoke.com/" target="_blank"><img title="fugue icons" src="http://jblog.it/wp-content/uploads/2009/12/fugue.gif" alt="fugue icons" width="540" height="100" /></a></p>
<p style="text-align: left;">Sia graficamente che per il gran numero di icone che contiene, questo è sicuramente il <strong>miglior pacchetto</strong>.</p>
<p style="text-align: left;">Sono in una <strong>doppia versione grafica</strong> (con e senza ombreggiatura) e il gran numero di icone permette di <strong>coprire molti ambiti</strong>.</p>
<p style="text-align: left;">Tuttavia, se non dovessero soddisfarti puoi sempre modificarle grazie ai <strong>file .psd inclusi</strong> nel pacchetto. Un consiglio: fatti un giro nei file .psd, esplora i livelli, guarda i vari elementi che compongono una singola icona&#8230; approfittane per imparare a disegnare le tue icone!</p>
<p style="text-align: left;">Dato che molte delle icone sono simili a quelle di sistemi operativi o famose applicazioni (es. microsoft word), ci sono concrete possibilità che gli utenti conoscano già la funzione associata, il ché fa guadagnare dei punticini in <strong>usabilità</strong>.</p>
<p style="text-align: left;">L&#8217;unica pecca che sento di segnalare sta nel fatto che, a differenza di altri pacchetti, <strong>non sono suddivise in directory</strong> e a volte è veramente dura trovare l&#8217;icona desiderata!</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="z0y4" title="http://www.pinvoke.com/" href="http://www.pinvoke.com/" target="_blank">http://www.pinvoke.com/</a><br />
<strong>Numero di icone</strong>: 2360<br />
<strong>Formati</strong>: psd, png<br />
<strong>Dimensioni</strong>: 16 x 16<br />
<strong>Licenza</strong>: <a id="klhi" title="http://creativecommons.org/licenses/by/3.0/" href="http://creativecommons.org/licenses/by/3.0/" target="_blank">http://creativecommons.org/licenses/by/3.0/</a></p>
<h2 id="famfamfamsilk" style="text-align: left;">FamFamFam Silk Icons</h2>
<p style="text-align: left;"><a href="http://www.famfamfam.com/lab/icons/silk/" target="_blank"><img title="famfamfam silk icons" src="http://jblog.it/wp-content/uploads/2009/12/famfamfam.gif" alt="famfamfam silk icons" width="540" height="100" /></a></p>
<p style="text-align: left;">Fortunatamente le icone di questo pacchetto <strong>si assomigliano a quelle precedenti</strong>, quindi, se non dovessi trovarne una potrai sempre cercarla nell&#8217;altro pacchetto (e viceversa).</p>
<p style="text-align: left;">Un po&#8217; di tempo fa utilizzai queste icone e l&#8217;esperienza è stata molto positiva, grazie anche allo stile molto gradevole e ai colori non troppo forti.</p>
<p style="text-align: left;">Come il pacchetto precedente, il gran numero di icone permette di <strong>coprire molti ambiti</strong> e l&#8217;unica pecca sta nel fatto che, a differenza di altri pacchetti, <strong>non sono suddivise in directory</strong> ed è un po&#8217; difficile sfogliarle.</p>
<p style="text-align: left;"><strong>Autore</strong>: Mark James<br />
<strong>Url</strong>: <a id="aa9l" title="http://www.famfamfam.com/lab/icons/silk/" href="http://www.famfamfam.com/lab/icons/silk/" target="_blank">http://www.famfamfam.com/lab/icons/silk/</a><br />
<strong>Numero di icone</strong>: 1000<br />
<strong>Formato</strong>: png<br />
<strong>Dimensioni</strong>: 16 x 16<br />
<strong>Licenza</strong>: <a id="yxsu" title="http://creativecommons.org/licenses/by/3.0/" href="http://creativecommons.org/licenses/by/3.0/" target="_blank">http://creativecommons.org/licenses/by/3.0/</a></p>
<h2 style="text-align: left;">Led Icon Set v1.0</h2>
<p style="text-align: left;"><a href="http://led24.de/iconset" target="_blank"><img title="led_icon" src="http://jblog.it/wp-content/uploads/2009/12/led_icon.gif" alt="led icon 19 pacchetti di icone completi e definitivi" width="540" height="100" /></a></p>
<p style="text-align: left;">Graficamente tra le più belle, sono particolarmente indicate per <strong>applicazioni grafiche e di scrittura</strong>.</p>
<p style="text-align: left;"><strong>Autore</strong>: Aleksandr Kozmenko<br />
<strong>Url</strong>: <a id="slnm" title="http://led24.de/iconset" href="http://led24.de/iconset" target="_blank">http://led24.de/iconset</a><br />
<strong>Numero di icone</strong>: 512<br />
<strong>Formato</strong>: png<br />
<strong>Dimensioni</strong>: 16 x 16<br />
<strong>Licenza</strong>: <a id="ph7c" title="http://creativecommons.org/licenses/by-sa/3.0/" href="http://creativecommons.org/licenses/by-sa/3.0/" target="_blank">http://creativecommons.org/licenses/by-sa/3.0/</a></p>
<h2 style="text-align: left;">Splashy Icons</h2>
<p style="text-align: left;"><a href="http://splashyfish.com/sketches/comments/splashy-icons-an-icon-library-for-prototyping/" target="_blank"><img title="splashy icons" src="http://jblog.it/wp-content/uploads/2009/12/splashy.gif" alt="splashy icons" width="540" height="100" /></a></p>
<p style="text-align: left;">Abbastanza &#8220;piatte&#8221;, senza troppe ombreggiature e bordi ma con gradienti ben definiti.</p>
<p style="text-align: left;">Orientate per l&#8217;utilizzo in <strong>applicazioni &#8220;social&#8221; e multimediali</strong>.</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="qit." title="http://splashyfish.com/sketches/comments/splashy-icons-an-icon-library-for-prototyping/" href="http://splashyfish.com/sketches/comments/splashy-icons-an-icon-library-for-prototyping/" target="_blank">http://splashyfish.com/sketches/comments/splashy-icons-an-icon-library-for-prototyping/</a><br />
<strong>Numero di icone</strong>: 512<br />
<strong>Formati</strong>: png, MacOSx png<br />
<strong>Dimensioni</strong>: 16 x 16</p>
<h2 style="text-align: left;">Flavour Icon set</h2>
<p style="text-align: left;"><a href="http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/" target="_blank"><img title="flavour icon set" src="http://jblog.it/wp-content/uploads/2009/12/flavour_ext.jpg" alt="flavour icon set" width="540" height="100" /></a></p>
<p style="text-align: left;">Sono <strong>molto generiche</strong>:  difficile stabilire in quali ambiti possano essere indispensabili.</p>
<p style="text-align: left;">Meritano di essere segnalate per la grafica molto curata ma soprattutto per la presenza di <strong>tutti i pulsanti della tastiera</strong>, a mio avviso difficili da trovare.</p>
<p style="text-align: left;"><strong>Autore</strong>: <a id="u208" title="http://www.addictedtocoffee.de/" href="http://www.addictedtocoffee.de/" target="_blank">Oliver Twardowski</a><br />
<strong>Url</strong>: <a id="khgf" title="http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/" href="http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/" target="_blank">http://www.smashingmagazine.com/2009/05/20/flavour-extended&#8230;</a><br />
<strong>Numero di icone</strong>: 452<br />
<strong>Formato</strong>: psd, png, MacOSx png<br />
<strong>Dimensioni</strong>: 48 x 48<br />
<strong>Licenza</strong>: uso personale e commerciale</p>
<h2 style="text-align: left;">Diagona Icons</h2>
<p style="text-align: left;"><a href="http://www.pinvoke.com/" target="_blank"><img title="diagona icons" src="http://jblog.it/wp-content/uploads/2009/12/diagona.gif" alt="diagona icons" width="540" height="100" /></a></p>
<p style="text-align: left;">Mi sembrano una specie di &#8220;evoluzione grafica&#8221; del pacchetto FamFamFam Silk Icons.</p>
<p style="text-align: left;">Secondo me sono molto <strong>adatte a blog e applicazioni &#8220;social&#8221;</strong>.</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="l-yk" title="http://www.pinvoke.com/" href="http://www.pinvoke.com/" target="_blank">http://www.pinvoke.com/</a><br />
<strong>Numero di icone</strong>: 400<br />
<strong>Formato</strong>: png<br />
<strong>Dimensioni</strong>: 16 x 16, 10 x 10<br />
<strong>Licenza</strong>: <a id="kxha" title="http://creativecommons.org/licenses/by-sa/3.0/" href="http://creativecommons.org/licenses/by-sa/3.0/" target="_blank">http://creativecommons.org/licenses/by-sa/3.0/</a></p>
<h2 style="text-align: left;">Mini Pixel Icons</h2>
<p style="text-align: left;"><a href="http://icondock.com/free/mini-pixel-icons" target="_blank"><img title="mini pixel icons" src="http://jblog.it/wp-content/uploads/2009/12/mini_pixel2.gif" alt="mini pixel icons" width="540" height="100" /></a></p>
<p style="text-align: left;">Graficamente molto delicate, particolarmente <strong>adatte a siti di ecommerce</strong> data la presenza di carte di credito, borse, carrelli, stampanti, shopping bag, ecc.</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="d7wy" title="http://icondock.com/free/mini-pixel-icons" href="http://icondock.com/free/mini-pixel-icons" target="_blank">http://icondock.com/free/mini-pixel-icons</a><br />
<strong>Numero di icone</strong>: 322<br />
<strong>Formati</strong>: gif<br />
<strong>Dimensioni</strong>: 14 x 14</p>
<h2 style="text-align: left;">Free Web Design Icon Set</h2>
<p style="text-align: left;"><a href="http://semlabs.co.uk/journal/free-web-design-icon-set" target="_blank"><img title="free web design icon set" src="http://jblog.it/wp-content/uploads/2009/12/freeiconset.gif" alt="free web design icon set" width="540" height="100" /></a></p>
<p style="text-align: left;">Non hanno dei particolari campi di applicazione ma mi sono sembrate molto <strong>adatte per cms generici</strong> in quanto le icone presenti corrispondono alle più classiche funzioni di un cms, che secondo me sarebbero in grado di soddisfarle completamente.</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="e5lp" title="http://semlabs.co.uk/journal/free-web-design-icon-set" href="http://semlabs.co.uk/journal/free-web-design-icon-set" target="_blank">http://semlabs.co.uk/journal/free-web-design-icon-set</a><br />
<strong>Numero di icone</strong>: 310<br />
<strong>Formati</strong>: png<br />
<strong>Dimensioni</strong>: 16 x 16</p>
<h2 id="bwpx" style="text-align: left;">bwpx.icns</h2>
<p style="text-align: left;"><a href="http://paularmstrongdesigns.com/projects/bwpx-icns/" target="_blank"><img title="bwpx.icns" src="http://jblog.it/wp-content/uploads/2009/12/bwpx_icns.gif" alt="bwpx.icns" width="540" height="100" /></a></p>
<p style="text-align: left;">Questo pacchetto ha icone molto classiche, quindi <strong>adatte a cms generici</strong>.</p>
<p style="text-align: left;">Graficamente molto leggere ma originali. L&#8217;autore afferma che:</p>
<blockquote style="text-align: left;"><p>&#8230; ogni icona è stata accuratamente creata un pixel alla volta &#8230;</p>
</blockquote>
<p style="text-align: left;">sarà vero? Quanta pazienza! <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' title="19 pacchetti di icone completi e definitivi" /> </p>
<p style="text-align: left;"><strong>Autore</strong>: <a id="akdw" title="http://paularmstrongdesigns.com/" href="http://paularmstrongdesigns.com/" target="_blank">Paul Armstrong</a><br />
<strong>Url</strong>: <a id="neda" title="http://paularmstrongdesigns.com/projects/bwpx-icns/" href="http://paularmstrongdesigns.com/projects/bwpx-icns/" target="_blank">http://paularmstrongdesigns.com/projects/bwpx-icns/</a><br />
<strong>Numero di icone</strong>: 260<br />
<strong>Formati</strong>: gif<br />
<strong>Dimensioni</strong>: 18 x 18<br />
<strong>Licenza</strong>: <a id="xg7g" title="http://creativecommons.org/licenses/by-sa/3.0/us/" href="http://creativecommons.org/licenses/by-sa/3.0/us/" target="_blank">http://creativecommons.org/licenses/by-sa/3.0/us/</a></p>
<h2 id="mini2" style="text-align: left;">Mini Icons 2</h2>
<p style="text-align: left;"><strong><a href="http://www.brandspankingnew.net/archive/2006/12/hohoho.html" target="_blank"><img title="hohoho" src="http://jblog.it/wp-content/uploads/2009/12/hohoho.gif" alt="hohoho 19 pacchetti di icone completi e definitivi" width="540" height="100" /></a></strong></p>
<p style="text-align: left;">Graficamente semplici, leggere e molto gradevoli sono particolarmente<strong> adatte ad applicazioni di scrittura.</strong></p>
<p style="text-align: left;"><strong>Url</strong>: <a id="x5.8" title="http://www.brandspankingnew.net/archive/2006/12/hohoho.html" href="http://www.brandspankingnew.net/archive/2006/12/hohoho.html" target="_blank">http://www.brandspankingnew.net/archive/2006/12/hohoho.html</a><br />
<strong>Numero di icone</strong>: 113<br />
<strong>Formato</strong>: gif<br />
<strong>Dimensioni</strong>: 10 x 10<br />
<strong>Licenza</strong>: <a id="p0iw" title="http://creativecommons.org/licenses/by-sa/2.5/" href="http://creativecommons.org/licenses/by-sa/2.5/" target="_blank">http://creativecommons.org/licenses/by-sa/2.5/</a><br />
<strong>Note</strong>: al momento della scrittura dell&#8217;articolo il link per il download non è funzionante; quindi scaricare l&#8217;immagine del post.</p>
<h2 id="mini12" style="text-align: left;">Mini Pixel Icon Set v.1.2</h2>
<p style="text-align: left;"><strong><a href="http://www.paulolyslager.com/free-mini-pixel-web-icons" target="_blank"><img title="mini icons 2" src="http://jblog.it/wp-content/uploads/2009/12/mini_pixel.gif" alt="mini icons 2" width="540" height="100" /></a></strong></p>
<p style="text-align: left;">Semplici e leggere dal punto di vista grafico; l&#8217;autore ha pensato bene di adattarle alla dimensione, variandone leggermente il disegno.</p>
<p style="text-align: left;">Particolarmente <strong>adatte a siti di ecommerce e cms generici</strong>.</p>
<p style="text-align: left;"><strong>Autore</strong>: <a id="tq_s" title="Paul Olyslager" href="http://www.paulolyslager.com/" target="_blank">Paul Olyslager</a><br />
<strong>Url</strong>: <a id="cvoa" title="http://www.paulolyslager.com/free-mini-pixel-web-icons" href="http://www.paulolyslager.com/free-mini-pixel-web-icons" target="_blank">http://www.paulolyslager.com/free-mini-pixel-web-icons</a><br />
<strong>Numero di icone</strong>: 111<br />
<strong>Formati</strong>: gif, png, psd<br />
<strong>Dimensioni</strong>: 25 x 25 (dimensioni e stili variabili)<br />
<strong>Note</strong>: due versioni di design (con e senza antialiasing).</p>
<h2 style="text-align: left;">Tango Icon Library</h2>
<p style="text-align: left;"><a href="http://tango.freedesktop.org/Tango_Icon_Library" target="_blank"><img title="tango icon library" src="http://jblog.it/wp-content/uploads/2009/12/tango_icons.gif" alt="tango icon library" width="540" height="100" /></a></p>
<p style="text-align: left;">Questo pacchetto di icone nasce per GNOME, ambiente desktop per Linux.</p>
<p style="text-align: left;">Credo che <strong>non possano essere la soluzione definitiva</strong> poiché, essendo orientate a sistemi operativi e applicazioni desktop, non hanno molte di quelle icone ampiamente utilizzate nelle comuni applicazioni web.</p>
<p style="text-align: left;">Tuttavia, meritano di essere segnalate per lo stile interessante ed originale e per la presenza dei <strong>file vettoriali .svg</strong>.</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="gh7u" title="http://tango.freedesktop.org/Tango_Icon_Library" href="http://tango.freedesktop.org/Tango_Icon_Library" target="_blank">http://tango.freedesktop.org/Tango_Icon_Library</a><br />
<strong>Numero di icone</strong>: 215<br />
<strong>Formati</strong>: svg, png<br />
<strong>Dimensioni</strong>: 32 x 32, 22 x 22, 16 x 16</p>
<h2 style="text-align: left;">Twotiny Icon Set</h2>
<p style="text-align: left;"><a href="http://code.google.com/p/twotiny/" target="_blank"><img title="twotiny icon set" src="http://jblog.it/wp-content/uploads/2009/12/twotiny.gif" alt="twotiny icon set" width="540" height="100" /></a></p>
<p style="text-align: left;">Icone molto generiche, adatte a vari ambiti e, benché non siano tantissime, potrebbero essere una buona soluzione.</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="tygs" title="http://code.google.com/p/twotiny/" href="http://code.google.com/p/twotiny/" target="_blank">http://code.google.com/p/twotiny/</a><br />
<strong>Numero di icone</strong>: 122<br />
<strong>Formati</strong>: gif, MacOSx<br />
<strong>Dimensioni</strong>: variabili, mediamente 16 x 16<br />
<strong>Licenza</strong>: <a id="qbfa" title="http://dev.perl.org/licenses/" href="http://dev.perl.org/licenses/" target="_blank">http://dev.perl.org/licenses/</a><br />
<strong>Note</strong>: nella pagina ci sono due pacchetti; il link per il download relativo a questo pacchetto è &#8220;twotiny-plus-expansion.zip&#8221;.</p>
<h2 id="snpack" style="text-align: left;">Social Network Icon Pack</h2>
<p style="text-align: left;"><a href="http://www.komodomedia.com/blog/2009/06/social-network-icon-pack/" target="_blank"><img title="social network icon pack" src="http://jblog.it/wp-content/uploads/2009/12/sn_iconspng.gif" alt="sn iconspng 19 pacchetti di icone completi e definitivi" width="540" height="100" /></a></p>
<p style="text-align: left;">Questo è in assoluto il pacchetto di <strong>icone &#8220;social&#8221; più famoso</strong>.</p>
<p style="text-align: left;">Almeno per quattro ragioni:</p>
<ul style="text-align: left;">
<li>è <strong>completo </strong>di tutti i principali social network (molti pacchetti di questo tipo non avevano addirittura l&#8217;icona di last.fm!)</li>
<li>viene <strong>aggiornato spesso</strong> (c&#8217;è già l&#8217;icona di Google Wave)</li>
<li>a differenza della maggior parte delle icone &#8220;social&#8221; non hanno uno<br />
stile particolare e sono <strong>facilmente intonabili</strong> con qualsiasi grafica</li>
<li>sono molto <strong>fedeli al logo originale</strong> (molti pacchetti le personalizzano troppo al punto da non essere riconoscibili!)</li>
</ul>
<p style="text-align: left;"><strong>Url</strong>: <a id="n.i_" title="http://www.komodomedia.com/blog/2009/06/social-network-icon-pack/" href="http://www.komodomedia.com/blog/2009/06/social-network-icon-pack/" target="_blank">http://www.komodomedia.com/blog/2009/06/social-network-icon-pack/</a><br />
<strong>Numero di icone</strong>: 60<br />
<strong>Formati</strong>: png, MacOSx png<br />
<strong>Dimensioni</strong>: 32 x 32, 16 x 16<br />
<strong>Licenza</strong>: <a id="jxhg" title="http://creativecommons.org/licenses/by-sa/3.0/" href="http://creativecommons.org/licenses/by-sa/3.0/" target="_blank">http://creativecommons.org/licenses/by-sa/3.0/</a></p>
<h2 id="chalkwork" style="text-align: left;">Chalkwork Payments</h2>
<p style="text-align: left;"><a href="http://www.mezzoblue.com/icons/chalkwork/payments/" target="_blank"><img title="chalkwork payments icons" src="http://jblog.it/wp-content/uploads/2009/12/chalkwork.gif" alt="chalkwork payments icons" width="540" height="100" /></a></p>
<p style="text-align: left;">In questo pacchetto sono presenti <strong>molte carte di credito</strong>, da quelle più famose a quelle più recenti o meno conosciute.</p>
<p style="text-align: left;">Di ogni icona, oltre all&#8217;icona base, ci sono <strong>5 varianti</strong> (aggiungi, modifica, cancella, sicura, condividi).</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="wxte" title="http://www.mezzoblue.com/icons/chalkwork/payments/" href="http://www.mezzoblue.com/icons/chalkwork/payments/" target="_blank">http://www.mezzoblue.com/icons/chalkwork/payments/</a><br />
<strong>Numero di icone</strong>: 21<br />
<strong>Formati</strong>: png, tif, gif, bmp, ico, icns<br />
<strong>Dimensioni</strong>: 32 x 32, 24 x 24, 16 x 16<br />
<strong>Licenza</strong>: <a id="xwpn" title="http://www.mezzoblue.com/icons/license/" href="http://www.mezzoblue.com/icons/license/" target="_blank">http://www.mezzoblue.com/icons/license/</a></p>
<h2 id="famfamfamflag" style="text-align: left;">FamFamFam Flag Icons</h2>
<p style="text-align: left;"><a href="http://famfamfam.com/lab/icons/flags/" target="_blank"><img title="famfamfam flags" src="http://jblog.it/wp-content/uploads/2009/12/famfamfam_flags.gif" alt="famfamfam flags" width="540" height="100" /></a></p>
<p style="text-align: left;">Le <strong>bandiere di tutti gli stati del mondo</strong> in una grafica accettabile e sobria.</p>
<p style="text-align: left;"><strong>Autore</strong>: Mark James<br />
<strong>Url</strong>: <a id="r_s." title="http://famfamfam.com/lab/icons/flags/" href="http://famfamfam.com/lab/icons/flags/" target="_blank">http://famfamfam.com/lab/icons/flags/</a><br />
<strong>Numero di icone</strong>: 247<br />
<strong>Formati</strong>: png, gif, MacOSx png, MacOSx gif<br />
<strong>Dimensioni</strong>: 16 x 11</p>
<h2 style="text-align: left;">2s-space Emotions v2</h2>
<p style="text-align: left;"><a href="http://kirozeng.deviantart.com/art/2s-space-Emotions-v2-72785912" target="_blank"><img title="2s space emotions" src="http://jblog.it/wp-content/uploads/2009/12/2s_space.gif" alt="2s space 19 pacchetti di icone completi e definitivi" width="540" height="100" /></a></p>
<p style="text-align: left;">Tante emoticons <strong>espressive</strong>, divertenti, <strong>alternative </strong>e ben disegnate. Mi ricordano tanto i cartoni animati giapponesi!</p>
<p style="text-align: left;"><strong>Autore</strong>: <a id="vjgx" title="http://kirozeng.deviantart.com/" href="http://kirozeng.deviantart.com/" target="_blank">kirozeng</a><br />
<strong>Url</strong>: <a id="m06j" title="http://kirozeng.deviantart.com/art/2s-space-Emotions-v2-72785912" href="http://kirozeng.deviantart.com/art/2s-space-Emotions-v2-72785912" target="_blank">http://kirozeng.deviantart.com/art/2s-space-Emotions-v2-72785912</a><br />
<strong>Numero di icone</strong>: 20<br />
<strong>Formati</strong>: png<br />
<strong>Dimensioni</strong>: 256 x 256</p>
<h2 style="text-align: left;">PNGs Smilies for Wordpress</h2>
<p style="text-align: left;"><a href="http://vikiworks.com/2007/09/25/pngs-smilies-for-wordpress/" target="_blank"><img title="wordpress smiles" src="http://jblog.it/wp-content/uploads/2009/12/wpsmiles.gif" alt="wordpress smiles" width="540" height="100" /></a></p>
<p style="text-align: left;">Questo pacchetto nasce con l&#8217;intento di <strong>rimpiazzare le emoticons di wordpress</strong>.</p>
<p style="text-align: left;">Rispetto a quelle di wordpress sono più morbide e gradevoli, anche se proprio per queste caratteristiche risulterebbero meno evidenti all&#8217;interno del testo. A te la scelta!</p>
<p style="text-align: left;"><strong>Autore</strong>: <a id="lms." title="http://www.dlanham.com/" href="http://www.dlanham.com/" target="_blank">David Lanham</a><br />
<strong>Url</strong>: <a id="zxat" title="http://vikiworks.com/2007/09/25/pngs-smilies-for-wordpress/" href="http://vikiworks.com/2007/09/25/pngs-smilies-for-wordpress/" target="_blank">http://vikiworks.com/2007/09/25/pngs-smilies-for-wordpress/</a><br />
<strong>Numero di icone</strong>: 19<br />
<strong>Formati</strong>: png<br />
<strong>Dimensioni</strong>: 16 x 16<br />
<strong>Licenza</strong>: <a id="m.xc" title="http://creativecommons.org/licenses/by-sa/3.0/" href="http://creativecommons.org/licenses/by-sa/3.0/" target="_blank">http://creativecommons.org/licenses/by-sa/3.0/</a></p>
<h2 style="text-align: left;">Free smiles</h2>
<p style="text-align: left;"><a href="http://www.icojoy.com/articles/18/" target="_blank"><img title="freesmiles" src="http://jblog.it/wp-content/uploads/2009/12/freesmiles.gif" alt="freesmiles 19 pacchetti di icone completi e definitivi" width="540" height="100" /></a></p>
<p style="text-align: left;">Probabilmente starai pensando: &#8220;tutto qui?&#8221;. In realtà potremmo definirlo come il &#8220;<strong>framework degli emoticons</strong>&#8220;.</p>
<p style="text-align: left;">All&#8217;interno del pacchetto ci sono <strong>tutti i pezzi</strong> per realizzare le proprie emoticons.</p>
<p style="text-align: left;">Ho calcolato che con tutte le combinazioni dei diversi pezzi si avrebbero fino a <strong>600 emoticons</strong>!</p>
<p style="text-align: left;"><strong>Se non ti va di utilizzare programmi di grafica</strong> puoi sempre andare su <a id="vsh1" title="http://icojoy.com/lj/free/smiles/form.php" href="http://icojoy.com/lj/free/smiles/form.php" target="_blank">http://icojoy.com/lj/free/smiles/form.php</a>, uno script in cui potrai <strong>comporre e scaricare l&#8217;emoticons in pochi secondi</strong>.</p>
<p style="text-align: left;"><strong>Url</strong>: <a id="bwyj" title="http://www.icojoy.com/articles/18/" href="http://www.icojoy.com/articles/18/" target="_blank">http://www.icojoy.com/articles/18/</a><br />
<strong>Numero di icone</strong>: 10<br />
<strong>Formati</strong>: psd, png, gif, bmp<br />
<strong>Dimensioni</strong>: 20 x 20</p>
<h2 style="text-align: left;">Problemi con i link?</h2>
<p style="text-align: left;">Hai difficoltà a scaricare i pacchetti? Il sito o la pagina non è più disponibile? Nessun problema!</p>
<p style="text-align: left;"><strong>Io conservo tutti i pacchetti di questa lista</strong>. Quindi contattami e li metterò a disposizione per il download.</p>
<p style="text-align: left;">Perfavore, <strong>se qualche link non è più funzionante</strong> avvertimi e provvederò ad aggiornare l&#8217;articolo. Grazie.</p>
<h5 class="highlight_green" style="text-align: left;">Ti è piaciuta questa raccolta?<br />
Conosci altri pacchetti che meritano di essere segnalati?</h5>
<img src="http://jblog.it/?ak_action=api_record_view&id=774&type=feed" alt=" 19 pacchetti di icone completi e definitivi"  title="19 pacchetti di icone completi e definitivi" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/12/07/pacchetti-icone-definitivi-completi-icons-set-social-emoticons_774.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Commenti audio nei blog?</title>
		<link>http://jblog.it/2009/11/09/commenti-audio-nei-blog_770.html</link>
		<comments>http://jblog.it/2009/11/09/commenti-audio-nei-blog_770.html#comments</comments>
		<pubDate>Mon, 09 Nov 2009 04:59:40 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[commenti]]></category>
		<category><![CDATA[player]]></category>
		<category><![CDATA[podcasting]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=770</guid>
		<description><![CDATA[Su ImpressiveWebs viene segnalato un articolo su Boagworld intitolato "The biggest ecommerce lies and how to avoid them" in cui l'autore del blog, Paul Boag, risponde ai lettori con un commento audio. Ottima idea! E soprattutto molto originale... Pensando un po' più in grande, immagini la possibilità di commentare un post parlando anziché scrivendo?]]></description>
			<content:encoded><![CDATA[<p><a title="Commenti audio nei blog?" href="http://jblog.it/2009/11/09/commenti-audio-nei-blog_770.html"><img class="alignnone size-full wp-image-771" title="Commenti audio nel blog?" src="http://jblog.it/wp-content/uploads/2009/11/audiocomment1.jpg" alt="Commenti audio nel blog?" width="540" height="130" /></a></p>
<p>Su <a title="Audio comments on blogs" href="http://www.impressivewebs.com/audio-comments-on-blogs-now-thats-a-great-idea/" target="_blank">ImpressiveWebs</a> viene segnalato un articolo su <a href="http://boagworld.com/">Boagworld</a> intitolato <a href="http://boagworld.com/site-content/ecommerce-lies">The biggest ecommerce lies and how to avoid them</a> in cui l&#8217;autore del blog, Paul Boag, risponde ai lettori con un commento audio. Ottima idea! E soprattutto molto originale&#8230;</p>
<p>Pensando un po&#8217; più in grande, immagini la possibilità di commentare un post <em>parlando </em>anziché <em>scrivendo</em>?<span id="more-770"></span><!--adv300--></p>
<h2>Il lato tecnico</h2>
<p>Credo che l&#8217;autore del blog abbia semplicemente registrato la sua voce, caricato il file e &#8220;embeddato&#8221; il player nel testo del suo commento.</p>
<p>Ma, se volessimo dare ai lettori del nostro blog la possibilità di commentare in formato audio gli interventi tecnici non sarebbero né semplici né immediati.</p>
<p><strong>In pratica</strong> dovremmo:</p>
<ul>
<li>gestire il microfono</li>
<li>avere uno script per la registrazione (per intenderci, una specie di player con i pulsanti &#8220;rec&#8221;, &#8220;play&#8221;, &#8220;stop&#8221;, ecc.)</li>
<li>avere a che fare con codec e script per la conversione/compressione (non vorrai memorizzare in &#8220;.wav&#8221;?!? <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' title="Commenti audio nei blog?" />  )</li>
<li>disporre di uno spazio web di quelli che non hanno i megabyte contati</li>
</ul>
<p>Per avere un&#8217;<strong>idea</strong>, il sito <a href="http://www.laphotocabine.com/" target="_blank">LaPhotoCabine</a> dà la possibilità di stampare le fototessere direttamente da casa in un formato molto simile a quello delle cambine fotografiche. Il sito è realizzato completamente in Flash e ActionScript, con i quali viene gestita la webcam del proprio pc.</p>
<h2>I lettori del blog</h2>
<p>Lasciamo stare il lato tecnico e pensiamo invece come <em><strong>lettori di un blog</strong></em>. Potrebbe essere una soluzione comoda per commentare? Ci impiegheremmo lo stesso tempo per lasciare un commento?</p>
<p>Beh, credo che questo dipenda unicamente dalla <strong>qualità dell&#8217;applicazione</strong> che provvederà a registrare, convertire e memorizzare il commento audio. L&#8217;obiettivo principale sarà quello di agevolare il più possibile l&#8217;operazione rendendendo il tutto <strong>trasparente al lettore</strong>.</p>
<h2>Quale formato per i commenti?</h2>
<p>Infine, dobbiamo considerare se è <strong>meglio memorizzare i commenti in formato audio o testuale</strong>. Penso che il formato dei commenti andrebbe scelto tenendo conto dell&#8217;utilizzo che ne vogliamo fare. In pratica, commenti audio andrebbero bene per un sito o blog concepito in maniera multimediale, ad esempio per un sito Flash che promuove un gioco. Invece, per un blog tecnico, non so fino a che punto i commenti audio andrebbero bene: non si può mica dettare il codice a voce! <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' title="Commenti audio nei blog?" /> </p>
<p>Sicuramente i commenti audio porterebbero nelle pagine dei blog una <strong>multimedialità </strong>che attualmente non c&#8217;è e i <strong>commenti lunghi</strong> verrebbero letti (o ascoltati) molto più volentieri&#8230;</p>
<p><span class="highlight_red"><strong>Che ne pensi dei commenti audio? Se esistesse un servizio web per la gestione dei commenti audio (come Disqus per i commenti testuali) daresti la possibilità di lasciare dei commenti audio nel tuo blog?</strong></span></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=770&type=feed" alt=" Commenti audio nei blog?"  title="Commenti audio nei blog?" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/11/09/commenti-audio-nei-blog_770.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Le ultime 3 novità su Twitter: liste, retweet e trending topics</title>
		<link>http://jblog.it/2009/11/06/internet-news-ultime-novita-twitter-liste-retweet-trending-topics_753.html</link>
		<comments>http://jblog.it/2009/11/06/internet-news-ultime-novita-twitter-liste-retweet-trending-topics_753.html#comments</comments>
		<pubDate>Fri, 06 Nov 2009 13:53:09 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Internet news]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[retweet]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[trending topics]]></category>
		<category><![CDATA[twitter api]]></category>
		<category><![CDATA[twitter list]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=753</guid>
		<description><![CDATA[Nelle ultime settimane su Twitter sono state introdotte diverse novità che vanno a modificare non di poco l'utilizzo e l'utilità della piattaforma di microblogging. In particolare parliamo delle liste e della gestione dei retweet, quest'ultima già annunciata da tempo. Mentre, per quanto riguarda i trending topics, sono in atto degli interventi per migliorarne la ricerca e la selezione.]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><a title="Le ultime 3 novità su Twitter: liste, retweet, trending topics" href="http://jblog.it/2009/11/06/internet-news-ultime-novita-twitter-liste-retweet-trending-topics_753.html" target="_blank"><img class="alignnone size-full wp-image-759" title="RT-1_top" src="http://jblog.it/wp-content/uploads/2009/11/RT-1_top.jpg" alt="RT 1 top Le ultime 3 novità su Twitter: liste, retweet e trending topics" width="540" height="80" /></a></p>
<p style="text-align: left;">Nelle ultime settimane su Twitter sono state introdotte diverse novità che vanno a modificare non di poco l&#8217;utilizzo e l&#8217;utilità della piattaforma di microblogging.</p>
<p style="text-align: left;">In particolare parliamo delle liste e della gestione dei retweet, quest&#8217;ultima già annunciata da tempo. Mentre, per quanto riguarda i trending topics, sono in atto degli interventi per migliorarne la ricerca e la selezione.</p>
<p><span id="more-753"></span><!--adv300--></p>
<h2 style="text-align: left;">Le liste</h2>
<p style="text-align: left;">E&#8217; già da tempo che sono state introdotte le liste, quindi non è propriamente una novità &#8220;hot&#8221;, e come succede per ogni funzionalità di Twitter, sono nati in breve tempo software, siti e strumenti vari per gestirle al meglio.</p>
<p style="text-align: left;">Le liste non sono altro che &#8220;insiemi di account&#8221;, generalmente raggruppati per argomento, provenienza, ecc.</p>
<p style="text-align: left;"><strong>In breve</strong>, grazie a questa nuova funzionalità possiamo:</p>
<ol style="text-align: left;">
<li>dividere gli account che seguiamo in liste, ad esempio tematiche o per provenienza, proprio come una rubrica telefonica</li>
<li>seguire una lista come se fosse un singolo account</li>
<li>conoscere chi ci ha inserito all&#8217;interno di una lista</li>
</ol>
<p style="text-align: left;">Inoltre, riguardo la promozione, le liste ci danno la possibilità di essere conosciuti da chi segue una lista in cui siamo presenti, senza &#8220;seguire per essere seguiti&#8221;, il ché, a mio avviso, non è una cosa da poco&#8230;</p>
<p style="text-align: left;"><img class="alignnone size-full wp-image-766" title="Twitter Lists" src="http://jblog.it/wp-content/uploads/2009/11/list1.jpg" alt="Twitter Lists" width="540" height="232" /></p>
<p style="text-align: left;"><img class="alignnone size-full wp-image-767" title="Twitter Lists 2" src="http://jblog.it/wp-content/uploads/2009/11/list2.jpg" alt="Twitter Lists 2" width="540" height="196" /></p>
<p style="text-align: left;"><img class="alignnone size-full wp-image-768" title="Twitter Lists 3" src="http://jblog.it/wp-content/uploads/2009/11/list3.jpg" alt="Twitter Lists 3" width="540" height="190" /></p>
<p style="text-align: left;">Probabilmente eravamo in tanti che attendevamo una cosa del genere. Si, perché con le liste si risolve il <strong>problema dei troppi account</strong> che si seguono, che intasano la homepage di tweet che non ci interessano. Diciamocelo, tutti utilizziamo <strong>Twitter come strumento promozionale</strong>, quindi seguiamo tanta gente solo per &#8220;farci notare&#8221;. Questo, se da una parte può essere estremamente importante, dall&#8217;altra è estremamente dannoso per la vita su Twitter perché di fatto ci impedisce di frequentare l&#8217;homepage per leggere i tweet delle persone che più ci interessano.</p>
<h4 style="text-align: left;">Articoli che ti consiglio di leggere</h4>
<p style="text-align: left;"><a title="The next step for Twitter Lists - Entire countries" rel="bookmark" href="http://eu.techcrunch.com/2009/11/04/the-next-step-for-twitter-lists-%e2%80%94-entire-countries/" target="_blank">The next step for Twitter Lists &#8211; Entire countries</a><br />
Il prossimo passo per le Twitter Lists &#8211; Paesi interi</p>
<p style="text-align: left;"><a title="4 Ways News Organizations are Using Twitter Lists" rel="bookmark" href="http://mashable.com/2009/11/03/news-twitter-lists/" target="_blank">4 Ways News Organizations are Using Twitter Lists</a><br />
4 modi di organizzare le Twitter Lists</p>
<p style="text-align: left;"><a title="10 Twitter List Widgets You Can Grab &amp; Embed Right Now" rel="bookmarks" href="http://www.readwriteweb.com/archives/10_twitter_list_widgets_you_can_grab_embed_right_n.php" target="_blank">10 Twitter List Widgets You Can Grab &amp; Embed Right Now</a><br />
10 widget per le Twitter Lists
</p>
<p style="text-align: left;"><a title="Twitter Lists, presto le API" rel="bookmark" href="http://www.geekissimo.com/2009/11/01/twitter-lists-presto-le-api/" target="_blank">Twitter Lists, presto le API</a></p>
<h2 style="text-align: left;">ReTweet</h2>
<p style="text-align: left;">Fino ad oggi ci eravamo adattati a fare i ReTweet con messaggi del tipo:</p>
<blockquote style="text-align: left;"><p><strong>RT </strong>bla bla bla bla bla <strong>(via @account)</strong></p></blockquote>
<p style="text-align: left;">oppure</p>
<blockquote style="text-align: left;"><p><strong>@account</strong> bla bla bla bla bla</p></blockquote>
<p style="text-align: left;">La nuova gestione dei ReTweet era stata annunciata in Agosto. Chi (come me) frequenta spesso la <a title="Twitter API Documentation" href="http://apiwiki.twitter.com/Twitter-API-Documentation" target="_blank">documentazione delle API di Twitter</a> si sarà accorto dei nuovi metodi per i ReTweet con la scritta &#8220;coming soon&#8221;, presente tutt&#8217;ora.</p>
<p style="text-align: left;"><a title="Project Retweet: Phase One " href="http://blog.twitter.com/2009/08/project-retweet-phase-one.html" target="_blank"><img class="aligncenter size-full wp-image-754" title="retweet" src="http://jblog.it/wp-content/uploads/2009/11/retweet.jpg" alt="retweet Le ultime 3 novità su Twitter: liste, retweet e trending topics" width="400" height="300" /></a></p>
<p style="text-align: left;">Purtroppo <strong>le funzionalità dei ReTweet sono attive solo su una piccola percentuale di utenti scelti a caso</strong>, in modo da testarle prima di attivarle su tutti gli account. Intanto, grazie agli screenshot pubblicati su Mashable!, ma realizzati da <a href="http://www.marketingshindig.com/2009/11/05/twitter-retweet-feature/">Marketing Shindig</a> (<a href="http://www.twitter.com/marketwire" target="_blank">@marketwire</a> on Twitter) possiamo avere un&#8217;idea di quello che potremo fare:</p>
<ol style="text-align: left;">
<li>per ogni tweet, visualizzare la lista degli account che ne hanno fatto il ReTweet</li>
<li>avere un comodo pulsante &#8220;retweet&#8221; su ogni tweet, proprio come &#8220;reply&#8221; o la stellina per i preferiti, con la possibilità di ritornare sui propri passi cliccando su &#8220;undo&#8221;</li>
<li>bloccare la visualizzazione di un account fra i retweet</li>
</ol>
<p style="text-align: left;"><img class="size-full wp-image-755 alignnone" title="RT-1" src="http://jblog.it/wp-content/uploads/2009/11/RT-1.jpg" alt="retweet 1" width="540" height="250" /></p>
<p style="text-align: left;"><img class="alignnone size-full wp-image-756" title="RT-3" src="http://jblog.it/wp-content/uploads/2009/11/RT-3.jpg" alt="retweet 3" width="540" height="127" /></p>
<p style="text-align: left;"><img class="alignnone size-full wp-image-757" title="RT-4" src="http://jblog.it/wp-content/uploads/2009/11/RT-4.jpg" alt="retweet 4" width="540" height="97" /></p>
<p style="text-align: left;"><img class="alignnone size-full wp-image-758" title="RT-2" src="http://jblog.it/wp-content/uploads/2009/11/RT-2.jpg" alt="retweet 2" width="540" height="192" /></p>
<p style="text-align: left;">Questo è l&#8217;articolo del 13 Agosto sul blog ufficiale di Twitter: <a title="Project Retweet: Phase One " href="http://blog.twitter.com/2009/08/project-retweet-phase-one.html" target="_blank">Project Retweet: Phase One</a></p>
<h2 style="text-align: left;">Trending Topics</h2>
<p style="text-align: left;"><img class="alignright size-full wp-image-769" title="trending topics" src="http://jblog.it/wp-content/uploads/2009/11/trending.jpg" alt="trending topics" width="194" height="279" />Questa mattina, sul blog di Twitter, con un <a title="Twitter Blog: Get to the point: Twitter trends" href="http://blog.twitter.com/2009/11/get-to-point-twitter-trends.html" target="_blank">breve articolo</a> vengono annunciati degli interventi con l&#8217;intento di migliorare la lista dei trending topics.</p>
<p style="text-align: left;"><strong>IL PROBLEMA.</strong> I trending topics sono uno strumento creato per scoprire in tempo reale cosa sta succedento e gli argomenti di maggior interesse. Secondo lo staff di Twitter, con l&#8217;aumentare dei tweet sta diventando un ammasso di parole inutili e di scarso interesse.</p>
<p style="text-align: left;"><strong>LA SOLUZIONE.</strong> Attualmente sono al lavoro per migliorare la qualità delle ricerche e fornire dei trending topics più utili.</p>
<p style="text-align: left;">Sono pienamente d&#8217;accordo con lo staff di Twitter. Inoltre  spero che miglioreranno la gestione degli hashtag, cioé quei tag con il cancelletto &#8220;#&#8221;, che vengono linkati automaticamente. Cosa c&#8217;entra? Avete mai notato che nei trending topics spesso sono presenti contemporaneamente le stesse parole con e senza il carattere &#8220;#&#8221;?</p>
<p style="text-align: left;">Una possibile soluzione sarebbe quella di linkare gli hashtag alla pagina <code>http://twitter.com/search?q=hashtag</code> anziché <code>http://twitter.com/search?q=#hashtag</code>, e nella pagina di ricerca far apparire i tweet che corrispondono sia alla parola senza il &#8220;#&#8221; sia alla parola con il &#8220;#&#8221;. In pratica, rendere un po&#8217; più trasparente la gestione degli hashtag&#8230;</p>
<img src="http://jblog.it/?ak_action=api_record_view&id=753&type=feed" alt=" Le ultime 3 novità su Twitter: liste, retweet e trending topics"  title="Le ultime 3 novità su Twitter: liste, retweet e trending topics" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/11/06/internet-news-ultime-novita-twitter-liste-retweet-trending-topics_753.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter e Facebook: attenzione ai messaggi</title>
		<link>http://jblog.it/2009/11/03/twitter-facebook-attenzione-messaggi-scammers_751.html</link>
		<comments>http://jblog.it/2009/11/03/twitter-facebook-attenzione-messaggi-scammers_751.html#comments</comments>
		<pubDate>Tue, 03 Nov 2009 11:22:05 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Internet news]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[account]]></category>
		<category><![CDATA[falsi account]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[scammers]]></category>
		<category><![CDATA[sicurezza facebook]]></category>
		<category><![CDATA[sicurezza twitter]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[truffe]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=751</guid>
		<description><![CDATA[In questi ultimi giorni gli scammers sono molto attivi sia su Twitter che su Facebook. La loro attività consiste nel compromettere gli account e da questi inviare messaggi contenenti un link verso un sito che sicuramente non ti farà piacere visitare... Anch'io ho ricevuto un messaggio del genere su Twitter da parte, però, di un utente italiano (che ho subito avvisato).]]></description>
			<content:encoded><![CDATA[<p><img src="http://jblog.it/wp-content/img/loghi/multi_socialnetwork/twitter_facebook_big1.jpg" alt="Twitter e Facebook: attenzione ai messaggi" title="Twitter e Facebook: attenzione ai messaggi" /></p>
<p>In questi ultimi giorni gli scammers sono molto attivi sia su Twitter che su Facebook.</p>
<p>La loro attività consiste nel compromettere gli account e da questi inviare messaggi contenenti un link verso un sito che sicuramente non ti farà piacere visitare&#8230;</p>
<p>Anch&#8217;io ho ricevuto un messaggio del genere su Twitter da parte, però, di un utente italiano (che ho subito avvisato). Il ché mi ha fatto insospettire e in pochi minuti ne ho avuto la conferma leggendo le news.<span id="more-751"></span></p>
<h3>Il messaggio su Twitter</h3>
<blockquote><p>I made $426.23 online today with [link]</p></blockquote>
<h3>Il messaggio su Facebook</h3>
<blockquote><p>Just take a look at it and read it over and try it if you want [link].</p></blockquote>
<p><!--adv300--></p>
<h3>Consigli</h3>
<ul>
<li><strong>Avvisa</strong> subito il mittente del messaggio</li>
<li><strong>Non visitare il link</strong>. Neanche per curiosità! <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' title="Twitter e Facebook: attenzione ai messaggi" /> </li>
<li>Anche se il tuo account non è stato compromesso, <strong>cambia la password</strong> in modo da evitare l&#8217;invio di futuri messaggi</li>
</ul>
<h6>Ne approfitto per dare qualche piccolo consiglio sulla password</h6>
<ul>
<li>scegli una password lunga</li>
<li>inserisci sia lettere che numeri</li>
<li>non inserire nome, cognome, anno di nascita e altre parole direttamente collegabili a te</li>
</ul>
<h6><span class="highlight_cyan">Perfavore, potresti avvisarmi se ricevi un messaggio di questo tipo? Io sono &#8220;giacomoratta&#8221; su Twitter e &#8220;Giacomo Ratta&#8221; su Facebook. Ti ringrazio in anticipo. <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' title="Twitter e Facebook: attenzione ai messaggi" /> </span></h6>
<img src="http://jblog.it/?ak_action=api_record_view&id=751&type=feed" alt=" Twitter e Facebook: attenzione ai messaggi"  title="Twitter e Facebook: attenzione ai messaggi" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/11/03/twitter-facebook-attenzione-messaggi-scammers_751.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>10 formati di banner e annunci da evitare</title>
		<link>http://jblog.it/2009/06/19/10-formati-banner-annunci-ads-da-evitare-odiati_702.html</link>
		<comments>http://jblog.it/2009/06/19/10-formati-banner-annunci-ads-da-evitare-odiati_702.html#comments</comments>
		<pubDate>Fri, 19 Jun 2009 02:48:17 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Usabilità]]></category>
		<category><![CDATA[Web design]]></category>
		<category><![CDATA[adsense]]></category>
		<category><![CDATA[annunci]]></category>
		<category><![CDATA[banner]]></category>
		<category><![CDATA[guadagnare]]></category>
		<category><![CDATA[promuovere]]></category>
		<category><![CDATA[pubblicità]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=702</guid>
		<description><![CDATA[Se stai considerando l&#8217;idea di inserire un po&#8217; di banner e annunci sul tuo sito ti consiglio di leggere questo interessante articolo pubblicato su Business Insider in cui vengono classificati i formati più odiati dagli utenti.
L&#8217;articolo è stato strutturato molto bene in quanto descrive i 10 formati incriminati fornendo lo screenshot del sito che lo [...]]]></description>
			<content:encoded><![CDATA[<p><a title="10 formati di banner e annunci da evitare" href="http://jblog.it/2009/06/19/10-formati-banner-annunci-ads-da-evitare-odiati_702.html"><img class="alignright size-full wp-image-703" src="http://jblog.it/wp-content/uploads/2009/10/anger.jpg" alt="anger 10 formati di banner e annunci da evitare" width="196" height="214" title="10 formati di banner e annunci da evitare" /></a>Se stai considerando l&#8217;idea di inserire un po&#8217; di banner e annunci sul tuo sito ti consiglio di leggere <a title="The 10 Online Ad Formats People Hate Most" href="http://www.businessinsider.com/10-online-ad-formats-people-hate-most-2009-6" target="_blank"><strong>questo interessante articolo</strong></a> pubblicato su <strong><em>Business Insider </em></strong>in cui vengono classificati i formati più odiati dagli utenti.</p>
<p>L&#8217;articolo è stato strutturato molto bene in quanto descrive i 10 formati incriminati fornendo lo <strong>screenshot</strong> del sito che lo utilizza, il tutto all&#8217;interno di una bellissima <strong><a title="Slideshow" href="http://www.businessinsider.com/10-online-ad-formats-people-hate-most-2009-6/banner-ad-below-header-1" target="_blank">slide-show</a></strong>.<span id="more-702"></span></p>
<h4>1. Banner sotto l&#8217;header</h4>
<p>Spacca in due la pagina e sposta più in basso il suo vero contenuto.</p>
<h4>2. Annunci simili al contenuto</h4>
<p>Sono ingannevoli e causano l&#8217;abbandono involontario del sito da parte dell&#8217;utente.</p>
<h4>3. Annunci animati</h4>
<p>Provoca distrazione e, poiché sono di bassa qualità, riduce la credibilità del sito.</p>
<h4>4. Annuncio espandibile al centro della pagina</h4>
<p>Obbliga l&#8217;utente a cliccare sul pulsante &#8220;chiudi&#8221;, interrompendo fastidiosamente la navigazione.</p>
<p><!--adv300--></p>
<h4>5. Banner vicini al logo</h4>
<p>Anche se ha il vantaggio di non interferire sulla struttura della pagina e, quindi, di non trascinare ulteriormente in basso il contenuto, riduce lo spazio riservato al logo diminuendo la chiarezza e la visibilità del brand.</p>
<h4>6. Banner ampio in alto a sinistra</h4>
<p>In molti casi, con un banner di questo tipo gli utenti si accorgono subito che non fa parte del reale contenuto della pagina.</p>
<h4>7. Google Ads testuali</h4>
<p>Interrompono il contenuto della pagina. Naturalmente il gestore del sito spera che vengano confusi con il contenuto e che, di conseguenza, vengano cliccati.</p>
<h4>8. Pulsante &#8220;chiudi&#8221; nascosto</h4>
<p>Spesso nei banner graficamente carini e animati si cerca di camuffare il pulsante &#8220;chiudi&#8221; o di ritardarne la sua apparizione. In questo caso gli utenti sono costretti a perdere tempo a cercarlo o a sorbirsi tutta l&#8217;animazione che generalmente è una sgradevole interruzione della navigazione.</p>
<h4>9. Banner &#8220;a tutto schermo&#8221;</h4>
<p>Questo tipo di banner occupa tutta l&#8217;area della pagina e obbliga l&#8217;utente a cliccare su &#8220;continua&#8221; (o qualcosa di simile) per accedere ai contenuti desiderati. Abbastanza &#8220;violenta&#8221; come soluzione.</p>
<h4>10. Annunci appariscenti e ben amalgamati</h4>
<p>Quando un banner o un annuncio assomiglia graficamente al sito e al suo contenuto tende a fondersi con la pagina risultando indistinguibile agli occhi dell&#8217;utente. In questo caso l&#8217;utente rimane disorientato, soprattutto se è un assiduo visitatore abituato al normale layout del sito.</p>
<p><em>Questa è solo una sintesi. Per leggere l&#8217;articolo originale e osservare i 10 screenshot dei siti che utilizzano questi formati vai su <a title="The 10 Online Ad Formats People Hate Most" href="http://www.businessinsider.com/10-online-ad-formats-people-hate-most-2009-6" target="_blank">http://www.businessinsider.com/10-online-ad-formats-people-hate-most-2009-6</a>.</em></p>
<p><strong><span class="highlight_green">Che ne pensi di questa lista? Secondo te è completa o avresti altri esempi negativi da aggiungere?</span></strong></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=702&type=feed" alt=" 10 formati di banner e annunci da evitare"  title="10 formati di banner e annunci da evitare" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/19/10-formati-banner-annunci-ads-da-evitare-odiati_702.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Wordpress plugin: stampare una lista di &#8220;featured posts&#8221; o &#8220;post in evidenza&#8221;</title>
		<link>http://jblog.it/2009/06/17/wordpress-plugin-stampare-lista-featured-posts-in-evidenza_690.html</link>
		<comments>http://jblog.it/2009/06/17/wordpress-plugin-stampare-lista-featured-posts-in-evidenza_690.html#comments</comments>
		<pubDate>Wed, 17 Jun 2009 02:49:56 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Wordpress plugin]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[wordpress trick]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=690</guid>
		<description><![CDATA[I cosiddetti &#8220;featured posts&#8221; sono un insieme di post che vengono scelti per esser messi in risalto. In questo blog, i &#8220;post in evidenza&#8221; sono quelli che considero essere i migliori. Mettendoli in risalto ho la possibilità di mostrare il meglio dei miei articoli al nuovo visitatore. Potrebbero esserci altri motivi, ad esempio di tipo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jblog.it/2009/06/17/wordpress-plugin-stampare-lista-featured-posts-in-evidenza_690.html"><img class="alignright size-full wp-image-697" title="Highlighter" src="http://jblog.it/wp-content/uploads/2009/10/featuredposts.jpg" alt="Highlighter" width="200" height="286" /></a>I cosiddetti &#8220;featured posts&#8221; sono un insieme di post che vengono scelti per esser messi in <strong>risalto</strong>. In questo blog, i &#8220;post in evidenza&#8221; sono quelli che considero essere i migliori. Mettendoli in risalto ho la possibilità di mostrare il meglio dei miei articoli al nuovo visitatore. Potrebbero esserci altri motivi, ad esempio di tipo commerciale (se i post in evidenza pubblicizzano qualcosa).</p>
<p>Nonostante ci siano un po&#8217; di ottimi plugin per la gestione e la stampa dei &#8220;featured posts&#8221; ho sviluppato questo mio plugin che, credo, sia diverso dai plugin in circolazione e per certi versi offra una gestione più <strong>user friendly</strong>. Probabilmente questo sarà un giudizio soggettivo&#8230; In pratica, ci sono alcuni plugin che permettono di inserire gli id dei post, separati da virgole, in una casella di testo. Il mio plugin legge i &#8220;custom fields&#8221; (in italiano &#8220;campo personalizzati&#8221;) dei post che si decide di mettere in evidenza. In questo senso credo che impostare un campo personalizzato sia un po&#8217; più user friendly rispetto all&#8217;aver a che fare con insiemi di numeri. <strong>Secondo te?</strong><br />
<span id="more-690"></span></p>
<h2>Per gli impazienti</h2>
<p><!--adv300--></p>
<p>Per iniziare a utilizzare il plugin:</p>
<ol>
<li>effettua il download: <a href="http://download.jblog.it/wp-plugins/jblog_featured_posts.zip" target="_blank">http://download.jblog.it/wp-plugins/jblog_featured_posts.zip</a></li>
<li>copialo nella directory &#8220;plugins&#8221; e attivalo</li>
<li>inserisci la funzione jblog_print_featured_posts() nel punto del template in cui vuoi stampare la lista dei post in evidenza</li>
</ol>
<p><strong>Per far comparire un determinato post fra i post in evidenza</strong> è necessario entrare nella pagina di editing dell&#8217;articolo e inserire un campo personalizzato di nome &#8220;featured&#8221; con il valore &#8220;ok&#8221; o uno qualsiasi. <em><strong>Il valore non incide sul funzionamento del plugin</strong></em>. Tuttavia consiglio di inserire il valore &#8220;ok&#8221; in modo da beneficiare di futuri aggiornamenti in cui eventualmente verrà utilizzato.</p>
<h2>In profondità</h2>
<p>Il plugin è composto da due funzioni:</p>
<ul>
<li><strong>jblog_getFeaturedPosts</strong> seleziona i post e li restituisce in un array, ordinati dal più recente al più vecchio</li>
<li><strong>jblog_printFeaturedPosts</strong> seleziona i post e li stampa sottoforma di lista &lt;ul&gt;&#8230;&lt;li&gt;</li>
</ul>
<h3>jblog_getFeaturedPosts</h3>
<p>Questa funzione è il cuore del plugin. Seleziona i post e li restituisce in un array. In questo modo potrai essere libero di gestire e stampare i dati restituiti come più ti piace.</p>
<p>La funzione ha <strong>2 argomenti</strong>:</p>
<ul>
<li><strong>$args</strong> [default "limit=10&amp;len=0"] è una stringa in cui vengono passate le opzioni (nella forma [opzione]=[valore]) separate da &#8220;&amp;&#8221;. Le uniche due opzioni sono <strong>limit</strong> (-1 per stampare tutti i post in evidenza, un numero maggiore di 0 per stampare un numero limitato di post) e <strong>len</strong> per la lunghezza del contenuto (per non selezionare il contenuto basta impostarlo con zero o non impostarla affatto)</li>
<li><strong>$metakey</strong> [default "featured"] è una stringa utilizzata per impostare il nome del campo personalizzato utilizzato per indicare che il post deve esser messo in evidenza</li>
</ul>
<p><strong>Esempio</strong></p>
<p><code>$myarray = jblog_getFeaturedPosts("limit=-1&amp;len=150","myfeatured");</code></p>
<ul>
<li>$myarray è l&#8217;array in cui verranno restituiti i post</li>
<li>limit=-1 fa in modo che si selezionino tutti i post che hanno il campo &#8220;myfeatured&#8221;</li>
<li>len=150 imposta il numero di caratteri del contenuto da restituire</li>
<li>&#8220;myfeatured&#8221; è il campo personalizzato utilizzato per indicare che il post deve esser messo in evidenza</li>
</ul>
<p><strong>L&#8217;array</strong> restituito dalla funzione è composto dai post selezionati, ordinati dal più recente al più vecchio. Ogni elemento dell&#8217;array è a sua volta un array associativo contenente le informazioni del singolo post divise in corrispondenza degli indici &#8220;id&#8221;, &#8220;title&#8221;, &#8220;link&#8221; e &#8220;content&#8221;.</p>
<p><strong>Esempio</strong></p>
<p>Un semplice esempio per la stampa delle informazioni di ogni singolo post selezionato.</p>
<pre lang="php">// Seleziona i post
$posts_array = jblog_getFeaturedPosts("limit=20&amp;len=300","myfeatured");

// Ciclo: stampa le informazioni di ogni singolo post
foreach($posts_array as $post)
{
     echo "ID: ".$post['id'];
     echo "Titolo: ".$post['title'];
     echo "Link: ".$post['link'];
     echo "Contenuto: ".$post['content'];
}</pre>
<h3>jblog_printFeaturedPosts</h3>
<p>Oltre a selezionare i post in evidenza, li stampa in una lista del tipo &lt;ul&gt;&#8230;&lt;li&gt;.</p>
<p>Gli <strong>argomenti </strong>sono gli stessi della funzione jblog_getFeaturedPosts (vedi sopra).</p>
<p><strong>Esempio</strong></p>
<p>Questa funzione va utilizzata direttamente all&#8217;interno del template inserendo la riga seguente nel punto in cui si desidera visualizzare la lista.</p>
<p><code>&lt;? jblog_printFeaturedPosts("limit=-1&amp;len=100") ?&gt;</code></p>
<h2>Come impostare un post &#8220;in evidenza&#8221;</h2>
<p>Questo se vogliamo è il lato del plugin un po&#8217; più &#8220;macchinoso&#8221;.</p>
<p>Per fare in modo che un post venga stampato nella lista dei post in evidenza è necessario andare nella pagina di editing dell&#8217;articolo e creare un <strong>&#8220;custom field&#8221;</strong> (o campo personalizzato) di nome &#8220;featured&#8221; oppure uguale all&#8217;argomento <strong>$metakey</strong> passato alle funzioni.</p>
<p>Come valore scrivere una cosa qualsiasi. Tuttavia consiglio di inserire il valore &#8220;ok&#8221; in modo da beneficiare di futuri aggiornamenti in cui eventualmente verrà utilizzato. <em><strong>Il valore non incide sul funzionamento del plugin</strong></em>, ma è necessario dato che wordpress non permette la creazione di un campo personalizzato senza un valore.</p>
<h2>HTML e utilizzo dei CSS</h2>
<p>Se utilizzi la funzione<strong> jblog_printFeaturedPosts </strong>ecco le informazioni che ti servono per poter formattare adeguatamente la lista dei post.</p>
<ul>
<li>Per formattare il contenitore principale della lista (&lt;ul&gt;) fare riferimento all&#8217;id &#8220;featured_posts&#8221;</li>
<li>Ad ogni contenitore del singolo post (&lt;li&gt;) viene attribuito l&#8217;id &#8220;featured_post_&#8221; al quale viene aggiunto in coda l&#8217;id del post</li>
<li>Il titolo di ogni post viene inserito all&#8217;interno di un tag &lt;a&gt;, il cui attributo href sarà impostato con il link del post</li>
<li>Il contenuto dei post viene inserito in un tag &lt;p&gt;</li>
</ul>
<p><span class="highlight_red"><strong>Vuoi personalizzare il codice html?</strong> Apri il file del plugin, individua la funzione jblog_printFeaturedPosts e buon lavoro! <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' title="Wordpress plugin: stampare una lista di featured posts o post in evidenza" /> </span></p>
<h4>Esempio dell&#8217;output</h4>
<pre lang="html">&lt;ul id="featured_posts"&gt;
	 &lt;li&gt;
		&lt;a href="http://...html" id="featured_post_270"&gt;Titolo 1 - post 270&lt;/a&gt;
		&lt;p&gt;Howwww! Nab him, jab him, tab him, grab him, stop that pigeon now.&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="http://...html" id="featured_post_320"&gt;Titolo 2 - post 320&lt;/a&gt;
		&lt;p&gt;Grab him, stop that pigeon now.&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="http://...html" id="featured_post_450"&gt;Titolo 1 - post 450&lt;/a&gt;
		&lt;p&gt;Tab him, grab him, stop that pigeon now.&lt;/p&gt;
	&lt;/li&gt;
&lt;/ul&gt;</pre>
<h2>Script e Download</h2>
<p>Per vedere il codice del plugin fai su <a href="http://test.jblog.it/wp-plugins/jblog_featured_posts.txt" target="_blank">http://test.jblog.it/wp-plugins/jblog_featured_posts.txt</a></p>
<p>Per scaricare il plugin vai su <a href="http://download.jblog.it/wp-plugins/jblog_featured_posts.zip" target="_blank">http://download.jblog.it/wp-plugins/jblog_featured_posts.zip</a></p>
<p><span class="highlight_green"><strong>Per eventuali segnalazioni e malfunzionamenti scrivi dei commenti a questo post o contattami sull&#8217;email che trovi nella pagina &#8220;contatti&#8221;.</strong></span></p>
<p><strong>Questo plugin non fa per te?</strong> In <a title="Ricerca Wordpress plugin &quot;featured posts&quot;" href="http://wordpress.org/extend/plugins/search.php?q=featured+posts" target="_blank">questa pagina</a> (su wordpress.org) trovi tantissimi plugin riguardanti i &#8220;post in evidenza&#8221;. Sicuramente ne troverai uno adatto alle tue esigenze! <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' title="Wordpress plugin: stampare una lista di featured posts o post in evidenza" /> </p>
<p><strong>Foto: </strong><a href="http://www.flickr.com/photos/deadmanjones/2263906774/" target="_blank">still managed to draw a straight line</a> di <a href="http://www.flickr.com/photos/deadmanjones/">deadmanjones</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=690&type=feed" alt=" Wordpress plugin: stampare una lista di featured posts o post in evidenza"  title="Wordpress plugin: stampare una lista di featured posts o post in evidenza" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/17/wordpress-plugin-stampare-lista-featured-posts-in-evidenza_690.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>CommonTag, un nuovo standard per il tagging e un altro passo verso il web semantico</title>
		<link>http://jblog.it/2009/06/11/commontag-nuovo-standard-tagging-altro-passo-web-semantico_666.html</link>
		<comments>http://jblog.it/2009/06/11/commontag-nuovo-standard-tagging-altro-passo-web-semantico_666.html#comments</comments>
		<pubDate>Thu, 11 Jun 2009 20:15:08 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Internet news]]></category>
		<category><![CDATA[Web 3.0]]></category>
		<category><![CDATA[common tag]]></category>
		<category><![CDATA[dbpedia]]></category>
		<category><![CDATA[freebase]]></category>
		<category><![CDATA[nuovi standard]]></category>
		<category><![CDATA[promuovere]]></category>
		<category><![CDATA[standard web]]></category>
		<category><![CDATA[tagging]]></category>
		<category><![CDATA[web semantico]]></category>
		<category><![CDATA[wikipedia]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[zemanta]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=666</guid>
		<description><![CDATA[A partire da oggi è stato reso pubblico il progetto Common Tag ed il sito commontag.org che ne rappresenterà il punto di riferimento. Questo progetto si propone di creare un nuovo standard per migliorare il collegamento fra i contenuti web sfruttando il significato delle parole e dei tag.]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-670" title="CommonTag logo" src="http://jblog.it/wp-content/uploads/2009/06/logo.png" alt="CommonTag logo" width="240" height="100" />A partire da oggi è stato reso pubblico il progetto Common Tag ed il sito <strong><a href="http://commontag.org" target="_blank">commontag.org</a></strong> che ne rappresenterà il punto di riferimento.</p>
<p>Questo progetto si propone di creare un <strong>nuovo standard</strong> per migliorare il collegamento fra i contenuti web sfruttando il <strong>significato delle parole</strong> e dei tag.</p>
<h2>Il tagging attuale</h2>
<p><!--adv200--></p>
<p>Per loro natura, i tag servono a <strong>etichettare e organizzare</strong> i contenuti sul web e, di conseguenza, migliorare i risultati di ricerca. Tuttavia, in assenza di uno standard comune i vantaggi dei tag risultano <strong>limitati </strong>in quanto software e siti web non riescono a interpretarli al meglio.</p>
<p>Un&#8217;altro problema è di tipo <strong>semantico</strong>. Poiché una parola può avere più di un significato non è possibile avere la certezza che dei contenuti collegati fra loro si riferiscano allo stesso argomento. Ad esempio, con il tagging attuale una foto di un ragno verrebbe collegata a un documento che parla di internet solo perché entrambi potrebbero riferirsi al tag &#8220;web&#8221; (ragnatela).</p>
<p>Da qui nasce il bisogno di definire uno standard che, oltre a gestire i tag, sappia tener conto dei <strong>significati delle parole</strong> in determinati contesti.<br />
<span id="more-666"></span></p>
<h2>Il formato Common Tag</h2>
<p>Il progetto è stato sviluppato per affrontare le attuali carenze del tagging e aiutare utenti, editori e sviluppatori a ottenere maggiori e più precisi collegamenti fra i propri contenuti e il resto del web. Ecco i <strong>punti chiave</strong>:</p>
<ul>
<li>Common Tag si basa sul<strong> formato standard <a title="RDFa Primer - Bridging the Human and Data Webs" href="http://www.w3.org/TR/xhtml-rdfa-primer/" target="_blank">RDFa</a></strong></li>
<li>Il significato dei singoli tag è memorizzato in grandi database gestiti come <strong>dizionari</strong></li>
<li>Ai contenuti e ai tag vengono attribuiti i rispettivi significati, grazie ai quali potranno relazionarsi con altri contenuti del web</li>
</ul>
<p><span class="highlight_pink"><strong>La precisione</strong> delle relazioni si ottiene grazie all&#8217;utilizzo di <strong>metadati e concetti ben definiti</strong> con cui vengono taggati i contenuti.</span> Attualmente questo progetto si serve di due grandi dizionari da cui prelevare i significati dei vari tag:</p>
<ul>
<li><a href="http://www.freebase.com/" target="_blank"><strong>FreeBase</strong></a>, un database sociale di concetti e argomenti che più interessano agli utenti</li>
<li><a href="http://dbpedia.org/About" target="_blank"><strong>DBpedia</strong></a>, un server in cui le informazioni sono rappresentate come in <a class="zem_slink" title="Wikipedia" rel="homepage" href="http://www.wikipedia.org/">Wikipedia</a> e leggibile dall&#8217;esterno grazie all&#8217;interfaccia pubblica</li>
</ul>
<p><a href="http://commontag.org/Image:CommonTag-ecosystem.png" target="_blank"><img class="aligncenter size-full wp-image-680" title="Ecosistema dei Common Tag" src="http://jblog.it/wp-content/uploads/2009/06/commontag-ecosystem.jpg" alt="Ecosistema dei Common Tag" width="575" height="426" /></a></p>
<h2>Come funziona, tecnicamente</h2>
<p><img class="alignright size-full wp-image-677" title="Modello Common Tag" src="http://jblog.it/wp-content/uploads/2009/06/commontagmodel.jpg" alt="Modello Common Tag" width="221" height="289" />Il formato Common Tag si basa sul formato standard <a title="RDFa Primer - Bridging the Human and Data Webs" href="http://www.w3.org/TR/xhtml-rdfa-primer/" target="_blank">RDFa</a>, un meccanismo che consente di strutture il contenuto di documenti <a class="zem_slink" title="HTML" rel="wikipedia" href="http://en.wikipedia.org/wiki/HTML">HTML</a>. Lo standard <a title="RDFa Primer - Bridging the Human and Data Webs" href="http://www.w3.org/TR/xhtml-rdfa-primer/" target="_blank">RDFa</a> è stato sviluppato dal W3C ed è supportato da <a class="zem_slink" title="Google" rel="homepage" href="http://google.com">Google</a> e <a class="zem_slink" title="Yahoo!" rel="homepage" href="http://www.yahoo.com">Yahoo!</a> grazie al quale forniscono maggiori risultati nelle ricerche.</p>
<p>La struttura del modello Common Tag è molto semplice.</p>
<ul>
<li>I contenuti (e le loro singole parole) possono essere taggati con uno o più tag</li>
<li>Ogni Common Tag può contenere la <a class="zem_slink" title="Uniform Resource Locator" rel="wikipedia" href="http://en.wikipedia.org/wiki/Uniform_Resource_Locator">URL</a> di un&#8217;altra risorsa che ne identifica univocamente il <strong>concetto descritto</strong>, cioè il suo <strong>significato</strong></li>
<li>Opzionalmente potrebbe contenere altre informazioni come la <strong>data di creazione</strong> e l&#8217;<strong>etichetta</strong></li>
</ul>
<p><strong>Il significato dei singoli tag</strong> è memorizzato in grandi database (come Freebase.com e dbpedia.org)  che di fatto vengono gestiti come dizionari; grazie a questi database è possibile effettuare collegamenti basati sul significato anziché sulla parola. In questi enormi database ogni tag ha una pagina composta da tutte le sue informazioni, strutturate secondo lo standard <a title="RDFa Primer - Bridging the Human and Data Webs" href="http://www.w3.org/TR/xhtml-rdfa-primer/" target="_blank">RDFa</a>.</p>
<p><strong>I database dei significati</strong> possono essere letti da siti e applicazioni esterne grazie alle interfacce pubbliche (o <a class="zem_slink" title="Application programming interface" rel="wikipedia" href="http://en.wikipedia.org/wiki/Application_programming_interface">API</a>), da imparare grazie alla relativa e approfondita documentazione. Guarda la <a href="http://www.freebase.com/make" target="_blank">documentazione di Freebase</a> e la <a href="http://wiki.dbpedia.org/OnlineAccess" target="_blank">documentazione di DBpedia</a>.</p>
<p><strong>Maggiori informazioni.</strong> Se ti interessa approfondire il lato tecnico dei Common Tag non ti resta che consultare la <a href="http://commontag.org/QuickStartGuide" target="_blank">Quick Start Guide</a> e le <a href="http://commontag.org/Specification" target="_blank">Specifiche</a> dei Common Tag, e lo standard <a title="RDFa Primer - Bridging the Human and Data Webs" href="http://www.w3.org/TR/xhtml-rdfa-primer/" target="_blank">RDFa</a> (sul sito del W3C).</p>
<p><strong>ESEMPIO.</strong> Ecco un semplice esempio preso da commontag.org. Con questo codice si indica che il documento corrente riguarda la band U2 (vedi l&#8217;attributo &#8220;resource&#8221;).</p>
<pre>&lt;body xmlns:ctag="http://commontag.org/ns#" rel="ctag:tagged"&gt;
   &lt;span   typeof="ctag:Tag"
           rel="ctag:means"
           resource="http://rdf.freebase.com/ns/en.u2"/&gt;
&lt;/body&gt;</pre>
<h2>Contenuti più usabili</h2>
<p>Man mano che i Common Tag saranno utilizzati i contenuti web verranno attribuiti a un numero sempre maggiore di tag e significati. Questo sarà vantaggioso sia per gli utenti, che avranno <strong>più contenuti</strong> fra i quali scegliere, sia per gli editori, che vedranno aumentare notevolmente le <strong>visite</strong> nel proprio sito.</p>
<p>Inoltre, il fatto che i <strong>principali motori di ricerca</strong> supportino adeguatamente il markup standard RDFa gioca a favore della diffusione dei Common Tag. Quindi gli sviluppatori non avranno molte scuse per non utilizzarli. Entrambi i motori di ricerca hanno sviluppato le proprie applicazioni che sfruttano i Common Tag per fornire maggiori e più dettagliati risultati di ricerca: <strong><a href="http://developer.yahoo.com/searchmonkey/" target="_blank">SearchMonkey</a></strong> di Yahoo! e <strong><a href="http://googlewebmastercentral.blogspot.com/2009/05/introducing-rich-snippets.html" target="_blank">Rich Snippets</a></strong> di Google.</p>
<h2>Maggiori relazioni fra i contenuti</h2>
<p>Tutte le informazioni relative a un particolare concetto sono collegate fra loro e rappresentate da un singolo tag, sia all&#8217;interno dei singoli siti che in tutto il web. Questo consente, a editori e sviluppatori, di fornire <strong>molte più informazioni e risorse correlate</strong> al contenuto del proprio sito web.</p>
<p>Ad <strong>esempio</strong>, se un articolo parla di Tom Cruise, i Common Tag ci permettono di collegarvi articoli che parlano di Katie Holmes per il semplice fatto che sono sposati e non perché nei titoli e nel contenuto di questi articoli compaiono le parole &#8220;Tom&#8221; o &#8220;Cruise&#8221;. Se così fosse, tra questi comparirebbero tutti gli articoli che parlano del &#8220;Cruise control&#8221; e dell&#8217;automobile &#8220;Land Cruiser&#8221;!</p>
<h2>Contenuti di qualità e applicazioni innovative</h2>
<p>Il fatto che i computer capiscano il significato delle parole <strong>migliora l&#8217;esperienza dell&#8217;utente</strong>. Infatti, ciò permette a editori e sviluppatori di avere contenuti più completi e creare applicazioni innovative che lavorano sui contenuti taggati con i Common Tag.</p>
<p>Ad esempio, consideriamo un blog sul cinema e un sito per la vendita di biglietti, e supponiamo che entrambi abbiano i contenuti taggati con i Common Tag. Inoltre supponiamo che un utente stia leggendo un articolo riguardante Star Trek. Uno sviluppatore potrebbe creare un&#8217;applicazione che permetta a questo utente di acquistare i biglietti per Star Trek direttamente all&#8217;interno dell&#8217;articolo, basandosi sul fatto che l&#8217;articolo e la pagina per l&#8217;acquisto dei biglietti hanno il Common Tag relativo al film di Star Trek. Immagini quante applicazioni potrebbero nascere sulla falsa riga di questa? Moltiplica per 1000! <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' title="CommonTag, un nuovo standard per il tagging e un altro passo verso il web semantico" /> </p>
<p><a href="http://commontag.org/Image:CommonTag-users.png" target="_blank"><img class="aligncenter size-full wp-image-675" title="Schema CommonTag" src="http://jblog.it/wp-content/uploads/2009/06/commontag-users.png" alt="Schema CommonTag" width="580" height="344" /></a></p>
<h2>Conclusione</h2>
<p>Adottare uno standard ben definito per descrivere i propri contenuti <strong>si rivelerà estremamente vantaggioso</strong>. Applicazioni e servizi web sapranno finalmente collegare innumerevoli risorse sulla base dell&#8217;argomento trattato e non più sull&#8217;analisi delle parole chiave. <strong>Senza grossi interventi da parte di editori e sviluppatori!</strong></p>
<p>Per me, come ho scritto nel titolo, questo standard rappresenta un piccolo, ma fondamentale, passo per il <strong>web semantico</strong>, quello che tutti chiamano <strong>Web 3.0</strong>. In fondo, si chiama web semantico proprio perché si basa sull&#8217;analisi del significato delle parole e non più su una &#8220;ricerca di caratteri&#8221;. <span class="highlight_green"><strong>Mi piacerebbe sapere cosa ne pensi sui Common Tag</strong>: ritieni che siano così importanti tanto da utilizzarli fin da subito o preferisci aspettare in attesa di altre tecniche che siano più semplici da implementare?</span></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=666&type=feed" alt=" CommonTag, un nuovo standard per il tagging e un altro passo verso il web semantico"  title="CommonTag, un nuovo standard per il tagging e un altro passo verso il web semantico" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/11/commontag-nuovo-standard-tagging-altro-passo-web-semantico_666.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>20 servizi web e librerie per ottimizzare i componenti della pagina: immagini, javascript, css</title>
		<link>http://jblog.it/2009/06/10/ottimizzare-componenti-pagina-velocizzare-caricamento-immagini-css-script_640.html</link>
		<comments>http://jblog.it/2009/06/10/ottimizzare-componenti-pagina-velocizzare-caricamento-immagini-css-script_640.html#comments</comments>
		<pubDate>Wed, 10 Jun 2009 11:36:50 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Css]]></category>
		<category><![CDATA[Grafica]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Ottimizzazione]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[classe php]]></category>
		<category><![CDATA[classi librerie]]></category>
		<category><![CDATA[csstidy]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[espressioni regolari]]></category>
		<category><![CDATA[ottimizzare]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[richieste http]]></category>
		<category><![CDATA[servizi web]]></category>
		<category><![CDATA[sprite css]]></category>
		<category><![CDATA[yui compressor]]></category>
		<category><![CDATA[yui library]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=640</guid>
		<description><![CDATA[Dopo gli articoli &#8220;ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser&#8221; e &#8220;ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css&#8221; vorrei parlarti delle tecniche per l&#8217;ottimizzazione dei componenti più comuni di una pagina web: immagini, script e css.

In questo articolo non verranno descritti dei metodi per [...]]]></description>
			<content:encoded><![CDATA[<p>Dopo gli articoli &#8220;<a href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html">ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser</a>&#8221; e &#8220;<a href="http://jblog.it/2009/05/15/ridurre-richieste-http-parte-2-come-combinare-immagini-script-css-sprite-image-maps_405.html">ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css</a>&#8221; vorrei parlarti delle tecniche per l&#8217;ottimizzazione dei componenti più comuni di una pagina web: immagini, script e css.</p>
<p><img class="aligncenter size-full wp-image-657" title="forty-nine: compressed work week" src="http://jblog.it/wp-content/uploads/2009/10/ottimizzare.jpg" alt="forty-nine: compressed work week" width="500" height="333" /></p>
<p><span class="highlight_yellow"><strong>In questo articolo</strong> non verranno descritti dei metodi per la riduzione delle richieste HTTP ma parlerò delle modifiche e degli strumenti che ti permetteranno di ottimizzare i componenti della pagina per velocizzarne le relative richieste HTTP.</span><br />
<span id="more-640"></span><br />
<!--adv300--></p>
<h2>Ottimizzare le immagini</h2>
<p>Anche se l&#8217;ottimizzazione non riduce le richieste http, è comunque importante per <strong>abbassare i tempi di caricamento</strong> delle pagine.</p>
<p>Ottimizzare un&#8217;immagine non è immediato; spesso sono necessarie molte prove e test per individuare il <strong>giusto bilanciamento</strong> fra qualità e dimensione del file.</p>
<p>Generalmente la compressione di un immagine è un&#8217;operazione da eseguire <strong>manualmente </strong>prima di caricare l&#8217;immagine nel proprio sito. Per fare ciò esistono numerosi <strong>script e tool gratuiti</strong>. Eccone alcuni.</p>
<div style="padding-left:20px;">
<h4><a href="http://www.imagemagick.org/" target="_blank">ImageMagick</a></h4>
<p><img class="alignright size-full wp-image-648" title="ImageMagick logo" src="http://jblog.it/wp-content/uploads/2009/06/logo.jpg" alt="ImageMagick logo" width="114" height="118" />ImageMagick è un set di librerie per creare, modificare e comporre immagini bitmap. Può leggere, convertire e scrivere immagini in vari formati (es. <strong>DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, <a class="zem_slink" title="Portable Network Graphics" rel="wikipedia" href="http://en.wikipedia.org/wiki/Portable_Network_Graphics">PNG</a>, Postscript, SVG, e TIFF</strong>). ImageMagick, oltre alla rotazione e al ridimensionamento, permette di effettuare operazioni abbastanza complesse, applicare effetti speciali e tracciare forme.</p>
<p>Sul sito potrai trovare i libri consigliati (in lingua inglese) e tutto il necessario per iniziare a utilizzare queste librerie.</p>
<h4><a href="http://www.imagemagick.org/script/api.php" target="_blank">ImageMagick APIs</a></h4>
<p>ImageMagick include interfacce ed estensioni per utilizzare queste magnifiche librerie con i tuoi linguaggi di programmazione preferiti.</p>
<h4><a href="http://pmt.sourceforge.net/pngcrush/" target="_blank">PNGCrush</a></h4>
<p>PNGCrush è un tool per l&#8217;ottimizzazione di immagini PNG. Può essere eseguito dalla <strong>linea di comando di MSDOS, UNIX o LINUX</strong>. L&#8217;obiettivo principale è quello di ridurre la dimensione delle immagini PNG scegliendo vari livelli di compressione e filtri. Può essere anche utilizzato per purificare le immagini da tutte quelle informazioni aggiuntive lasciate dai vari software, o aggiungere altri tipi di blocchi.</p>
<h4><a href="http://jpegclub.org/jpegtran/" target="_blank">JPEGtran</a></h4>
<p>JPEGtran è una libreria per la trasformazioni di immagini JPEG con l&#8217;obiettivo di minimizzare la perdita informazioni e avere la maggior qualità possibile. Questa libreria comprende anche una funzione per determinare la miglior compressione per una certa immagine, in modo da evitare che si facciano numerosi test e verifiche.</p>
<p>Una <strong>guida </strong>sulle funzioni di questa libreria la puoi trovare <a href="http://www.gsp.com/cgi-bin/man.cgi?section=1&amp;topic=jpegtran" target="_blank">qui</a>.</p>
<h4><a href="http://tools.dynamicdrive.com/imageoptimizer/" target="_blank">Online Image Optimizer (GIF, JPG, and PNG)</a></h4>
<p><img class="alignright size-full wp-image-649" title="DynamicDrive Logo" src="http://jblog.it/wp-content/uploads/2009/06/logo.gif" alt="DynamicDrive Logo" width="200" height="30" />DynamicDrive ha sviluppato un ottimo tool per la compressione di immagini nei classici formati <strong>GIF, JPG e PNG</strong>. Questo è lo script originale sul quale sono nati numerosi servizi online per la compressione. Peccato che il limite sia di 300kb.</p>
<h4><a href="http://www.imageoptimizer.net/Pages/Home.aspx" target="_blank">Free Image Optimizer</a></h4>
<p><img class="alignright size-full wp-image-650" title="ImageOptimizer" src="http://jblog.it/wp-content/uploads/2009/06/banner.jpg" alt="ImageOptimizer" width="200" height="31" />Questo servizio web è un po&#8217; più evoluto rispetto a quello di <strong>DynamicDrive</strong> poiché non ti permette solo di compressare l&#8217;immagine ma anche di scegliere la dimensione di destinazione. Nel caso ti piacesse potrai scaricarne gratuitamente una versione trial.</p>
<h4><a href="http://luci.criosweb.ro/riot/" target="_blank">RIOT (Radical Image Optimization Tool)</a></h4>
<p><img class="alignright size-full wp-image-651" title="Radical Image Optimizer Tool" src="http://jblog.it/wp-content/uploads/2009/06/riot.jpg" alt="Radical Image Optimizer Tool" width="160" height="130" />RIOT è un <strong>software gratuito</strong> che ti aiuta a scegliere la miglior compressione osservandone i risultati in <strong>tempo reale</strong> grazie a un&#8217;interfaccia &#8220;dual view&#8221;. Grazie a questo software sarà facilissimo controllare la compressione, il numero di colori, le impostazioni, il formato delle immagini e molto altro. Compatibile con Windows 2000, XP e VISTA.</p>
<p>Sono disponibili anche le <strong>estensioni DLL </strong>per i più comuni linguaggi di programmazione (C, C++, Perl, PHP, Java, Phyton, ecc.).</p>
<h4><a href="http://www.softplatz.net/freeware/batch-image-compression/" target="_blank">Batch Image Compression Freeware</a></h4>
<p>Questa è un&#8217;enorme <strong>lista di software</strong> per la compressione e l&#8217;elaborazione di gruppi di immagini. Spazia dalla semplice conversione alla correzione di colore e occhi rossi. Assolutamente da vedere.</p>
</div>
<h2>Compressione di file CSS e Javascript</h2>
<p>Questa pratica (in inglese chiamata &#8220;minification&#8221;) consiste nel rimuovere dal codice tutti i caratteri non necessari in modo da ridurre la dimensione del file. Tecnicamente avviene quanto segue:</p>
<ul>
<li>vengono ristretti i nomi di variabili</li>
<li>caratteri di spaziatura come tab, a capo e spazio vengono eliminati (dove possibile)</li>
<li>vengono cancellati tutti i commenti</li>
</ul>
<p><strong>ATTENZIONE.</strong> Dopo la compressione il funzionamento degli script e i nomi delle funzioni rimangono invariati, quindi non è necessario modificare i file di template. In altre parole, i nomi delle variabili che vengono modificati sono i parametri locali delle funzioni, che non influenzano la modalità di chiamata delle funzioni.</p>
<h2>Offuscare il codice Javascript</h2>
<p><img class="alignright size-full wp-image-662" title="Offuscare javascript" src="http://jblog.it/wp-content/uploads/2009/06/2245309248_dc22bd13591.jpg" alt="Offuscare javascript" width="270" height="165" />Offuscare il codice (in inglese &#8220;obfuscate&#8221;, &#8220;obfuscation&#8221;) significa comprimerlo e trasformarlo in modo che risulti illeggibile (per i programmatori) per evitare che venga effettuato il cosiddetto reverse engineering, il procedimento attraverso cui è possibile leggere, capire ed utilizzare il codice di uno script.</p>
<p><strong>PRO:</strong> si raggiunge un ottimo livello di compressione, riducendo notevolmente la dimensione dello script.</p>
<p><strong>CONTRO:</strong> è un procedimento molto complesso attraverso cui si rischia di generare bug e malfunzionamenti; pertanto si consiglia di limitarsi esclusivamente a comprimere il codice anziché offuscarlo.</p>
<h2>Servizi web, librerie, software</h2>
<p>Ecco un po&#8217; di strumenti e servizi web per la compressione e l&#8217;offuscamento di file Javascript e CSS. Inizialmente trovi quelli riguardanti Javascript; in basso potrai vedere tutti quelli per la compressione di CSS.</p>
<h4><a href="http://yuilibrary.com/projects/yuicompressor/wiki" target="_blank">YUI Compressor</a></h4>
<p><img class="alignright size-full wp-image-652" title="YUI Library - Compressor" src="http://jblog.it/wp-content/uploads/2009/06/yuilibrary-masthead.png" alt="YUI Library - Compressor" width="180" height="46" />YUI Compressor è la più famosa libreria (open source) per la <strong>compressione di file CSS e Javascript</strong>. La compressione Javascript elimina commenti, caratteri di spaziatura e accorcia i nomi delle variabili. La compressione CSS utilizza un compressore basato su espressioni regolari.</p>
<h4><a href="http://www.crockford.com/javascript/jsmin.html" target="_blank">JSMin</a></h4>
<p>JSMin è un filtro che rimuove commenti e caratteri di spaziatura dai file <strong>Javascript</strong>. Generalmente la dimensione del file viene dimezzata. Questa libreria incoraggia i programmatori a esprimersi liberamente evitando che si preoccupino di risparmiare spazio. In fondo alla pagina puoi trovare i link per scaricare l&#8217;<strong>eseguibile MS-DOS.exe</strong> oppure i codici sorgenti in <strong>C, C#, Java, JavaScript, Perl, PHP, Python, OCAML, Ruby</strong>.</p>
<h4><a href="http://dojotoolkit.org/docs/shrinksafe" target="_blank">DojoToolkit ShrinkSafe</a></h4>
<p><img class="alignright size-full wp-image-653" title="Dojo Toolkit" src="http://jblog.it/wp-content/uploads/2009/06/images.jpg" alt="Dojo Toolkit" width="122" height="80" />Dojo, il famoso <strong>toolkit javascript</strong>, utilizza uno strumento per ridurre la dimensione, e quindi il tempo di caricamento, dei file <strong>Javascript</strong>. La particolarità sta nel fatto che invece di ricorrere alle solite espressioni regolari, Dojo Compressor è basato su <strong>Rhino</strong>, un javascript engine del progetto Mozilla. Quindi, poiché legge il flusso effettivo del codice javascript, può avere una visione migliore del contesto in cui una variabile viene letta e/o scritta, rispetto alle espressioni regolari.</p>
<h4><a href="http://dean.edwards.name/packer/" target="_blank">Packer</a></h4>
<p>Semplice servizio web per la <strong>compressione e l&#8217;offuscamento di codice Javascript</strong>. La libreria è disponibile anche per PHP e .NET. <strong>Download:</strong> <a href="http://dean.edwards.name/download/#packer" target="_blank">http://dean.edwards.name/download/#packer</a>.</p>
<h4><a href="http://web.2point1.com/2008/06/14/javascript-obfuscator-and-minifier/" target="_blank">JavaScript Obfuscator and Minifier</a></h4>
<p><strong>Librerie PHP</strong> per l&#8217;esecuzione da riga di comando. Richiedono la versione 5.2 (o superiore) di PHP CLI binary. Windows non è supportato e, a detta dello sviluppatore, non lo sarà mai.</p>
<p><strong>jsobf</strong>: compressa e offusca codice <strong>Javascript</strong>.</p>
<p><strong>jsfmt</strong>: effettua il <strong>processo inverso</strong> su un codice che ha subito compressione e offuscamento.</p>
<p><strong>Download</strong>: <a href="http://web.2point1.com/2008/09/07/jsfmt-and-jsobf-available-for-download/" target="_blank">http://web.2point1.com/2008/09/07/jsfmt-and-jsobf-available-for-download/</a>.</p>
<p><strong>Demo</strong>: <a href="http://timwhitlock.info/plug/examples/JavaScript/j_obfuscate.php" target="_blank">http://timwhitlock.info/plug/examples/JavaScript/j_obfuscate.php</a>.</p>
<h4><a href="http://farhadi.ir/works/smartoptimizer" target="_blank">SmartOptimizer</a></h4>
<p>SmartOptimizer (precedentemente chiamata JSmart) è una <strong>libreria PHP</strong> che si occupa di comprimere, offuscare, memorizzare in cache, fondere più file o stampare gli script direttamente nella pagina.</p>
<h4><a href="http://sourceforge.net/projects/packtag" target="_blank">pack:tag</a></h4>
<p><strong>Libreria JSP</strong> che compressa e combina risorse (come <strong>Javascript e CSS</strong>) e li memorizza nella cache del browser o in un file generato dinamicamente. Questo script si può inserire facilmente all&#8217;interno delle pagine e lavora in maniera trasparente sia all&#8217;utente sia allo sviluppatore.</p>
<h4><a href="http://tools.2vi.nl/" target="_blank">ObfuscateJS</a></h4>
<p><strong>Progetto Java</strong><strong> </strong>per la compressione e l&#8217;offuscamento di codice javascript. Si occupa di rimuovere caratteri di spaziatura e commenti, e di accorciare i nomi delle variabili locali.</p>
<h4><a href="http://jscompress.com/" target="_blank">JsCompress</a></h4>
<p>Servizio web per la compressione di <strong>codice javascript</strong>. Si può scegliere di eseguire la compressione con JsMin o con Packer. Molto interessante.</p>
<h4><a href="http://www.digitaloverload.co.uk/jsmin/" target="_blank">Javascript Minifier</a></h4>
<p>Servizio web (basato su JsMin) per la <strong>compressione di codice javascript</strong>. Puoi decidere se effettuare direttamente il download oppure visualizzare il risultato in una textarea.</p>
<h4><a href="http://www.javascriptobfuscator.com/" target="_blank">Free Javascript Obfuscator</a></h4>
<p>Servizio web che si occupa di <strong>comprimere e offuscare codice javascript</strong>. Offrendo diverse opzioni ti lascia libero di decidere completamente l&#8217;aspetto finale del codice.</p>
<h4><a href="http://www.daftlogic.com/projects-online-javascript-obfuscator.htm" target="_blank">Online Javascript Obfuscator</a></h4>
<p>Servizio web per la compressione e l&#8217;offuscamento di codice javascript.</p>
<h4><img class="alignright size-full wp-image-656" title="File CSS" src="http://jblog.it/wp-content/uploads/2009/06/page.png" alt="File CSS" width="128" height="128" /> <a href="http://www.ibloomstudios.com/articles/php_css_compressor" target="_blank">PHP CSS Compressor</a></h4>
<p>In questo articolo vengono fornite alcune <strong>righe di codice PHP</strong> da inserire direttamente nei <strong>file CSS</strong>. Questo codice provvede automaticamente alla compressione del contenuto del file CSS. In fondo all&#8217;articolo vengono descritte le modifiche da apportare al file .htaccess in modo che il file .css venga elaborato come file .php.</p>
<h4><a href="http://shygypsy.com/cssCompress/" target="_blank">CSS Compressor</a></h4>
<p>Servizio web per la <strong>compressione di codice CSS</strong>. L&#8217;applicazione è un&#8217;applet Java.</p>
<h4><a href="http://dotnetperls.com/Content/Minify-CSS.aspx" target="_blank">CSS Tidy</a></h4>
<p>Software, eseguibile da riga di comando, per la <strong>compressione di file CSS</strong>. La pagina del progetto è completa di tutta la documentazione necessaria per iniziare a utilizzarlo.</p>
<h2>Conclusione</h2>
<p><img class="alignright size-full wp-image-658" title="Analizza il tuo sito web" src="http://jblog.it/wp-content/uploads/2009/06/2349098787_2cd660c18c.jpg" alt="Analizza il tuo sito web" width="250" height="188" /><span class="highlight_green">Imparare a utilizzarli tutti è impossibile. Quindi, prima perder tempo tra download e righe di codice ti consiglio di <strong>analizzare il tuo sito</strong> per individuare i componenti che ne influenzano maggiormente le prestazioni.</span></p>
<p>Ad esempio, se il tuo sito è una <strong>galleria di immagini</strong> gestita con un paio di file javascript la cosa migliore da fare è scegliere il miglior tool per ottimizzare le foto, considerando anche il loro formato. Se, invece, hai un <strong>sito dinamico</strong> che fa un largo uso di javascript e tecniche Ajax, comprimere (e offuscare) il codice dei tuoi file javascript sarà fondamentale per migliorare il caricamento e la reattività del tuo sito web.</p>
<h4>Crediti</h4>
<ul>
<li><a title="Yahoo! Developer Network" href="http://developer.yahoo.com/" target="_blank">Yahoo! Developer Network</a> &#8211; <a title="Best Practices for Speeding Up Your Web Site" href="http://developer.yahoo.com/performance/rules.html" target="_blank">Best Practices for Speeding Up Your Web Site</a></li>
<li><strong>Foto1</strong>: forty-nine: <a title="forty-nine: compressed work week" href="http://www.flickr.com/photos/deadsquid/2614952166/" target="_blank">compressed work week</a> di <a href="http://www.flickr.com/photos/deadsquid/" target="_blank">dead_squid</a></li>
<li><strong>Foto2</strong>: <a title="fog over Istanbul skyscrapers" href="http://www.flickr.com/photos/whatcouldgowrong/2245309248/" target="_blank">fog over Istanbul skyscrapers</a> di <a href="http://www.flickr.com/photos/whatcouldgowrong/" target="_blank">WhatCouldPossiblyGoWrong?</a></li>
<li><strong>Foto3</strong>: <a title="MAGNIFYING GLASS" href="http://www.flickr.com/photos/andercismo/2349098787/" target="_blank">MAGNIFYING GLASS</a> di <a rel="dc:creator cc:attributionURL" href="http://www.flickr.com/photos/andercismo/" target="_blank">andercismo</a></li>
</ul>
<img src="http://jblog.it/?ak_action=api_record_view&id=640&type=feed" alt=" 20 servizi web e librerie per ottimizzare i componenti della pagina: immagini, javascript, css"  title="20 servizi web e librerie per ottimizzare i componenti della pagina: immagini, javascript, css" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/10/ottimizzare-componenti-pagina-velocizzare-caricamento-immagini-css-script_640.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Il Risiko dei social network</title>
		<link>http://jblog.it/2009/06/08/il-risiko-dei-social-network-studio-diffusione-utilizzo-social-network-nel-mondo_627.html</link>
		<comments>http://jblog.it/2009/06/08/il-risiko-dei-social-network-studio-diffusione-utilizzo-social-network-nel-mondo_627.html#comments</comments>
		<pubDate>Mon, 08 Jun 2009 12:08:28 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Internet news]]></category>
		<category><![CDATA[Social network]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[alexa]]></category>
		<category><![CDATA[bebo]]></category>
		<category><![CDATA[google trends]]></category>
		<category><![CDATA[myspace]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=627</guid>
		<description><![CDATA[Vincenzo Cosenza, sul suo blog, ha pubblicato uno studio sulla diffusione e l'utilizzo dei social network nel mondo, basandosi sui dati forniti da Google Trends e Alexa. Oltre alla mappa puoi trovare una piccola tabella in cui vengono classificati i 3 social network maggiormente utilizzati in corrispondenza di alcuni paesi.]]></description>
			<content:encoded><![CDATA[<p><strong>Vincenzo Cosenza</strong>, sul suo <a title="Vincos" href="http://www.vincos.it/" target="_blank">blog</a>, ha pubblicato uno studio sulla diffusione e l&#8217;utilizzo dei <strong>social network nel mondo</strong>, basandosi sui dati forniti da <strong>Google Trends e Alexa</strong>. Oltre alla mappa puoi trovare una piccola tabella in cui vengono classificati i 3 social network maggiormente utilizzati in corrispondenza di alcuni paesi.</p>
<p><a href="http://jblog.it/2009/06/08/il-risiko-dei-social-network-studio-diffusione-utilizzo-social-network-nel-mondo_627.html"><img class="aligncenter size-full wp-image-629" title="World map of social network - Diffusione e utilizzo dei social netwoek nel mondo" src="http://jblog.it/wp-content/uploads/2009/10/wmsn-06-09.jpg" alt="World map of social network - Diffusione e utilizzo dei social netwoek nel mondo" width="540" height="260" /></a><span id="more-627"></span>In breve questo studio dimostra che:</p>
<ul>
<li><strong>Facebook </strong>sia il leader incontrastato in Europa con oltre 200 milioni di utenti</li>
<li><strong>QZone </strong>è in assoluto il più utilizzato con circa 300 milioni di utenti, anche perché è il leader in Cina&#8230;</li>
<li><strong>MySpace </strong>è, in generale, in netto calo in tutti i paesi</li>
</ul>
<p>Non vorrei ripetere ciò che hanno detto altri, quindi ti segnalo un po&#8217; di<strong> link per approfondire</strong>.<br />
<!--adv300--></p>
<p><strong>Articolo originale:</strong> <a title="World Map of Social Networks" rel="bookmark" href="http://www.vincos.it/world-map-of-social-networks/">Vincos Blog » World Map of Social Networks</a></p>
<p><strong>Approfondimento facebook: </strong><a title="Permanent Link to &quot;Osservatorio Facebook&quot;" rel="bookmark" href="http://www.vincos.it/osservatorio-facebook/">Vincos Blog » Osservatorio Facebook</a></p>
<h4>Italiani</h4>
<ul>
<li><a title="La mappa dei social network nel mondo (giugno 2009)" rel="bookmark" href="http://businessandblog.com/index.php/2009/06/08/la-mappa-dei-social-network-nel-mondo-giugno-2009/">BusinessAndBlog » La mappa dei social network nel mondo (giugno 2009)</a></li>
<li><a title="La mappa di penetrazione dei Social Network nel mondo" rel="bookmark" href="http://www.zeropuntodue.it/2009/06/la-mappa-di-penetrazione-dei-social-network-nel-mondo.html">ZeroPuntoDue » La mappa di penetrazione dei Social Network nel mondo</a></li>
</ul>
<h4>Inglesi</h4>
<ul>
<li><a title="A Map Of Social (Network) Dominance" rel="bookmark" href="http://www.techcrunch.com/2009/06/07/a-map-of-social-network-dominance/">TechCrunch » A Map Of Social (Network) Dominance</a></li>
<li><a title="Social Networks Around the World" href="http://www.readwriteweb.com/archives/post_2.php" target="_blank">ReadWriteWeb » Social Networks Around the World</a></li>
</ul>
<img src="http://jblog.it/?ak_action=api_record_view&id=627&type=feed" alt=" Il Risiko dei social network"  title="Il Risiko dei social network" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/08/il-risiko-dei-social-network-studio-diffusione-utilizzo-social-network-nel-mondo_627.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Novità su Twitter: account verificati a partire da questa estate</title>
		<link>http://jblog.it/2009/06/08/novita-twitter-account-verificati_617.html</link>
		<comments>http://jblog.it/2009/06/08/novita-twitter-account-verificati_617.html#comments</comments>
		<pubDate>Sun, 07 Jun 2009 23:07:35 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Internet news]]></category>
		<category><![CDATA[Social network]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[biz stone]]></category>
		<category><![CDATA[falsi account]]></category>
		<category><![CDATA[followers]]></category>
		<category><![CDATA[microblogging]]></category>
		<category><![CDATA[social networking]]></category>
		<category><![CDATA[tweet]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=617</guid>
		<description><![CDATA[Biz Stone, co-fondatore di Twitter annuncia l'introduzione degli account verificati, uno strumento di controllo degli account di persone pubbliche e famose. Gli account verificati saranno contrassegnati da una particolare etichetta.]]></description>
			<content:encoded><![CDATA[<p><a href="http://jblog.it/2009/06/08/novita-twitter-account-verificati_617.html"><img class="alignright size-full wp-image-622" title="Twitter Verified Account - Account verificati su Twitter" src="http://jblog.it/wp-content/uploads/2009/06/veriffied.jpg" alt="Twitter Verified Account - Account verificati su Twitter" width="270" height="169" /></a>Quante volte ti sarà capitato di seguire degli account che hai poi scoperto essere falsi? Purtroppo di falsi account ce ne sono tanti. Purtroppo è facile cascarci finendo per credere ai tweet lasciati da quella persona&#8230;</p>
<p>Il 5 Giugno <strong>Tony La Russa, il manager dei St. Louis Cardinals</strong> (squadra di baseball), ha portato <strong>Twitter in tribunale</strong> a causa della presenza del suo falso account, in particolare di alcuni tweet in cui si rivangavano episodi spiacevoli della vita del manager.</p>
<p>In occasione di questo episodio <strong>Biz Stone</strong> (il co-fondatore di Twitter), nel blog ufficiale, ha detto la sua riguardo la querela avanzata da Tony La Russa ed ha fornito alcuni dettagli sui piani futuri che adotterà Twitter per combattere la creazione di falsi account.</p>
<p>Stone ha ribadito che la società cancella, sospende o trasferisce il controllo (ai legittimi proprietari) di account creati da persone diverse da quello che dicono di essere, aggiungendo che queste misure sono state adottate anche nel caso del manager La Russa.<span id="more-617"></span><!--adv300--></p>
<h4>Verified account</h4>
<p><a href="http://jblog.it/2009/06/08/novita-twitter-account-verificati_617.html"><img class="alignright size-full wp-image-623" title="Scoprire se un account di Twitter è vero" src="http://jblog.it/wp-content/uploads/2009/06/newsom.jpg" alt="Scoprire se un account di Twitter è vero" width="270" height="201" /></a>Stone ha annunciato che l&#8217;azienda ritiene comunque opportuno migliorare ulteriormente il servizio, e da <strong>questa estate</strong> gli account di Twitter potranno essere contrassegnati dall&#8217;<strong>etichetta &#8220;account verificato&#8221;</strong>. Questa caratteristica indicherà che le persone dietro un account sono effettivamente quelle che dicono di essere.</p>
<p>Per ora non si è capito bene come si procederà tecnicamente. Tuttavia, sul blog viene detto che un modo consiste nel verificare se nel sito della persona relativa all&#8217;account è presente il link verso lo stesso account su Twitter.</p>
<p>La <strong>sperimentazione </strong>inizierà con la verifica degli account di politici, atleti, artisti famosi, e altri personaggi pubblici. L&#8217;azienda spera di poter verificare molti più account in futuro, ma sarà necessario iniziare da un <strong>ristretto numero di account</strong> a causa delle notevoli risorse richieste.</p>
<p><span class="highlight_green">Che ne pensi? Credi che sia fatica sprecata o che migliorerà notevolmente la vita su Twitter?</span></p>
<p><strong>FONTI</strong></p>
<ul>
<li><a title="Not Playing Ball " href="http://blog.twitter.com/2009/06/not-playing-ball.html" target="_blank">http://blog.twitter.com/2009/06/not-playing-ball.html</a></li>
<li><a title="Twitter to roll out 'Verified Accounts' this summer" href="http://news.cnet.com/8301-1023_3-10258816-93.html" target="_blank">http://news.cnet.com/8301-1023_3-10258816-93.html</a></li>
</ul>
<img src="http://jblog.it/?ak_action=api_record_view&id=617&type=feed" alt=" Novità su Twitter: account verificati a partire da questa estate"  title="Novità su Twitter: account verificati a partire da questa estate" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/08/novita-twitter-account-verificati_617.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Digg annuncia un nuovo modello di business con i Digg Ads</title>
		<link>http://jblog.it/2009/06/07/digg-annuncia-nuovo-modello-business-digg-ads_604.html</link>
		<comments>http://jblog.it/2009/06/07/digg-annuncia-nuovo-modello-business-digg-ads_604.html#comments</comments>
		<pubDate>Sat, 06 Jun 2009 22:43:10 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Internet news]]></category>
		<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Social network]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[digg]]></category>
		<category><![CDATA[social bookmarking]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=604</guid>
		<description><![CDATA[Digg, nel suo blog ufficiale, ha annunciato l'introduzione dii una nuova piattaforma di advertising (interno a Digg.com) chiamata Digg Ads tanto semplice quanto originale. Gli annunci dovrebbero integrarsi con il contesto, un po' come Google Adsense.]]></description>
			<content:encoded><![CDATA[<p><a title="Digg Ads - Esempio annunci sponsorizzati" href="http://jblog.it/wp-content/uploads/2009/06/digg-ad-example-large.jpg" target="_blank"><img class="alignright size-full wp-image-606" title="Digg Ads - Esempio annunci sponsorizzati" src="http://jblog.it/wp-content/uploads/2009/06/digg-ad-example-small.jpg" alt="Digg Ads - Esempio annunci sponsorizzati" width="270" height="200" /></a>Digg, nel suo <a title="Ads You Can Digg…or Bury" href="http://blog.digg.com/?p=808" target="_blank"><strong>blog ufficiale</strong></a>, ha annunciato l&#8217;introduzione dii una nuova piattaforma di advertising (interno a Digg.com) chiamata <strong>Digg Ads</strong>, tanto semplice quanto originale. Vediamo subito perché.</p>
<p><strong>L&#8217;aspetto degli annunci</strong> sarà praticamente identico alle migliaia di post che vengono pubblicati ogni ora, ma verranno contraddistinti da una piccola linea verde che indicherà il fatto di essere sponsorizzati. Proprio come i normali post, gli annunci sponsorizzati potranno contenere e linkare notizie, immagini, video riguardanti un&#8217;azienda e i suoi prodotti, ed essere aggiunti all&#8217;interno dei bookmarks degli utenti. Un <strong>esempio </strong>su come potrebbero apparire gli annunci lo puoi vedere cliccando sull&#8217;immagine in alto oppure <a title="Digg Ads - Esempio annunci sponsorizzati" href="http://jblog.it/wp-content/uploads/2009/06/digg-ad-example-large.jpg" target="_blank">qui</a>.<!--adv300--></p>
<p><strong>Il successo di un annuncio</strong> (o il fallimento) sarà determinato dagli utenti semplicemennte esprimendo il loro interessamento, con gli strumenti messsi a disposizione da Digg. In pratica, quanti più utenti aggiungeranno ai loro bookmarks un annuncio, tanto meno l&#8217;insersionista dovrà pagare. Viceversa, se l&#8217;annuncio verrà sepolto fra i post il prezzo da pagare aumenterà notevolmente. Per questo motivo gli inserzionisti avranno un motivo in più a pubblicare <strong>post sponsorizzati di qualità</strong> in modo che interessino il più possibile agli utenti di Digg. Con questo meccanismo, quando un utente leggerà un annuncio sponsorizzato non risponderà con un semplice &#8220;non mi interessa, è solo  pubblicità&#8221; ma &#8220;<em>questo post </em>non mi interessa&#8221;.</p>
<p><strong>Il principale obiettivo</strong> che si propone lo staff è quello di fornire agli inserzionisti una maggiore probabilità che il loro annuncio interessi realmente gli utenti, facendolo apparire all&#8217;interno di post simili. Inoltre gli utenti del celebre social bookmarker avranno un ruolo fondamentale nel giudicare la rilevanza di un annuncio, e di conseguenza il successo di una campagna pubblicitaria.</p>
<p>Lo staff ha avvertito che il servizio sarà continuamente &#8220;sotto i ferri&#8221; e verrà migliorato anche grazie ai feedback degli utenti.</p>
<p><strong>Progetto molto originale</strong>&#8230; Staremo a vedere! <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' title="Digg annuncia un nuovo modello di business con i Digg Ads" /> </p>
<p><strong>FONTE: </strong><a title="Ads You Can Digg…or Bury" href="http://blog.digg.com/?p=808" target="_blank">http://blog.digg.com/?p=808</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=604&type=feed" alt=" Digg annuncia un nuovo modello di business con i Digg Ads"  title="Digg annuncia un nuovo modello di business con i Digg Ads" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/07/digg-annuncia-nuovo-modello-business-digg-ads_604.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Facebook: 10 applicazioni che potrebbero insegnarti qualcosa</title>
		<link>http://jblog.it/2009/06/06/10-applicazioni-di-facebook-insegnan-qualcosa-facebook-apps_582.html</link>
		<comments>http://jblog.it/2009/06/06/10-applicazioni-di-facebook-insegnan-qualcosa-facebook-apps_582.html#comments</comments>
		<pubDate>Fri, 05 Jun 2009 22:57:13 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Social network]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[facebook app]]></category>
		<category><![CDATA[libri]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=582</guid>
		<description><![CDATA[Nell&#8217;articolo 10 Facebook apps that teach you something pubblicato su news.cnet.com vengono segnalate un po&#8217; di applicazioni di Facebook che potrebbero essere utili utenti di Facebook, ancora di più se studenti o professori.
Grazie a queste applicazioni Facebook può rendersi utile a migliorare la cultura dei suoi utenti, come succede spesso in Twitter.
Ecco le applicazioni più [...]]]></description>
			<content:encoded><![CDATA[<p>Nell&#8217;articolo <a title="10 Facebook apps that teach you something" href="http://news.cnet.com/8301-17939_109-10256991-2.html?part=rss&amp;subj=news&amp;tag=2547-1_3-0-20" target="_blank">10 Facebook apps that teach you something</a> pubblicato su <a title="CNet News" href="http://news.cnet.com" target="_blank">news.cnet.com</a> vengono segnalate un po&#8217; di applicazioni di Facebook che potrebbero essere utili utenti di Facebook, ancora di più se<strong> studenti o professori</strong>.</p>
<p>Grazie a queste applicazioni Facebook può rendersi utile a <strong>migliorare la cultura</strong> dei suoi utenti, come succede spesso in Twitter.</p>
<p>Ecco le applicazioni più interessanti, secondo me.</p>
<h3><a title="Facebook app: Books" href="http://www.facebook.com/apps/application.php?id=2392094817&amp;ref=appd" target="_blank">Books</a></h3>
<p>Books ti permette di condividere i tuoi<strong> libri preferiti</strong> con i tuoi amici, scoprire altri libri che potrebbero interessarti, vedere i libri preferiti dai tuoi amici, acquistare libri su Amazon.com.</p>
<p><img class="size-full wp-image-587" title="Facebook apps: Books" src="http://jblog.it/wp-content/uploads/2009/10/facebook_10_apps_max.jpg" alt="Facebook apps: Books" width="570" height="285" /><span id="more-582"></span></p>
<h3><a title="Facebook app: CourseFeed" href="http://www.facebook.com/apps/application.php?id=5243732877&amp;ref=appd#/apps/application.php?id=5243732877&amp;v=info&amp;viewas=1194754027" target="_blank">CourseFeed</a></h3>
<p><!--adv300--></p>
<p>Grazie a questa applicazione è possibile trovare scuole superiori e compagni di college, e collegarti con loro attraverso questo servizio. Il punto forte è l&#8217;<strong>apprendimento</strong>, poiché è possibile collegarsi con i professori delle maggiori università e accedere agli appunti ed ai quiz che mettono a disposizione degli studenti. Attualmente ci sono <strong>tantissimi professori e studenti</strong>.</p>
<p><img class="alignnone size-full wp-image-589" title="Facebook app: CourseFeed" src="http://jblog.it/wp-content/uploads/2009/06/2.jpg" alt="Facebook app: CourseFeed" width="620" height="240" /></p>
<h3><a title="Facebook app: MyPersonality" href="http://www.facebook.com/apps/application.php?id=2318966938&amp;ref=appd#/apps/application.php?id=2490151219&amp;v=info&amp;viewas=1194754027" target="_blank">MyPersonality</a></h3>
<p>Con questa applicazione potrai <strong>conoscere meglio la tua personalità</strong>. In pratica dovrai rispondere onestamente a tante semplici domande e alla fine verrà descritta la tua personalità. Ad esempio, ti verrà detto quanto sei affidabile, quanto sei sicuro/a di te, ecc.</p>
<p><img class="alignnone size-full wp-image-590" title="Facebook app: MyPersonality" src="http://jblog.it/wp-content/uploads/2009/06/3.jpg" alt="Facebook app: MyPersonality" width="570" height="241" /></p>
<h3><a title="Facebook app: Teach the People" href="http://www.facebook.com/apps/application.php?id=3416245603&amp;ref=appd" target="_blank">Teach the People</a></h3>
<p>Teach the People è una<strong> community di insegnanti </strong>attraverso la quale condividono la loro conoscenza con altri utenti Facebook. Ci sono diversi argomenti a cui ci si può iscrivere per ricevere materiale didattico e aggiornamenti. Vengono condivisi documenti, immagini, video, audio, ecc. che è possibile commentare nella rispettiva bacheca.</p>
<p><img class="alignnone size-full wp-image-591" title="Facebook app: Teach the People" src="http://jblog.it/wp-content/uploads/2009/06/4.jpg" alt="Facebook app: Teach the People" width="570" height="261" /></p>
<h3><a title="Facebook app: Typing Speed" href="http://www.facebook.com/apps/application.php?id=20649406600&amp;ref=appd" target="_blank">Typing Speed</a></h3>
<p>Semplice tool con cui è possibile vedere <strong>quanto sei veloce a scrivere con la tastiera</strong>. Misura anche l&#8217;accuratezza delle parole scritte e il rapporto velocità/accuratezza. La tua velocità a precisione aumenterà quanto più farai pratica con questo fantastico tool.</p>
<p><img class="alignnone size-full wp-image-592" title="Facebook app: Typing Speed" src="http://jblog.it/wp-content/uploads/2009/06/5.jpg" alt="Facebook app: Typing Speed" width="570" height="177" /></p>
<h3><a title="Facebook app: WeRead" href="http://www.facebook.com/apps/application.php?id=2406120893&amp;ref=appd" target="_blank">WeRead</a></h3>
<p>Leggere libri è importante ma molta gente non legge abbastanza. Questa applicazione cerca di spingerti a leggere di più selezionando automaticamente i <strong>libri che potrebbero interessarti</strong>. Come? Quando la aggiungi al tuo profilo ti mostra un elenco di libri e ti chiede di sceglierne alcuni. Basandosi sulle scelte fatte selezionerà alcuni libri che molto probabilmente ti interesseranno.</p>
<p><img class="alignnone size-full wp-image-593" title="Facebook app: WeRead" src="http://jblog.it/wp-content/uploads/2009/06/6.jpg" alt="Facebook app: WeRead" width="570" height="265" /></p>
<h2>Crediti</h2>
<ul>
<li> <a title="CNet News" href="http://news.cnet.com" target="_blank">News.Cnet.com</a> &#8211; <a title="10 Facebook apps that teach you something" href="http://news.cnet.com/8301-17939_109-10256991-2.html?part=rss&amp;subj=news&amp;tag=2547-1_3-0-20" target="_blank">10 Facebook apps that teach you something</a></li>
<li>Foto1, foto2, foto3, foto4, foto5, foto6: <a href="http://news.cnet.com/8301-17939_109-10256991-2.html?part=rss&amp;subj=news&amp;tag=2547-1_3-0-20" target="_blank">Don Reisinger/CNET</a></li>
</ul>
<h2>Conosci altre applicazioni?</h2>
<p>Se conosci altre applicazioni o hai scritto un articolo su questo argomento puoi segnalarmelo. Scriverò un articolo o integrerò questo con le applicazioni segnalate da te. In particolare, conosci <strong>applicazioni &#8220;italiane&#8221;</strong>?</p>
<img src="http://jblog.it/?ak_action=api_record_view&id=582&type=feed" alt=" Facebook: 10 applicazioni che potrebbero insegnarti qualcosa"  title="Facebook: 10 applicazioni che potrebbero insegnarti qualcosa" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/06/10-applicazioni-di-facebook-insegnan-qualcosa-facebook-apps_582.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Wordpress: ordinare gli articoli in modo casuale</title>
		<link>http://jblog.it/2009/06/04/wordpress-query-ordinare-post-articoli-modo-casuale-random_573.html</link>
		<comments>http://jblog.it/2009/06/04/wordpress-query-ordinare-post-articoli-modo-casuale-random_573.html#comments</comments>
		<pubDate>Thu, 04 Jun 2009 21:11:25 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Php e MySql]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[classe php]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[wordpress trick]]></category>
		<category><![CDATA[wp_query]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=573</guid>
		<description><![CDATA[Un lettore del blog mi ha contattato per chiedermi di aiutarlo a impostare Wordpress.
In particolare, ha bisogno di ordinare i post in modo casuale nell&#8217;archivio di categoria.
Dopo aver spulciato le librerie di Wordpress e aver eseguito un po&#8217; di prove ho sfornato questa funzione che sembra funzionare a dovere.
La classe WP_Query

In Wordpress le query (interrogazioni) [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jblog.it/2009/06/04/wordpress-query-ordinare-post-articoli-modo-casuale-random_573.html"><img class="alignright size-full wp-image-574" title="Logo Wordpress" src="http://jblog.it/wp-content/uploads/2009/10/wordpress-logo.jpg" alt="Logo Wordpress" width="220" height="220" /></a>Un lettore del blog mi ha contattato per chiedermi di aiutarlo a impostare Wordpress.</p>
<p>In particolare, ha bisogno di ordinare i post in modo casuale nell&#8217;archivio di categoria.</p>
<p>Dopo aver spulciato le librerie di Wordpress e aver eseguito un po&#8217; di prove ho sfornato questa funzione che sembra funzionare a dovere.</p>
<h2>La classe WP_Query</h2>
<p><!--adv300--></p>
<p>In Wordpress le query (interrogazioni) al database vengono gestite con la classe WP_Query che si trova in <strong>wp-includes/query.php</strong>.</p>
<p>Ecco le proprietà e i metodi della classe WP_Query che utilizziamo:</p>
<ul>
<li>con il metodo <code>set($query_var, $value)</code> impostiamo le caratteristiche della query</li>
<li>il metodo <code>get($query_var)</code> restituisce il valore di una variabile</li>
<li>per eseguire la query utilizziamo la funzione <code>get_posts()</code></li>
</ul>
<p>Tuttavia, questi tre metodi non bastano a modificare l&#8217;elenco dei post che verranno visualizzati.</p>
<p>Questo elenco è memorizzato all&#8217;interno della proprietà <code>posts</code> (di tipo array) che verrà sovrascritta con l&#8217;array restituito dal metodo get_posts(), nell&#8217;ultima riga.</p>
<p><strong>Per saperne di più</strong> sulla classe WP_Query vai su <a title="Wordpress - Function Reference: WP Query" href="http://codex.wordpress.org/Function_Reference/WP_Query" target="_blank">http://codex.wordpress.org/Function_Reference/WP_Query</a>.<span id="more-573"></span></p>
<h2>Il codice</h2>
<pre lang="php">function jblog_orderbyRand()
{
	global $wp_query;

	// Imposta il tipo di ordinamento
	$wp_query-&gt;set('orderby', 'rand');

	// Disabilita la paginazione dei post
	$wp_query-&gt;set('nopaging', true);
	$wp_query-&gt;set('posts_per_page', -1);

	// Reimposta l'array dei post da stampare
	$wp_query-&gt;posts = $wp_query-&gt;get_posts();
}</pre>
<h2>Come utilizzare la funzione</h2>
<p>Innanzitutto copiamo il codice precedente nel file <strong>functions.php</strong> (all&#8217;interno della directory del template). Se il file non esiste basterà crearlo.</p>
<p>Anche se la necessità originale era quella di modificare l&#8217;elenco dell&#8217;archivio di categoria, questa funzione è efficace in ogni pagina del blog che contenga un elenco di post, quindi nell&#8217;homepage, nell&#8217;archivio di tag, ecc.</p>
<p>Per utilizzarla basterà inserirla in testa alla pagina da modificare. Ad esempio, se vogliamo che tutti gli archivi vengano ordinati in modo casuale, dobbiamo aprire il file <strong>archive.php</strong> del template e inserirla in testa:</p>
<pre lang="php">&lt;? // Ordinamento casuale
   jblog_orderbyRand(); 	?&gt;

&lt;? get_header(); ?&gt;
	&lt;div id="content" class="narrowcolumn"&gt;
		&lt;?php if (have_posts()) : ?&gt;
			. . .</pre>
<p>Se, come nel caso del lettore, si deve ordinare in modo casuale solo l&#8217;archivio di categoria scriveremo la funzione all&#8217;interno di un costrutto if in cui si controlla che l&#8217;archivio sia relativo a una categoria.</p>
<p>Questo controllo si esegue ottenendo l&#8217;id della categoria grazie alla funzione <code>get_query_var('cat')</code> che restituisce il valore di una variabile per la query. Nota che quella funzione è equivalente all&#8217;istruzione <code>$wp_query-&gt;get('cat')</code>. Entrambe restituiscono l&#8217;<strong>id (di tipo intero) della categoria</strong>. Questo sarà maggiore di zero se l&#8217;archivio che si sta visualizzando è di categoria.</p>
<pre lang="php">&lt;? // Ordinamento casuale (se id categoria è positivo)
   if(get_query_var('cat')&gt;0)
   jblog_orderbyRand(); 	?&gt;

&lt;? get_header(); ?&gt;
	&lt;div id="content" class="narrowcolumn"&gt;
		&lt;?php if (have_posts()) : ?&gt;
		. . .</pre>
<h2>Svantaggio: non è possibile dividere i post per pagine</h2>
<p>Ogni volta che si carica la pagina viene rigenerato l&#8217;elenco e, dato che viene ordinato in modo casuale, i post non vengono adeguatamente distribuiti nelle varie pagine. In pratica è concreto il <strong>rischio </strong>che dei post apparsi nella pagina 1 possano apparire nuovamente in altre pagine. Per questo motivo viene disabilitata la paginazione.</p>
<p>Inoltre, è necessario applicare un <strong>ultima modifica</strong> al tema della pagina che ospiterà l&#8217;elenco da ordinare in modo casuale. Cioé, è necessario evitare che appaiano <strong>i link &#8220;post precedenti&#8221; e &#8220;post successivi&#8221;</strong>. Nei casi più semplici basterà eliminare il codice relativo a questi link. Se invece l&#8217;ordinamento casuale è condizionato (come nel codice precedente) bisognerà applicare le condizioni (contrarie rispetto a quelle relative alla funzione) alla visualizzazione di questi link:</p>
<pre lang="html">&lt;? // Per la funzione la condizione era get_query_var('cat')&gt;0 (con il "&gt;" anziché "&lt;=")
if(get_query_var('cat')&lt;=0) : ?&gt;
	&lt;div class="navigation"&gt;
		&lt;div class="alignleft"&gt;&lt;?php next_posts_link(__('&amp;laquo; Older Entries', 'kubrick')); ?&gt;&lt;/div&gt;
		&lt;div class="alignright"&gt;&lt;?php previous_posts_link(__('Newer Entries &amp;raquo;', 'kubrick')); ?&gt;&lt;/div&gt;
	&lt;/div&gt;
&lt;? endif; ?&gt;</pre>
<h2>Serve aiuto?</h2>
<p>Come vedi quello che ho scritto nella pagina &#8220;Informazioni&#8221; riguardo l&#8217;aiuto ai lettori non sono solo un mucchio di frasi fatte per riempire una pagina. Quindi <strong>se hai bisogno di aiuto o, più semplicemente, di un consiglio ricordati di passare da qui</strong>. Finché ne avrò il tempo sarò felice di aiutarti! <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' title="Wordpress: ordinare gli articoli in modo casuale" /> </p>
<img src="http://jblog.it/?ak_action=api_record_view&id=573&type=feed" alt=" Wordpress: ordinare gli articoli in modo casuale"  title="Wordpress: ordinare gli articoli in modo casuale" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/04/wordpress-query-ordinare-post-articoli-modo-casuale-random_573.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Ridurre le richieste HTTP con Mime HTML e data:URL</title>
		<link>http://jblog.it/2009/06/01/ridurre-richieste-http-mime-html-data-url-mhtml_537.html</link>
		<comments>http://jblog.it/2009/06/01/ridurre-richieste-http-mime-html-data-url-mhtml_537.html#comments</comments>
		<pubDate>Mon, 01 Jun 2009 03:41:32 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Css]]></category>
		<category><![CDATA[Ottimizzazione]]></category>
		<category><![CDATA[Web design]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[classe php]]></category>
		<category><![CDATA[classi librerie]]></category>
		<category><![CDATA[data:URL]]></category>
		<category><![CDATA[mhtml]]></category>
		<category><![CDATA[mime]]></category>
		<category><![CDATA[multipart]]></category>
		<category><![CDATA[ottimizzare]]></category>
		<category><![CDATA[richieste http]]></category>
		<category><![CDATA[sprite css]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=537</guid>
		<description><![CDATA[
Il Mime HTML e lo schema data:URL sono due importanti ingredienti nella ricetta che ti permetterà di ridurre le richieste HTTP.

Una pagina Mime HTML è un tipo di pagina web in cui è possibile scriverci sia il codice html sia dei dati come immagini, oggetti flash, file audio
Lo schema data:URL è una tecnica grazie alla [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jblog.it/2009/06/01/ridurre-richieste-http-mime-html-data-url-mhtml_537.html"><img class="alignright size-full wp-image-559" title="MHTML Shake" src="http://jblog.it/wp-content/uploads/2009/06/senza-nome-33.jpg" alt="MHTML Shake" width="230" height="371" /></a></p>
<p>Il Mime HTML e lo schema data:URL sono due importanti ingredienti nella ricetta che ti permetterà di ridurre le richieste HTTP.</p>
<ul>
<li>Una pagina <strong>Mime HTML</strong> è un tipo di pagina web in cui è possibile scriverci sia il codice html sia dei dati come immagini, oggetti flash, file audio</li>
<li>Lo schema <strong>data:URL</strong> è una tecnica grazie alla quale è possibile inserire i dati nella pagina web (che abbiamo già visto nell&#8217;articolo <a title="Link permanente al post Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css" rel="bookmark" href="http://jblog.it/2009/05/15/ridurre-richieste-http-parte-2-come-combinare-immagini-script-css-sprite-image-maps_405.html">Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css</a> e che riprenderò per evitarti di fare su e giù per il blog)</li>
</ul>
<p>Non utilizzeremo queste due tecniche separatamente ma ci serviranno per creare il <strong>mix esplosivo</strong> <img src='http://jblog.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' title="Ridurre le richieste HTTP con Mime HTML e data:URL" />  per caricare quanti più dati possibile in una sola richiesta http: quella della pagina web.</p>
<h2>Lo schema data:URL</h2>
<p><!--adv300--></p>
<p>Per capire bene il Mime HTML è necessario sapere come codificare i file in base64 e come utilizzarli all&#8217;interno della pagina per poi vedere l&#8217;intera struttura di un documento MHTML.</p>
<p>Il vantaggio fondamentale di questa tecnica consiste nel risparmio di tante richieste http quanti sono gli oggetti e le immagini codificati in base64 che inseriamo nella pagina.<span id="more-537"></span></p>
<p>Vediamo subito un <strong>esempio</strong>.</p>
<pre lang="html">&lt;IMG ALT="Foto" SRC="data:image/gif; base64,
	R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwhhx4dbgYKAAA7B72VFgl2Tf7452
	AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
	ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
	a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
	ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
	F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH" /&gt;</pre>
<p>Dopo la paura iniziale, in genere ci si domanda: <strong>cosa sono quei caratteri e come faccio a inserirli?</strong></p>
<p>Quell&#8217;ammasso di caratteri è la <strong>codifica in base64</strong> dell&#8217;immagine. In pratica, è il contenuto del file immagine codificato in base64.</p>
<p>Per<strong> codificare un&#8217;immagine in base64</strong> si utilizza una semplice <strong>funzione php</strong>: <em>base64_encode</em>.</p>
<p>L&#8217;ultima questione riguarda il tipo <strong>MIME</strong> che si può ottenere in due modi:</p>
<ul>
<li>utilizzando la funzione <strong>mime_content_type</strong>, dopo aver abilitato l&#8217;<strong>estensione php_mime_magic.dll</strong>.</li>
<li>leggendo le informazioni del file grazie le funzioni <a title="File Information" href="http://it2.php.net/manual/en/book.fileinfo.php"><strong>File Information</strong></a> di php. Era un&#8217;estensione PECL, ma ora non lo è più. Bisogna utilizzare la <strong>libreria esterna magic_open</strong></li>
</ul>
<p>Nel caso non si possano utilizzare queste funzioni si dovrà <strong>scrivere manualmente</strong>, il che presuppone che si conosca il tipo dell&#8217;oggetto o dell&#8217;immagine da inserire.</p>
<h4>Come inserire un&#8217;immagine in base64 (senza funzioni per il tipo MIME)</h4>
<pre lang="php">&lt;img src="data:image/jpeg;base64,&lt;?
echo base64_encode(file_get_contents("img.jpg")); ?&gt;" alt="Immagine" /&gt;</pre>
<h4>Come inserire un&#8217;immagine in base64 (con funzioni per il tipo MIME)</h4>
<pre lang="php">&lt;? $mime = mime_content_type("img.jpg"); ?&gt;
&lt;img src="data:&lt;? echo $mime; ?&gt;;base64,&lt;?
echo base64_encode(file_get_contents("img.jpg")); ?&gt;" alt="Immagine" /&gt;</pre>
<h4>Script, demo e download</h4>
<p>Per vedere lo script vai a <a href="http://test.jblog.it/img_base64/index.txt" target="_blank">http://test.jblog.it/img_base64/index.txt</a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/img_base64/" target="_blank">http://test.jblog.it/img_base64/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/img_base64.zip" target="_blank">http://download.jblog.it/img_base64.zip</a></p>
<h2>Mime HTML</h2>
<p>Il termine &#8220;<em>Mime HTML</em>&#8221; sta per &#8220;<em>Multipurpose Internet Mail Extensions HyperText Markup Language</em>&#8220;.</p>
<p>Per avere un&#8217;idea di quella che può essere una pagina mhtml (di estensione .mht) pensiamo ad un&#8217;<strong>email con dei file allegati</strong> (che possono essere anche delle immagini presenti all&#8217;interno del testo). I file che vengono inviati tramite email, sottoforma di allegati, vengono codificati in <strong>base64 </strong>e successivamente inseriti nell&#8217;intestazione dell&#8217;email. Quando il nostro client riceve l&#8217;email, prima decodifica gli allegati per renderli fruibili ed eventualmente pronti per il download. Una pagina MHTML funziona grosso modo così.</p>
<p><strong>ATTENZIONE.</strong> Una pagina MHTML non deve necessariamente essere quella in cui viene scritto il codice html. Infatti può esserlo anche un file css che utilizza delle immagini (che vedremo successivamente).</p>
<h3>Struttura di una pagina MHTML</h3>
<p><img class="alignright size-full wp-image-545" title="Schema Pagina MHTML" src="http://jblog.it/wp-content/uploads/2009/05/mhtml_schema.png" alt="Schema Pagina MHTML" width="271" height="253" />Generalmente una pagina di questo tipo è composta da <strong>3 mattoni fondamentali</strong>:</p>
<ul>
<li>nell&#8217;<strong>intestazione </strong>si specifica che il file è di tipo &#8220;multipart/related&#8221;, il separatore dei dati codificati in base64 e il tipo di contenuto del file (es. &#8220;text/html&#8221;)</li>
<li>la seconda parte è quella relativa ai <strong>dati codificati in base 64</strong> separati dal separatore specificato nell&#8217;intestazione e definiti dai rispettivi campi &#8220;Content-Location&#8221;, &#8220;Content-Type&#8221; e &#8220;Content-Transfer-Encoding&#8221; (naturalmente, quest&#8217;ultimo viene impostato con &#8220;base64&#8243;). Possono trovarsi anche in fondo alla pagina, il che è meglio poiché si da priorità al caricamento del codice</li>
<li>nella terza parte viene scritto il <strong>corpo della pagina</strong> (o del messaggio, nel caso delle email) in html, css o altro, all&#8217;interno del quale verranno richiamati i dati specificati nella seconda parte del documento</li>
</ul>
<h3>Esempio di documento</h3>
<p>L&#8217;esempio seguente è una pagina web con allegate 2 immagini, e segue lo schema in figura.</p>
<p>Purtroppo <strong>Internet Explorer</strong> gestisce diversamente i dati allegati e ci costringe a scrivere due versioni di codice. Tuttavia, questa è una delle rare volte in cui preferisco IE poiché con il browser Microsoft i dati in base64 vengono scritti una sola volta e possono essere <strong>richiamati infinite volte </strong>all&#8217;interno del documento grazie alla stringa specificata in &#8220;Content-Location&#8221;. Con <strong>gli altri browser</strong> (Firefox, Opera, Safari, Chrome) è necessario scrivere i dati codificati per ogni utilizzo dell&#8217;oggetto o immagine, il che rende il tutto più pesante e ci costringe a pensare due volte prima di decidere di inviare un&#8217;oggetto all&#8217;interno del documento MIME Html.</p>
<pre lang="html">&lt;!--
MIME-Version: 1.0
Content-Type: multipart/related; boundary="|b|o|u|n|d|a|r|y|"

--|b|o|u|n|d|a|r|y|
Content-Location:2bmp24869
Content-Type:image/bmp
Content-Transfer-Encoding:base64

Qk0eCgAAAAAAADYEAAAoA[...caratteri...]QEBAQEBAQEBZA==
--|b|o|u|n|d|a|r|y|
Content-Location:1bmp21242
Content-Type:image/bmp
Content-Transfer-Encoding:base64

Qk12CwAAAAAAAD[...caratteri...]JCQkJCQkJ
--&gt;
&lt;!--
--|b|o|u|n|d|a|r|y|
Content-Location:5bmp92853
Content-Type:image/bmp
Content-Transfer-Encoding:base64

<span class="attribute-value">DCwmoA2NiOAKioQ</span>[...caratteri...]<span class="attribute-value">QDz87gA0dGCALq6X</span>
--&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"  dir="ltr" lang="en-US"&gt;
&lt;head&gt;
  &lt;title&gt;Titolo pagina&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

	&lt;object data="data:image/bmp;base64,Qk0eCgAAAAAAADYEAAAoA[...caratteri...]QEBAQEBAQEBZA=="&gt;
		&lt;img src="mhtml:http://localhost/jblog_script/mhtml_dataurl/index2.php!2bmp24869" alt="img3" /&gt;
	&lt;/object&gt;

	&lt;div style=" width:200px; height:200px; background-image:url(data:image/bmp;base64,Qk12CwAAAAAAAD[...caratteri...]JCQkJCQkJ); *background-image:url(mhtml:http://localhost/jblog_script/mhtml_dataurl/index2.php!1bmp21242);"&gt;&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Il fatto che queste immagini abbiano questo &#8220;strano&#8221; formato non ci deve assolutamente far preoccupare. Gli utilizzi sono quelli di sempre: all&#8217;interno del tag &lt;img&gt;, come sfondo di un elemento grazie alle regole css, ecc.</p>
<p><strong>Compatibilità con IE.</strong> Per gestire la compatibilità con il browser Internet Explorer è necessario inserire l&#8217;immagine compatibile con IE all&#8217;interno dei tag &lt;object&gt; in cui viene specificata l&#8217;immagine in un formato compatibile con i restanti browser. I risultati sono i seguenti:</p>
<ul>
<li>se si accede alla pagina con un <strong>browser diverso da IE</strong>, il tag object funzionerà correttamente mostrando l&#8217;immagine; il tag &lt;img&gt; al suo interno non verrà preso in considerazione dal browser</li>
<li>nel caso in cui si acceda con <strong>Internet Explorer</strong>, poiché il tag &lt;object&gt; non funzionerà verrà considerato il tag &lt;img&gt; in cui l&#8217;immagine specificata è in un formato compatibile con IE</li>
</ul>
<p><strong>Regole da rispettare.</strong> Per concludere vorrei evidenziare alcune importanti caratteristiche riguardo il formato di un documento MHTML:</p>
<ul>
<li>&#8220;Mime Version&#8221; e &#8220;Content-Type&#8221; devono trovarsi obbligatoriamente in testa alla pagina, prima del &lt;!Doctype&#8230;&gt;</li>
<li>Il primo separatore può essere separato a piacere dall&#8217;intestazione del documento</li>
<li>Il separatore (boundary) deve trovarsi esattamente fra i dati in base64 dell&#8217;oggetto precedente e le intestazioni dell&#8217;oggetto successivo, senza ulteriori &#8220;a capo&#8221;, &#8220;spazi&#8221;, &#8220;tab&#8221;, e altri caratteri</li>
<li>I vari oggetti possono essere separati solo da &#8220;fine&#8221; (&#8211;&gt;) e &#8220;inizio&#8221; (&lt;!&#8211;) commenti, stando attenti a non inserire altri caratteri tra &lt;!&#8211; e il separatore; invece, fra il contenuto in base64 e &#8211;&gt; possono esserci caratteri di escape (a capo, tab, ecc.)</li>
<li>Prima del separatore è necessario inserire due trattini &#8220;&#8211;&#8221;</li>
<li>Riguardo IE, l&#8217;indirizzo da scrivere dopo <strong>mhtml:</strong> deve essere identico all&#8217;indirizzo visibile nella barra degli indirizzi. Questo indirizzo si ottiene dalla variabile riservata <strong>$_SERVER['REQUEST_URI']</strong></li>
</ul>
<h2>Utilizzare concretamente Mime HTML e data:URL</h2>
<p>Ecco come immagino la generazione di un documento Mime HTML con lo schema data:URL.</p>
<p><img class="aligncenter size-full wp-image-553" title="Schema MHTML e data:URL, processo" src="http://jblog.it/wp-content/uploads/2009/06/mhtml_dataurl.png" alt="Schema MHTML e data:URL, processo" width="507" height="268" /><strong>Prima fase.</strong> Gli oggetti e le immagini vengono codificati in base64 e sistemati all&#8217;interno del documento.</p>
<p><strong>Seconda fase.</strong> Il browser legge il codice html e decodifica i dati allegati portandoli al loro formato primitivo: le immagini ritornano immagini, gli oggetti flash ritornano animazioni, ecc.</p>
<h3>La classe MimeHtmlHandler</h3>
<p>Per automatizzare il tutto ho sviluppato una piccola classe PHP che con un paio di righe ti permetterà di inserire all&#8217;interno del documento MHtml un&#8217;immagine precedentemente allegata.</p>
<p><strong>N.B.</strong> la proprietà <strong>*background-image </strong>serve per rimpiazzare la prima background-image nel caso questa non funzionasse. In particolare, la proprietà *background-image viene utilizzata per IE mentre background-image funziona con i restanti browser.</p>
<p>Il codice dell&#8217;esempio precedente è stato ottenuto da questo script PHP:</p>
<pre lang="php">&lt;?
// ( 1 ) Crea l'oggetto
$mhh = new MimeHtmlHandler("http://test.jblog.it","|b|o|u|n|d|a|r|y|","MIME Version 1.0");

// ( 2 ) Header "Content-Type" e "MIME Version"
$mph-&gt;printHeader();

?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"  dir="ltr" lang="en-US"&gt;
&lt;head&gt;
  &lt;title&gt;mhtml test page&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id="test1"&gt;test #1&lt;/div&gt;
  &lt;div id="test2"&gt;test #2&lt;/div&gt;

  &lt;object data="&lt;? $mhh-&gt;inc("2.bmp","image/bmp"); ?&gt;"&gt;
	  &lt;img src="&lt;? $mhh-&gt;incIE("2.bmp"); ?&gt;" alt="img3" /&gt;
  &lt;/object&gt;

 &lt;div style=" width:200px; height:200px; background-image:url(&lt;? $mhh-&gt;inc("1.bmp","image/bmp"); ?&gt;); *background-image:url(&lt;? $mhh-&gt;incIE("1.bmp"); ?&gt;);"&gt;&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
&lt;?
// ( 3 ) Crea la lista dei dati (per IE)
$mhh-&gt;incAll();
?&gt;</pre>
<h4>Caratteristiche principali della classe MimeHtmlHandler</h4>
<p>La classe ha due <strong>array privati</strong>: il primo è quello in cui vengono conservati gli oggetti che vengono inseriti nella pagina in modo da evitare di codificarli e impostarli nuovamente per un successivo inserimento; il secondo è quello relativo ai nomi in codice specificati in &#8220;Content-Location&#8221; quando si stampa la lista dei dati codificati che verrà utilizzata solo da Internet Explorer.</p>
<p>Le <strong>funzioni da utilizzare</strong> sono solo due: inc e incIE. Queste due funzioni permettono di inserire oggetti in formati compatibili con tutti i browser e con IE. Inoltre, in base al tipo e al numero di argomenti passati è possibile creare da zero un oggetto o richiamarne uno già inserito.</p>
<p>Quando si vuole stampare un&#8217;oggetto già inserito precedentemente il nome del file verrà cercato nell&#8217;array degli oggetti. La <strong>ricerca </strong>viene effettuata a partire dall&#8217;<strong>ultimo elemento</strong> in quanto sono molto più probabili gli inserimenti consecutivi di immagini rispetto a quelli richiesti in punti molto diversi e lontani di una pagina.</p>
<h4>Le 3 istruzioni fondamentali</h4>
<ol>
<li>Crea l&#8217;oggetto della classe specificando l&#8217;url di base delle immagini, il separatore (boundary) e la versione MIME</li>
<li>Stampa l&#8217;intestazione &#8220;Content-Type&#8221; e &#8220;MIME Version&#8221;</li>
<li>In fondo alla pagina viene stampata la lista dei dati in base64 che servono a Internet Explorer, mentre per gli altri browser i dati codificati vengono specificati all&#8217;interno del tag in cui si utilizzano</li>
</ol>
<h4>Come inserire un&#8217;immagine</h4>
<p>Sono state create due funzioni distinte per l&#8217;inserimento di un&#8217;immagine compatibile con IE o con gli altri browser (rispettivamente incIE e inc). Analizziamo i casi più comuni relativi all&#8217;utilizzo di queste funzioni.</p>
<ul>
<li><strong>Inserire un&#8217;immagine in modo che sia compatibile con tutti i browser. </strong>Richiamare la funzione inc() all&#8217;interno dell&#8217;attributo &#8220;data&#8221; del tag &lt;object&gt;, passando come parametri il percorso del file e il tipo mime. All&#8217;interno dei tag &lt;object&gt; e &lt;/object&gt; inserire il tag &lt;img&gt; richiamando la funzione incIE() all&#8217;interno dell&#8217;attributo &#8220;src&#8221;. Alla funzione incIE basterà passare solo il nome del file grazie al quale verranno recuperati gli altri dati relativi all&#8217;oggetto da stampare.</li>
<li><strong>Inserire un&#8217;immagine esistente.</strong> Alle funzioni inc() e incIE() basterà passare il nome del file.</li>
</ul>
<h4>Demo e download</h4>
<p>Per vedere una demo vai su <a href="http://test.jblog.it/mhtml1/index.php" target="_blank">http://test.jblog.it/mhtml1/</a></p>
<p>Per scaricare la classe MimeHtmlHandler e l’esempio vai su <a href="http://download.jblog.it/mhtml1.zip" target="_blank">http://download.jblog.it/mhtml1.zip</a></p>
<h2>Esempio2. CSS e data:URL</h2>
<p>Per utilizzare la classe MimeHtmlHandler all&#8217;interno di un file CSS, la prima operazione da fare è impostare il server Apache in modo che processi i file CSS come file PHP. Per fare ciò basterà aggiungere queste righe:</p>
<pre>&lt;FilesMatch "myfile.css$"&gt;
	AddHandler application/x-httpd-php .css
&lt;/FilesMatch&gt;</pre>
<p>Infine componiamo il file css:</p>
<ul>
<li>processandolo come file php si perde la natura del file css che ripristiniamo inviando l&#8217;header &#8220;Content-Type:text/css&#8221;</li>
<li>includiamo la classe MimeHtmlHandler, e richiamiamo le prime due funzioni fondamentali (costruttore e printHeader() )</li>
<li>componiamo il corpo del file css utilizzando, dove occorrono, le funzioni inc() e incIE()</li>
<li>infine, richiamiamo l&#8217;ultima funzione fondamentale incAll() per stampare la lista dei file che servirà ad Internet Explorer</li>
</ul>
<pre lang="php">&lt;? header("Content-Type: text/css"); ?&gt;
/*&lt;?
include("MimeHtmlHandler.php");

// ( 1 ) Crea l'oggetto
$mhh = new MimeHtmlHandler("http://localhost","|b|o|u|n|d|a|r|y|","");

// ( 2 ) Header "Content-Type" e "MIME Version"
$mhh-&gt;printHeader();
?&gt;*/

#test1 {
  background-image: url("&lt;? $mhh-&gt;inc("2.bmp","image/bmp"); ?&gt;"); /* normal */
  *background-image: url(&lt;? $mhh-&gt;incIE("2.bmp"); ?&gt;); /* IE &lt; 8 */
}

#test2 {
  background-image: url("&lt;? $mhh-&gt;inc("1.bmp","image/bmp"); ?&gt;"); /* normal */
  *background-image: url(&lt;? $mhh-&gt;incIE("1.bmp"); ?&gt;); /* IE &lt; 8 */
}

div {
  width: 100px;
  height: 100px;
  font: bold 24px Arial;
}
/*&lt;?
// ( 3 ) Crea la lista dei dati (per IE)
$mhh-&gt;incAll();

?&gt;*/</pre>
<h4>Demo e download</h4>
<p>Per vedere una demo vai su <a href="http://test.jblog.it/mhtml2/index.php" target="_blank">http://test.jblog.it/mhtml2/</a></p>
<p>Per scaricare la classe MimeHtmlHandler e l’esempio vai su <a href="http://download.jblog.it/mhtml2.zip" target="_blank">http://download.jblog.it/mhtml2.zip</a></p>
<h2>Considerazioni finali</h2>
<p>Nei precedenti esempi abbiamo visto solo come utilizzare queste tecniche per allegare le immagini, anche perché è questa la situazione più frequente. Tuttavia, nello stesso modo potresti allegare facilmente <strong>oggetti flash e applet Java</strong>: nello stesso modo!</p>
<p><strong>Compatibilità IE.</strong> Ho testato queste tecniche con Internet Explorer, dalla versione 5.5 alla 8 e non ho riscontrato grossi problemi. Una piccola anomalia si verifica quando si aggiorna la pagina più volte e le immagini non vengono caricate. Sinceramente non so da cosa può dipendere.</p>
<p>Queste tecniche, in confronto ai CSS Sprite sembrano<strong> &#8220;roba da smanettoni&#8221;</strong> a causa dell&#8217;ammasso di numeri e lettere che genera la codifica in base64 e dell&#8217;utilizzo (leggero) di php. Non farti ingannare&#8230; In fondo cosa c&#8217;è di così difficile?!? Dovrai solo pensare alcuni minuti alle immagini da allegare ai documenti (html, css, ecc.) e analizzare un po&#8217; le velocità di caricamento per capire fino a che punto potranno avvantagiarti. Io dico di provarci! <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' title="Ridurre le richieste HTTP con Mime HTML e data:URL" /> </p>
<p><span class="highlight_green">Non escludo che nella classe MimeHtmlHandler ci possano essere dei <strong>bug</strong>. Per qualsiasi problema, chiarimento e curiosità sarei felice se mi contattattassi. Dimmi com&#8217;è andata e se queste tecniche ti sono state utili: non vedo l&#8217;ora di sapere gli esiti dei tuoi esperimenti!</span></p>
<h2>Crediti</h2>
<p><a href="http://www.phpied.com/" target="_blank">Phpied.com</a> &#8211; <a href="http://www.phpied.com/data-urls-what-are-they-and-how-to-use/" target="_blank">data:urls &#8211; what are they and how to use them</a></p>
<p><a href="http://www.phpied.com/" target="_blank">Phpied.com</a> &#8211; <a href="http://www.phpied.com/mhtml-when-you-need-data-uris-in-ie7-and-under/" target="_blank">MHTML &#8211; when you need data: URIs in IE7 and under</a></p>
<p><strong>Foto1.</strong> <a href="http://www.flickr.com/photos/benbeiske/3028805547/" target="_blank">Vientiane 04 &#8211; Pink Dragonfruit shake</a> di <a href="http://www.flickr.com/photos/benbeiske/">Ben Beiske</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=537&type=feed" alt=" Ridurre le richieste HTTP con Mime HTML e data:URL"  title="Ridurre le richieste HTTP con Mime HTML e data:URL" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/06/01/ridurre-richieste-http-mime-html-data-url-mhtml_537.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>50 set di icone gratis di social media &#8230; spettacolari!</title>
		<link>http://jblog.it/2009/05/26/icone-gratis-social-media-spettacolare_528.html</link>
		<comments>http://jblog.it/2009/05/26/icone-gratis-social-media-spettacolare_528.html#comments</comments>
		<pubDate>Tue, 26 May 2009 09:58:49 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Grafica]]></category>
		<category><![CDATA[Social network]]></category>
		<category><![CDATA[directory]]></category>
		<category><![CDATA[icone]]></category>
		<category><![CDATA[promuovere]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=528</guid>
		<description><![CDATA[Mentre cercavo un po&#8217; di icone da sostituire a quelle (non proprio bellissime) che avevo mi sono imbattuto in un bel post.
Ci sono 50 set di icone libere da royality e complete di tutti i maggiori social media. Quest&#8217;ultima caratteristica mi è piaciuta particolarmente poiché in tanti pacchetti mancavano le icone di social media anche [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-529" title="Free icons - Smashing Magazine Icon set" src="http://jblog.it/wp-content/uploads/2009/05/smashing_icon.png" alt="Free icons - Smashing Magazine Icon set" width="270" height="160" />Mentre cercavo un po&#8217; di icone da sostituire a quelle (non proprio bellissime) che avevo mi sono imbattuto in un bel post.</p>
<p>Ci sono 50 set di icone <strong>libere da royality</strong> e complete di tutti i <strong>maggiori social media</strong>. Quest&#8217;ultima caratteristica mi è piaciuta particolarmente poiché in tanti pacchetti mancavano le icone di social media anche abbastanza famosi come lastfm!!!</p>
<p>Spero ti sia gradito: <a title="50 Free Social Media Icon Sets for Your Blog" href="http://directoryfordesigners.com/50-free-social-media-icon-sets-for-your-blog" target="_blank">http://directoryfordesigners.com/50-free-social-media-icon-sets-for-your-blog</a><!--adv300--></p>
<p><span class="highlight_green">Il sito è <a href="http://directoryfordesigners.com/" target="_blank"><strong>Directory4Designers</strong></a>, una directory sottoforma di blog in cui i web designer possono condividere i propri lavori e possono essere facilmente contattati tramite i social network. Da tenere d&#8217;occhio, magari abbonandosi ai feed&#8230;</span></p>
<p><strong>Foto1.</strong> <a href="http://www.smashingmagazine.com" target="_blank">SmashingMagazine</a> &#8211; <a title="Cheers: A Free “Social” Icon Set" href="http://www.smashingmagazine.com/2008/09/10/cheers-a-free-social-icon-set/" target="_blank">Cheers: A Free “Social” Icon Set</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=528&type=feed" alt=" 50 set di icone gratis di social media ... spettacolari!"  title="50 set di icone gratis di social media ... spettacolari!" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/05/26/icone-gratis-social-media-spettacolare_528.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tecniche javascript e jquery per selezionare e scorrere elementi html e nodi</title>
		<link>http://jblog.it/2009/05/25/tecniche-javascript-jquery-selezionare-scorrere-elementi-html-nodi_492.html</link>
		<comments>http://jblog.it/2009/05/25/tecniche-javascript-jquery-selezionare-scorrere-elementi-html-nodi_492.html#comments</comments>
		<pubDate>Mon, 25 May 2009 16:31:52 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[classi librerie]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=492</guid>
		<description><![CDATA[Dopo aver letto l&#8217;interessante articolo di ImpressiveWebs su alcune tecniche javascript mi è venuta un&#8217;idea che ti piacerà. Ho deciso di integrarlo con le rispettive tecniche jquery ma, anziché limitarle esclusivamente all&#8217;ambito jquery cerco di mantenere comunque un legame con il puro codice javascript.
Per quale motivo? Innanzitutto perché è interessante vedere come da jquery si [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Tecniche javascript e jquery per selezionare e scorrere gli elementi html" href="http://jblog.it/2009/05/25/tecniche-javascript-jquery-selezionare-scorrere-elementi-html-nodi_492.html" target="_self"><img class="alignright size-full wp-image-519" title="Craw machine" src="http://jblog.it/wp-content/uploads/2009/05/craw_machine.jpg" alt="Craw machine" width="290" height="190" /></a>Dopo aver letto l&#8217;<a title="10 Essential DOM Methods &amp; Techniques for Practical JavaScript" href="http://www.impressivewebs.com/10-essential-dom-methods-techniques-for-practical-javascript/" target="_blank">interessante articolo di <strong>ImpressiveWebs </strong>su alcune tecniche javascript</a> mi è venuta un&#8217;idea che ti piacerà. Ho deciso di integrarlo con le <strong>rispettive tecniche jquery</strong> ma, anziché limitarle esclusivamente all&#8217;ambito jquery cerco di mantenere comunque un legame con il puro codice javascript.</p>
<p><strong>Per quale motivo?</strong> Innanzitutto perché è interessante vedere come da jquery si possa passare ai classici oggetti javascript e poi perché in alcuni casi si preferisce programmare in javascript senza rinunciare ad alcune potenzialità di jquery come, ad esempio, i selettori, spesso argomento di scontro (e confronto) fra i vari framework. Inoltre, come dice ImpressiveWebs, alcuni sviluppatori si trovano a dover lavorare a progetti già avviati nei quali non è possibile (o non è sicuro) utilizzare librerie come jquery, mootools, dojo, ecc.</p>
<p>Un <strong>ringraziamento speciale</strong> va a <a href="http://www.impressivewebs.com/" target="_blank">ImpressiveWebs</a> che mi ha gentilmente autorizzato a tradurre buona parte dell&#8217;<a title="10 Essential DOM Methods &amp; Techniques for Practical JavaScript" href="http://www.impressivewebs.com/10-essential-dom-methods-techniques-for-practical-javascript/" target="_blank">articolo orginale</a>.<span id="more-492"></span></p>
<h2>getElementById: selezionare un elemento conoscendo l&#8217;id</h2>
<p><!--adv300--></p>
<p>Sappiamo che quasi tutti i tag html hanno l&#8217;attributo id. Questo attributo serve a <strong>identificare univocamente un elemento</strong> all&#8217;interno del documento html. Non è possibile specificare lo stesso id per due elementi diversi e, se ciò accade, il w3c validator segnalerà l&#8217;errore.</p>
<p>Supponiamo di avere un tag html con l&#8217;id &#8220;my_element_id&#8221;:</p>
<pre lang="html">&lt;div id="my_element_id"&gt;Questo è un elemento generico&lt;/div&gt;</pre>
<p>La caratteristica fondamentale dell&#8217;id ci permette di selezionare esattamente un elemento che ha come id un certo valore. Non a caso infatti la funzione restituisce un solo elemento e non un array di elementi, come avviene per funzioni che effettuano selezioni più generiche.</p>
<pre lang="js">var elemento = document.getElementById("my_element_id");</pre>
<p>Con jquery è possibile fare lo stesso ma, al contrario della precedente, la funzione jquery prevede la restituzione di un array di elementi poiché viene utilizzata anche per selezioni più generiche. Quindi sarà necessario selezionare il primo, nonché l&#8217;unico, elemento dell&#8217;array restituito. L&#8217;elemento ottenuto è esattamente uguale a quello ottenuto con la funzione getElementById.</p>
<pre lang="js">var elemento = $("#my_element_id")[0];</pre>
<h3>Ottenuto l&#8217;elemento che si fà?</h3>
<p>Si possono utilizzare tutte le proprietà e le funzioni (o meglio, metodi) javascript previste dal quel tipo di oggetto. Ad esempio:</p>
<pre lang="js">elemento.style.border = "1px solid #000";
elemento.disabled = "true";</pre>
<p>Se, invece, preferisci utilizzare jquery dovrai ricorrere necessariamente alle proprietà e ai metodi definiti nella libreria jquery. Ad esempio:</p>
<pre lang="js">$("#my_element_id").css("border",""1px solid #000"");
$("#my_element_id").attr("disabled","true");</pre>
<p><strong>ATTENZIONE.</strong> Spesso si sbaglia la scrittura della funzione scrivendo getElementBy<span style="text-decoration: underline;">ID</span> anziché getElementBy<span style="text-decoration: underline;">Id</span> (notare la &#8220;d&#8221; minuscola).</p>
<p><strong>Vantaggi.</strong> L&#8217;utilizzo di questa funzione impone la definizione di identificatori per i vari elementi che si vogliono gestire all&#8217;interno di funzioni javascript. Questo rappresenta un vantaggio poiché si tende a migliorare la scrittura del codice html. Un&#8217;altro possibile vantaggio è la maggior velocità della selezione per id rispetto alla selezione fra un&#8217;insieme di più elementi, che vedremo di seguito.</p>
<h2>getElementByTagName: selezionare un gruppo di tag</h2>
<p><img class="alignright size-full wp-image-525" title="Toystory craw machine" src="http://jblog.it/wp-content/uploads/2009/05/toystory2.jpg" alt="Toystory craw machine" width="170" height="115" />Se per qualche motivo non puoi o non vuoi specificare un id per alcuni elementi, questa funzione ti viene in aiuto. L&#8217;unico argomento della funzione è il tag degli elementi da selezionare i quali verranno poi restituiti in un <strong>array</strong>.</p>
<p><strong>Esempio.</strong> Supponiamo di avere una lista di link e di voler selezionare solo quelli che hanno l&#8217;attributo &#8220;target&#8221; uguale a &#8220;_blank&#8221; in modo da modificare il valore di questo attributo in &#8220;_top&#8221;.</p>
<pre lang="html">&lt;ul id="lista_5link"&gt;
	&lt;li&gt;&lt;a href="link1.html" target="_blank"&gt;Primo link&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="link2.html"&gt;Secondo link&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="link3.html" target="_blank"&gt;Terzo link&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="link4.html" target="_top"&gt;Quarto link&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="link5.html" target="_self"&gt;Quinto link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>Per selezionare i tag &#8220;&lt;a&gt;&#8221; con l&#8217;attributo &#8220;target&#8221; uguale a &#8220;_blank&#8221; dobbiamo innanzitutto ottenere un&#8217;array di tutti i tag &#8220;&lt;a&gt;&#8221; e successivamente modificare quelli che rispettano la nostra condizione.</p>
<pre lang="js">var myLinks = document.getElementsByTagName("a");

for(i=0; i&lt;myLinks.length; i++)
{
	if (myLinks[i].getAttribute("target") == "_blank")
	myLinks[i].setAttribute("target","_top");
}</pre>
<p>Con jquery il tutto si riduce a:</p>
<pre lang="js">$("a[target='_blank']").attr("target","_top");</pre>
<p>Con &#8220;a&#8221; si chiede di selezionare tutti i tag &#8220;&lt;a&gt;&#8221; e con &#8220;[target='_blank']&#8221; si chiede che questi tag abbiano l&#8217;attributo &#8220;target&#8221; uguale a &#8220;_blank&#8221;. Infine con <code>attr("target","_top")</code>, che viene eseguito solo se è stato trovato il tag richiesto, si imposta l&#8217;attributo &#8220;target&#8221; con il valore &#8220;_top&#8221;.</p>
<p><strong>Miglioramento.</strong> Per evitare che la ricerca dei tag &#8220;&lt;a&gt;&#8221; venga effettuata all&#8217;interno dell&#8217;intero documento, si può impostare l&#8217;id  alla lista in modo da <strong>restringere la ricerca</strong> agli elementi interni alla lista.</p>
<p>Al tag &#8220;&lt;ul&gt;&#8221; ho precedentemente assegnato l&#8217;id &#8220;lista_5link&#8221;. Ora vediamo come restringere la ricerca.</p>
<pre lang="js">// Seleziona l'elemento con l'id "lista_5link"
var oggettoLista = document.getElementById("lista_5link");

// Dell'elemento "oggettoLista" ricaviamo l'insieme dei tag &lt;a&gt;
var myLinks = oggettoLista.getElementsByTagName("a");

// Il ciclo for rimane uguale al precedente
for(i=0; i&lt;myLinks.length; i++)
{
	if (myLinks[i].getAttribute("target") == "_blank")
	myLinks[i].setAttribute("target","_top");
}</pre>
<p>Con jquery si aggiunge il vincolo &#8220;#lista_5link&#8221;:</p>
<pre lang="js">$("#lista_5link a[target='_blank']").attr("target","_top");
/* Invece di $("a[target='_blank']").attr("target","_top"); */</pre>
<h4>Soluzione ibrida</h4>
<pre lang="js">// Seleziona gli elementi &lt;a&gt; con jQuery
var myLinks = $("#lista_5link a")

// Il ciclo for rimane uguale al precedente
for(i=0; i&lt;myLinks.length; i++)
{
	if (myLinks[i].getAttribute("target") == "_blank")
	myLinks[i].setAttribute("target","_top");
}</pre>
<p><strong>Osservazione.</strong> Potresti dirmi &#8220;<em>perché non assegniamo lo stesso id a tutti i tag &lt;a&gt;?</em>&#8220;. Questa operazione non si può fare poiché l&#8217;id, per sua natura, deve necessariamente essere unico all&#8217;interno del documento, cioè solo un elemento può avere un certo id. Infatti, come spiegato prima, l&#8217;id deve servire a identificare univocamente <strong>un solo elemento</strong> all&#8217;interno del documento html.</p>
<h2>Leggere e scorrere i nodi del documento</h2>
<p><strong><img class="alignright size-full wp-image-521" title="node" src="http://jblog.it/wp-content/uploads/2009/05/node.jpg" alt="node Tecniche javascript e jquery per selezionare e scorrere elementi html e nodi" width="249" height="159" />Cosa sono i nodi?</strong> Un nodo è un qualsiasi elemento, tag, contenitore, blocco autonomo (es. &lt;br /&gt;, &lt;hr /&gt;), frammento di testo. I nodi hanno una <strong>relazione genitore-figlio</strong>. Ad esempio, nel caso della lista illustrata precedentemente, &lt;ul&gt; è il genitore e &lt;li&gt; il figlio, che a sua volta è il genitore di &lt;a&gt;.</p>
<p><strong>Ogni elemento è un nodo</strong> e come tale ha alcune proprietà e metodi che ci permettono di ricavare i suoi figli diretti (children), il suo genitore (parent), e di manipolarli in vari modi.</p>
<h4>Codice html che utilizzeremo per tutti gli esempi</h4>
<pre lang="html">&lt;div id="parent_div"&gt;
	&lt;p&gt;Paragrafo1&lt;/p&gt;
	&lt;p&gt;Paragrafo2&lt;/p&gt;
	&lt;a href="#"&gt;Link&lt;/a&gt;
	&lt;p&gt;Paragrafo3&lt;/p&gt;
	&lt;h5&gt;Titolo h5&lt;/h5&gt;
&lt;/div&gt;</pre>
<h2>Ottenere i nodi figli con childNodes e children</h2>
<p>Le due proprietà, childNode e children, sono costituite da un array dei figli diretti.</p>
<p>La differenza fra le due consiste nel fatto che children ignora i nodi di tipo testo concentrandosi sugli elementi html e xml.</p>
<ul>
<li>La <strong>proprietà childNodes</strong> rileva come &#8220;figli del contenitore&#8221; tutti gli elementi: tag, elementi, testo, ecc. Come si può vedere in figura, l&#8217;array childNodes avrà <strong>10 elementi</strong>: gli indici pari saranno gli elementi &#8220;testuali&#8221; e gli indici dispari i tag html. <strong>N.B.</strong> i blocchi evidenziati sono i figli &#8220;testuali&#8221;, quelli non evidenziati sono i figli &#8220;html&#8221;</li>
<li>La <strong>proprietà children </strong>rileva come &#8220;figli del contenitore&#8221; solo i tag html. Quindi l&#8217;array children avrà solo 5 elementi: i tag contenuti nel div &#8220;parent_div&#8221;</li>
</ul>
<p><a title="childNodes - children | Visualizza l'immagine al 100%" href="http://jblog.it/wp-content/uploads/2009/05/childnodes_children.png"><img class="aligncenter size-full wp-image-507" title="Differenza fra childNodes e children" src="http://jblog.it/wp-content/uploads/2009/05/childnodes_children.png" alt="Differenza fra childNodes e children" width="540" height="183" /></a><strong>Esempio. </strong>Supponiamo di voler assegnare a tutti i figli del div &#8220;parent_div&#8221; la classe &#8220;newclass&#8221;.</p>
<h3>La proprietà children</h3>
<pre lang="js">// Otteniamo i figli diretti di "parent_div"
var div_children = document.getElementById("parent_div").children;

for(i=0;i&lt;div_children.length;i++)
{
	// Assegniamo la classe "newclass"
	div_children[i].className="newclass";
}</pre>
<p><strong>ATTENZIONE.</strong> Ho riscontrato alcuni problemi legati a questa proprietà, ad esempio su Firefox. L&#8217;<strong>alternativa </strong>è proprio childNodes, da utilizzare con qualche piccolo accorgimento.</p>
<h3>La proprietà childNodes e nodeType</h3>
<p>Gli stessi risultati della proprietà children possono essere ottenuti con la proprietà childNodes, controllando il tipo di nodo che si sta leggendo grazie alla proprietà <strong>nodeType</strong>. Questa proprietà può avere 12 valori diversi (interi, da 1 a 12). La lista completa la puoi trovare qui: <a title="XML DOM Node Types" href="http://www.w3schools.com/Dom/dom_nodetype.asp" target="_blank">http://www.w3schools.com/Dom/dom_nodetype.asp</a> . In particolare, poiché la proprietà children non considera i <strong>nodi testuali</strong>, controlliamo che nodeType non sia 3 (codice corrispondente ai nodi testuali).</p>
<pre lang="js">// Otteniamo i figli diretti di "parent_div"
var div_children = document.getElementById("parent_div").childNodes;

for(i=0;i&lt;div_children.length;i++)
{
	// Controlliamo il tipo di nodo: noteType=3 se è un nodo testuale
	if(div_children[i].nodeType==3) continue;

	// Assegniamo la classe "newclass"
	div_children[i].className="newclass";
}</pre>
<p>Il <strong>risultato è identico</strong> al codice precedente in cui si utilizza la proprietà children.</p>
<h3>Soluzione ibrida</h3>
<pre lang="js">// Selezione figli con jquery
var div_children = $("#parent_div").children();

// Ciclo for uguale al precedente
for(i=0;i&lt;div_children.length;i++)
{
	// Assegniamo la classe "newclass"
	div_children[i].className="newclass";
}</pre>
<p><strong>N.B.</strong> la selezione con jquery ha lo stesso effetto della proprietà children, ovvero seleziona tutti i figli tranne quelli di tipo testuale.</p>
<h3>Soluzione con jquery</h3>
<pre lang="js">// Selezione figli con jquery e assegnazione della classe "newclass"
$("#parent_div").children().addClass("newclass");</pre>
<p>Con <code>$("#parent_div").children()</code> otteniamo i figli e con <code>addClass("newclass")</code> assegniamo la classe &#8220;newclass&#8221; ai figli trovati.</p>
<h2>Ottenere il primo e l&#8217;ultimo nodo figlio con firstChild e lastChild</h2>
<p>Normalmente per recuperare il primo o l&#8217;ultimo nodo figlio di un elemento si dovrebbero scrivere le seguenti righe di codice:</p>
<pre lang="js">// Primo nodo figlio
var first_child = document.getElementById("parent_div").firstChild;

// Ultimo nodo figlio
var last_child = document.getElementById("parent_div").lastChild;</pre>
<p><strong>Problema.</strong> Come per la proprietà childNodes, anche queste leggono qualsiasi tipo di nodo. Quindi, se fra due elementi c&#8217;è un carattere di spaziatura o un tab, questo verrà considerato un nodo.</p>
<p><strong>Soluzione.</strong> Con un semplice ciclo while possiamo leggere i successivi (o precedenti) nodi di tipo non testuale.</p>
<pre lang="js">// Primo nodo figlio
var first_child = document.getElementById("parent_div").firstChild;

// Se il nodo letto è di tipo testuale leggiamo il successivo
while(first_child!=null &amp;&amp; first_child.nodeType==3)
first_child = first_child.nextSibling;

// Ultimo nodo figlio
var last_child = document.getElementById("parent_div").lastChild;

// Se il nodo letto è di tipo testuale leggiamo il precedente
while(last_child!=null &amp;&amp; last_child.nodeType==3)
last_child = last_child.previousSibling;</pre>
<p><strong>Osservazioni.</strong> Le condizioni del <strong>ciclo while</strong> controllano che il nodo sia stato trovato (cioé che sia diverso da null) e che il tipo sia testuale (cioé nodeType = 3). Se entrambe le condizioni sono verificate il nodo attuale viene rimpiazzato con il successivo (nel caso del primo nodo) o con il precedente (nel caso dell&#8217;ultimo nodo). Questo procedimento si ripete finché non ci sono più nodi figli o non viene trovato un nodo di tipo &#8220;non testuale&#8221;. La proprietà <strong>nextSibling </strong>permette di ottenere il nodo successivo; la proprietà <strong>previousSibling </strong>permette di ottenere il nodo precedente.</p>
<h3>Soluzione ibrida con jquery</h3>
<p>Poiché il metodo children() di jquery legge i nodi figlio di tipo &#8220;non testuale&#8221;.</p>
<p>Per ricavare il primo e l&#8217;ultimo nodo figlio si passa come argomento &#8220;:first&#8221; (per il primo nodo) e &#8220;:last&#8221; (per l&#8217;ultimo nodo).</p>
<pre lang="js">// Primo nodo figlio
var first_child = $("#parent_div").children(":first");

// Ultimo nodo figlio
var last_child = $("#parent_div").children(":last");</pre>
<h2>Ottenere il genitore di un nodo con parentNode</h2>
<p>Supponiamo di avere il seguente codice html:</p>
<pre lang="html">&lt;div id="parent_div"&gt;
	&lt;p id="child1"&gt;Paragrafo1&lt;/p&gt;
	&lt;p id="child2"&gt;Paragrafo2&lt;/p&gt;
	&lt;p id="child3"&gt;Paragrafo3&lt;/p&gt;
&lt;/div&gt;</pre>
<p>Per ottenere il genitore dei tre paragrafi utilizzeremo la proprietà parentNode su uno dei tre paragrafi.</p>
<pre lang="js">var parent_node1 = document.getElementById("child1").parentNode;
var parent_node2 = document.getElementById("child2").parentNode;
var parent_node3 = document.getElementById("child3").parentNode;</pre>
<p>Le <strong>tre variabili</strong> (parent_node1, parent_node2, parent_node3) avranno lo <strong>stesso nodo</strong>: il div &#8220;parent_div&#8221;.</p>
<h3>Soluzione con jquery</h3>
<pre lang="js">// parent() restituisce un array di un solo elemento
var my_node = $("#ciaociao").parent()[0];</pre>
<h2>Ottenere i &#8220;fratelli&#8221; dei nodi con nextSibling e previousSibling</h2>
<p>Per ottenere il fratello di un nodo si possono utilizzare due funzioni:</p>
<ul>
<li><strong>nextSibling</strong>, per leggere il fratello successivo</li>
<li><strong>previousSibling</strong>, per leggere il fratello precedente</li>
</ul>
<p>Supponiamo di avere il seguente codice html:</p>
<pre lang="html">&lt;div id="parent_div"&gt;
	&lt;p id="child1"&gt;Paragrafo1&lt;/p&gt;
	&lt;p id="child2"&gt;Paragrafo2&lt;/p&gt;
	&lt;p id="child3"&gt;Paragrafo3&lt;/p&gt;
&lt;/div&gt;</pre>
<p>Vogliamo ottenere il nodo corrispondente al paragrafo di id &#8220;child2&#8243;.</p>
<p><strong>Problema.</strong> Anche queste proprietà selezionano i nodi di tipo &#8220;testuale&#8221;.</p>
<p><strong>Soluzione.</strong> Inseriamo un ciclo while identico a quello scritto per le proprietà firstChild e lastChild.</p>
<pre lang="js">// Ottenere il nodo "child2" partendo dal paragrafo "child1"
var node_child2_mod1 = document.getElementById("child1").nextSibling;

// Se il nodo letto è di tipo testuale leggiamo il successivo
while(node_child2_mod1!=null &amp;&amp; node_child2_mod1.nodeType==3)
node_child2_mod1 = node_child2_mod1.nextSibling;

// Ottenere il nodo "child2" partendo dal paragrafo "child3"
var node_child2_mod2 = document.getElementById("child1").previousSibling;

// Se il nodo letto è di tipo testuale leggiamo il precedente
while(node_child2_mod2!=null &amp;&amp; node_child2_mod2.nodeType==3)
node_child2_mod2 = node_child2_mod2.previousSibling;</pre>
<h3>Soluzione con jquery</h3>
<p>Fortunatamente i metodi next() e prev() di jquery selezionano solo i nodi &#8220;non testuali&#8221; e restituiscono un set di nodi costituito di fatto da un solo nodo.</p>
<pre lang="js">// Ottenere il nodo "child2" partendo dal paragrafo "child1"
var node_child2_mod1 = $("#child1").next()[0];

// Ottenere il nodo "child2" partendo dal paragrafo "child3"
var node_child2_mod2 = $("#child3").next()[0];</pre>
<h2>Attraversare i &#8220;fratelli&#8221; dei nodi con nextSibling e previousSibling</h2>
<p><img class="aligncenter size-full wp-image-522" title="Children climbing" src="http://jblog.it/wp-content/uploads/2009/05/climbing.jpg" alt="Children climbing" width="490" height="270" />Supponiamo di voler modificare tutti i fratelli di un certo nodo. Per fare ciò è necessario scorrere tutti i nodi &#8220;fratelli&#8221; modificandoli in base alle nostre esigenze. In realtà l&#8217;attraversamento dei nodi fratelli l&#8217;abbiamo già fatto in occasione dei cicli while utilizzati per risolvere il problema della selezione dei nodi testuali.</p>
<p>Utiliziamo il codice html dell&#8217;esempio precedente.</p>
<pre lang="js">// Otteniamo il nodo corrispondente al paragrafo "child1"
var node_child1 = document.getElementById("child1");

// Scorriamo tutti i fratelli di node_child1
while(node_child1!=null &amp;&amp; node_child1.nodeType!=3)
{
	// Leggiamo il fratello di node_child1 e lo inseriamo nella stessa variabile
	node_child1 = node_child1.nextSibling;

	// Esempio: applichiamo la classe "newclass"
	node_child1.className="newclass";
}</pre>
<h2>Conclusioni</h2>
<p>Queste sono alcune delle principali tecniche per selezionare e scorrere gli elementi html con il codice javascript &#8220;puro&#8221; e utilizzando il famoso framework jquery che, come avrai potuto notare, semplifica la scrittura di codice javascript e ne riduce drasticamente la lunghezza.</p>
<p><strong class="highlight_green">In queste situazioni preferisci utilizzare javascript puro o jquery? Hai avuto problemi durante l&#8217;utilizzo di queste tecniche? Si possono migliorare in qualche modo?</strong></p>
<h2>Crediti</h2>
<ul>
<li><a href="http://www.impressivewebs.com" target="_blank">ImpressiveWebs</a> &#8211; <a title="10 Essential DOM Methods &amp; Techniques for Practical JavaScript" href="http://www.impressivewebs.com/10-essential-dom-methods-techniques-for-practical-javascript/" target="_blank">10 Essential DOM Methods &amp; Techniques for Practical JavaScript</a></li>
<li><strong>Libro</strong>. Javascript &#8211; La guida di Danny Goodman, Michael Morrison (<a href="http://www.informatica.mcgraw-hill.it/" target="_blank">McGraw-Hill</a>)</li>
<li>Foto1: <a href="http://www.flickr.com/photos/joshnjerry/2453291663/" target="_blank">Catch me if you can!</a> di <a href="http://www.flickr.com/photos/joshnjerry/">Josh n Jerry</a></li>
<li>Foto2: <a href="http://www.freerepublic.com/focus/f-chat/2096935/posts" target="_blank">http://www.freerepublic.com/focus/f-chat/2096935/posts</a></li>
<li>Foto3: <a href="http://www.flickr.com/photos/12184548@N02/1428798524/" target="_blank">Node</a> di <a href="http://www.flickr.com/photos/12184548@N02/" target="_blank">dixit M</a></li>
<li>Foto5: <a href="http://www.flickr.com/photos/docman/6107473/" target="_blank">Climbing</a> di <a href="http://www.flickr.com/photos/docman/" target="_blank">docman</a></li>
</ul>
<h4 class="highlight_red">Non perdere il prossimo articolo sulle tecniche javascript e jquery per manipolare i nodi e gli elementi html.</h4>
<img src="http://jblog.it/?ak_action=api_record_view&id=492&type=feed" alt=" Tecniche javascript e jquery per selezionare e scorrere elementi html e nodi"  title="Tecniche javascript e jquery per selezionare e scorrere elementi html e nodi" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/05/25/tecniche-javascript-jquery-selezionare-scorrere-elementi-html-nodi_492.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Controllare il formato di un indirizzo email con le espressioni regolari (RegEx) in PHP e Javascript</title>
		<link>http://jblog.it/2009/05/20/controllare-formato-indirizzo-email-espressioni-regolari-regex-php-javascript_468.html</link>
		<comments>http://jblog.it/2009/05/20/controllare-formato-indirizzo-email-espressioni-regolari-regex-php-javascript_468.html#comments</comments>
		<pubDate>Wed, 20 May 2009 17:56:16 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Php e MySql]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[espressioni regolari]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=468</guid>
		<description><![CDATA[Ogni programmatore web prima o poi si scontra con la necessità di controllare se il formato dell&#8217;indirizzo email inserito dall&#8217;utente è valido.
Senza dubbio, il modo migliore per farlo consiste nell&#8217;utilizzo delle espressioni regolari, chiamate anche RegEx (da &#8220;regular expressions&#8221;).
Perché è il modo migliore? Anziché scrivere un&#8217;intera funzione composta da decine e decine di righe di [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Controllare il formato di un indirizzo email con le espressioni regolari (RegEx) in PHP e Javascript" href="http://jblog.it/2009/05/20/controllare-formato-indirizzo-email-espressioni-regolari-regex-php-javascript_468.html"><img class="alignright size-full wp-image-483" title="Logo Regex simile a FedEx" src="http://jblog.it/wp-content/uploads/2009/05/fts-regex-front.jpg" alt="Logo Regex simile a FedEx" width="252" height="144" /></a>Ogni programmatore web prima o poi si scontra con la necessità di controllare se il formato dell&#8217;indirizzo email inserito dall&#8217;utente è valido.</p>
<p>Senza dubbio, il <strong>modo migliore</strong> per farlo consiste nell&#8217;utilizzo delle espressioni regolari, chiamate anche RegEx (da &#8220;regular expressions&#8221;).</p>
<p><strong>Perché è il modo migliore? </strong>Anziché scrivere un&#8217;intera funzione composta da decine e decine di righe di codice, grazie alle RegEx basta defire il modello (o <strong>pattern</strong>) della stringa email e far eseguire il confronto da un&#8217;apposita funzione.<br />
<span id="more-468"></span></p>
<h2>Caratteristiche di un indirizzo email</h2>
<p>Il primo passo consiste nell&#8217;individuare le caratteristiche di un indirizzo email in modo da definirle successivamente in un modello (pattern).</p>
<p><img class="aligncenter size-full wp-image-472" title="Struttura di un indirizzo email" src="http://jblog.it/wp-content/uploads/2009/05/email_address.png" alt="Struttura di un indirizzo email" width="511" height="147" /></p>
<h3>Local part</h3>
<p>Questa parte, che indica spesso l&#8217;username, può essere costituita da:</p>
<ul>
<li>un massimo di 64 caratteri</li>
<li>lettere minuscole e maiuscole dell&#8217;alfabeto inglese, cioè a-z e A-Z</li>
<li>numeri, da 0 a 9</li>
<li>caratteri speciali <code>. ! # $ % &amp; ' * + - / = ? ^ _ ` { | } ~</code>. Alcuni servizi email non permettono di creare indirizzi solo con i caratteri speciali più comuni come &#8220;.&#8221; , &#8220;-&#8221;, e &#8220;_&#8221;</li>
</ul>
<p><strong>N.B.</strong> il carattere &#8220;.&#8221; non può trovarsi né all&#8217;inizio né alla fine.</p>
<h3>Domain name</h3>
<p>La parte successiva alla &#8220;@&#8221; è il nome del dominio (es. example.com) che può essere costituito da:</p>
<ul>
<li>un massimo di 255 caratteri</li>
<li>lettere minuscole dell&#8217;alfabeto inglese, cioè a-z</li>
<li>numeri, da 0 a 9</li>
<li>caratteri speciali &#8220;.&#8221; e &#8220;-&#8221;</li>
</ul>
<p><strong>N.B.</strong> il carattere &#8220;.&#8221; non può trovarsi né all&#8217;inizio né alla fine. Inoltre deve essere presente almeno un punto.</p>
<h2>Il pattern per un indirizzo email</h2>
<p><!--adv300--></p>
<p>Ora che sappiamo la struttura di un indirizzo email possiamo definire precisamente il pattern che verrà confrontato all&#8217;indirizzo email da controllare.</p>
<p>Definiamo un pattern per indirizzi email semplici che contengano sono lettere, numeri, punti &#8220;.&#8221;, underscore &#8220;_&#8221; e trattini &#8220;-&#8221;. In seguito vedremo come modificare i pattern in modo da accettare anche i caratteri speciali.</p>
<h3>Pattern per la &#8220;local part&#8221;</h3>
<p><img class="aligncenter size-full wp-image-477" title="Pattern per la local part" src="http://jblog.it/wp-content/uploads/2009/05/localpart_pattern2.png" alt="Pattern per la local part" width="487" height="128" />La <strong>prima parte</strong> impone che l&#8217;indirizzo <strong>inizi </strong>almeno con una lettera (maiuscola o minuscola) o con un numero. Vengono <strong>esclusi </strong>i caratteri con cui non può iniziare l&#8217;email.</p>
<p>La <strong>seconda parte</strong> è un po&#8217; più complicata:</p>
<ul>
<li>vengono definiti tutti i <strong>caratteri accettati</strong> dall&#8217;email</li>
<li>corrisponde a un punto seguito da a-z, A-Z, 0-9, &#8211; o 0</li>
<li>il codice &#8220;\.?&#8221; indica che i successivi caratteri possono (opzionalmente) essere preceduti da <strong>un solo punto</strong></li>
<li>la parte <code>[a-zA-Z0-9\-\_]</code> è seguita dal <strong>carattere +</strong> perché deve essere trovato un carattere del tipo a-z, A-Z, 0-9, &#8211; o 0 almeno una volta</li>
<li>viene racchiusa nelle <strong>parentesi tonde</strong> e seguita dal <strong>carattere *</strong> per impostare la condizione in base alla quale la seconda parte può essere presente facoltativamente</li>
</ul>
<h3>Pattern per il &#8220;domain name&#8221;</h3>
<p><img class="aligncenter size-full wp-image-479" title="Pattern per il domain name" src="http://jblog.it/wp-content/uploads/2009/05/domain_pattern1.png" alt="Pattern per il domain name" width="563" height="212" /></p>
<p>La <strong>prima parte</strong> impone che l&#8217;indirizzo <strong>inizi </strong>almeno con una lettera (maiuscola o minuscola) dell&#8217;alfabeto inglese. Vengono <strong>esclusi </strong>i caratteri con cui non può iniziare un nome di dominio.</p>
<p>Nella <strong>seconda parte</strong>, come per la &#8220;local part&#8221;:</p>
<ul>
<li>vengono definiti tutti i <strong>caratteri accettati</strong> dall&#8217;email</li>
<li>corrisponde a un punto seguito da a-z, A-Z, 0-9, &#8211; o 0</li>
<li>il codice &#8220;\.?&#8221; indica che i successivi caratteri possono (opzionalmente) essere preceduti da <strong>un solo punto</strong></li>
<li>la parte <code>[a-zA-Z0-9\-\_]</code> è seguita dal <strong>carattere +</strong> perché deve essere trovato un carattere del tipo a-z, A-Z, 0-9, &#8211; o 0 almeno una volta</li>
<li>viene racchiusa nelle <strong>parentesi tonde</strong> e seguita dal <strong>carattere *</strong> per impostare la condizione in base alla quale la seconda parte può essere presente facoltativamente</li>
</ul>
<p>La <strong>terza parte</strong> impone la presenza di un punto fra il nome del dominio e il codice del dominio di primo livello. In pratica, se il dominio è example.com, il punto di cui si impone la presenza è quello che si trova fra example e com.</p>
<p>L&#8217;<strong>ultima parte</strong> stabilisce il formato del codice del dominio di primo livello. Questo deve essere composto da <strong>almeno due caratteri</strong> e da sole lettere (del tipo a-z e A-Z) dell&#8217;alfabeto inglese.</p>
<h3>Lunghezza della &#8220;local part&#8221; e del &#8220;domain name&#8221;</h3>
<p>Purtroppo non è possibile imporre la lunghezza totale dei due segmenti (o almeno io non ci sono riuscito).</p>
<p>Scrivendo <code>(\.?[a-zA-Z0-9\-\_]){0,63}</code> la condizione <code>{0,63}</code> viene attribuita sia <code>\.</code> sia a <code>[a-zA-Z0-9\-\_]</code>. Quindi, l&#8217;indirizzo email risulterà troppo lungo se sia i punti sia i restanti caratteri corrispondenti a <code>[a-zA-Z0-9\-\_]</code> saranno più di 63. Ecco cosa succederebbe:</p>
<ul>
<li><code>punti&lt;=63, caratteri&lt;=63</code>: indirizzo ok</li>
<li><code>punti&gt;=63, caratteri&lt;=63</code>: indirizzo errato</li>
<li><span class="highlight_red"><code>punti&lt;=63, caratteri&gt;=63</code>: indirizzo ok<em> (non è ciò che vogliamo)</em></span></li>
<li><code>punti&gt;=63, caratteri&gt;=63</code>: indirizzo errato</li>
</ul>
<p>Il <strong>terzo caso</strong> non va bene a causa dei controlli sul numero dei caratteri. Infatti, se i caratteri sono più di 63 l&#8217;indirizzo email viene considerato corretto.</p>
<p>Ho fatto diverse prove ma ho sempre avuto esiti negativi. Come ho detto prima, probabilmente non ci sono riuscito io.</p>
<p><span class="highlight_green">Sono ben accetti suggerimenti e soluzioni alternative.</span></p>
<h4>La mia soluzione</h4>
<p>In seguito vedremo che per controllare se i due segmenti rispettano le dimensioni massime, rispettivamente 64 e 255, si possono scrivere un paio di righe di codice per:</p>
<ul>
<li>dividere l&#8217;indirizzo email in due in corrispondenza della @</li>
<li>controllare la lunghezza di ciascuna stringa</li>
</ul>
<h3>Accettare i caratteri speciali</h3>
<p>Per fare in modo che la tua funzioni accetti alcuni o tutti i caratteri speciali basterà sostituire la stringa <code>[a-zA-Z0-9\-\_]</code> (presente nella &#8220;local part&#8221;) con la stringa <code>[a-zA-Z0-9\-\_</code><code>\!\#\$\%\&amp;\'\*\+\/\=\?\^\`\{\|\}\~</code><code>]</code>.</p>
<p>Se non vuoi accettare alcuni caratteri bisogna eliminare il carattere speciale e il &#8220;\&#8221; che lo precede.</p>
<h2>Codice Javascript</h2>
<pre lang="js">function isEmail(string)
{
	/* Confronta la stringa con il pattern RegEx */
	if(string.search(/^[a-zA-Z0-9]+(\.?[a-zA-Z0-9\-\_]+)*\@[a-zA-Z]+(\.?[a-zA-Z0-9\-\_]+)*\.[a-zA-Z]{2,}$/)==-1)
	return false;

	/* Divide l'indirizzo in due parti: "local part" e "domain name" */
	var parts = string.split("@");

	/* Controlla se "local part" supera i 64 caratteri */
	if(parts[0].length&gt;64) return false;

	/* Controlla se "local part" supera i 255 caratteri */
	if(parts[1].length&gt;255) return false;

	return true;
}</pre>
<h2>Codice PHP</h2>
<pre lang="php">function isEmail($string)
{
	/* Confronta la stringa con il pattern RegEx */
	if(!eregi("[a-zA-Z0-9]+(\.?[a-zA-Z0-9\-\_]+)*\@[a-zA-Z]+(\.?[a-zA-Z0-9\-\_]+)*\.[a-zA-Z]{2,}$",$string))
	return false;

	/* Divide l'indirizzo in due parti: "local part" e "domain name" */
	$parts = explode("@",$string);

	/* Controlla se "local part" supera i 64 caratteri */
	if(strlen($parts[0])&gt;64) return false;

	/* Controlla se "local part" supera i 255 caratteri */
	if(strlen($parts[1])&gt;255) return false;

	return true;
}</pre>
<h2>Demo e download</h2>
<p>Per vedere lo script vai su <a href="http://test.jblog.it/email_checker/email_checker.txt" target="_blank">http://test.jblog.it/email_checker/email_checker.txt</a></p>
<p>Per vedere una demo vai su <a href="http://test.jblog.it/email_checker/" target="_blank">http://test.jblog.it/email_checker/</a></p>
<p>Per scaricare l’esempio vai su <a href="http://download.jblog.it/email_checker.zip" target="_blank">http://download.jblog.it/email_checker.zip</a></p>
<h2>Conclusione</h2>
<p>Le espressioni regolari sono un potente strumento, ma <strong>fanno lavorare la cpu</strong>.</p>
<p>Quindi, ti consiglio di utilizzare le espressioni regolari solo quando la stringa da controllare ha un <strong>formato complesso</strong> come, appunto, un indirizzo email o un numero di telefono. Se invece devi verificare che contenga solo caratteri numerici è meglio ricorrere a funzioni che controllano carattere per carattere.</p>
<p>Per quanto riguarda le funzioni email, personalmente le ritengo buone ma non le migliori. Le ho provate e sembrano funzionare adeguatamente. Per qualsiasi errore o malfunzionamento io sono qui&#8230; <span class="highlight_green">Sono graditi consigli, critiche e opinioni in genere.</span></p>
<h2>Crediti</h2>
<p><a title="Wikipedia" href="http://en.wikipedia.org/" target="_blank">Wikipedia (english)</a> &#8211; <a title="E-mail address" href="http://en.wikipedia.org/wiki/E-mail_address" target="_blank">E-mail address</a></p>
<p>Foto1 &#8211; <a href="#"><span style="text-decoration: line-through;">Formatear cadenas de Texto/String como númericas con o sin decimales – Regex – Expresiones Regulares</span></a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=468&type=feed" alt=" Controllare il formato di un indirizzo email con le espressioni regolari (RegEx) in PHP e Javascript"  title="Controllare il formato di un indirizzo email con le espressioni regolari (RegEx) in PHP e Javascript" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/05/20/controllare-formato-indirizzo-email-espressioni-regolari-regex-php-javascript_468.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css</title>
		<link>http://jblog.it/2009/05/15/ridurre-richieste-http-parte-2-come-combinare-immagini-script-css-sprite-image-maps_405.html</link>
		<comments>http://jblog.it/2009/05/15/ridurre-richieste-http-parte-2-come-combinare-immagini-script-css-sprite-image-maps_405.html#comments</comments>
		<pubDate>Fri, 15 May 2009 15:04:06 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Css]]></category>
		<category><![CDATA[Grafica]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Ottimizzazione]]></category>
		<category><![CDATA[Web design]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[classe php]]></category>
		<category><![CDATA[data:URL]]></category>
		<category><![CDATA[ottimizzare]]></category>
		<category><![CDATA[richieste http]]></category>
		<category><![CDATA[sprite css]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=405</guid>
		<description><![CDATA[Dopo il precedente articolo su come utilizzare la cache del browser passiamo ad azioni più concrete per ridurre le richieste http: minimizzare il numero di componenti di una pagina. Dico &#8220;concrete&#8221; perché, mentre i comportamenti e le tecniche relative alla cache possono avere effetti diversi a seconda del browser e delle sue impostazioni, diminuire i [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css" href="http://jblog.it/2009/05/15/ridurre-richieste-http-parte-2-come-combinare-immagini-script-css-sprite-image-maps_405.html" target="_blank"><img class="alignright size-full wp-image-438" title="Ghepardo in corsa" src="http://jblog.it/wp-content/uploads/2009/05/2913134974_6d1839b33b.jpg" alt="2913134974 6d1839b33b Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css" width="300" height="154" /></a>Dopo il precedente articolo su <a title="Ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser" rel="bookmark" href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html">come utilizzare la cache del browser</a> passiamo ad <strong>azioni più <em>concrete</em></strong><em> </em>per ridurre le richieste http: <strong>minimizzare il numero di componenti di una pagina</strong>. Dico &#8220;concrete&#8221; perché, mentre i comportamenti e le tecniche relative alla cache possono avere effetti diversi a seconda del browser e delle sue impostazioni, diminuire i componenti di una pagina è qualcosa che <strong>dipende esclusivamente dal webmaster</strong>, con risultati e prestazioni prevedibili.</p>
<h4>Gestire la cache è fatica sprecata?</h4>
<p><strong>Assolutamente no!</strong> Il fatto è che ogni utente che accede al sito la prima volta deve comunque attendere il caricamento completo della pagina e dei suoi componenti, che vengono subito memorizzati in cache. Il miglioramento di prestazioni si verifica a partire dalla seconda pagina che viene visitata in quanto i componenti vengono letti dalla cache, evitando di effettuare nuove (e inutili) richieste http.</p>
<h4>Vantaggi immediati</h4>
<p>Diminuire i componenti di una pagina consente di avere un notevole aumento delle prestazioni che <strong>migliora l&#8217;esperienza tutti gli utenti</strong>, vecchi e nuovi, dalla prima all&#8217;ultima pagina.</p>
<p><span class="highlight_yellow"><strong>In questo articolo</strong> vedremo alcune tecniche che <strong>riducono drasticamente</strong> il numero e il tempo di caricamento relativo a immagini, script e css. Queste tecniche non fanno altro che <strong>combinare questi componenti</strong> in modo da caricarne pochi ma più pesanti anziché molti ma leggeri. Parleremo di image maps, sprite css, dello schema data:URL, di generatori di sprite css, di come combinare automaticamente javascript e css, vedremo che a volte è meglio inserire il codice direttamente nella pagina html, e come è possibile evitare gli script duplicati.</span><span id="more-405"></span></p>
<h2>Pochi ma buoni</h2>
<p><!--adv300--></p>
<p><img class="alignright size-full wp-image-439" title="Olimpiadi Pechino - Ciclismo" src="http://jblog.it/wp-content/uploads/2009/05/cic02.jpg" alt="Olimpiadi Pechino - Ciclismo" width="270" height="180" />A primo impatto potrebbe sembrare un&#8217;assurdità affermare che &#8220;è meglio caricare un file da 300 kbyte anziché 10 file da 40kb&#8221;. Fortunatamente non lo è!</p>
<p>Infatti, se prendiamo 10 immagini e le copiamo all&#8217;interno di un solo file immagine, quest&#8217;ultimo file occuperà molto meno rispetto alla somma delle 10 immagini. <strong>Il motivo</strong> è che nei file vengono memorizzate tantissime informazioni oltre al contenuto che i software ci mostrano.</p>
<p><strong>Ad esempio</strong>, se apriamo una fotografia quello che vediamo è semplicemente un&#8217;immagine. Tuttavia, quel file contiene anche una serie di informazioni come: modello fotocamera, altezza, larghezza, risoluzione, ecc.</p>
<p>Caricare una sola immagine (ed un set di informazioni) è meglio che caricare dieci immagini (e dieci set di informazioni) perché:</p>
<ul>
<li>la dimensione del file più grosso è minore della somma di tanti file più piccoli</li>
<li>tante richieste http si riducono a una sola</li>
</ul>
<p>Mentre sulla riduzione delle richieste http possiamo essere d&#8217;accordo, credo che tu abbia qualche dubbio sul fatto che diminuisca la dimensione del file più grande. Bene, fai questo<strong> semplice esperimento</strong>:</p>
<ul>
<li>prendi un&#8217;immagine e fanne 10 copie</li>
<li>crea un&#8217;immagine grande abbastanza da contenere perfettamente 10 immagini uguali</li>
<li>confronta la dimensione dei 10 file immagine con quella del file immagine più grande</li>
</ul>
<h4>I componenti incriminati</h4>
<p>Generalmente si focalizza l&#8217;attenzione su immagini, javascript e css perché sono presenti in tutte le pagine e, se mal gestiti, non solo provocano un eccessivo numero di richieste http ma rallentano il normale caricamento delle pagine.</p>
<h2>Combinare le immagini: &#8220;image maps&#8221;</h2>
<p><img class="alignright size-full wp-image-440" title="Puzzle di gatti" src="http://jblog.it/wp-content/uploads/2009/05/312855876_abbdbcf21b.jpg" alt="Puzzle di gatti" width="270" height="162" />Se vogliamo inserire due immagini affiancate basta combinarle in un unico file immagine e inserire quest&#8217;ultimo all&#8217;interno della pagina.</p>
<p>I problemi nascono nel momento in cui, ad esempio, vogliamo applicare un diverso link a ciascuna immagine. Infatti, essendo un&#8217;unica immagine, non possiamo racchiuderla all&#8217;interno di un tag &lt;a&gt;, ma dobbiamo <strong>&#8220;mappare&#8221; le immagini</strong>.</p>
<p>Prima di illustrare i tre metodi è necessario descrivere gli <strong>strumenti a nostra disposizione</strong>.</p>
<h4>Il tag &lt;area&gt;</h4>
<p>Serve per creare le singole aree, cliccabili o meno, dell&#8217;immagine. Non richiede il tag di chiusura completo (&lt;/area&gt;).</p>
<p><strong>Formato</strong>. <code>&lt;area shape="..." coords="..." href="http://example.com/link1.html"&gt;</code></p>
<p><span class="highlight_green">Per creare<strong> documenti più accessibili</strong>, si può utilizzare il tag &lt;a&gt;&#8230;&lt;/a&gt; con gli stessi attributi di &lt;area&gt;. Infatti, grazie al tag &lt;a&gt; si può specificare un testo alternativo per l&#8217;area.</span></p>
<p><strong>Formato</strong>. <code>&lt;a </code><code>href="http://example.com/link1.html" </code><code>shape="..." coords="..." /&gt;Area1&lt;/a&gt;<br />
</code></p>
<p><strong>shape</strong>: (default, rect, circle, poly), cioè (default, rettangolo, cerchio, poligono). Specifica la forma di una regione.</p>
<p><strong>coords</strong>: coordinate. Specificano la posizione e la sagoma. Il numero e l&#8217;ordine dei valori dipendono dalla forma specificata da <em>shape</em>.</p>
<ul>
<li><em>rect</em>: left-x, top-y, right-x, bottom-y. I vertici opposti del rettangolo.</li>
<li><em>circle</em>: center-x, center-y, radius. Coordinate del centro e lunghezza del raggio.</li>
<li><em>poly</em>: x1, y1, x2, y2, &#8230;, xN, yN. Coordinate di tutti i vertici del poligono.</li>
</ul>
<p><strong>href</strong>: link associato alla regione.</p>
<p><strong>nohref</strong>: impostare con true per specificare che la regione non ha link associati, altrimenti non impostare.</p>
<h4>Il tag &lt;map&gt;</h4>
<p>Specifica una mappa da far richiamare da un oggetto. È richiesto il tag di chiusura &lt;/map&gt;.</p>
<p>All&#8217;interno dei tag &lt;map&gt;&#8230;&lt;/map&gt; si inseriscono tutte le aree relative alla mappa.</p>
<p><strong>name</strong>. Assegna un nome alla mappa.</p>
<h4>Associare una mappa a un elemento</h4>
<p>Utilizzare l&#8217;attributo <strong>usemap</strong> fra gli attributi dell&#8217;elemento, specificando un URI.</p>
<p>Ricorda che un URI può essere un indirizzo del tipo http://www.example&#8230; o un id del tipo #nome-mappa.</p>
<p><strong>Formato</strong>. <code>&lt;img src="foto.jpg" alt="La mia foto" usemap="mappafoto" /&gt;</code></p>
<h3>Image maps lato client</h3>
<p>La presenza di usemap <strong>implica che l&#8217;oggetto sia un immagine</strong>. Se non lo è, i browser potrebbero comunque implementare un&#8217;interazione con l&#8217;utente simile a quella per le immagini. Purtroppo <strong>non tutti i browser</strong> eseguono correttamente la mappatura di un immagine o di un oggetto.</p>
<p>Un blocco &lt;map&gt; può contenere sia elementi &lt;area&gt; sia elementi a livello di blocco come &lt;a&gt; per aumentare la compatibilità con i browser più datati.</p>
<h4>Alcune osservazioni</h4>
<ol>
<li>Se sono presenti contemporaneamente &lt;a&gt; ed &lt;area&gt;, i browser recenti ignorano il tag &lt;area&gt;</li>
<li>Se due o più regioni si sovrappongono, la prima regione avrà la precedenza sulle altre</li>
<li>L&#8217;elemento &lt;map&gt; non è compatibile con i browser HTML 2.0</li>
</ol>
<h4>Demo e download</h4>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/imagemap_cs/" target="_blank">http://test.jblog.it/imagemap_cs/</a></p>
<p>In quest&#8217;altro esempio le aree sono rettangolari, circolari e poligonali. <a href="http://test.jblog.it/imagemap_cs2/" target="_blank">http://test.jblog.it/imagemap_cs2/</a></p>
<p>Per scaricare entrambi gli esempi vai a <a href="http://download.jblog.it/imagemap_cs_cs2.zip" target="_blank">http://download.jblog.it/imagemap_cs_cs2.zip</a></p>
<h4>Esempio 1</h4>
<p>Classico esempio con &lt;map&gt; all&#8217;interno dell&#8217;oggetto, ed i tag &lt;a&gt; all&#8217;interno di &lt;map&gt;.</p>
<pre lang="html">&lt;HTML&gt;
	&lt;HEAD&gt;&lt;TITLE&gt;The cool site!&lt;/TITLE&gt;&lt;/HEAD&gt;
	&lt;BODY&gt;
	&lt;P&gt;&lt;OBJECT data="navbar1.gif" type="image/gif" usemap="#map1"&gt;
		&lt;MAP name="map1"&gt;
			Navigate the site:
			&lt;A href="guide.html" shape="rect" coords="0,0,118,28"&gt;Access Guide&lt;/a&gt; |
			&lt;A href="shortcut.html" shape="rect" coords="118,0,184,28"&gt;Go&lt;/A&gt; |
			&lt;A href="search.html" shape="circle" coords="184,200,60"&gt;Search&lt;/A&gt; |
			&lt;A href="top10.html" shape="poly" coords="276,0,276,28,100,200,50,50,276,0"&gt;Top Ten&lt;/A&gt;
		&lt;/MAP&gt;
	&lt;/OBJECT&gt;&lt;/P&gt;
	&lt;/BODY&gt;
&lt;/HTML&gt;</pre>
<h4>Esempio 2</h4>
<p>Come utilizzare la mappa richiamandola con usemap, senza inglobarla all&#8217;interno dei tag &lt;object&gt;.</p>
<pre lang="html">&lt;HTML&gt;
	&lt;HEAD&gt;&lt;TITLE&gt;The cool site!&lt;/TITLE&gt;&lt;/HEAD&gt;
	&lt;BODY&gt;
	&lt;P&gt;&lt;OBJECT data="navbar1.gif" type="image/gif" usemap="#map1"&gt;&lt;/OBJECT&gt;&lt;/P&gt;
	&lt;MAP name="map1"&gt;
		Navigate the site:
		&lt;A href="guide.html" shape="rect" coords="0,0,118,28"&gt;Access Guide&lt;/a&gt; |
		&lt;A href="shortcut.html" shape="rect" coords="118,0,184,28"&gt;Go&lt;/A&gt; |
		&lt;A href="search.html" shape="circle" coords="184,200,60"&gt;Search&lt;/A&gt; |
		&lt;A href="top10.html" shape="poly" coords="276,0,276,28,100,200,50,50,276,0"&gt;Top Ten&lt;/A&gt;
	&lt;/MAP&gt;
&lt;/HTML&gt;</pre>
<h4>Esempio 3</h4>
<p>Utilizzo degli elementi &lt;area&gt;.</p>
<pre lang="html">&lt;HTML&gt;
	&lt;HEAD&gt;&lt;TITLE&gt;The cool site!&lt;/TITLE&gt;&lt;/HEAD&gt;
	&lt;BODY&gt;
	&lt;P&gt;&lt;OBJECT data="navbar1.gif" type="image/gif" usemap="#map1"&gt;&lt;/OBJECT&gt;&lt;/P&gt;
	&lt;MAP name="map1"&gt;
		Navigate the site:
		&lt;AREA href="guide.html" alt="Access Guide" shape="rect" coords="0,0,118,28"&gt;
		&lt;AREA href="search.html" alt="Search" shape="rect" coords="184,0,276,28"&gt;
		&lt;AREA href="shortcut.html" alt="Go" shape="circle" coords="184,200,60"&gt;
		&lt;AREA href="top10.html" alt="Top Ten" shape="poly" coords="276,0,276,28,100,200,50,50,276,0"&gt;
	&lt;/MAP&gt;
&lt;/HTML&gt;</pre>
<h4>Esempio 4</h4>
<p>Questo è un utilizzo concreto della condivisione di una mappa fra più immagini. Questo codice carica l&#8217;immagine più interna (navbar1.gif) se l&#8217;immagine esterna (navbar1.png) non viene processata correttamente dal browser. Ad entrambe le immagini viene associata la stessa mappa.</p>
<pre lang="html">&lt;HTML&gt;
	&lt;HEAD&gt;&lt;TITLE&gt;The cool site!&lt;/TITLE&gt;&lt;/HEAD&gt;
	&lt;BODY&gt;
	&lt;P&gt;&lt;OBJECT data="navbar1.png" type="image/png" usemap="#map1"&gt;
		&lt;OBJECT data="navbar1.gif" type="image/gif" usemap="#map1"&gt;&lt;/OBJECT&gt;
	&lt;/OBJECT&gt;&lt;/P&gt;
	&lt;MAP name="map1"&gt;
		Navigate the site:
		&lt;A href="guide.html" shape="rect" coords="0,0,118,28"&gt;Access Guide&lt;/a&gt; |
		&lt;A href="shortcut.html" shape="rect" coords="118,0,184,28"&gt;Go&lt;/A&gt; |
		&lt;A href="search.html" shape="circle" coords="184,200,60"&gt;Search&lt;/A&gt; |
		&lt;A href="top10.html" shape="poly" coords="276,0,276,28,100,200,50,50,276,0"&gt;Top Ten&lt;/A&gt;
	&lt;/MAP&gt;
&lt;/HTML&gt;</pre>
<h4>Esempio 5</h4>
<p>Utilizzo combinato di &lt;area&gt; e &lt;a&gt; per avere una maggiore compatibilità. I browser più recenti non considerano gli elementi &lt;area&gt;.</p>
<pre lang="html">&lt;HTML&gt;
	&lt;HEAD&gt;&lt;TITLE&gt;The cool site!&lt;/TITLE&gt;&lt;/HEAD&gt;
	&lt;BODY&gt;
	&lt;P&gt;&lt;OBJECT data="navbar1.gif" type="image/gif" usemap="#map1"&gt;&lt;/OBJECT&gt;&lt;/P&gt;
	&lt;MAP name="map1"&gt;
		Navigate the site:
		&lt;AREA href="guide.html" alt="Access Guide" shape="rect" coords="0,0,118,28"&gt;
		&lt;AREA href="search.html" alt="Search" shape="rect" coords="184,0,276,28"&gt;
		&lt;AREA href="shortcut.html" alt="Go" shape="circle" coords="184,200,60"&gt;
		&lt;AREA href="top10.html" alt="Top Ten" shape="poly" coords="276,0,276,28,100,200,50,50,276,0"&gt;
		&lt;A href="guide.html" shape="rect" coords="0,0,118,28"&gt;Access Guide&lt;/a&gt; |
		&lt;A href="shortcut.html" shape="rect" coords="118,0,184,28"&gt;Go&lt;/A&gt; |
		&lt;A href="search.html" shape="circle" coords="184,200,60"&gt;Search&lt;/A&gt; |
		&lt;A href="top10.html" shape="poly" coords="276,0,276,28,100,200,50,50,276,0"&gt;Top Ten&lt;/A&gt;
	&lt;/MAP&gt;
&lt;/HTML&gt;</pre>
<h4>Esempio 6</h4>
<p>Come sovrapporre due aree. Da notare l&#8217;ultima coordinata specificata, il raggio). I due cerchi hanno lo stesso centro, ma il primo ha un raggio minore del secondo.</p>
<p>Il risultato è che posizionandosi sul primo (che non ha link) non appare la &#8220;manina&#8221;. Spostandosi leggermente fuori dal primo ci si posiziona sul secondo (che ha un link) ed appare la &#8220;manina&#8221;. In pratica, l&#8217;area specificata prima ha la <strong>precedenza</strong> sulle altre che sovrascrive.</p>
<pre lang="html">&lt;MAP name="map1"&gt;
	&lt;A shape="circle" coords="100,200,50"&gt;Non ho link&lt;/A&gt;
	&lt;A href="outer-ring-link.html" shape="circle" coords="100,200,250"&gt;Ho un link&lt;/A&gt;
&lt;/MAP&gt;</pre>
<h3>Image maps lato server</h3>
<p>A volte la mappatura delle immagini può essere <strong>troppo complicata</strong> da scrivere come html.</p>
<p>In questi casi è meglio ricorrere a tecniche lato server.</p>
<p>Partiamo dal <strong>codice html</strong>. Da notare l&#8217;attributo <strong>ismap</strong>.</p>
<pre lang="html">&lt;HTML&gt;
	&lt;HEAD&gt;&lt;TITLE&gt;The cool site!&lt;/TITLE&gt;&lt;/HEAD&gt;
	&lt;BODY&gt;
	&lt;A href="map_script.php"&gt;
		&lt;IMG src="navbar1.png" alt="Navigazione" ismap /&gt;
	&lt;/A&gt;
&lt;/HTML&gt;</pre>
<p><strong>Come funziona?</strong> Quando ci si posiziona sull&#8217;immagine, il browser aggiunge all&#8217;url di &lt;a&gt;, quindi a map_script.php, le due coordinate. Ad esempio, se ci posizioniamo sul pixel di coordinate (18,46), il link del tag &lt;a&gt; verrà<strong> trasformato automaticamente</strong> da map_script.php a map_script.php?18,46.</p>
<p>Lo <strong>script lato server</strong> ha il compito di leggere i <strong>due parametri $_GET</strong> relativi alle coordinate e comportarsi a seconda dei valori letti.</p>
<pre lang="php">&lt;?php
/* $_GET array associativo. Ottiene le chiavi dell'array. */
$keys = array_keys($_GET);

/* Prende la prima chiave, la divide e inserisce i due valori in $x e $y */
list($x,$y) = explode(",",$keys[0]);

/* Comportamenti */
if(($x&gt;=0 &amp;&amp; $x&lt;=118) &amp;&amp; ($y&gt;=0 &amp;&amp; $y&lt;=28))	 include("guide.html");
elseif(($x&gt;118 &amp;&amp; $x&lt;=184) &amp;&amp; ($y&gt;=0 &amp;&amp; $y&lt;=28)) include("shortcut.html");
elseif( ($x&gt;=(184-30) &amp;&amp; $x&lt;=(184+30)) &amp;&amp; ($y&gt;=(200-30) &amp;&amp; $y&lt;=(200+30)) ) include("search.html");
elseif(($x&gt;220 &amp;&amp; $x&lt;=280) &amp;&amp; ($y&gt;=30 &amp;&amp; $y&lt;=54)) include("top10.html");
?&gt;</pre>
<p>Nel codice dell&#8217;esempio 1, l&#8217;area relatva a <strong>top10.html</strong> è un poligono. Non è semplice controllare se un punto è presente in un poligono. Bisogna trovare e utilizzare appositi algoritmi e funzioni. Potresti trovarli su <a title="Geometry Algorithms" href="http://www.geometryalgorithms.com/" target="_blank">geometryalgorithms.com</a> (che nel momento in cui scrivo è &#8220;temporaneamente sospeso&#8221;).</p>
<h4>Script, demo e download</h4>
<p>Per vedere e scaricare lo script vai a <a href="http://test.jblog.it/imagemap_ss/map_script.txt" target="_blank">http://test.jblog.it/imagemap_ss/map_script.txt</a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/imagemap_ss/" target="_blank">http://test.jblog.it/imagemap_ss/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/imagemap_ss.zip" target="_blank">http://download.jblog.it/imagemap_ss.zip</a></p>
<h3>Image maps lato client e lato server</h3>
<p>Per avere la compatibilità con i vecchi browser è bene combinare le due tecniche.</p>
<pre lang="html">&lt;HTML&gt;
	&lt;HEAD&gt;&lt;TITLE&gt;The cool site!&lt;/TITLE&gt;&lt;/HEAD&gt;
	&lt;BODY&gt;
	&lt;A href="map_script.php"&gt;
		&lt;IMG src="navbar1.gif" alt="Navigazione" usemap="#map1" ismap /&gt;
	&lt;/A&gt;
	&lt;MAP name="map1"&gt;
		Navigate the site:
		&lt;A href="guide.html" shape="rect" coords="0,0,118,28"&gt;Access Guide&lt;/a&gt; |
		&lt;A href="shortcut.html" shape="rect" coords="118,0,184,28"&gt;Go&lt;/A&gt; |
		&lt;A href="search.html" shape="circle" coords="184,200,60"&gt;Search&lt;/A&gt; |
		&lt;A href="top10.html" shape="poly" coords="276,0,276,28,100,200,50,50,276,0"&gt;Top Ten&lt;/A&gt;
	&lt;/MAP&gt;
	&lt;/BODY&gt;
&lt;/HTML&gt;</pre>
<h3>Il testo alternativo</h3>
<p>I tag &lt;a&gt; con il testo all&#8217;interno si utilizzano per avere un testo alternativo nel caso in cui l&#8217;immagine non venga caricata.</p>
<p>Naturalmente questo comportamento non è gestito dal browser, infatti il testo dei link appare sempre.</p>
<p><strong>Per nasconderlo</strong> è necessario operare con i css. Consiglio anche di guardare le tecniche di &#8220;image replacement&#8221;.</p>
<h4>Script, demo e download</h4>
<p>Per vedere lo script vai a <a href="http://test.jblog.it/imagemap_css/map_script.txt" target="_blank">http://test.jblog.it/imagemap_css/map_script.txt</a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/imagemap_css/" target="_blank">http://test.jblog.it/imagemap_css/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/imagemap_css.zip" target="_blank">http://download.jblog.it/imagemap_css.zip</a></p>
<h2>Lo schema data:URL</h2>
<p>Questa tecnica permette di <strong>inserire i dati direttamente nel codice html</strong>, risparmiando quindi la relativa richiesta http.</p>
<p>Scopriamo le carte e vediamo subito un <strong>esempio</strong>.</p>
<pre lang="html">&lt;IMG ALT="Foto" SRC="data:image/gif; base64,
	R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwhhx4dbgYKAAA7B72VFgl2Tf7452
	AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
	ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
	a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
	ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
	F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH" /&gt;</pre>
<p>Dopo la paura iniziale, in genere ci si domanda: <strong>cosa sono quei caratteri e come faccio a inserirli?</strong></p>
<p>Quell&#8217;ammasso di caratteri è la <strong>codifica in base64</strong> dell&#8217;immagine. In pratica, è il contenuto del file immagine codificato in base64.</p>
<p>Per<strong> codificare un&#8217;immagine in base64</strong> si utilizza una semplice <strong>funzione php</strong>: <em>base64_encode</em>.</p>
<p>L&#8217;ultima questione riguarda il tipo <strong>MIME</strong> che si può ottenere in due modi:</p>
<ul>
<li>utilizzando la funzione <strong>mime_content_type</strong>. Deve essere abilitata l&#8217;<strong>estensione php_mime_magic.dll</strong>.</li>
<li>leggendo le informazioni su un file grazie le funzioni <a title="File Information" href="http://it2.php.net/manual/en/book.fileinfo.php"><strong>File Information</strong></a> di php. Era un&#8217;estensione PECL, ma ora non lo è più. Bisogna utilizzare la <strong>libreria esterna magic_open</strong></li>
</ul>
<p>Nel caso non si possano utilizzare queste funzioni si dovrà <strong>scrivere manualmente</strong>.</p>
<h4>Come inserire un&#8217;immagine in base64 (senza funzioni per il tipo MIME)</h4>
<pre>&lt;img src="data:image/jpeg;base64,&lt;?
echo base64_encode(file_get_contents("img.jpg")); ?&gt;" alt="Immagine" /&gt;</pre>
<h4>Come inserire un&#8217;immagine in base64 (con funzioni per il tipo MIME)</h4>
<pre>&lt;? $mime = mime_content_type("img.jpg"); ?&gt;
&lt;img src="data:&lt;? echo $mime; ?&gt;;base64,&lt;?
echo base64_encode(file_get_contents("img.jpg")); ?&gt;" alt="Immagine" /&gt;</pre>
<h4>Script, demo e download</h4>
<p>Per vedere lo script vai a <a href="http://test.jblog.it/img_base64/index.txt" target="_blank">http://test.jblog.it/img_base64/index.txt</a><a href="http://test.jblog.it/imagemap_css/map_script.txt" target="_blank"></a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/img_base64/" target="_blank">http://test.jblog.it/img_base64/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/img_base64.zip" target="_blank">http://download.jblog.it/img_base64.zip</a></p>
<h2>Gli sprite CSS</h2>
<p><img class="alignright size-full wp-image-453" title="Icone per webdesigner" src="http://jblog.it/wp-content/uploads/2009/05/developpers_icons_preview2.jpg" alt="Icone per webdesigner" width="282" height="140" />Partiamo dalla situazione più comune. Supponiamo di voler realizzare un menù composto da 5 pulsanti grafici che cambino colore quando si passa sopra col mouse. La cosa più logica sarebbe quella di creare 10 immagini: 5 per il pulsante in modalita &#8220;normale&#8221;, 5 per il pulsante in modalità &#8220;mouse sopra&#8221;.</p>
<p>Poiché caricare 10 immagini significa effettuare <strong>10 richieste http</strong>, utilizziamo la tecnica degli sprite CSS.</p>
<p><strong>Questa tecnica</strong> consiste nel:</p>
<ul>
<li>creare un file immagine abbastanza grande da contenere tutte e 10 le immagini del menù (come ho detto all&#8217;inizio dell&#8217;articolo, è meglio un&#8217;immagine grande anziché tante piccole immagini)</li>
<li>impostare questa immagine come sfondo agli elementi del menù (cioè &lt;a&gt;, &lt;li&gt;, &lt;div&gt;, ecc.)</li>
<li>per ogni elemento impostare la proprietà <strong>background-position</strong> per spostare lo sfondo all&#8217;interno dell&#8217;elemento in modo da avere l&#8217;immagine desiderata</li>
</ul>
<p>Gli <strong>utilizzi </strong>di questa tecnica sono infiniti: dal menù al singolo rollover, dalla serie di immagini allineate al contenitore con gli angoli arrotondati.</p>
<p><strong>VANTAGGI</strong></p>
<ul>
<li>riduce notevolmente le <strong>richieste http</strong> e migliora il caricamento delle pagine</li>
<li>elimina del tutto i <strong>ritardi </strong>relativi ai rollover poiché non viene caricata una nuova immagine ma viene spostato lo sfondo</li>
</ul>
<p><strong>SVANTAGGI</strong></p>
<ul>
<li>richiede un po&#8217; più di <strong>lavoro </strong>nell&#8217;impostazione dei css e nella creazione delle immagini</li>
<li>non è sempre possibile combinare in una sola immagine tutte le immagini del sito, a causa delle difficoltà che si incontrano nel <strong>posizionamento dello sfondo</strong> con le regole dei css</li>
</ul>
<h4>Esempio 1</h4>
<p>Inserire le immagini con il <strong>tag &lt;img&gt;</strong>. Questo metodo è a dir poco geniale poiché permette di inserire le immagini come si è sempre fatto col vantaggio di ridurre le richieste http. In pratica viene impostato lo <strong>sfondo al tag &lt;img&gt;</strong>.</p>
<p>L&#8217;articolo completo è di <a title="CssGlobe" href="http://cssglobe.com/" target="_blank">CssGlobe</a>. Lo puoi trovare <a title="Creating easy and useful CSS Sprites" href="http://cssglobe.com/post/3028/creating-easy-and-useful-css-sprites" target="_blank">qui</a>.</p>
<p>Abbiamo bisogno di un&#8217;immagine gif trasparente 1px x 1px (spacer.gif), e l&#8217;immagine sprite (tuttelefoto.jpg).</p>
<p><img class="size-full wp-image-429 alignnone" title="tuttelefoto.jpg - Immagine utilizzata come sfondo degli elementi" src="http://jblog.it/wp-content/uploads/2009/05/tuttelefoto.jpg" alt="tuttelefoto Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css" width="210" height="140" /></p>
<p><em>tuttelefoto.jpg &#8211; L&#8217;immagine sprite che utilizzeremo</em></p>
<pre lang="html">&lt;html&gt;
&lt;head&gt;&lt;title&gt;Sprite CSS - Esempio 1&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
	&lt;img src="spacer.gif" id="foto1" alt="Foto1" /&gt;
	&lt;img src="spacer.gif" id="foto2" alt="Foto2" /&gt;
	&lt;img src="spacer.gif" id="foto3" alt="Foto3" /&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>L&#8217;immagine trasparente serve per far assumere al tag &lt;img&gt; il suo normale comportamento (ad es. in modo che quando selezioni l&#8217;immagine si colora l&#8217;area di &lt;img&gt;).</p>
<p><strong>Codice css</strong></p>
<pre lang="css">#foto1, #foto2, #foto3 { background:url(tuttelefoto.jpg) no-repeat; }
#foto1 { width:100px; height:50px; background-position:0px 0px; }
#foto2 { width:120px; height:90px; background-position:0px -50px; }
#foto3 { width:90px; height:130px; background-position:-120px 0px; }</pre>
<p><strong>Demo e download</strong></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/img_sprite1/" target="_blank">http://test.jblog.it/img_sprite1/</a><a href="http://test.jblog.it/img_base64/" target="_blank"></a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/img_sprite1.zip" target="_blank">http://download.jblog.it/img_sprite1.zip</a><a href="http://download.jblog.it/img_base64.zip" target="_blank"></a></p>
<h4>Esempio 2</h4>
<p>Un&#8217;altro modo per inserire delle immagini è impostarle come sfondo ad elementi flottanti.</p>
<p><img class="size-full wp-image-431 alignnone" title="spriteimg" src="http://jblog.it/wp-content/uploads/2009/05/spriteimg.png" alt="spriteimg Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css" width="150" height="80" /></p>
<p><em>spriteimg.png &#8211; L&#8217;immagine sprite che utilizzeremo</em></p>
<pre lang="html">&lt;html&gt;
&lt;head&gt;&lt;title&gt;Sprite CSS - Esempio 2&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
	&lt;a href="#" id="feedburner"&gt;&lt;/a&gt;
	&lt;a href="#" id="subscribe"&gt;&lt;/a&gt;
	&lt;a href="#" id="bookmarks"&gt;&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p><strong>Demo e download</strong></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/img_sprite2/" target="_blank">http://test.jblog.it/img_sprite2/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/img_sprite2.zip" target="_blank">http://download.jblog.it/img_sprite2.zip</a></p>
<p><strong>Codice css</strong></p>
<pre lang="css">#feedburner { margin-right:20px; background:url(spriteimg.png) no-repeat -5px -5px; float:left; width:91px; height:29px; }
#subscribe { margin-right:20px; background:url(spriteimg.png) no-repeat -5px -35px; float:left; width:127px; height:18px; }
#bookmarks { background:url(spriteimg.png) no-repeat -5px -55px; float:left; width:127px; height:18px; }</pre>
<h4>Esempio 3</h4>
<p>Gli sprite css sono ideali per sviluppare menù di navigazione.</p>
<p><img class="size-full wp-image-432 alignnone" title="spriteimg1" src="http://jblog.it/wp-content/uploads/2009/05/spriteimg1.png" alt="spriteimg1 Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css" width="700" height="60" /></p>
<p><em>spritemenu.png &#8211; L&#8217;immagine sprite che utilizzeremo</em></p>
<pre lang="html">&lt;html&gt;
&lt;head&gt;&lt;title&gt;Sprite CSS - Esempio 3&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
	&lt;ul id="navmenu"&gt;
		&lt;li id="nav_homepage"&gt;&lt;a href="#"&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li id="nav_informazioni"&gt;&lt;a href="#"&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li id="nav_catalogo"&gt;&lt;a href="#"&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li id="nav_indirizzi"&gt;&lt;a href="#"&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li id="nav_contact"&gt;&lt;a href="#"&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p><strong>Codice css</strong></p>
<pre lang="css">#navmenu ul { list-style:none; }
#navmenu li { float:left; list-style:none; }
#navmenu a { display:block; height:30px; width:135px; background:url(spritemenu.png) no-repeat;  }

#nav_homepage a:link, #nav_homepage a:visited { background-position:0px 0px; }
#nav_informazioni a:link, #nav_informazioni a:visited { background-position:-270px 0px; }
#nav_catalogo a:link, #nav_catalogo a:visited { background-position:-560px 0px; }
#nav_indirizzi a:link, #nav_indirizzi a:visited { background-position:-420px 0px; }
#nav_contact a:link, #nav_contact a:visited { background-position:-135px 0px; }

#nav_homepage a:hover, #nav_homepage a:focus, #nav_homepage a:active { background-position:0px -30px; }
#nav_informazioni a:hover, #nav_informazioni a:focus, #nav_informazioni a:active { background-position:-270px -30px; }
#nav_catalogo a:hover, #nav_catalogo a:focus, #nav_catalogo a:active { background-position:-560px -30px; }
#nav_indirizzi a:hover, #nav_indirizzi a:focus, #nav_indirizzi a:active { background-position:-420px -30px; }
#nav_contact a:hover, #nav_contact a:focus, #nav_contact a:active { background-position:-135px -30px; }</pre>
<p><strong>Demo e download</strong></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/img_sprite3/" target="_blank">http://test.jblog.it/img_sprite3/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/img_sprite3.zip" target="_blank">http://download.jblog.it/img_sprite3.zip</a></p>
<h2>Generatori di Sprite CSS</h2>
<p>I generatori di sprite css <strong>semplificano la creazione</strong> di un&#8217;immagine abbastanza grande da contenere tutte le immagini da utilizzare nel proprio sito. Questi, secondo me, sono i migliori.</p>
<p><strong>Generatore di Sprite CSS</strong><br />
<a href="http://spritegen.website-performance.org/" target="_blank">http://spritegen.website-performance.org/</a><br />
<a href="https://launchpad.net/css-sprite-generator" target="_blank">https://launchpad.net/css-sprite-generator</a> <em><strong>(codice sorgente)</strong></em></p>
<p><strong>CSS Sprites Generator</strong><br />
<a href="http://www.csssprites.com/" target="_blank">http://www.csssprites.com/</a></p>
<p><strong>CSS sprites for humanoid beings (and the like)</strong><br />
<a href="http://printf.ru/spritr/" target="_blank">http://printf.ru/spritr/</a></p>
<p><strong>SmartSprites (Alpha!)</strong><br />
<a href="http://smartsprites.osinski.name/" target="_blank">http://smartsprites.osinski.name/</a></p>
<h2>Combinare javascript e css</h2>
<p><img class="alignright size-full wp-image-445" title="Cubetti di legno" src="http://jblog.it/wp-content/uploads/2009/05/288478628_56ed41bc2c.jpg" alt="Cubetti di legno" width="270" height="405" />Spesso una pagina richiama <strong>più di uno script e più di un css</strong>. Per ridurre le richieste http relative ai css (o agli script) basta copiare il contenuto di tutti i file css (o script) in un unico file.</p>
<p>Il bello di questa tecnica è che, a differenza delle immagini, è quasi sempre possibile <strong>combinare tutti i file dello stesso tipo in un unico file</strong>. Il &#8220;quasi&#8221; è dovuto al fatto che alcuni script, se inseriti nello stesso file, potrebbero dare dei problemi. Quindi è sempre meglio testare il funzionamento dello script combinato. Se si verificano dei problemi, basta <strong>escludere dalla fusione</strong> i file &#8220;incompatibili&#8221;.</p>
<p>La combinazione degli script in un unico file può essere eseguita in due modi:</p>
<ul>
<li><strong>manualmente</strong>, cioé copiando il contenuto di ogni script all&#8217;interno di un file più grande</li>
<li><strong>dinamicamente</strong>, ricorrendo a semplici script lato server</li>
</ul>
<p>Gli <strong>script lato server</strong> che vedremo sono strutturati in <strong>5 fasi</strong>:</p>
<ul>
<li>lettura dei nomi dei file da includere passati come parametri $_GET</li>
<li>impostazione delle opzioni</li>
<li>inclusione effettiva dei file</li>
<li>stampa dei campi di intestazione con la funzione header() per la gestione della cache, il tipo mime, ETag</li>
<li>stampa del contenuto finale del file</li>
</ul>
<h3>Script php: combinare più file css</h3>
<p>La particolarità dello script relativo ai file css è che per ogni file da includere è necessario <strong>specificare l&#8217;attributo media</strong> (all, screen, print, ecc.), cioé quell&#8217;attributo che indica il tipo di dispositivo per cui deve valere quel file css. <strong>Non è necessario specificare l&#8217;estensione</strong> dei file poiché viene aggiunta automaticamente all&#8217;interno dello script.</p>
<p><strong>Attenzione.</strong> Non passare nomi di file contenenti il carattere &#8220;.&#8221; in quanto, nelle richieste $_GET, viene convertito automaticamente in &#8220;_&#8221;.</p>
<p><strong>Codice html</strong></p>
<pre lang="html">&lt;link rel="stylesheet" type="text/css"
href="combined.css?file1:all&amp;file2:screen&amp;file3:print" /&gt;</pre>
<p><strong>Impostare Apache</strong></p>
<p>Poiché lo script che ha l&#8217;estensione <strong>.css</strong> è necessario impostare il server Apache affinché processi il file combined.css come un file .php. Basterà aggiungere un paio di righe.</p>
<pre>&lt;FilesMatch "combined.css$"&gt;
	AddHandler application/x-httpd-php .css
&lt;/FilesMatch&gt;</pre>
<h4>Script, demo e download</h4>
<p>Per vedere lo script vai a <a href="http://test.jblog.it/combine_css/combine.txt" target="_blank">http://test.jblog.it/combine_css/combine.txt</a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/combine_css/combine.css?file1:all&amp;file2:screen&amp;file3:print" target="_blank">http://test.jblog.it/combine_css/combine.css?file1:all&amp;file2:screen&amp;file3:print</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/combine_css.zip" target="_blank">http://download.jblog.it/combine_css.zip</a></p>
<h3>Script php: combinare più file javascript</h3>
<p><strong>Non è necessario specificare l&#8217;estensione</strong> dei file poiché viene aggiunta automaticamente all&#8217;interno dello script.</p>
<p><strong>Attenzione.</strong> Non passare nomi di file contenenti il carattere &#8220;.&#8221; in quanto, nelle richieste $_GET, viene convertito automaticamente in &#8220;_&#8221;.</p>
<h4>Codice html</h4>
<pre lang="html">&lt;script type="application/javascript" src="combined.js?file1&amp;file2&amp;file3"&gt;&lt;/script&gt;</pre>
<h4>Impostare Apache</h4>
<p>Poiché lo script che ha l&#8217;estensione <strong>.js</strong> è necessario impostare il server Apache affinché processi il file combined.js come un file .php. Basterà aggiungere un paio di righe.</p>
<pre>&lt;FilesMatch "combined.js$"&gt;
	AddHandler application/x-httpd-php .js
&lt;/FilesMatch&gt;</pre>
<h4>Script, demo e download</h4>
<p>Per vedere lo script vai a <a href="http://test.jblog.it/combine_js/combine.txt" target="_blank">http://test.jblog.it/combine_js/combine.txt</a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/combine_js/combine.js?file1&amp;file2&amp;file3" target="_blank">http://test.jblog.it/combine_js/combine.js?file1&amp;file2&amp;file3</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/combine_js.zip" target="_blank">http://download.jblog.it/combine_js.zip</a></p>
<h2>Stampare javascript e css nel codice html</h2>
<p>Sappiamo che per utilizzare codice javascript o css ci sono 3 modi:</p>
<ol>
<li>stamparli direttamente nel codice html</li>
<li>dividerli su più file esterni (da richiamare)</li>
<li>stamparne alcuni e richiamare gli altri</li>
</ol>
<h4>Il terzo metodo</h4>
<p>Come succede in tante occasioni, la &#8220;via di mezzo&#8221; è da preferire. La successiva domanda è: <strong>su che criterio si scelgono</strong> i file da stampare nel codice html e quelli da richiamare esternamente?</p>
<p>Sinceramente, non saprei dirlo con precisione. Probabilmente esistono degli studi che potrebbero aiutarti in questo. Secondo me, il codice da stampare nel documento html è quello che presumibilmente <strong>potrebbe essere utilizzato prima</strong>. Ad esempio:</p>
<ul>
<li>per <strong>javascript</strong>, il codice e le funzioni che verranno eseguite nell&#8217;<strong>evento &#8220;onload&#8221; dell&#8217;oggetto &#8220;document&#8221;</strong></li>
<li>per i <strong>css</strong>, il codice che serve a formattare gli <strong>elementi principali della pagina</strong>, come html, layout, contenitori, ecc.</li>
</ul>
<h4>Come automatizzare il tutto</h4>
<p>Fortunatamente, questa tecnica si può automatizzare con un paio di righe di codice lato server (php).</p>
<pre lang="html">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Javascript e Css nella pagina&lt;/title&gt;

&lt;style type="text/css"&gt;
&lt;?
	/* Array dei file css */
	$css_array = array("file3.css","file2.css");
	foreach($css_array as $css)
	{
		if(file_exists($css))
		include($css);
		echo "\n\n";
	}
?&gt;
&lt;/style&gt;

&lt;script type="application/javascript"&gt;
//&lt;![CDATA[
&lt;?
	/* Array dei javascript */
	$js_array = array("file1.js","file3.js");
	foreach($js_array as $js)
	{
		if(file_exists($js))
		include($js);
		echo "\n\n";
	}
?&gt;
//]]&gt;
&lt;/script&gt;

&lt;!-- File css esterni --&gt;
&lt;link rel="stylesheet" type="text/css" href="file1.css" /&gt;

&lt;!-- File javascript esterni --&gt;
&lt;script type="application/javascript" src="file2.js"&gt;&lt;/script&gt;

&lt;/head&gt;
&lt;body&gt;
	&lt;h1&gt;Javascript e Css nella pagina&lt;/h1&gt;
	&lt;p&gt;Guarda il codice html&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<h4>Script, demo e download</h4>
<p>Per vedere lo script vai a <a href="http://test.jblog.it/inhtml/inhtml.txt" target="_blank">http://test.jblog.it/inhtml/inhtml.txt</a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/inhtml/" target="_blank">http://test.jblog.it/inhtml/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/inhtml.zip" target="_blank">http://download.jblog.it/inhtml.zip</a></p>
<h2>Eliminare gli script duplicati</h2>
<p><img class="alignright size-full wp-image-446" title="Do not duplicate" src="http://jblog.it/wp-content/uploads/2009/05/331357312_893ef9e791.jpg" alt="Do not duplicate" width="270" height="180" />Quando si gestiscono <strong>grandi progetti</strong> si rischia di stampare e richiamare gli stessi script.</p>
<p>Alcuni browser, come Firefox, evitano di effettuare una nuova richiesta http per un file che è stato già scaricato. Purtroppo Internet Explorer non lo fa. Allora è necessario trovare una soluzione che valga per tutti.</p>
<p>Una semplice soluzione consiste nel fare una <strong>funzione php </strong>che riceva il nome del file da linkare e si occupi di stampare i tag &lt;script&gt;. Per registrare gli script che vengono inseriti di volta in volta si utilizza un array in modo che la funzione, prima di inserire uno script, controlla se il nome dello script non è già presente nell&#8217;array.</p>
<p>Normalmente per inserire script e css si dovrebbe scrivere:</p>
<pre>&lt;link rel="stylesheet" type="text/css" href="print_style.css" media="print" /&gt;
&lt;script src="library.js" type="application/javascript"&gt;&lt;/script&gt;</pre>
<p><strong>Classe PHP: noDuplicate (per php 4 e php 5)<br />
</strong></p>
<p>Ti descrivo brevemente la classe &#8220;noDuplicate&#8221;.</p>
<p><strong>La struttura</strong></p>
<pre lang="php">class noDuplicate
{
	/* Array dei file javascript */
	var $js_array = array();

	/* Array dei file css */
	var $css_array = array();

	/* Stampa i file specificati. */
	function incScript() { ... }

	/* Privata: registra il file e stampa il link al file javascript */
	function __js($file) { ... }

	/* Privata: registra il file stampa il link al file css */
	function __css($file) { ... }
}</pre>
<p><strong>Creare l&#8217;oggetto</strong></p>
<pre lang="php">$noDuplicateObj = new noDuplicate();</pre>
<p><strong>La funzione incScript()</strong></p>
<ul>
<li>il primo argomento deve essere &#8220;js&#8221; o &#8220;css&#8221;</li>
<li>dal secondo argomento in poi accetta da uno a più file <strong>dello stesso tipo</strong></li>
<li>se si devono inserire file <strong>.css</strong> è necessario passarli nella forma [nomefile]:[media] (ad es. &#8220;style.css:print&#8221;). Se vengono passati nella forma normale (&#8220;style.css&#8221;,&#8221;file.css&#8221;) verrà automaticamente impostato &#8220;all&#8221; come media</li>
</ul>
<pre lang="php">// singolo file
$noDuplicate-&gt;incScript("css","file2.css:all");
$noDuplicate-&gt;incScript("js","file1.js");

// più di un file
$noDuplicate-&gt;incScript("css","file2.css:all","mystyle.css:screen");
$noDuplicate-&gt;incScript("js","file1.js","jquery.js","prototype.js");

// file css senza specificare il "media"
$noDuplicate-&gt;incScript("css","file1.css","file3.css");<strong>
</strong></pre>
<p><strong>Risultato</strong></p>
<pre lang="html">&lt;!-- singolo file --&gt;
&lt;link rel="stylesheet" type="text/css" href="file2.css" media="all" /&gt;
&lt;script src="file1.js" type="application/javascript"&gt;&lt;/script&gt;

&lt;!-- più di un file --&gt;
&lt;link rel="stylesheet" type="text/css" href="file2.css" media="all" /&gt;
&lt;link rel="stylesheet" type="text/css" href="mystyle.css" media="screen" /&gt;
&lt;script src="file1.js" type="application/javascript"&gt;&lt;/script&gt;
&lt;script src="jquery.js" type="application/javascript"&gt;&lt;/script&gt;
&lt;script src="prototype.js" type="application/javascript"&gt;&lt;/script&gt;

&lt;!-- file css senza specificare il "media" --&gt;
&lt;link rel="stylesheet" type="text/css" href="file1.css" media="all" /&gt;
&lt;link rel="stylesheet" type="text/css" href="file3.css" media="all" /&gt;</pre>
<h4>Script, demo e download</h4>
<p>Per vedere lo script vai a <a href="http://test.jblog.it/rem_duplicate/rem_duplicate.txt" target="_blank">http://test.jblog.it/rem_duplicate/rem_duplicate.txt</a></p>
<p>Per vedere una demo vai a <a href="http://test.jblog.it/rem_duplicate/" target="_blank">http://test.jblog.it/rem_duplicate/</a></p>
<p>Per scaricare l&#8217;esempio vai a <a href="http://download.jblog.it/rem_duplicate.zip" target="_blank">http://download.jblog.it/rem_duplicate.zip</a></p>
<h2>Conclusione</h2>
<p>Queste tecniche esprimono la massima utilità e potenza se utilizzate contemporaneamente. La riduzione di richieste http e, quindi, l&#8217;abbassamento dei tempi di caricamento saranno notevoli.</p>
<p>Spero di essere stato abbastanza esaustivo e chiaro. Se non lo sono stato basterà dirmelo in modo da ritoccare l&#8217;articolo nelle sezioni meno comprensibili.</p>
<p><span class="hightlight_green">Hai mai utilizzato una di queste tecniche? Gli script hanno funzionato correttamente? È stato semplice metterle in pratica? Hai avuto concreti miglioramenti?</span></p>
<h3>Prossimo appuntamento</h3>
<p>L&#8217;ultima questione sull&#8217;ottimizzazione dei siti web riguarda appunto l&#8217;ottimizzazione dei componenti da caricare cioé:</p>
<ul>
<li>compressione delle immagini, degli script e dei css</li>
<li>offuscamento del codice javascript</li>
<li>utilizzo di gzip per la compressione delle pagine html, script e css</li>
</ul>
<h4 class="highlight_red">Non perdere il prossimo articolo sull&#8217;ottimizzazione dei componenti delle pagine web: codice html, immagini, script e css.</h4>
<h2>Crediti</h2>
<ul>
<li><strong>Libro</strong>. Creare siti web ad alte prestazioni di <a href="http://stevesouders.com" target="_blank">Steve Soulders</a></li>
<li><a href="http://www.websiteoptimization.com" target="_blank">WebSiteOptimization</a> &#8211; <a href="http://www.websiteoptimization.com/speed/tweak/combine/" target="_blank">Combine Images to Save HTTP Requests</a></li>
<li><a href="http://developer.yahoo.com/" target="_blank">Yahoo Developer Network</a> &#8211; <a href="http://developer.yahoo.com/performance/rules.html" target="_blank">Best Practices for Speeding Up Your Web Site</a></li>
<li><a href="http://www.w3.org">W3C</a> &#8211; <a href="http://www.w3.org/TR/html401/struct/objects.html#h-13.6" target="_blank">Objects, Images, and Applets: Image maps</a></li>
<li><a href="http://www.ietf.org/" target="_blank">The Internet Engineering Task Force</a> &#8211; <a href="http://tools.ietf.org/html/rfc2397" target="_blank">The &#8220;data&#8221; URL scheme</a></li>
<li><a href="http://cssglobe.com/" target="_blank">CssGlobe</a> &#8211; <a href="http://cssglobe.com/post/3028/creating-easy-and-useful-css-sprites" target="_blank">Creating easy and useful CSS Sprites</a></li>
<li>Foto1: <a href="http://www.flickr.com/photos/jasephotos/2913134974/" target="_blank">Mast Farm Picnic</a> &#8211; 030 di <a href="http://www.flickr.com/photos/jasephotos/" target="_blank">JasonBechtel</a></li>
<li>Foto2: <a href="http://olimpiadi.blogosfere.it/2008/08/davide-rebellin-argento-la-prima-medaglia-italiana-di-queste-olimpiadi.html" target="_blank">Davide Rebellin Argento, la prima medaglia italiana di queste Olimpiadi</a> di <a href="http://olimpiadi.blogosfere.it/" target="_blank">olimpiadi.blogosfere.it</a></li>
<li>Foto3: <a href="http://www.flickr.com/photos/kaibara/312855876/" target="_blank">Cats Puzzle</a> di <a href="http://www.flickr.com/photos/kaibara/" target="_blank">kaibara87</a></li>
<li>Foto4: <a href="http://elementiks.com/downloads/developpers_icons_preview.jpg" target="_blank">icone per sviluppatori</a></li>
<li>Foto5: <a href="http://www.flickr.com/photos/egansnow/288478628/" target="_blank">Puzzle</a> di <a href="http://www.flickr.com/photos/egansnow/" target="_blank">Egan Snow</a></li>
<li>Foto6: <a href="http://www.flickr.com/photos/popilop/331357312/" target="_blank">Do not duplicate</a> di <a href="http://www.flickr.com/photos/popilop/">Sam UL</a></li>
</ul>
<img src="http://jblog.it/?ak_action=api_record_view&id=405&type=feed" alt=" Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css"  title="Ridurre le richieste HTTP (parte 2): come unire e combinare immagini, script, css" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/05/15/ridurre-richieste-http-parte-2-come-combinare-immagini-script-css-sprite-image-maps_405.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Marketing e business su Twitter: consigli e strategie per promuovere blog, siti e aziende</title>
		<link>http://jblog.it/2009/05/05/marketing-business-twitter-consigli-strategie-trucchi-promuovere-blog-siti-aziende_382.html</link>
		<comments>http://jblog.it/2009/05/05/marketing-business-twitter-consigli-strategie-trucchi-promuovere-blog-siti-aziende_382.html#comments</comments>
		<pubDate>Tue, 05 May 2009 20:54:41 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Social network]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[followers]]></category>
		<category><![CDATA[microblogging]]></category>
		<category><![CDATA[promuovere]]></category>
		<category><![CDATA[social networking]]></category>
		<category><![CDATA[tweet]]></category>
		<category><![CDATA[tweetdeck]]></category>
		<category><![CDATA[tweetie]]></category>
		<category><![CDATA[twhirl]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=382</guid>
		<description><![CDATA[Twitter è la prima e più importante piattaforma di &#8220;microblogging&#8221;.
Il microblogging è un modo di bloggare che rispetta essenzialmente una regola: scrivere post utilizzando pochi caratteri (160 su Twitter).
Utilizzando Twitter sono rimasto sorpreso dal gran numero di gente interessante che si può trovare: dal medico che informa sui nuovi prodotti all&#8217;avvocato che dà consigli legali, [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a title="Marketing e business su Twitter: consigli e strategie per promuovere blog, siti e aziende" href="http://jblog.it/2009/05/05/marketing-business-twitter-consigli-strategie-trucchi-promuovere-blog-siti-aziende_382.html"><img class="alignright size-full wp-image-394" title="twitter" src="http://jblog.it/wp-content/uploads/2009/05/twitter.jpg" alt="twitter Marketing e business su Twitter: consigli e strategie per promuovere blog, siti e aziende" width="300" height="76" /></a>Twitter </strong>è la prima e più importante <strong>piattaforma di &#8220;microblogging&#8221;</strong>.</p>
<p>Il <strong>microblogging </strong>è un modo di bloggare che rispetta essenzialmente una regola: scrivere post utilizzando pochi caratteri (160 su Twitter).</p>
<p>Utilizzando Twitter sono rimasto sorpreso dal gran numero di <strong>gente interessante</strong> che si può trovare: dal medico che informa sui nuovi prodotti all&#8217;avvocato che dà consigli legali, dal blogger che segnala costantemente link &#8220;da vedere assolutamente&#8221; al webmaster che consiglia articoli, guide e libri da leggere.</p>
<p>Se hai un&#8217;azienda, un sito o un blog da far conoscere, <strong>Twitter è il posto giusto</strong> per farlo. Infatti grazie a Twitter, in pochi giorni potresti raggiungere centinaia di potenziali visitatori/lettori, conoscere ottime persone e iniziare a <strong>porre le basi per la tua community</strong>.</p>
<p><span class="highlight_yellow"><strong>In questo articolo</strong> parlo dell&#8217;utilizzo di Twitter a scopi promozionali, i comportamenti da seguire per attrarre visitatori, come rendersi utili, come interagire con i followers e l&#8217;utilizzo di Twitter per l&#8217;azienda.</span><span id="more-382"></span></p>
<h2>Un po&#8217; di consigli</h2>
<ul>
<li>Non è necessario leggere tutti i tweet (su Twitter, i post vengono chiamati anche &#8220;tweet&#8221;).</li>
<li>Non c&#8217;è bisogno di rispondere ad ogni tweet rivolto a te (cioé quando scrivono un tweet che contiene &#8220;@tuonome&#8221;).</li>
<li>Cerca persone interessanti e seguile: riceverai i loro tweet all&#8217;interno del tuo profilo.</li>
<li>Avere <strong>migliaia di followers</strong> non significa necessariamente &#8220;essere i migliori&#8221;.</li>
<li>Se pensi che un tweet non interessi a tutti, scrivi &#8220;@destinatario&#8221; all&#8217;interno del tweet per indicare che il messaggio è rivolto all&#8217;utente che si chiama &#8220;destinatario&#8221;. Se il tweet è rivolto a più utenti, basta inserire nel tweet la lista degli username facendoli precedere dalla &#8220;@&#8221; (es. &#8220;@dest1 @dest2 @dest3&#8243;).</li>
<li>Utilizza i servizi per l&#8217;<strong>abbreviazione delle URL</strong>, come <a title="TinyUrl" href="http://tinyurl.com/" target="_blank">tinyurl.com</a>, <a title="Owly" href="http://ow.ly/" target="_blank">ow.ly</a>, <a title="Bitly" href="http://bit.ly/" target="_blank">bit.ly</a>. Abbreviare le URL è indispensabile. Hai a disposizione solo 160 caratteri: sfruttali bene!</li>
<li>Utilizza <strong>software di terze parti</strong> per facilitarti la vita su Twitter, come <a href="http://www.tweetdeck.com/" target="_blank">TweetDeck</a> e <a href="http://www.twhirl.org/" target="_blank">Twhirl</a>.</li>
</ul>
<p><!--adv300--></p>
<h2>Perché utilizzare Twitter?</h2>
<ul>
<li>Twitter è un <strong>concentrato di persone interessanti</strong> dalle quali <strong>imparare </strong>qualcosa di nuovo ogni giorno.</li>
<li>Le <strong>notizie </strong>arrivano molto più <strong>velocemente </strong>rispetto ai normali mezzi di comunicazione.</li>
<li>Segnalando i tuoi lavori avrai centinaia di <strong>giudizi e opinioni.</strong></li>
<li>Migliora la presenza online e l&#8217;<strong>assistenza clienti</strong> delle aziende.</li>
</ul>
<h2>Maneggiare con cura</h2>
<ul>
<li>Senza <strong>obiettivi </strong>e <strong>strategie </strong>Twitter diventa una perdita di tempo.</li>
<li>Twitter potrebbe portarti lontano da attività più produttive.</li>
<li>Ha ancora un po&#8217; di <strong>bug </strong>ed è un po&#8217; <strong>lento</strong>: non ancora è pronto per un utilizzo professionale.</li>
<li>Anche utilizzando <strong>account protetti</strong>, non viene garantita la sicurezza. Quindi è meglio <strong>evitare lo scambio di informazioni confidenziali.</strong></li>
</ul>
<h2>Cinguettare con successo</h2>
<p><img class="alignright size-full wp-image-395" title="twitterbird" src="http://jblog.it/wp-content/uploads/2009/05/twitterbird.jpg" alt="twitterbird Marketing e business su Twitter: consigli e strategie per promuovere blog, siti e aziende" width="122" height="120" /><strong>Ricorda</strong>: hai solo 160 caratteri a tua disposizione. Sfruttali al meglio scrivendo il necessario e segnalando ottimi contenuti.</p>
<ul>
<li>Invece di rispondere alla domanda &#8220;cosa stai facendo?&#8221; rispondi alla domanda <strong>&#8220;cosa ha attirato la tua attenzione?&#8221;.</strong></li>
<li><strong>Renditi utile</strong>: parla di cose interessanti e condividi dei buoni link.</li>
<li>Quando parli di qualcosa,<strong> non limitarti a due parole</strong>. Dai consigli, approfondisci, segnala immagini e risorse esterne.</li>
<li>Quando inserisci il link di un post del tuo blog, <strong>non limitarti a linkare</strong>: spendi qualche parola per <strong>spiegare di cosa parli.</strong></li>
<li>Se ti capita di leggere un tweet interessante, fai il cosiddetto &#8220;<strong>retweet</strong>&#8220;, cioé pubblica un tweet con il link al tweet che hai letto.</li>
</ul>
<h3>In azienda</h3>
<ul>
<li>Segnala i <strong>link verso i nuovi post del blog aziendale</strong> (o &#8220;corporate blog&#8221;), comunicati stampa, promozioni, novità.</li>
<li>Utilizza Twitter per operazioni di <strong>marketing </strong>e <strong>pubbliche relazioni</strong>, come estensione del blog aziendale.</li>
<li>Incarica più di un dipendente alla gestione dell&#8217;account aziendale di Twitter. Questo permette di <strong>aumentare il numero dei tweet e variare i contenuti.</strong></li>
<li>Se la tua azienda è molto grande, può essere utile avere <strong>più account dedicati a compiti diversi</strong>: assistenza clienti, promozioni, ecc.</li>
</ul>
<h2>Qualcuno parla di te</h2>
<p>Appena ti iscrivi, cerca subito gli <strong>username simili</strong> al tuo e le persone con <strong>interessi simili ai tuoi</strong>.</p>
<p>Alcune aziende, almeno inizialmente, preferiscono <strong>&#8220;ascoltare&#8221; la gente che parla di loro</strong>.</p>
<ul>
<li>Utilizza la <strong>ricerca di Twitter</strong>, <a title="Twitter Search" href="http://search.twitter.com/" target="_blank">search.twitter.com</a></li>
<li>Utilizza <strong>software </strong>come <a href="http://www.tweetdeck.com/" target="_blank">TweetDeck</a> e <a href="http://tweetie.softonic.it/mac" target="_blank">Tweetie</a> per eseguire e salvare le ricerche</li>
<li><strong>Salva le tue ricerche</strong> per consultarle periodicamente. Per tenere traccia delle ricerche su <a title="Twitter Search" href="http://search.twitter.com/" target="_blank">search.twitter.com</a> basta abbonarsi ai <strong>feed RSS</strong> della pagina dei risultati di ricerca</li>
</ul>
<h2>C&#8217;è nessunooo?!?</h2>
<p>Non basta scrivere e pubblicare materiale interessante. Bisogna dimostrare che dietro quell&#8217;account c&#8217;è una persona vera facendosi conoscere  meglio, in modo da conquistare la fiducia di potenziali lettori e clienti.</p>
<ul>
<li><strong>Non automatizzare i tweet</strong>. Esistono strumenti come TwitterFeed che permettono la pubblicazione automatica di tweet che linkano il nuovo articolo del tuo blog. Non usarli. Rischieresti di far sembrare il tuo account come uno strumento rivolto solo alla promozione del tuo blog. Devi mostrare il tuo lato umano: <strong>scrivi i tweet personalmente</strong>.</li>
<li>Twitter è nato per far comunicare la gente. Account a scopi promozionali e tweet impersonali <strong>allontanano lettori e clienti</strong>.</li>
<li>Inserisci una tua <strong>foto </strong>e personalizza al meglio lo <strong>sfondo </strong>del tuo account.</li>
<li><strong>Discuti sugli interessi dei tuoi followers</strong>. Non è una perdita di tempo, ma contribuisce ad <strong>attrarre simpatie</strong> e a rendersi più umani.</li>
</ul>
<h3>Il lato umano dell&#8217;azienda</h3>
<ul>
<li>La presenza su Twitter deve servire a<strong> dare un volto umano all&#8217;azienda</strong>. Bisogna parlare e comportarsi come una persona, anche se l&#8217;account rappresenza un brand. Alcune aziende preferiscono incaricare alcuni dipendenti alla gestione delle attività legate a Twitter: scrivere tweet, rispondere ai messaggi, cercare followers, ecc.</li>
<li><strong>Conversa amichevolmente con i tuoi followers</strong>, anche di argomenti non legati direttamente agli affari. Ad esempio, racconta i fatti che succedono con i tuoi dipendenti fuori dall&#8217;ambito lavorativo. Farai conoscere meglio la persona che c&#8217;è dietro.</li>
<li>Alcune aziende permettono ai loro dipendenti di <strong>utilizzare Twitter per parlare dei propri lavori</strong>, dei nuovi prodotti e dei compiti che svolgono durante il lavoro. In questo modo si mettono in luce le persone che portano avanti l&#8217;azienda, aumentando la <strong>reputazione </strong>e il <strong>feeling con i clienti</strong>.</li>
</ul>
<h2>Interagisci con i tuoi followers e clienti</h2>
<ul>
<li>Usa Twitter per porre delle <strong>domande ai tuoi clienti</strong>, e otterrai delle<strong> ottime risposte</strong>. In questo modo potrai effettuare dei sondaggi istantanei per <strong>sapere cosa vorrebbero</strong>. Ad esempio, l&#8217;argomento di un articolo, la scelta del nuovo tema del sito, ecc.</li>
<li><strong>Rispondi alle domande</strong>. La gente si riferisce all&#8217;account aziendale come se fosse una persona e si aspetta una certa disponibilità. In questo modo i clienti si sentiranno impegnati con il brand in prima persona.</li>
<li><strong>Twitter non deve sostituire il servizio clienti</strong>, ma deve contribuire ad avvicinare di più l&#8217;azienda ai clienti</li>
<li><strong>Twitter non deve sostituire l&#8217;email marketing</strong>, poiché non tutti i clienti hanno un account</li>
<li><strong>Rispondere ai commenti</strong> può essere un&#8217;ottimo servizio. Tuttavia, questo non è sempre vantaggioso in quanto l&#8217;azienda risulta molto più<strong> esposta a critiche e lamentele</strong>.</li>
</ul>
<h2>Twitter in azienda</h2>
<ul>
<li><strong>Cerca i tuoi collaboratori e dipendenti, e tieniti in contatto con loro</strong>. Conversare con il tuo staff contribuisce a <strong>rendere più forti i legami personali</strong>. Tuttavia, è necessario stabilire prima di cosa parlare in modo da evitare di pubblicare informazioni strettamente riservate. Per non rischiare, i membri del tuo staff potrebbero avere <strong>due account</strong>: uno pubblico e uno aziendale, per comunicare esclusivamente con i membri dello staff.</li>
<li><strong>Condividi idee e infomazioni</strong> riguardanti progetti sui quali si sta lavorando, con i membri del tuo staff.</li>
<li><strong>Segui gente interessante e attinente alla tua azienda</strong>. Segui i tuoi collaboratori, colleghi, società del tuo settore, brand simili e giornalisti importanti.</li>
<li><span style="text-decoration: underline;">Non</span> si dovrebbe utilizzare Twitter per <strong>comunicare all&#8217;interno dell&#8217;azienda</strong>. Come detto prima, Twitter non offre alcuna garanzia sulla sicurezza. Se hai bisogno di comunicare con i dipendenti attraverso piattaforme di microblogging, esistono soluzioni professionali come <a href="https://www.yammer.com/" target="_blank">Yammer</a> e <a href="https://presentlyapp.com/" target="_blank">present.ly</a> che ti permettono di farlo in tutta sicurezza.</li>
</ul>
<p><span class="highlight_green">Hai mai pensato a queste prospettive per promuovere il tuo sito, blog, o azienda su Twitter? Ne hai già sperimentato alcune? Com&#8217;è andata? Quanto è migliorato il rapporto con i tuoi lettori/clienti grazie a Twitter? Potresti farne a meno? Ti è piaciuto l&#8217;articolo?</span></p>
<h2>Crediti</h2>
<p><a href="http://www.chrisbrogan.com/" target="_blank"><strong>ChrisBrogan.com</strong></a> &#8211; <a href="http://www.chrisbrogan.com/50-ideas-on-using-twitter-for-business/" target="_blank">50 Ideas on Using Twitter for Business</a></p>
<p><a href="http://www.readwriteweb.com/" target="_blank"><strong>ReadWriteWeb.com</strong></a> &#8211; <a href="http://www.readwriteweb.com/archives/4_ways_companies_use_twitter_for_business.php" target="_blank">4 Ways Companies Use Twitter for Business</a></p>
<p><a href="http://www.pcworld.com/" target="_blank"><strong>PcWorld.com</strong></a> &#8211; <a href="http://www.pcworld.com/article/164290/nine_twitter_tips_for_business.html" target="_blank">Nine Twitter Tips for Business</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=382&type=feed" alt=" Marketing e business su Twitter: consigli e strategie per promuovere blog, siti e aziende"  title="Marketing e business su Twitter: consigli e strategie per promuovere blog, siti e aziende" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/05/05/marketing-business-twitter-consigli-strategie-trucchi-promuovere-blog-siti-aziende_382.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Come utilizzare Ajax: librerie, framework, ottimizzazione, caching, usabilità</title>
		<link>http://jblog.it/2009/05/02/come-utilizzare-ajax-basi-librerie-framework-ottimizzazione-caching-usabilita_202.html</link>
		<comments>http://jblog.it/2009/05/02/come-utilizzare-ajax-basi-librerie-framework-ottimizzazione-caching-usabilita_202.html#comments</comments>
		<pubDate>Sat, 02 May 2009 09:39:15 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Ottimizzazione]]></category>
		<category><![CDATA[Usabilità]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[classi librerie]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[ottimizzare]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xmlhttprequest]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=202</guid>
		<description><![CDATA[
Ajax è una tecnica di programmazione (non un linguaggio) che ti permette di sviluppare applicazioni web interattive. In pratica, grazie ad Ajax puoi aggiornare alcuni dati della pagina senza ricaricare completamente la pagina, migliorando le prestazioni del tuo sito.
In questo articolo: effettuare le richieste e gestire le risposte, formati per lo scambio dati, utilizzare librerie [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Come utilizzare Ajax: libreria, framework, ottimizzazione, caching, usabilità" rel="attachment wp-att-375" href="http://jblog.it/2009/05/02/come-utilizzare-ajax-basi-librerie-framework-ottimizzazione-caching-usabilita_202.html/18xokt04_ajax_logo_150_rgb" target="_self"><img class="alignright size-full wp-image-375" title="Ajax logo" src="http://jblog.it/wp-content/uploads/2009/05/18xokt04_ajax_logo_150_rgb.jpg" alt="Ajax logo" width="157" height="140" /></a></p>
<p>Ajax è una tecnica di programmazione (non un linguaggio) che ti permette di sviluppare applicazioni web interattive. In pratica, grazie ad Ajax puoi aggiornare alcuni dati della pagina senza ricaricare completamente la pagina, migliorando le prestazioni del tuo sito.</p>
<p><span class="highlight_yellow"><strong>In questo articolo</strong>: effettuare le richieste e gestire le risposte, formati per lo scambio dati, utilizzare librerie e framework javascript, memorizzare Ajax in cache, evitare risposte duplicate, migliorare l&#8217;usabilità delle applicazioni ajax.</span></p>
<p><span id="more-202"></span></p>
<p><strong>Il termine &#8220;Ajax&#8221; è l&#8217;acronimo di Asynchronous JavaScript and XML.</strong></p>
<p>Vedremo che, nonostante la tecnica Ajax preveda l&#8217;utilizzo di XML, si potranno utilizzare altri formati per lo scambio dati.</p>
<p>Il termine &#8220;Ajax&#8221; è stato coniato da <a href="http://www.jjg.net/" target="_blank">Jesse James Garret</a> nel post &#8220;<a href="http://www.adaptivepath.com/ideas/essays/archives/000385.php" target="_blank">Ajax: A New Approach to Web Applications</a>&#8220;, il 18 febbraio 2005.</p>
<h2>Cosa succede con e senza Ajax</h2>
<p><!--adv300--></p>
<p>Supponiamo di avere una pagina con un form composto da tre campi di testo: nome, cognome e telefono. Lo script lato-server deve ricevere i tre dati, cercarli nel database e stampare l&#8217;indirizzo associato.</p>
<p><strong>Importante.</strong> Generalmente, lo script utilizzato con una chiamata Ajax è diverso da quello utilizzato per l&#8217;esecuzione senza javascript.</p>
<h4>L&#8217;esecuzione standard dello script</h4>
<p><a rel="attachment wp-att-213" href="http://jblog.it/2009/05/02/come-utilizzare-ajax-basi-librerie-framework-ottimizzazione-caching-usabilita_202.html/attachment/1"><img class="size-full wp-image-213 alignnone" title="Esecuzione di uno script senza utilizzare Ajax" src="http://jblog.it/wp-content/uploads/2009/04/1.png" alt="Esecuzione di uno script senza utilizzare Ajax" width="600" height="170" /></a></p>
<p><em>N.B. i rettangoli tratteggiati indicano cosa viene caricato.</em></p>
<p><strong>P</strong><strong>rima fase.</strong> Si carica la pagina html, si scrivono i dati nel form e si inviano al server premendo il pulsante &#8220;invia&#8221;. Oltre a quelle dei dati, il server riceverà le richieste http degli altri componenti della pagina che dovranno essere ricaricati.</p>
<p><strong>Seconda fase.</strong> Il server cerca l&#8217;indirizzo nel database, e il browser <strong>ricarica completamente </strong>la pagina con i nuovi dati o con un messaggio di errore (es. &#8220;indirizzo non trovato&#8221;).</p>
<h4>L&#8217;esecuzione dello script utilizzando Ajax</h4>
<p><a rel="attachment wp-att-218" href="http://jblog.it/2009/05/02/come-utilizzare-ajax-basi-librerie-framework-ottimizzazione-caching-usabilita_202.html/attachment/2"><img class="alignnone size-full wp-image-218" title="Esecuzione di uno script ajax" src="http://jblog.it/wp-content/uploads/2009/04/2.png" alt="Esecuzione di uno script ajax" width="600" height="170" /></a></p>
<p><strong>Prima fase.</strong> Si carica la pagina html, si scrivono i dati nel form e si inviano al server premendo il pulsante &#8220;invia&#8221;. Al server arriva solo una richiesta http: quella dei dati inviati. Inoltre vengono stampati i componenti da mostrare successivamente  (&#8220;tutto ok!&#8221;, &#8220;i dati &#8230; correttamente&#8221;, ecc.) nascondendoli con le regole dei css.</p>
<p><strong>Seconda fase.</strong> Il server cerca l&#8217;indirizzo nel database e, una volta trovato, viene rispedito al browser che aggiornerà il componente riservato all&#8217;indirizzo. Gli altri contenuti stampati precedentemente (&#8220;tutto ok!&#8221;, &#8220;i dati &#8230; correttamente&#8221;, ecc.), vengono resi visibili, mentre i componenti relativi al form vengono nascosti. Per nascondere e mostrare i componenti si utilizzano le regole dei css.</p>
<h2>Framework e librerie javascript</h2>
<p>Un framework javascript è un <strong>insieme di librerie</strong> che facilita la scrittura di codice e applicazioni javascript.</p>
<p><strong>Perché utilizzare un framework?</strong></p>
<ul>
<li>Ti permette di scrivere in <strong>poche righe</strong> quello che in javascript &#8220;puro&#8221; richiderebbe centinaia di righe</li>
<li>Elimina il problema della <strong>compatibilità browser-javascript</strong> eseguendo istruzioni diverse a seconda del browser che si sta utilizzando</li>
</ul>
<p>Ecco i framework più famosi.</p>
<h5>Prototype</h5>
<p><img class="alignright size-full wp-image-227" title="Prototype is a JavaScript Framework that aims to ease development of dynamic web applications" src="http://jblog.it/wp-content/uploads/2009/04/prototype.png" alt="Prototype is a JavaScript Framework that aims to ease development of dynamic web applications" width="139" height="72" />Prototype is a JavaScript Framework that aims to ease development of dynamic web applications.</p>
<p><a href="http://www.prototypejs.org/" target="_blank">http://www.prototypejs.org/</a></p>
<h5>jQuery</h5>
<p><img class="alignright size-full wp-image-230" title="jQuery is a new kind of JavaScript Library." src="http://jblog.it/wp-content/uploads/2009/04/jquery.png" alt="jQuery is a new kind of JavaScript Library." width="226" height="59" />jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.</p>
<p><a href="http://jquery.com/" target="_blank">http://jquery.com/</a></p>
<h5>MooTools</h5>
<p><img class="alignright size-full wp-image-231" title="MooTools is a compact, modular, Object-Oriented JavaScript framework" src="http://jblog.it/wp-content/uploads/2009/04/mootools.png" alt="MooTools is a compact, modular, Object-Oriented JavaScript framework" width="249" height="74" />MooTools is a compact, modular, Object-Oriented JavaScript framework designed for the intermediate to advanced JavaScript developer. It allows you to write powerful, flexible, and cross-browser code with its elegant, well documented, and coherent API.</p>
<p><a href="http://mootools.net/" target="_blank">http://mootools.net/</a></p>
<h5>Dojo</h5>
<p><img class="alignright size-full wp-image-232" title="Dojo. Solve problems faster. Create better user experiences. Liberally licensed. Everything you need, all in one place." src="http://jblog.it/wp-content/uploads/2009/04/dojo.png" alt="Dojo. Solve problems faster. Create better user experiences. Liberally licensed. Everything you need, all in one place." width="147" height="32" />Solve problems faster. Create better user experiences. Liberally licensed. Everything you need, all in one place.</p>
<p><a href="http://dojotoolkit.org/" target="_blank">http://dojotoolkit.org/</a></p>
<h2>Ajax, jQuery e Php all&#8217;opera</h2>
<p>Generalmente un&#8217;applicazione Ajax è composta dalla pagina html e dallo script lato-server da richiamare successivamente via javascript.</p>
<p>Il framework che utilizzo è <a href="http://jquery.com/" target="_blank">jQuery</a>, soprattutto perché, nel complesso, è molto più leggero e veloce rispetto agli altri.</p>
<p>Analizziamo ora il codice dell&#8217;applicazione Ajax di cui ho parlato prima.</p>
<p><strong>Requisiti.</strong> Php 5.2, MySql 5, jQuery 1.3.</p>
<p><strong>Demo dell&#8217;applicazione. </strong>Puoi provare l&#8217;applicazione Ajax <a href="http://download.jblog.it/ajax_phone/" target="_blank">qui</a>.</p>
<h4>Pagina html e codice javascript</h4>
<p>Questa pagina si può dividere in due parti.</p>
<ul>
<li>codice html</li>
<li>codice javascript per la gestione delle chiamate ajax e del codice html</li>
</ul>
<p>Puoi vedere il file completo <a title="Pagina html e codice javascript" href="http://download.jblog.it/ajax_phone/index.txt" target="_blank">qui</a>.</p>
<h5>Html</h5>
<p>All&#8217;interno del tag &lt;body&gt; si possono distinguere due &lt;div&gt;. Il primo (id=&#8221;form_panel&#8221;) ospita il form e un &lt;h3&gt; per la scrittura degli errori (id=&#8221;errors&#8221;); il secondo (id=&#8221;address_panel&#8221;) ospita un &lt;div&gt; (id=&#8221;the_address&#8221;) in cui si scriverà l&#8217;indirizzo trovato.</p>
<pre lang="html">&lt;body&gt;
	&lt;!-- Area del form --&gt;
	&lt;div id="form_panel"&gt;
		&lt;h1&gt;INSERISCI I DATI&lt;/h1&gt;
		&lt;h3 id="errors" style="display:none;color:#CC0000;"&gt;&lt;/h3&gt;
		&lt;form action=""&gt;
			&lt;p&gt;
				&lt;div&gt;&lt;b&gt;Nome&lt;/b&gt; &lt;small&gt;(solo lettere)&lt;/small&gt;&lt;/div&gt;
				&lt;input id="firstname" name="firstname" type="text" value="" /&gt;
				&lt;small id="firstname_msg" style="color:#CC0000;"&gt;&lt;/small&gt;
			&lt;/p&gt;
			&lt;p&gt;
				&lt;div&gt;&lt;b&gt;Cognome&lt;/b&gt; &lt;small&gt;(solo lettere)&lt;/small&gt;&lt;/div&gt;
				&lt;input id="lastname" name="lastname" type="text" size="30" value="" /&gt;
				&lt;small id="lastname_msg" style="color:#CC0000;"&gt;&lt;/small&gt;
			&lt;/p&gt;
			&lt;p&gt;
				&lt;div&gt;&lt;b&gt;Telefono&lt;/b&gt; &lt;small&gt;(numeri, trattino "-", parentesi "(" e ")", spazio " ")&lt;/small&gt;&lt;/div&gt;
				&lt;input id="phone" name="phone" type="text" value="" /&gt;
				&lt;small id="phone_msg" style="color:#CC0000;"&gt;&lt;/small&gt;
			&lt;/p&gt;
			&lt;p&gt;&lt;input id="send" name="send" type="button" value="Invia" /&gt;&lt;/p&gt;
		&lt;/form&gt;
	&lt;/div&gt;

	&lt;!-- Area dell'indirizzo (trovato) --&gt;
	&lt;div id="address_panel" style="display:none;"&gt;
		&lt;h1&gt;INDIRIZZO&lt;/h1&gt;
		&lt;p id="the_address"&gt;&lt;/p&gt;

		&lt;a href="#" id="back_to_form"&gt;&amp;lt; indietro&lt;/a&gt;
	&lt;/div&gt;
&lt;/body&gt;</pre>
<h5>Javascript</h5>
<p>Il codice javascript viene scritto direttamente nel codice html, ma potrebbe essere scritto in un file esterno (.js).</p>
<p>Vengono specificate 3 funzioni e 3 variabili.</p>
<p><strong>$(document).ready(function(){ &#8230; }).</strong> In realtà, questa non è una funzione, ma un metodo di jQuery che, al posto dei &#8220;&#8230;&#8221;, consente di specificare il codice javascript da eseguire quando la pagina ha completato il caricamento.</p>
<p><strong>function form_check().</strong> Esegue dei controlli sui valori dei campi e restituisce &#8220;true&#8221; se non ci sono errori, altrimenti &#8220;false&#8221;.</p>
<p><strong>function form_ajax_send().</strong> Invia i dati del form allo script &#8220;myscript.php&#8221;, attende e gestisce la risposta.</p>
<p><strong>var form_msgs = new Array(&#8230;).</strong> Array degli errori relativi al form (es. &#8220;dati non corretti&#8221;).</p>
<p><strong>var error_msgs = new Array(&#8230;).</strong> Array degli errori relativi all&#8217;invio e alla risposta dei dati (es. &#8220;errore del db&#8221;).</p>
<p><strong>var regexps = new Array(&#8230;).</strong> Espressioni regolari utilizzate in form_check() per controllare i caratteri dei dati inseriti.</p>
<h5>L&#8217;oggetto XMLHttpRequest</h5>
<p>Per inviare richieste http dinamiche bisogna utilizzare l&#8217;oggetto XMLHttpRequest. Questo oggetto ha una serie di <strong>proprietà </strong>e <strong>metodi</strong>.</p>
<p><strong>Uno dei principali svantaggi</strong> legati all&#8217;utilizzo di questo oggetto sta nel fatto che non è standardizzato, quindi non è riconosciuto universalmente da tutti i browser. Infatti, Internet Explorer 6 e precedenti lo vedono come un ActiveX da richiamare in maniera diversa rispetto ai browser Mozilla.</p>
<p><strong>La soluzione</strong> è quella di utilizzare un framework e lasciare che sia lui a occuparsi di effettuare i controlli di compatibilità e differenziare la chiamata e il funzionamento dell&#8217;oggetto XMLHttpRequest.</p>
<p><strong>Per conoscere meglio l&#8217;oggetto XMLHttpRequest</strong> puoi consultare la <a title="The XMLHttpRequest" href="http://www.w3.org/TR/XMLHttpRequest/" target="_blank">pagina ufficiale del w3c (in inglese)</a> oppure la <a title="XMLHttpRequest" href="http://it.wikipedia.org/wiki/XMLHttpRequest" target="_blank">pagina su Wikipedia</a>.</p>
<p><strong>Per approfondire</strong> la gestione di Ajax con jQuery puoi leggere la pagina della <strong>documentazione ufficiale di jQuery</strong> relativa ad Ajax: <a title="jQuery: Ajax" href="http://docs.jquery.com/Ajax" target="_blank">http://docs.jquery.com/Ajax</a>.</p>
<h5>Ajax</h5>
<p>Analizziamo le righe di codice javascript relative alla gestione della richiesta e della risposta asincrona.</p>
<pre lang="js">$.get("myscript.php",{firstname_get:firstname,lastname_get:lastname,phone_get:phone},
	// funzione "callback", cioé eseguita quando vengono restituiti i dati dallo script "myscript.php"
	function(data,status)
	{
		if(status=="success") { ... }
		else { ... } // status=="failure"
	}
);</pre>
<p><strong>$.get.</strong> Questa funzione effettua una richiesta GET. Alternativamente si poteva utilizzare $.post. A seconda del tipo di richiesta, nell0 script lato server bisogna utilizzare gli array $_GET e $_POST per ottenere i dati inviati.</p>
<p><strong>&#8220;myscript.php&#8221;.</strong> Il primo argomento della funzione $.get. Specifica lo script da utilizzare.</p>
<p><strong>{firstname_get:firstname,lastname_get:lastname,phone_get:phone}.</strong> Il secondo argomento della funzione $.get. Questo è un tipo di dati chiamato &#8220;Map&#8221;, dove &#8220;firstname&#8221;, &#8220;lastname&#8221; e &#8220;phone&#8221; sono le variabili riempite con i valori del form, e &#8220;firstname_get&#8221;, &#8220;lastname_get&#8221; e &#8220;phone_get&#8221; sono i nomi delle variabili passate allo script. Quindi, in myscript.php per leggere il cognome non utilizzeremo $_GET['lastname'] ma $_GET['lastname_get'].</p>
<p><strong>function(data,status).</strong> Il terzo argomento della funzione $.get. Rappresenta la funzione &#8220;callback&#8221;, ovvero la funzione da utilizzare quando si riceve la risposta. Poiché la risposta è asincrona, cioé avviene in un secondo momento rispetto all&#8217;invio dei dati, non possiamo scrivere:</p>
<pre lang="js">if(form_check())
{
	ajax_invia_dati();
	ajax_gestisci_risposta();
}</pre>
<p>poiché, quando verrà chiamata la funzione ajax_gestisci_risposta() sicuramente la risposta non sarà ancora arrivata.</p>
<p>Per questo motivo è necessario specificare la cosiddetta <strong>funzione &#8220;callback&#8221;</strong> che verrà eseguita non appena ajax fornirà una risposta. Questa funzione ha due parametri: <strong>data</strong> (dati ricevuti), <strong>status </strong>(stato della risposta). Se status è &#8220;success&#8221; significa che tutto è andato a buon fine, altrimenti status sarà &#8220;failure&#8221;.</p>
<p><strong>Come ottenere l&#8217;oggetto XMLHttpRequest.</strong> Le funzioni $.get, $.post, ecc. restituiscono l&#8217;oggetto XMLHttpRequest che potrà essere utilizzato con tutti i suoi metodi e le sue proprietà.</p>
<h4>Script lato server (php)</h4>
<ul>
<li>Effettua una connessione al database</li>
<li>Esegue la query con i dati ricevuti</li>
<li>Stampa una stringa fra queste: &#8220;db error&#8221;, &#8220;no data&#8221;, o l&#8217;indirizzo trovato</li>
</ul>
<p>Puoi vedere il file completo <a title="Pagina html e codice javascript" href="http://download.jblog.it/ajax_phone/myscript.txt" target="_blank">qui</a>.</p>
<pre lang="php">&lt;?php

header('Expires:'.date("D, d M Y H:i:s",time()+2600000).' GMT');
header('Cache-Control:public,max-age=2600000');

$mydb = @new mysqli('localhost', 'root', 'root', 'mydb');

if(mysqli_connect_errno()!=0) { echo 'db error'; }
else
{
	// effettua la query
	$result = @$mydb-&gt;query("
	SELECT	`Address`
	FROM	`info`
	WHERE	`Lastname`='".$_GET['lastname_get']."' AND
		`Firstname`='".$_GET['firstname_get']."' AND
		`Phone`='".$_GET['phone_get']."'		;");

	// controlla quanti record sono stati trovati (se 0: indirizzo non trovato)
	if($mydb-&gt;affected_rows==0)	{ echo 'no data'; }

	// indirizzo trovato
	else
	{
		$address = $result-&gt;fetch_array(MYSQLI_NUM);
		echo $address[0];
	}
}
?&gt;</pre>
<h5>Dati restituiti dallo script</h5>
<p><strong> </strong></p>
<ul>
<li>&#8220;db error&#8221;, se si verifica un errore relativo al database (in fase di connessione)</li>
<li>&#8220;no data&#8221;, se non viene trovato l&#8217;indirizzo</li>
<li>stringa dell&#8217;indirizzo, se viene trovato l&#8217;indirizzo</li>
</ul>
<h5>Come impostare lo script per i test</h5>
<p>Se vuoi testare lo script è necessario effettuare alcune semplici operazioni.</p>
<ul>
<li>All&#8217;interno di myscript.php individua la riga $mydb = @new mysqli(&#8216;localhost&#8217;, &#8216;root&#8217;, &#8216;root&#8217;, &#8216;mydb&#8217;); e sostituisci i valori del tuo database: host, username, password, database.</li>
<li>Crea la tabella &#8220;info&#8221; nel tuo database. Nello script c&#8217;è una query (CREATE TABLE &#8230; ) da copiare e far eseguire subito dal tuo dbms (es. phpMyAdmin). Se la crei manualmente è necessario creare 5 campi chiamati ID, Lastname, Firstname, Phone, Address.</li>
<li>Infine, inserisci un paio di record in modo che l&#8217;applicazione Ajax possa trovare qualc0sa nella tabella.</li>
</ul>
<h2>Formati di scambio dati</h2>
<p><img class="alignright size-full wp-image-361" title="Scambio dati" src="http://jblog.it/wp-content/uploads/2009/05/senza-titolo-1.png" alt="Scambio dati" width="342" height="134" />Per i dati da inviare come risposta possono essere utilizzati <strong>vari formati</strong>: testo semplice, html, xml, json, ebml.</p>
<p>Lo script dell&#8217;<strong>esempio precedente</strong> stampa <strong>testo semplice</strong>.</p>
<h4>Testo semplice e html</h4>
<p>Preferibile se si devono sviluppare applicazioni semplici che non richiedono massicci scambi di dati e complesse elaborazioni.</p>
<p>Il maggior vantaggio sta nel fatto che testo semplice e codice html non richiedono ulteriori elaborazioni per rendere i dati rappresentabili all&#8217;interno di una pagina xhtml o html.</p>
<h4>Json</h4>
<p>Json, acronimo di <em>JavaScript Object Notation</em>,  è un ottimo formato per lo scambio dati.</p>
<p>Si possono rappresentare <strong>oggetti </strong>e <strong>array</strong>:</p>
<pre lang="js">var object = { name : "Giacomo", phone: "123456789", object2: { msg: "Ciao" } };
var array = ["mystring", 100, { msg: "Ciao" }, object, 5*2, 0.134];</pre>
<p>Per processare una risposta in formato Json, anziché $.get è necessario utilizzare<strong>$.getJson</strong>. Questa funzion processa automaticamente una risposta in formato Json in modo da poter utilizzare subito i dati.</p>
<p>Ad esempio, se la risposta è:</p>
<pre lang="js">var object = { name : "Giacomo", phone: "123456789", object2: { msg: "Ciao" } };
var array = ["mystring", 100, { msg: "Ciao" }, object, 5*2, 0.134];</pre>
<p>all&#8217;interno della funzione &#8220;callback&#8221; potremmo utilizzare le due variabili scrivendo semplicemente:</p>
<pre lang="js">object.name.length; // per ottenere la lunghezza della stringa "Giacomo"
alert(object.object2.msg); // per stampare un alertbox con il messaggio "Ciao"
newvar = array[4] + 3; // per assegnare alla variabile newvar il valore (5*2)+3, cioé 13</pre>
<p>Per saperne di più vai alla pagina ufficiale di Json: <a title="Json official page" href="http://json.org/" target="_blank">http://json.org/</a>.</p>
<h4>XML</h4>
<p>XML, acronimo di <em>eXtensible Markup Language</em>, è un <strong>metalinguaggio di markup</strong> che permette di definire tag personalizzare per strutturare documenti complessi. Una volta ottenuta una risposta formattata in XML è necessario elaborarla per poterla gestire.</p>
<p>La lettura e l&#8217;elaborazione di un testo XML consiste nello scorrere la struttura del documento per recuperare i dati contenuti nei tag XML. Per scorrere la struttura del documento esistono <strong>librerie javascript</strong> che consentono di farlo semplicemente.</p>
<p>Utilizzare questo formato è vantaggioso nel caso in cui ci siano molti dati da ricevere, mentre è sconsigliabile nel caso in cui ricevano pochi dati in quanto i caratteri per i tag XML potrebbero superare quelli per i dati effettivi.</p>
<h2>Memorizza le risposte Ajax in cache per evitare richieste duplicate</h2>
<p>Come detto prima, le risposte Ajax non sono altro che risposte HTTP e, come in tutte le risposte HTTP, possono essere inviati gli header.</p>
<p>Naturalmente, gli header devono essere inviati dallo script lato server, prima di qualsiasi output.</p>
<p>Per memorizzare le risposte Ajax nella cache si possono utilizzare i campi di intestazione Cache-Control, Expires, Pragma, <strong>ETag</strong>. Nei casi in cui non si possa utilizzare la cache del browser ricorreremo a una tecnica javascript.</p>
<p><strong>Per approfondire la gestione della cache</strong> dai uno sguardo al post precedente: <a title="Ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser" href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html">http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html</a>.</p>
<h4>Richieste GET e POST: come si comporta il browser</h4>
<p>Nell&#8217;esempio, utiliziamo un solo script lato server che restituisce 3 output diversi a seconda dell&#8217;esito dell&#8217;operazione: &#8220;db error&#8221; per l&#8217;errore del database, &#8220;no data&#8221; se non è stato trovato l&#8217;indirizzo, e la stringa dell&#8217;indirizzo trovato nel database.</p>
<p>Ti consiglio di leggere questo interessante articolo (in inglese) del w3c: <a title="URIs, Addressability, and the use of HTTP GET and POST" href="http://www.w3.org/2001/tag/doc/whenToUseGet.html" target="_blank">URI, indirizzabilità, e l&#8217;uso di GET e POST</a>.</p>
<p>Il comportamento del browser cambia in base al tipo di richiesta (GET e POST) e agli header inviati dallo script lato server. Analizziamo alcuni casi più da vicino.</p>
<h5>Le richieste GET</h5>
<p><strong> </strong>L&#8217;indirizzo di una richiesta GET ha la forma:</p>
<pre lang="plaintext">http://localhost/ajax_phone/myscript.php?par1=ciao&amp;par2=hello</pre>
<p>Il comportamento di <strong>default </strong>del browser consiste nell&#8217;inviare sempre una nuova richiesta.</p>
<p>Tuttavia, se vogliamo che il browser memorizzi per 1 ora la risposta dello script lato server, inviamo i seguenti header:</p>
<pre lang="plaintext">header('Expires:Sun, 03 May 2009 23:18:45 GMT');
header('Cache-Control:public,max-age=3600');
header('Pragma:public');</pre>
<p>In questo caso, quando l&#8217;applicazione Ajax invia la prima richiesta, il browser legge lo script e lo memorizza in cache. La volta successiva possono verificarsi due casi:</p>
<ul>
<li>se si inviano dei <strong>dati diversi</strong> (ad es., se invece di &#8220;par2=hello&#8221; inviamo &#8220;par2=welcome&#8221;) il browser effettua una nuova richiesta e la memorizza in cache</li>
<li>se si inviano gli <strong>stessi dati</strong>, il browser si accorge che l&#8217;indirizzo della richiesta è uguale, quindi legge i dati dalla cache evitando di effettuare una nuova richiesta</li>
</ul>
<p><strong>Differenziare gli header.</strong> Se alcune richieste non devono essere memorizzate in cache, puoi inviare degli header diversi a seconda dell&#8217;ouput generato dallo script (prima di stampare qualsiasi output). Ad esempio:</p>
<pre lang="php">if($output!="error")
{
	header('Expires:Sun, 03 May 2009 23:18:45 GMT');
	header('Cache-Control:public,max-age=3600');
	header('Pragma:public');
}
else
{
	header('Expires:Sun, 01 Jan 1970 02:00:00 GMT');
	header('Cache-Control:no-cache');
	header('Pragma:no-cache');
}</pre>
<p><strong>Forzare la richiesta.</strong> Per fare in modo che il browser effettui una nuova richiesta, anche se questa è già presente nella cache, basta inviare un ulteriore parametro con un valore variabile, ad esempio un numero casuale.</p>
<pre lang="js">$.get("myscript.php",{firstname_get:firstname,lastname_get:lastname,phone_get:phone,random:Math.random()},
	function(data,status){...});</pre>
<h5>Le richieste POST</h5>
<p>L&#8217;indirizzo di una richiesta POST ha la forma:</p>
<pre lang="plaintext">http://localhost/ajax_phone/myscript.php</pre>
<p><strong>E i parametri?</strong> Vengono inviati tramite protocollo HTTP, ma non sono visibili al browser.</p>
<p><strong>Le richieste POST non possono essere memorizzate in cache.</strong></p>
<h5>Come evitare le richieste duplicate</h5>
<p>Abbiamo visto che le richieste POST non possono essere memorizzate in cache.</p>
<p>Tuttavia è possibile evitare le richieste duplicate grazie a qualche riga di javascript.</p>
<p>Questa tecnica consiste nel <strong>memorizzare i dati inviati e ricevuti in un array</strong>, in modo che, prima di inviare una richiesta, si controlla se i dati da inviare sono già presenti nell&#8217;array. Se sono presenti, si leggono i dati ricevuti in corrispondenza dei dati richiesti e si procede con l&#8217;esecuzione dell&#8217;applicazione.</p>
<pre lang="js">var my_array() = new Array();

/* Una volta riempito l'array avrà questo aspetto
myarray = Array(
	Array( Array('Mario','Rossi',3429752370), 'no data' ),
	Array( Array('Giacomo','Ratta',4325233), 'Via Beethoven, 21' ),
);
*/</pre>
<p>Ogni elemento dell&#8217;array è un array di due elementi. Il primo è l&#8217;array dei dati inviati; il secondo è la stringa dell&#8217;output restituito.</p>
<pre lang="js">// Esegue le operazioni con i dati ricevuti
function esegui_le_operazioni(data) { ... }

if(form_check())
{
	// Leggo i valori dei 3 campi del form
	firstname = $('#firstname').val();
	lastname = $('#lastname').val();
	phone = $('#phone').val();

	// Indica se sono state trovate i dati da inviare
	// Contiene l'indice dell'elemento contenente dati inviati e dati ricevuti
	found = -1;

	// Cerco i dati nell'array
	for(i=0;i&lt;my_array.length;i++)
	{
		// (riga da adattare in base alle proprie esigenze)
		if(my_array[i][0][0]==firstname &amp;&amp; my_array[i][0][1]==lastname &amp;&amp; my_array[i][0][1]==phone)
		{ found=i; break; }
	}

	// I dati sono stati trovati
	if(found&gt;=0)
	{
		esegui_le_operazioni(my_array[found][1]);
	}

	// Dati non trovati: nuova richiesta
	else {
		$.get("myscript.php",{firstname_get:firstname,lastname_get:lastname,phone_get:phone},
		// funzione "callback", cioé eseguita quando vengono restituiti i dati dallo script "myscript.php"
		function(data,status)
		{
			if(status=="success")
			{
				// Inserisco dati inviati e dati ricevuti nell'array
				// riga da adattare in base alle proprie esigenze)
				my_array.push(new Array(new Array(firstname,lastname,phone), data));

				esegui_le_operazioni(data);
			}
			else { ... } // status=="failure"

		}); //end-callback

	} //end-if
}</pre>
<h5>Quando utilizzare GET e quando POST<strong><br />
</strong></h5>
<ul>
<li>Il metodo GET è da preferire quando si devono inviare dati per il normale funzionamento della pagina e degli script</li>
<li>Il metodo POST si deve utilizzare quando quelli da scambiare sono dei dati sensibili (username, password, telefono)</li>
</ul>
<h2>Migliorare l&#8217;usabilità e l&#8217;accessibilità delle applicazioni Ajax</h2>
<p>Spesso nella progettazione delle applicazioni Ajax l&#8217;usabilità lascia un po&#8217; a desiderare: nessun messaggio di successo/errore, caricamenti infiniti senza segni di vita, ecc.</p>
<p>Certo, l&#8217;usabilità è un tema complesso e progettare siti e applicazioni usabili richiede tempo e buone competenze.</p>
<p>Tuttavia, ci sono alcune cose che devono essere fatte e che, fortunatamente, non richiedono troppo tempo.</p>
<p><strong><em>Potrai vedere queste modifiche nello script di esempio.</em></strong></p>
<h4>Errori e messaggi</h4>
<ul>
<li>Ogni campo di input deve avere la relativa area dedicata ai messaggi di errore (&#8220;dati obbligatori&#8221;, &#8220;caratteri non validi&#8221;, ecc.)</li>
<li>La pagina deve avere un&#8217;area destinata ad ospitare i messaggi relativi all&#8217;esecuzione dello script (&#8220;ricerca eseguita con successo&#8221;, &#8220;errore dell&#8217;applicazione&#8221;, &#8220;errore del database&#8221;, ecc.)</li>
</ul>
<h4>Barra di caricamento</h4>
<p><img class="alignright size-full wp-image-360" title="loader" src="http://jblog.it/wp-content/uploads/2009/05/loader.png" alt="loader Come utilizzare Ajax: librerie, framework, ottimizzazione, caching, usabilità" width="220" height="19" />Nella maggior parte della applicazioni, per motivi tecnici, non è possibile inserire una barra di caricamento che rilevi la percentuale reale dei dati caricati fino a quel momento.</p>
<p>Generalmente, si preferisce mostrare un&#8217;immagine gif che può essere una barra di caricamento o un&#8217;animazione generica in modo che faccia sapere all&#8217;utente che l&#8217;applicazione sta lavorando.</p>
<p><strong>Svantaggio.</strong> Durante il caricamento dei dati si potrebbe verificare un malfunzionamento che non blocca la richiesta. In questo caso il caricamento sarebbe infinito provocando l&#8217;abbandono del sito da parte dell&#8217;utente.</p>
<p><strong>Soluzione 1.</strong> Puoi inserire un pulsante da far premere all&#8217;utente per fermare la richiesta http.</p>
<pre lang="html">&lt;button type="button" onclick="stopAjaxRequest();"&gt;Stop&lt;/button&gt;</pre>
<p><strong>Soluzione 2.</strong> Analizza il tuo script e prevedi un tempo massimo entro cui restituire l&#8217;output, e, con javascript, impostare un timer che faccia fermare la richiesta Ajax una volta trascorso il tempo previsto.</p>
<pre lang="js">// esegue la funzione stopAjaxRequest() dopo 10 secondi
setTimeout(stopAjaxRequest(),10000);</pre>
<h5>Come creare la funzione stopAjaxRequest().</h5>
<ul>
<li>L&#8217;oggetto <span>XMLHttpRequest ha il metodo <strong>abort() </strong>che permette di fermare una richiesta http.</span></li>
<li>Le funzioni $.ajax, $.get, $.post, $.getScript, $.getJSON di jquery restituiscono un oggetto <span>XMLHttpRequest.</span></li>
</ul>
<p><strong>1. Creiamo una variabile globale per l&#8217;oggetto <span>XMLHttpRequest, che chiamiamo XHR</span></strong></p>
<pre lang="js"><span>var XHR;<strong>
</strong></span></pre>
<p><strong><span>2. Creiamo la funzione</span> stopAjaxRequest() che richiama XHR ed esegue il metodo abort()</strong></p>
<pre lang="js">function stopAjaxRequest() { XHR.abort(); }</pre>
<p><strong><span>3. Assegnamo a XHR l&#8217;oggetto restituito dalla funzione $.get che utilizziamo per inviare i dati</span></strong></p>
<pre lang="js"><span>XHR = $.get("myscript.php",{firstname_get:firstname,lastname_get:lastname,phone_get:phone},
	function(data,status)</span><span> { ... }</span><span>);
</span></pre>
<h4>Se javascript è disabilitato&#8230;</h4>
<p>Purtroppo, ancora oggi ci sono utenti che utilizzano browser che non eseguono codice javascript, che hanno scarsa compatibilità oppure con javascript disattivato.</p>
<p>La <strong>soluzione </strong>è quella di progettare applicazioni che funzionino sia con javascript che senza.</p>
<p>Questo potrebbe andare bene per la piccola applicazione Ajax realizzata per questo post. Tuttavia, se le applicazioni sono di un certo livello, il carico di lavoro aumenta notevolmente. Quindi progettare applicazioni ibride ha senso solo quando le applicazioni da realizzare <strong><span style="text-decoration: underline;">devono</span> </strong>offrire il <strong>massimo della compatibilità</strong> con i browser usati dagli utenti (ad es. siti governativi, pubblica amministrazione, ecc.)</p>
<p><strong>Secondo me</strong>, data la piccola percentuale di browser non compatibili e di utenti che disattivano (erroneamente) javascript, e la presenza di siti importanti come ebay, microsoft, youtube che non offrono l&#8217;alternativa &#8220;no javascript&#8221;, si può benissimo sviluppare un sito senza preoccuparsi degli utenti che non potranno eseguire javascript.</p>
<p>Nel <strong>tag &lt;noscript&gt;</strong> è possibile inserire il codice html da eseguire in caso di &#8220;javascript disabilitato&#8221;.</p>
<p>Alcune volte l&#8217;ho utilizzato per nascondere dei componenti che avevano senso solo con javascript disabilitato. Lo so&#8230; sintatticamente non è corretto, però potrebbe esserti utile.</p>
<p>Supponiamo di avere un link che fa apparire un alert:</p>
<pre lang="js">&lt;a id="alert_click" href="#" onclick="javascript:alert('Ciao!');"&gt;Clicca qui&lt;/a&gt;</pre>
<p>Per nasconderlo, in caso di javascript disabilitato, scriviamo:</p>
<pre lang="html">&lt;noscript&gt;
&lt;style type="text/css"&gt;
#alert_click { display:none; }
&lt;/style&gt;
&lt;/noscript&gt;</pre>
<h2>Svantaggi di Ajax</h2>
<ul>
<li>Le chiamate effettuate non vengono registrate nella cronologia, a differenza di quanto avviene utilizzando iframe nascosti</li>
<li>I pulsanti &#8220;avanti&#8221; e &#8220;dietro&#8221; non sono utilizzabili poiché le chiamate Ajax non vengono memorizzate nella cronologia</li>
<li>L&#8217;utilizzo esclusivo di javascript viola il requisito 15 della legge Stanca: &#8220;la pagina deve essere fruibile anche in assenza di script&#8221;</li>
<li>L&#8217;oggetto XMLHttpRequest non è compatibile con tutti i browser. Internet Explorer 6 e precedenti lo vedono come oggetto ActiveX, e il browser potrebbe essere impostato a un livello di sicurezza tale da non permettere l&#8217;esecuzione di controlli ActiveX</li>
<li>L&#8217;oggetto XMLHttpRequest può comunicare solo all&#8217;interno del dominio. Se la destinazione è esterna al dominio bisogna creare un proxy lato server per poter comunicare all&#8217;esterno.</li>
<li>Poiché i motori di ricerca non eseguono codice javascript, essi non possono indicizzare i contenuti generati dinamicamente con javascript e Ajax</li>
</ul>
<h2>Libri e risorse utili</h2>
<h5>Ajax. Guida per lo sviluppatore. Seconda edizione. Hoepli (2007).</h5>
<p><img class="alignright size-full wp-image-351" title="Ajax. Guida per lo sviluppatore. Seconda edizione" src="http://jblog.it/wp-content/uploads/2009/05/4960-300x300.jpg" alt="Ajax. Guida per lo sviluppatore. Seconda edizione" width="71" height="100" />Con Ajax guida per lo sviluppatore scoprirete come sfidare le regole tradizionali di quello che può accadere sul Web e come liberarvi del consueto approccio “click and wait”, approfondendo le tecniche, i pattern e i casi di utilizzo di Ajax, così da crearvi un’esperienza d’uso senza precedenti nelle vostre applicazioni.</p>
<p>Link: <a title="Ajax. Guida per lo sviluppatore. Seconda edizione" href="http://www.hoepli.it/editore/visbook.asp?id=978-88-203-3923-4" target="_blank">http://www.hoepli.it/editore/visbook.asp?id=978-88-203-3923-4</a>.</p>
<h5>Ajax e Php. Sviluppare applicazioni web dinamiche. Hoepli (2007)</h5>
<p><img class="alignright size-full wp-image-352" title="Ajax e Php. Sviluppare applicazioni web dinamiche" src="http://jblog.it/wp-content/uploads/2009/05/copj13.jpg" alt="Ajax e Php. Sviluppare applicazioni web dinamiche" width="70" height="100" /><span class="tcorpotesto">AJAX e PHP. Sviluppare applicazioni web dinamiche è la risorsa più pratica ed efficiente che possiate utilizzare per entrare nell&#8217;entusiasmante mondo di AJAX. Questo libro vi spiegherà infatti come creare applicazioni web in PHP che sfruttino al massimo le tecnologie Ajax.<br />
</span></p>
<p>Link: <a title="Ajax e Php. Sviluppare applicazioni web dinamiche" href="http://www.hoepli.it/libro/ajax-php.asp?ib=9788820339432&amp;pc=000022007002012" target="_blank">http://www.hoepli.it/libro/ajax-php.asp</a></p>
<h5>Siti e pagine</h5>
<p><a title="Ajax: A New Approach to Web Applications" href="http://www.adaptivepath.com/ideas/essays/archives/000385.php" target="_blank">Ajax: A New Approach to Web Applications</a></p>
<p><a title="The XMLHttpRequest Object" href="http://www.w3.org/TR/XMLHttpRequest/" target="_blank">W3C: The XMLHttpRequest Object</a></p>
<p><a title="Wikipedia: l'oggetto XMLHttpRequest" href="http://it.wikipedia.org/wiki/XMLHttpRequest" target="_blank">Wikipedia: l&#8217;oggetto XMLHttpRequest</a></p>
<p><a title="jQuery: Ajax" href="http://docs.jquery.com/Ajax" target="_blank">jQuery: Ajax</a></p>
<p><a title="Json official page" href="http://json.org/" target="_blank">JSON.org</a></p>
<p><a title="Ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser" href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html">Ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser</a></p>
<p><a title="URIs, Addressability, and the use of HTTP GET and POST" href="http://www.w3.org/2001/tag/doc/whenToUseGet.html" target="_blank">W3C: URIs, Addressability, and the use of HTTP GET and POST</a></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=202&type=feed" alt=" Come utilizzare Ajax: librerie, framework, ottimizzazione, caching, usabilità"  title="Come utilizzare Ajax: librerie, framework, ottimizzazione, caching, usabilità" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/05/02/come-utilizzare-ajax-basi-librerie-framework-ottimizzazione-caching-usabilita_202.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser</title>
		<link>http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html</link>
		<comments>http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html#comments</comments>
		<pubDate>Fri, 24 Apr 2009 20:56:12 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Ottimizzazione]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[mod_expires]]></category>
		<category><![CDATA[mod_headers]]></category>
		<category><![CDATA[ottimizzare]]></category>
		<category><![CDATA[richieste http]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=124</guid>
		<description><![CDATA[Iniziamo una lunga serie di articoli sull&#8217;ottimizzazione dei siti web in cui verranno trattate le tecniche e i suggerimenti per rendere efficiente il proprio sito web.
In questo articolo parlo della cache dei browser, come e perché gestirla. Vedrai cos&#8217;è una richiesta http, un&#8217;intestazione http e le tre tecniche principali per istruire il browser su come dovrà [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html"><img class="alignright size-full wp-image-184" title="Green Archive" src="http://jblog.it/wp-content/uploads/2009/04/greenarchive.jpg" alt="Green Archive" width="270" height="180" /></a>Iniziamo una <strong>lunga serie di articoli sull&#8217;ottimizzazione dei siti web</strong> in cui verranno trattate le tecniche e i suggerimenti per rendere efficiente il proprio sito web.</p>
<p><span class="highlight_yellow"><strong>In questo articolo</strong> parlo della cache dei browser, come e perché gestirla. Vedrai cos&#8217;è una richiesta http, un&#8217;intestazione http e le tre tecniche principali per istruire il browser su come dovrà comportarsi con gli elementi di una pagina, cioé, quando leggerli dal server d&#8217;origine e quando caricarli dalla cache.</span><br />
<span id="more-124"></span></p>
<h2>Cos&#8217;è una richiesta http?</h2>
<p><!--adv300--></p>
<p>Quando il browser visita un sito apre una connessione con l&#8217;host (il server che ospita il sito), composta da una <strong>richiesta </strong>e da una <strong>risposta</strong>. Supponiamo di voler visitare la pagina http://jblog.it/informazioni.html.</p>
<h5>La richiesta http che invia il browser</h5>
<p><code><strong>GET /informazioni HTTP/1.1</strong><br />
<strong>Host:</strong> jblog.it<br />
<strong>User-Agent:</strong> Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8<br />
<strong>Accept:</strong> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8<br />
<strong>Accept-Language:</strong> it<br />
<strong>Accept-Encoding:</strong> gzip,deflate<br />
<strong>Accept-Charset:</strong> ISO-8859-1,utf-8;q=0.7,*;q=0.7<br />
<strong>Keep-Alive: </strong>300<br />
<strong>Connection:</strong> keep-alive</code></p>
<h5>La risposta http</h5>
<p><code><strong>HTTP/1.1 200 OK</strong><br />
<strong>Date:</strong> Fri, 24 Apr 2009 10:26:08 GMT<br />
<strong>Server</strong>: Apache<br />
<strong>Keep-Alive:</strong> timeout=15, max=100<br />
<strong>Connection:</strong> Keep-Alive<br />
<strong>Transfer-Encoding:</strong> chunked<br />
<strong>Content-Type:</strong> text/html; charset=UTF-8</code></p>
<p>Le informazioni inviate e restituite potrebbero essere molte di più, ognuna ha un suo preciso significato, e possono essere controllate e gestite via codice (lato client e lato server). Sul sito del w3c puoi trovare l&#8217;elenco completo dei campi di intestazione delle connessioni http: <a rel="nofollow" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html</a>.</p>
<h5>La prima riga della richiesta: GET /informazioni HTTP/1.1</h5>
<p><strong> </strong>In questa riga si trovano sostanzialmente tre informazioni: il <strong>tipo della richiesta</strong> (GET, POST, HEAD, PUT, DELETE, OPTIONS, TRACE), l&#8217;<strong>indirizzo della risorsa</strong> (/informazioni) e il <strong>protocollo </strong>con cui si effettua la richiesta (HTTP/1.1).</p>
<h5>La prima riga della risposta: HTTP/1.1 200 OK</h5>
<p><strong> </strong>Il codice 200 indica il successo della risposta http. Esistono vari codici numerici per indicare l&#8217;esito della risposta http. Ad esempio, il classico <strong>codice 404</strong> indica che non è stata trovata la risorsa specificata nella richiesta http. Se ti interessa puoi trovare una <strong>lista completa</strong> su wikipedia: <a rel="nofollow" href="http://it.wikipedia.org/wiki/Elenco_dei_codici_di_stato_HTTP">http://it.wikipedia.org/wiki/Elenco_dei_codici_di_stato_HTTP</a>.</p>
<h3>Perché bisogna ridurre le richieste http?</h3>
<p>Il numero di richieste http dipende dal <strong>numero di elementi da caricare</strong>. Ad esempio, se in una pagina ci sono 2 immagini e 1 foglio di stile il browser effettuerà 4 richieste http (una è per il codice html della pagina).</p>
<p>Come avrai ben capito, la regola è &#8220;ridurre gli elementi della pagina&#8221;, o meglio &#8220;ottimizzare gli elementi di una pagina senza eliminarne nessuno&#8221;. Con &#8220;ottimizzare&#8221; non intendo &#8220;ridurre la loro dimensione&#8221;. Infatti riducendo la dimensione degli elementi avresti un miglior tempo di caricamento mantenendo lo stesso numero di richieste http.</p>
<h4>Ottimizzare o ridurre?</h4>
<p>Senza dubbio è importantissimo ottimizzare la qualità e le dimensioni dei componenti di una pagina, ma una singola richiesta http è molto più gravosa di qualche kbyte in più. Ecco perché <strong>ridurre le richieste http è fondamentale</strong>.</p>
<h2>I campi di intestazione del protocollo HTTP per gestire la cache</h2>
<p><span style="text-decoration: underline;"><a href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html"><img class="alignright size-full wp-image-185" title="Gift Tag" src="http://jblog.it/wp-content/uploads/2009/04/gifttag.jpg" alt="Gift Tag" width="267" height="200" /></a></span>Il protocollo HTTP 1.1 ha alcuni campi di intestazione (o header fields) che consentono di fornire alcune informazioni riguardo un file (data, ultima modifica, periodo, ecc.) e controllare la cache.</p>
<h4>Cache-Control</h4>
<p>Specifica le direttive che devono rispettare tutti i metodi di caching dei componenti restituiti. Le direttive di cache-control:</p>
<ol>
<li>sovrascrivono gli algoritmi di caching di default</li>
<li>non possono essere specificate per una singola cache (se si utilizza un proxy o un gateway)</li>
<li>sono unidirezionali, cioè non implicano che la risposta abbia le stesse direttive</li>
</ol>
<p>Alcune direttive possono essere utilizzate solo in fase di richiesta o solo in fase di risposta.</p>
<ul>
<li><strong>direttive di richiesta: </strong>no-cache, no-store, max-age, max-stale, min-fresh, no-transform, only-if-cached, cache-extension.</li>
<li><strong>direttive di risposta:</strong> public, private, no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age, s-maxage, cache-extension.</li>
</ul>
<p><strong>public.</strong> La risposta può essere memorizzata in qualsiasi cache. Utile se si utilizza una cache condivisa.</p>
<p><strong>private.</strong> La risposta non deve essere memorizzata nella cache condivisa.</p>
<p><strong>no-cache.</strong> Evita che la risposta venga memorizzata in cache. SOLO in fase di risposta è possibile scrivere <code>no-cache="field-name"</code>, dove <em>field-nam</em><em>e</em> è il nome di un campo di intestazione che non si vuole memorizzare in cache. In pratica, quando una risposta (ad es. una pagina) viene memorizzata in cache, vengono memorizzati anche i suoi campi di intestazione. Se uno di quei campi è &#8220;Set-Cookie&#8221; e non vogliamo che venga memorizzato in cache basterà scrivere <code>no-cache="Set-Cookie"</code>. In tal modo la pagina verrà comunque memorizzata in cache senza il campo di intestazione &#8220;Set-Cookie&#8221;. <strong>L&#8217;utilità?</strong> Dato che &#8220;Set-Cookie&#8221; crea un cookie, memorizzandolo con la pagina, quando si riutilizzerà la versione in cache verrà creato nuovamente il cookie.</p>
<p><strong>no-store.</strong> Evita che la risposta venga memorizzata permanentemente nella memoria non-volatile. Questa direttiva si applica a qualsiasi tipo di cache (condivisa e non). La sua utilità consiste nel fatto che si impedisce la memorizzazione di vecchie versioni di pagine e documenti che vengono costantemente aggiornati.</p>
<p><strong>s-maxage. </strong>Specifica il periodo (in secondi) dopo il quale devono essere aggiornate le risposte nella <strong>cache condivisa.</strong> Questa direttiva sovrascrive la direttiva <em>max-age </em>e il campo di intestazione <em>expires</em>.</p>
<p><strong>max-age.</strong> Indica che il client è disposto ad accettare una risposta con un periodo (in secondi) maggiore di quello specificato. Se non è specificata la direttiva <em>max-stale</em>, il client non accetterà una risposta datata.</p>
<p><strong>min-fresh.</strong> Indica che il client è disposto ad accettare una risposta che sia aggiornata <em>almeno</em> a un dato periodo (in secondi).</p>
<p><strong>max-stale.</strong> Indica che il client è disposto ad accettare una risposta che supera la sua scadenza di un certo numero di secondi.</p>
<p><strong>only-if-cached.</strong> Consente di caricare un contenuto solo se in cache è presente una sua versione, altrimenti non viene restituita alcuna risposta. Questa direttiva è utile nelle reti particolarmente lente.</p>
<p><strong>must-revalidate. </strong>Poichè una cache può essere configurata in modo che ignori il tempo di scadenza di una risposta, questa direttiva consente di forzare l&#8217;aggiornamento di una risposta già memorizzata in cache. Questa direttiva viene sempre rispettata dal browser.</p>
<p><strong>proxy-revalidate.</strong> Ha gli stessi effetti di must-revalidate, ma solo sulla cache condivisa.</p>
<p><strong>no-transform.</strong> Evita che una cache intermedia (ad es. di un proxy) manipoli la risposta per risparmiare risorse. Infatti può succedere che un proxy comprima un&#8217;immagine per risparmiare spazio. Questa direttiva è utile nel caso di immagini da trasmettere fedelmente (ad es. in campo medico) in cui ogni pixel deve rimanere al suo posto.</p>
<h4>Expires</h4>
<p>Indica una data (con l&#8217;ora) a partire dalla quale la risposta memorizzata in cache deve essere considerata &#8220;vecchia&#8221;, quindi essere aggiornata.</p>
<p>La data deve essere espressa in un preciso formato definito dal protocollo HTTP. Ad esempio: <code>Tue, 03 Nov 2007 17:30:00 GMT.</code></p>
<p><code>Expires: Tue, 03 Nov 2007 17:30:00 GMT</code></p>
<h4>Pragma</h4>
<p>Indica che la risposta non deve essere memorizzata in cache. L&#8217;unica direttiva è appunto &#8220;no-cache&#8221;.</p>
<p>In pratica esegue la stessa funzione di cache-control=&#8221;no-cache&#8221;, ma è necessario utilizzarla per mantenere la compatibilità con la versione 1.0 del protocollo HTTP.</p>
<p><code>Pragma: no-cache</code></p>
<h4>ETag</h4>
<p>Gli ETag o <strong>Entity Tag</strong> rappresentano un modo semplice ed efficiente per determinare se la risposta nella cache corrisponde a quella che si trova nel server di origine. Concretamente un ETag non è altro che una <strong>stringa che identifica univocamente una risposta memorizzata in cache</strong>.</p>
<p><strong>Com&#8217;è composta la stringa?</strong> Non ha dei valori predefiniti ma deve essere creata in base a dei valori che potrebbero identificare la versione di una risposta. Generalmente si preferisce identificare le risposte in base alla data dell&#8217;ultima modifica e alla dimensione. Queste due informazioni vengono compresse in modo da formare un&#8217;unica stringa di dimensioni contenute, ad esempio utilizzando algoritmi di hashing come md5.</p>
<p><strong>Gli svantaggi.</strong> L&#8217;unico svantaggio è che il formato e il valore di un ETag cambia da server a server. Se un determinato file risiede su più server nella stessa directory, con identiche dimensioni, permessi, timestamp, a seconda del server da cui si legge. La <strong>soluzione </strong>consiste nel creare il valore dell&#8217;ETag con un semplice script lato-server. In pratica, per <strong>avere dei benefici</strong> dagli ETag è necessario gestirli completamente con degli script lato-server, altrimenti è meglio non utilizzarli. <a href="#script1">Ecco un esempio di script</a>.</p>
<p><code>ETag: "0401g4ff812fgk12gqg2g4j7"</code></p>
<h4>Last-Modified</h4>
<p>Rappresenta la data e l&#8217;ora dell&#8217;ultima modifica del file sul server d&#8217;origine nella forma, ad esempio, <code>Tue, 03 Nov 2007 17:30:00 GMT.</code></p>
<p>Questo campo di intestazione è utile soprattutto nelle pagine dinamiche in cui vengono stampati dei dati ricavati da un database, o nei file creati dinamicamente (ad es. un foglio di stile che ne unisce 5 per evitare di avere 5 richieste http).</p>
<h4>If-Match</h4>
<p>Fornisce un metodo efficiente per controllare se la risposta ottenuta corrisponde a quella memorizzata in cache, utilizzando gli <strong>ETag</strong>, ed eventualmente aggiornarla. Viene anche usata per evitare <strong>modifiche accidentali</strong> sull&#8217;errata versione di una risorsa.</p>
<p><code>If-Match:*</code> oppure <code>If-Match:0401g4ff812fgk12gqg2g4j7</code></p>
<p>Nel primo caso, il carattere &#8220;*&#8221; è un carattere speciale e il campo fa corrispondere tutti i componenti di una risposta.</p>
<p>Nel secondo caso, il campo di intestazione fa corrispondere l&#8217;ETag con la stringa specificata.</p>
<h4>If-None-Match</h4>
<p>Fornisce un metodo efficiente per controllare se la risposta ottenuta corrisponde a quella memorizzata in cache, utilizzando gli <strong>ETag</strong>, ed eventualmente aggiornarla.</p>
<p>Al contrario di If-Match non si deve avere la corrispondenza con l&#8217;ETag confrontato o con il carattere &#8220;*&#8221;.</p>
<p><code>If-None-Match:*</code> oppure <code>If-Match:0401g4ff812fgk12gqg2g4j7</code></p>
<h4>If-Modified-Since</h4>
<p>Fornisce un metodo automatico per aggiornare la versione in cache di una risposta che non è stata modificata da una certa data (e ora) nel formato: <code>Tue, 03 Nov 2007 17:30:00 GMT. Se la risposta è stata modificata a partire dalla data specificata si effettua l'aggiornamento della versione in cache, altrimenti viene restituita la versione memorizzata in cache.</code></p>
<p><code>If-Modified-Since: Sat, 12 Oct 2008 20:12:00 GMT</code></p>
<h4>If-Unmodified-Since</h4>
<p>Fornisce un metodo automatico per aggiornare la versione in cache di una risposta che non è stata modificata da una certa data (e ora) nel formato: <code>Tue, 03 Nov 2007 17:30:00 GMT. Se la risposta NON è stata modificata a partire dalla data specificata si effettua l'aggiornamento della versione in cache, altrimenti viene restituita la versione memorizzata in cache.</code></p>
<p><code>If-Unmodified-Since: Sat, 12 Oct 2008 20:12:00 GMT</code></p>
<h4>If-Range</h4>
<p>Se la versione in cache di una risposta è parziale, questo campo di intestazione permette di ottenere solo la parte mancante. La condizione fallisce se la risorsa richiesta è stata modificata. In questo caso sarà effettuata una seconda richiesta per ottenere una risposta completa che aggiorni la versione memorizzata in cache.</p>
<p><code>If-Range: Sat, 12 Oct 2008 20:12:00 GMT</code></p>
<p><code>If-Range: 0401g4ff812fgk12gqg2g4j7</code></p>
<p>Nel primo caso si confronta la data dell&#8217;<strong>ultima modifica</strong>, mentre nel secondo caso si confronta la stringa dell&#8217;<strong>ETag</strong>.</p>
<h2>Come utilizzare i campi di intestazione</h2>
<p><span style="text-decoration: underline;"><a href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html"><img class="alignright size-full wp-image-186" title="Thinking" src="http://jblog.it/wp-content/uploads/2009/04/thinking.jpg" alt="Thinking" width="267" height="171" /></a></span>In questo paragrafo non troverai una ricetta pronta per gestire la cache perché non so quali sono le tue esigenze. Leggi attentamente il paragrafo precedente per decidere le operazioni da effettuare in ogni pagina e risorsa del tuo sito.</p>
<p><strong>Il mio consiglio</strong> è quello di analizzare i contenuti delle tue pagine (attuali e futuri) e decidere se memorizzare in cache una particolare risorsa, come gestire la versione della cache, il tempo di validità, ecc.</p>
<p>Se nel paragrafo precedente alcuni punti sono spiegati male, manca qualcosa o ci sono errori  fammelo sapere e correggerò tutto al più presto.</p>
<p>Ci sono <strong>tre metodi</strong> per impostare i campi di intestazione:</p>
<ol>
<li>impostando il tag &lt;meta&gt;</li>
<li>all&#8217;interno del proprio codice lato-server (php, asp, cgi, ecc.)</li>
<li>configurando il web server Apache tramite il file .htaccess o il file principale httpd.conf</li>
</ol>
<h3>1. Impostare i tag &lt;meta&gt;</h3>
<p>Sicuramente conoscerai già il tag &lt;meta&gt;. Probabilmente l&#8217;avrai utilizzato per inserire <strong>description</strong> e <strong>keywords</strong> nelle tue pagine web, per migliorare l&#8217;indicizzazione del tuo sito da parte dei motori di ricerca.</p>
<p>Per ogni campo di intestazione che decidi di utilizzare devi:</p>
<ul>
<li>creare un tag &lt;meta&gt; con gli attributi &#8220;http-equiv&#8221; e &#8220;content&#8221;</li>
<li>scrivere il nome del campo nell&#8217;attributo &#8221;http-equiv&#8221;, rispettando le lettere maiuscole e minuscole</li>
<li>scrivere il valore del campo nell&#8217;attributo &#8220;content&#8221;</li>
</ul>
<h5>Esempi</h5>
<p><code>&lt;meta http-equiv="Cache-Control" content="no-cache" /&gt;<br />
&lt;meta http-equiv="Pragma" content="no-cache" /&gt;<br />
&lt;meta http-equiv="Expires" content="Tue, 03 Nov 2007 17:30:00 GMT" /&gt;</code></p>
<h3>2. Il codice lato-server</h3>
<p>Ogni linguaggio di programmazione ha la sua funzione per inviare un campo di intestazione.</p>
<p>Al momento l&#8217;unico linguaggio che conosco è PHP, con cui basterà scrivere <code>header("Cache-Control: no-cache");</code> .</p>
<p>I campi di intestazione vanno scritti prima di qualsiasi output sulla pagina, altrimenti si verifica un errore che in sostanza dice &#8220;impossibile modificare l&#8217;intestazione &#8211; gli header sono stati già inviati&#8221;.</p>
<p><strong>Tutto qui?</strong> <span style="font-weight: normal;">In teoria non ci sarebbe altro&#8230; Posso solo aggiungere delle situazioni in cui diventa fondamentale utilizzare la funzione <em>header</em>.</span></p>
<h5>Combinare più fogli di stile</h5>
<p>Per diminuire le richieste http è una buona abitudine combinare più fogli di stile in uno solo. Si potrebbe fare manualmente, ma se in futuro vorrai effettuare delle modifiche dovrai modificare i singoli file e ricombinarli oppure modificare il file grande con la difficoltà di aver a che fare con centinaia di righe di codice.</p>
<p>Il metodo è quello di creare un file .css in cui inserire uno <strong>script php</strong> che permetta di stampare al suo interno tutti i file .css da te specificati. Dovrai inoltre impostare Apache affinché processi i file .css come file .php .</p>
<p>Per file dinamici di questo tipo sarà necessario richiamare più volte la funzione <em>header </em>all&#8217;inizio del file in modo da <strong>inviare i campi di intestazione</strong> riguardanti la gestione della cache.</p>
<p>Questo argomento farà parte del prossimo articolo su come combinare e ottimizzare immagini, css e script.</p>
<p><span id="script1">Ecco un <strong><em>semplice script php</em></strong>.</span></p>
<pre lang="php">&lt; ?
$files = array("css1.css","css2.css");
$mtime = 0;
$this_mtime = 0;
ob_start();
foreach($files as $file)
{
	if(file_exists($file))
	{
		include($file); /* includo il file */
		$this_mtime = filemtime($file); /* leggo la data dell'ultima modifica */
		if($mtime &lt; $this_mtime) $mtime=$this_mtime;
	}
}
$lenght = ob_get_length(); /* lunghezza del contenuto */
$content = ob_get_contents(); /* il contenuto nella variabile $content da stampare successivamente */ ob_end_clean();

/* Headers */
header("Content-Type: text/css");
header("Last-Modified: ".date("D, d M Y H:i:s",$mtime)." GMT");
header("Content-Length",$lenght);
header("ETag: ".md5("compressed.css".$lenght.$mtime)); /* il file si chiama compressed.css */
header("Cache-Control: max-age=345600");

/* Stampo il contenuto */
echo $content;
?&gt;</pre>
<ul>
<li>per calcolare l&#8217;ultima modifica da inviare nel campo di intestazione &#8220;Last-Modified&#8221; sarà quella del file che è stato modificato più recentemente</li>
<li>nell&#8217;ETag inserisco anche il nome del file per aumentare l&#8217;univocità dell&#8217;ETag</li>
</ul>
<p>Come ultima operazione inserire nel file .htaccess la riga:</p>
<p><code>AddHandler application/x-httpd-php .css</code></p>
<p>Questa riga fa in modo che Apache processi i file css come file php.</p>
<h5>Pagine dinamiche e database</h5>
<p>Quando una pagina &#8220;dinamica&#8221; ha sempre gli <strong>stessi dati per diversi giorni</strong> è importante fare in modo che un utente, a partire dalla seconda visita, non ricarichi una nuova versione di quella pagina ma legga la versione memorizzata in cache.</p>
<p>Nei cms, come in Wordpress, c&#8217;è una netta separazione fra template e codice. In alcuni non è possibile creare un template per una singola pagina per altri, come Wordpress, si. Tuttavia, secondo me, è totalmente inutile creare un template per scrivere solo i tag &lt;meta&gt; e avere una gestione personalizzata della cache per quella pagina. Per questo motivo conviene <strong>inviare i campi di intestazione all&#8217;interno del codice</strong>.</p>
<p>Una prima idea è quella di definire delle condizioni per cui dei record restituiti dal database devono essere considerati &#8220;vecchi&#8221;, e in base a queste ed altre condizioni inviare gli opportuni valori dei campi di intestazione.</p>
<h3>3. Configurare il web server Apache</h3>
<p><a href="http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html"><img class="alignright size-full wp-image-181" title="Apache Server" src="http://jblog.it/wp-content/uploads/2009/04/4229-apache-server.jpg" alt="Apache Server" width="172" height="83" /></a>Per gestire la cache con Apache è necessario caricare i moduli <strong>mod_expires</strong> e <strong>mod_headers</strong>.</p>
<h5>Caricare i moduli</h5>
<ul>
<li>cerca e apri il file <strong>httpd.conf</strong></li>
<li>individua la lunga lista di &#8220;mod_&#8230;&#8221;</li>
<li>individua le righe con &#8220;mod_expires&#8221; e &#8220;mod_header&#8221;</li>
<li>elimina (se c&#8217;è) il carattere &#8220;#&#8221; che si trova prima del nome dei moduli che vuoi attivare</li>
<li>riavvia il server Apache</li>
</ul>
<p>A questo punto, nel file <strong>.htaccess</strong> bisogna definire le regole che consentono di gestire la cache a seconda del tipo o estensione dei file richiesti durante le connessioni http.</p>
<h5>Il modulo mod_expires</h5>
<p>Per conoscere meglio questo modulo ti consiglio di andare a leggere la guida ufficiale di Apache (in inglese): <a rel="nofollow" href="http://httpd.apache.org/docs/2.2/mod/mod_expires.html">http://httpd.apache.org/docs/2.2/mod/mod_expires.html</a>.</p>
<h5>Il modulo mod_headers</h5>
<p>Per conoscere meglio questo modulo ti consiglio di andare a leggere la guida ufficiale di Apache (in inglese): <a rel="nofollow" href="http://httpd.apache.org/docs/2.2/mod/mod_headers.html">http://httpd.apache.org/docs/2.2/mod/mod_headers.html</a>.</p>
<h5>Gestione della cache in base all&#8217;estensione</h5>
<pre>ExpiresActive On
ExpiresDefault A300
&lt;FilesMatch ".html$"&gt;
	Expires A86400
&lt;/FilesMatch&gt;
&lt;FilesMatch ".(gif|jpg|png|js|css)$"&gt;
	Expires A2592000
&lt;/FilesMatch&gt;</pre>
<ul>
<li>la prima riga (<strong>ExpiresActive</strong>) attiva il modulo &#8220;mod_expires&#8221;</li>
<li>la seconda riga (<strong>ExpiresDefault</strong>) imposta un valore di default del campo di intestazione &#8220;Expires&#8221; pari a 300 secondi</li>
<li>il primo blocco &lt;FilesMatch&gt; fa in modo che tutti i file html abbiano il campo di intestazione &#8220;Expires&#8221; con il valore 86400 secondi</li>
<li>il secondo blocco &lt;FilesMatch&gt; fa in modo che tutti i file gif, jpg, png, js, css abbiano il campo di intestazione &#8220;Expires&#8221; con il valore 2592000 secondi</li>
<li>la lettera <strong>A</strong> indica che il valore viene impostato <strong>dopo l&#8217;accesso</strong> al file, mentre la lettera <strong>M</strong> imposterebbe il valore <strong>dopo la modifica</strong> al file</li>
</ul>
<p><strong>Svantaggi.</strong> Spesso capita che alcuni file, benché siano dello stesso tipo, abbiano estensioni diverse. Ad esempio, le immagini con una compressione Jpeg possono avere l&#8217;estensione jpg oppure jpeg. Quindi se capitasse un file jpeg non si avrebbe la corrispondenza.</p>
<h5>Gestione della cache in base al tipo MIME</h5>
<p>Per assicurarci di individuare tutti i file di un certo tipo è necessario leggere il loro tipo MIME.</p>
<pre>ExpiresActive On
ExpiresDefault A300
ExpiresByType text/css "access plus 1 day"
ExpiresByType text/javascript "access plus 3 days"
ExpiresByType image/png "access plus 2 months"</pre>
<h2>Forzare l&#8217;aggiornamento dei componenti</h2>
<p>Se si utilizzano dei componenti che devono essere sempre aggiornati spesso non basta scrivere i campi di intestazione <code>"Cache-Control: no-cache"</code> e <code>"Pragma: no-cache"</code>. Esistono infatti <strong>prove documentate</strong> sul fatto che a volte questi campi vengono <strong>ignorati dai browser</strong>.</p>
<p>Quando utilizzavo un <strong>script captcha</strong> notavo che non si aggiornava l&#8217;immagine, il che era davvero un problema in quanto se l&#8217;utente sbagliava il codice doveva ricaricarsi la pagina con una nuova immagine.</p>
<p>La <strong>soluzione</strong> consiste nello scrivere l&#8217;indirizzo dell&#8217;immagine con un elemento dipendente dal tempo. Quindi, invece di scrivere:<br />
<code>&lt;img src="myimage.jpg" alt="La mia immagine" /&gt;</code></p>
<p>si cambierà l&#8217;indirizzo in:<br />
<code>&lt;img src="myimage.jpg?&lt;? echo time(); ?&gt;" alt="La mia immagine" /&gt;</code><br />
dove la funzione <code>time()</code> restituisce data e ora attuali in numeri interi (ad es. 11022103710).</p>
<p>Nel caso si utilizzi l&#8217;<strong>immagine come sfondo</strong>, anziché scrivere:<br />
<code>&lt;div style="background:#000 url('img/blackback.png') no-repeat left bottom"&gt;&lt;/div&gt;</code></p>
<p>si dovrà modificare l&#8217;indirizzo in:<br />
<code>&lt;div style="background:#000 url('img/blackback.png?&lt;? echo time(); ?&gt;') no-repeat left bottom"&gt;&lt;/div&gt;</code></p>
<p>Uno dei <strong>possibili svantaggi</strong> sta nel fatto che non tutti i file possono essere processati con il compilatore php. Se vuoi che un file .js (javascript) o .css (foglio di stile) venga processato come un file php basterà aggiungere al file .htaccess le seguenti righe:</p>
<p><code>AddHandler application/x-httpd-php .css<br />
AddHandler application/x-httpd-php .js</code></p>
<p>Per concludere, scrivendo questo articolo ho scoperto un mondo riguardo la cache e la sua gestione, ed ho capito che gestire adeguatamente la cache permette di ottimizzare notevolmente il caricamento delle pagine di un sito web.</p>
<p>Come utilizzavi la cache fino ad oggi? Ti limitavi a scrivere i tre tag &lt;meta&gt; o avevi già pensato di iniziare a utilizzare la cache più seriamente? Ti sembra importante o è solo una mia impressione? L&#8217;articolo è scritto bene o manca qualcosa?</p>
<h6 class="highlight_red">Non perdere il prossimo articolo: &#8220;Ridurre le richieste HTTP (parte 2): combinare e ottimizzare immagini, script e css&#8221;.</h6>
<h4>Crediti</h4>
<ul>
<li><strong>Libro.</strong> Creare siti web ad alte prestazioni: <a rel="nofollow" href="http://www.tecnichenuove.com/libri/creare_siti_web_ad_alte_prestazioni.html" target="_blank">http://www.tecnichenuove.com/libri/creare_siti&#8230;</a></li>
<li>Guida ufficiale di Apache: <a rel="nofollow" href="http://httpd.apache.org/docs/2.2/" target="_blank">http://httpd.apache.org/docs/2.2/</a></li>
<li>Use Server Cache Control to Improve Performance: <a rel="nofollow" href="http://websiteoptimization.com/speed/tweak/cache/" target="_blank">http://websiteoptimization.com/speed/tweak/cache/</a></li>
<li>Foto1: <a rel="nofollow" href="http://www.flickr.com/photos/aureusbay/297387489/">http://www.flickr.com/photos/aureusbay/297387489/</a></li>
<li>Foto2: <a href="http://www.flickr.com/photos/thingsarebetterwithaparrott/1054908626/">http://www.flickr.com/photos/thingsarebetterwithaparrott/1054908626/</a></li>
<li>Foto3: <a rel="nofollow" href="http://www.flickr.com/photos/galopoulos/567890941/">http://www.flickr.com/photos/galopoulos/567890941/</a></li>
</ul>
<img src="http://jblog.it/?ak_action=api_record_view&id=124&type=feed" alt=" Ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser"  title="Ridurre le richieste HTTP (parte 1): come utilizzare la cache del browser" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/04/24/ridurre-richieste-http-come-utilizzare-cache-browser_124.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Wordpress plugin: post e pagine casuali (basato su Advanced Random Posts)</title>
		<link>http://jblog.it/2009/04/17/wordpress-plugin-post-pagine-casuali-advanced-random-posts_65.html</link>
		<comments>http://jblog.it/2009/04/17/wordpress-plugin-post-pagine-casuali-advanced-random-posts_65.html#comments</comments>
		<pubDate>Thu, 16 Apr 2009 22:08:55 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Wordpress plugin]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=65</guid>
		<description><![CDATA[Una nuova versione del plugin Advanced Random Posts. Questa versione permette di selezionare sia post che pagine, una parte del contenuto, specificare id dei post da includere e da escludere, decidere se inserire in cima alla lista i post inclusi.]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><span style="text-decoration: underline;"><a href="http://jblog.it/2009/04/17/plugin-post-pagine-casuali_65.html/"><img class="size-full wp-image-92 alignright" title="Immagine: plugin per post e pagine casuali" src="http://jblog.it/wp-content/uploads/2009/04/random_posts1.jpg" alt="Immagine: plugin per post e pagine casuali" width="270" height="270" /></a></span>A primo impatto avere una lista di post casuali potrebbe sembrarti inutile. Infatti quando un lettore entra in un blog sa già cosa cercare oppure ci è arrivato tramite un motore di ricerca. Allora, perché dovresti inserire una lista di post casuali?</p>
<h4>Vantaggi</h4>
<ul>
<li>leggendo libri sull&#8217;<strong>usabilità</strong> dei siti web ho imparato che gli utenti sono molto pigri ma allo stesso tempo molto curiosi; allora ho pensato che se un lettore vuole leggere altri articoli è troppo pigro per ritornare nella homepage o nell&#8217;archivio, ma non per consultare una lista pronta di articoli da raggiungere con pochi click</li>
<li>se hai inserito il plugin &#8220;post correlati&#8221; hai sicuramente notato che a volte ci sono <strong>pochi articoli correlati</strong>; è proprio in questi casi che torna utile avere una <strong>lista alternativa</strong>, da mostrare automaticamente quando articoli correlati</li>
<li>gli appassionati di seo e guadagni online avranno subito pensato agli effetti in termini di tempo di permanenza; infatti invogliando gli utenti a visitare altre sezioni del sito o leggere altri articoli, ad esempio, avresti un <strong>aumento delle pagine viste</strong> con piacevoli conseguenze sul conto ad-sense <img src='http://jblog.it/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' title="Wordpress plugin: post e pagine casuali (basato su Advanced Random Posts)" /> </li>
<li>quando un <strong>nuovo (e potenziale) lettore</strong> capita nel tuo blog è importante aiutarlo a <strong>scoprire il blog e gli articoli che scrivi</strong>; a tal proposito sarebbe vantaggioso avere il blocco &#8220;post in evidenza&#8221;, con gli articoli, secondo te, qualitativamente migliori</li>
</ul>
<p><span id="more-65"></span></p>
<h4>Svantaggi</h4>
<ul>
<li>il database ha un&#8217;<strong>ulteriore query</strong> da eseguire</li>
<li>anche se di poco, dovrai modificare il <strong>design </strong>della pagina (operazione non gravosa se hai già l&#8217;area riservata ai &#8220;post correlati&#8221;)</li>
</ul>
<h3>Casuali, ma non troppo</h3>
<p>L&#8217;autore del plugin, Yakup GÃ–VLER, ha avuto la bellissima idea di far selezionare (opzionalmente) i post appartenenti alle <strong>stesse categorie</strong> del post principale.  Secondo me è veramente un&#8217;ottima caratteristica perché si mantiene comunque un certo collegamento con il post che si sta leggendo.</p>
<h2>Il plugin</h2>
<p><!--adv300--></p>
<p>L&#8217;autore del <a rel="nofollow" href="http://www.yakupgovler.com/?p=416" target="_blank">plugin originale</a> è <a rel="nofollow" href="http://www.yakupgovler.com" target="_blank">Yakup GÃ–VLER</a>.  Poiché non ero completamente soddisfatto dalla versione originale ho modificato solo la funzione principale. Infatti <strong>la mia versione non può essere gestita dal pannello di controllo</strong>, quindi è necessario entrare nei file del tema per modificare le opzioni.</p>
<h4>Caratteristiche del plugin originale</h4>
<ul>
<li>gestione del plugin nel pannello di controllo</li>
<li>scelta del numero di post (da 1 a 20)</li>
<li>selezione delle categorie dei post da stampare</li>
<li>stampa dei post appartenenti alle stesse categorie del post che si sta leggendo</li>
<li>selezione di id, link e titolo di ogni singolo post</li>
</ul>
<h4>Caratteristiche della mia versione del plugin</h4>
<ul>
<li>unica funzione php da richiamare e configurare all&#8217;interno dei file di template</li>
<li>scelta del numero di post (da 1 a 20)</li>
<li>selezione delle categorie dei post da stampare</li>
<li>stampa dei post appartenenti alle stesse categorie del post che si sta leggendo</li>
<li>selezione di id, link, titolo e contenuto di ogni singolo post</li>
<li>scelta del tipo di post tra &#8220;post&#8221; e &#8220;page&#8221;, o entrambi</li>
<li>scelta del post genitore della pagina</li>
<li>impostazione della lunghezza del contenuto del post</li>
<li>segnalazione dei post da includere ed escludere, con l&#8217;opzione di stampare per primi i post inclusi</li>
</ul>
<h2>Guida all&#8217;utilizzo</h2>
<p>La particolarità di questo plugin (nella mia versione) è che non stampa automaticamente la lista dei post, ma <strong>restituisce un array associativo</strong> da gestire a tuo piacimento.  Per utilizzare la funzione all&#8217;interno del template bisogna avere un array in cui inserire i risultati della funzione. Ecco un <strong>esempio</strong>:</p>
<pre lang="php">&lt;?php
$random_posts = jblog_random_posts("limit=15&amp;current_cat=1&amp;len=200&amp;post_type=post|page");
/*
- limit=15: recupera fino a 15 post
- current_cat=1: recupera i post di tipo "post" appartenenti alle stesse categorie del post che si sta leggendo
- len=200: seleziona anche il contenuto, in particolare i primi 200 caratteri
- post_type=post|page: recupera i post di tipo "post" e di tipo "page"
*/

foreach($random_posts as $random_post) { ?&gt;
&lt;h5&gt;&lt;a href="&lt;? echo $random_post['link']; ?&gt;"&gt;&lt;? echo $random_post['title']; ?&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;? echo $random_post['content']; ?&gt;
&lt;?php } ?&gt;</pre>
<h4>Parametri della funzione</h4>
<p>Come hai potuto notare, la funzione ha un unico parametro di tipo stringa in cui vengono passate le opzioni (nella forma [opzione]=[valore]) separate da &#8220;&amp;&#8221;.</p>
<dl>
<dt><strong>post_type</strong></dt>
<dd>Tipo dei post: &#8220;post&#8221;, &#8220;page&#8221;, &#8220;both&#8221; (entrambi). Default: &#8220;post&#8221;.</dd>
<dt><strong>post_parent</strong></dt>
<dd>ID del genitore del post. Valido solo se post_type=&#8221;page&#8221; o post_type=&#8221;both&#8221;. Default: &#8220;0&#8243;.</dd>
<dt><strong>limit</strong></dt>
<dd>Numero di post da selezionare. Impostare a &#8220;0&#8243; per stampare tutti i post. Default: &#8220;10&#8243;.</dd>
<dt><strong>cats</strong></dt>
<dd>ID delle categorie alle quali devono appartenere i post da selezionare. Valido solo se post_type=&#8221;post&#8221; o post_type=&#8221;both&#8221;.</dd>
<dt><strong>currentcat</strong></dt>
<dd>Impostare a &#8220;1&#8243; per selezionare  tutti i post appartenenti alle categorie del post che si sta leggendo. Valido solo se post_type=&#8221;post&#8221; o post_type=&#8221;both&#8221;. Default: &#8220;0&#8243;.</dd>
<dt><strong>len</strong></dt>
<dd>Lunghezza del contenuto dei post. Impostare con un numero maggiore di &#8220;0&#8243; per stampare il contenuto. Default: &#8220;0&#8243; (quindi non viene restituito il contenuto).</dd>
<dt><strong>exclude</strong></dt>
<dd>ID dei post da escludere.</dd>
<dt><strong>include</strong></dt>
<dd>ID dei post da includere.</dd>
<dt><strong>include_top</strong></dt>
<dd>Impostare a &#8220;1&#8243; per inserire nelle prime posizioni i post specificati da &#8220;include&#8221;. Default: &#8220;0&#8243;.</dd>
</dl>
<h4>Valori restituiti dalla funzione</h4>
<p>Il plugin non prevede la stampa automatica dell&#8217;elenco dei post, ma dovrai provvedere a scrivere un ciclo per la stampa degli elementi.  L&#8217;array che viene restituito è un array di array associativi. Un array associativo invece degli indici numerici ha indici di tipo stringa (molto più user-friendly). In particolare, questo array ha <strong>quattro indici</strong>: id, link, title e content (se len&gt;0), utilizzati nell&#8217;esempio precedente.</p>
<h2>Analisi del codice</h2>
<p>Vorrei fare alcune considerazioni sul codice, soprattutto perché potrei aiutarti nel caso volessi effettuare ulteriori modifiche.</p>
<p><strong>Composizione della query.</strong> Ho avuto modo di provare diverse tecniche per comporre una query durante il controllo e l&#8217;impostazione dei parametri. Durante la modifica di questo plugin ho utilizzato un array associativo (chiamato <code>$sql)</code>. Ogni indice corrisponde a una determinata sezione della query (&#8220;post_type&#8221;, &#8220;include&#8221;, &#8220;limit&#8221;, ecc.). La comodità consiste nell&#8217;avere una singola variabile (anche se complessa) da impostare nelle varie parti del codice e da utilizzare alla fine per comporre la query da eseguire.</p>
<p><strong>Funzioni di wordpress.</strong> Quando si sviluppa un plugin o si scrive una funzione da richiamare all&#8217;interno di wordpress è consigliabile sfruttare le funzioni predefinite come <code>wp_parse_args</code>, <code>apply_filters</code>, ecc. La prima serve per la lettura dell&#8217;unico parametro, <code>$args</code>, e la seconda per applicare un determinato filtro a una stringa. In particolare, la funzione apply_filters è stata utilizzata per la formattazione del titolo: <code>apply_filters('the_title', $post-&gt;post_title)</code>.</p>
<p><strong>Vuoi modificare ulteriormente il plugin?</strong> In effetti potresti aver bisogno di stampare altri dati. Allora ti consiglio di analizzare la variabile <code>$post</code> all&#8217;interno del ciclo <code>foreach</code> (in fondo alla funzione) per scoprire gli altri dati relativi al singolo post da inserire in un nuovo indice dell&#8217;array di array associativi. Ricordati di utilizzare gli opportuni filtri e le opportune funzioni per evitare brutte sorprese!!!</p>
<h3>Prossimamente&#8230;</h3>
<p>Onestamente non credo che questa mia funzione si possa definire &#8220;plugin&#8221;. Tuttavia farò di tutto per sviluppare una versione migliore cioè priva il più possibile di errori, con più opzioni e gestibile interamente dal pannello di controllo.</p>
<h3>Download</h3>
<p>Puoi scaricare il file del plugin <a href="http://download.jblog.it/wp-plugins/jblog_random_posts.zip">qui</a>.</p>
<h3>Crediti</h3>
<ul>
<li><span style="color: #000000; text-decoration: none;">Il </span><a rel="nofollow" href="http://www.yakupgovler.com/?p=416" target="_blank">plugin originale</a> è di <a rel="nofollow" href="http://www.yakupgovler.com" target="_blank">Yakup GÃ–VLER</a></li>
<li>La <a rel="nofollow" href="http://www.flickr.com/photos/adrian_wallett/2324532081/" target="_blank">prima immagine</a> è di <a rel="nofollow" href="http://www.justgiving.com/aliceburns" target="_blank">Adrian Wallett</a></li>
</ul>
<p><span class="highlight_green">Hai domande o suggerimenti da fare? Si sono verificati malfunzionamenti o errori? Vorresti un po&#8217; di aiuto per effettuare particolari modifiche?</span></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=65&type=feed" alt=" Wordpress plugin: post e pagine casuali (basato su Advanced Random Posts)"  title="Wordpress plugin: post e pagine casuali (basato su Advanced Random Posts)" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/04/17/wordpress-plugin-post-pagine-casuali-advanced-random-posts_65.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>echo &#8220;Hello world!&#8221;</title>
		<link>http://jblog.it/2009/04/14/echo-hello-world_43.html</link>
		<comments>http://jblog.it/2009/04/14/echo-hello-world_43.html#comments</comments>
		<pubDate>Tue, 14 Apr 2009 16:30:52 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://jblog.it/?p=43</guid>
		<description><![CDATA[Da &#8220;buon&#8221; programmatore &#8230; come iniziare se non con la classica riga di codice stampata nelle prime pagine dei manuali?!?
Un caloroso benvenuti a tutti! Finalmente ho finito (si fa per dire&#8230;) di sistemare il blog.
Ho iniziato a progettarlo a dicembre con l&#8217;obiettivo di metterlo on-line prima di Natale: naturalmente questo non è avvenuto. Con progettarlo intendo: [...]]]></description>
			<content:encoded><![CDATA[<p>Da &#8220;buon&#8221; programmatore &#8230; come iniziare se non con la classica riga di codice stampata nelle prime pagine dei manuali?!?</p>
<p>Un caloroso benvenuti a tutti! Finalmente ho finito (si fa per dire&#8230;) di sistemare il blog.</p>
<p>Ho iniziato a progettarlo a dicembre con l&#8217;obiettivo di metterlo on-line prima di Natale: naturalmente questo non è avvenuto. Con progettarlo intendo: decidere gli argomenti di cui parlare, disegnare un layout, leggere e imparare dai blogger più famosi.</p>
<p>Pensavo che aprire un blog, tutto sommato, fosse una cosa semplice: fai un logo, scarichi wordpress, scarichi un tema, configuri un po&#8217; di cose e inizi a scrivere. Non è stato così! Poteva esserlo, ma mentre ero alla ricerca di temi gradevoli che avessero una buona usabilità mi sono reso conto che forse era meglio farne uno partendo da zero. La progettazione e la realizzazione del tema grafico hanno ritardato di molto la pubblicazione del blog. Inoltre, bisogna considerare il tempo speso a cercare i plugin, configurarli e a volte personalizzarli (nel codice). Mi fermo qui per non annoiarti.</p>
<p>A breve inizierò a pubblicare i miei primi articoli su tutte quelle cose imparate durante la realizzazione di questo blog: design, plugin, wordpress, ecc.</p>
<p><strong>Torna a trovarmi ogni tanto e, se ti va, dammi la tua preziosa opinione</strong> sul blog, sugli articoli o su tutto quello che ti senti di criticare.</p>
<p>Nell&#8217;attesa <strong>ti</strong><strong> consiglio di dare uno sguardo alla pagina &#8220;</strong><a href="http://jblog.it/informazioni"><strong>informazioni</strong></a><strong>&#8220; </strong>dove potrai sapere tutto su di me e sul blog.</p>
<p>Buona lettura!</p>
<img src="http://jblog.it/?ak_action=api_record_view&id=43&type=feed" alt=" echo Hello world!"  title="echo Hello world!" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/2009/04/14/echo-hello-world_43.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mappa del blog</title>
		<link>http://jblog.it/mappa-blog</link>
		<comments>http://jblog.it/mappa-blog#comments</comments>
		<pubDate>Mon, 13 Apr 2009 13:17:58 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://jblog.it/?page_id=38</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[]]></content:encoded>
			<wfw:commentRss>http://jblog.it/mappa-blog/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contattami</title>
		<link>http://jblog.it/contattami</link>
		<comments>http://jblog.it/contattami#comments</comments>
		<pubDate>Mon, 13 Apr 2009 13:53:41 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://jblog.it/?page_id=31</guid>
		<description><![CDATA[



Puoi contattarmi direttamente su 
]]></description>
			<content:encoded><![CDATA[<div id="contact_form">
<div class="bottom">
<div class="wpcf7" id="wpcf7-f1-p31-o1"><form action="/feed#wpcf7-f1-p31-o1" method="post" class="wpcf7-form">
<div style="display: none;">
<input type="hidden" name="_wpcf7" value="1" />
<input type="hidden" name="_wpcf7_version" value="2.0.6" />
<input type="hidden" name="_wpcf7_unit_tag" value="wpcf7-f1-p31-o1" />
</div>
<div class="name_input"><span class="wpcf7-form-control-wrap email_name"><input type="text" name="email_name" value="" id="email_name" class="wpcf7-validates-as-required" size="40" /></span></div>
<div class="name_label"><label>NOME <small>(richiesto)</small></label></div>
<div class="clear"></div>
<div class="email_input"><span class="wpcf7-form-control-wrap email_email"><input type="text" name="email_email" value="" id="email_email" class="wpcf7-validates-as-required" size="40" /></span></div>
<div class="email_label"><label>EMAIL <small>(richiesta)</small></label></div>
<div class="clear"></div>
<div class="url_input"><span class="wpcf7-form-control-wrap email_website"><input type="text" name="email_website" value="" id="email_url" size="40" /></span></div>
<div class="url_label"><label>SITO WEB</label></div>
<div class="clear"></div>
<div class="subject_input">
<div class="right"><span class="wpcf7-form-control-wrap email_subject"><input type="text" name="email_subject" value="" id="email_subject" size="40" /></span></div>
</div>
<div class="subject_label"><label>OGGETTO</label></div>
<div class="clear"></div>
<div class="textarea_input"><span class="wpcf7-form-control-wrap email_message"><textarea name="email_message" id="email_message" class="wpcf7-validates-as-required" cols="40" rows="10"></textarea></span></div>
<div class="captcha_input">
<div class="captcha_img"><input type="hidden" name="_wpcf7_captcha_challenge_email_captcha" value="1429053202" /><img alt="1429053202 Contattami" src="http://jblog.it/wp-content/uploads/wpcf7_captcha/1429053202.png" id="email_captcha_img" class="wpcf7-captcha-email_captcha" width="84" height="28" title="Contattami" /></div>
<div class="captcha_data"><span class="wpcf7-form-control-wrap email_captcha"><input type="text" name="email_captcha" value="" id="email_captcha_data" size="40" /></span> <span class="captcha_label">Per favore, inserisci il codice di sicurezza</span></div>
<div class="clear"></div>
</div>
<div class="submit_input"><input type="submit" value="Invia il messaggio" id="email_submit" /> <img class="ajax-loader" style="visibility: hidden;" alt="ajax loader" src="http://jblog.it/wp-content/plugins/contact-form-7/images/ajax-loader.gif" title="Contattami" /></div>
<div class="wpcf7-response-output wpcf7-display-none"></div></form></div>
</div>
</div>
<p>Puoi contattarmi direttamente su <img class="alignnone size-full wp-image-35" title="mail" src="http://jblog.it/wp-content/uploads/2009/04/mail.png" alt="mail Contattami" width="174" height="21" /></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=31&type=feed" alt=" Contattami"  title="Contattami" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/contattami/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bookmarks</title>
		<link>http://jblog.it/bookmarks</link>
		<comments>http://jblog.it/bookmarks#comments</comments>
		<pubDate>Mon, 13 Apr 2009 13:50:48 +0000</pubDate>
		<dc:creator>Giacomo</dc:creator>
				<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://jblog.it/?page_id=28</guid>
		<description><![CDATA[Ecco la lista completa di tutti i miei siti, blog, pagine e link preferiti divisi per categoria.
Puoi trovare di tutto: da siti e blog tecnici a servizi web, da tutorial a giochi online.
N.B. per ogni categoria, i link più recenti si trovano all&#8217;inizio.
Spero possano esserti utili. Buona navigazione!
]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">Ecco la lista completa di <strong>tutti </strong>i miei siti, blog, pagine e link preferiti <strong>divisi per categoria</strong>.</p>
<p style="text-align: left;"><strong>Puoi trovare di tutto</strong>: da siti e blog tecnici a servizi web, da tutorial a giochi online.</p>
<p style="text-align: left;"><strong>N.B.</strong> per ogni categoria, <strong>i link più recenti si trovano all&#8217;inizio</strong>.</p>
<p style="text-align: left;">Spero possano esserti utili. <em><strong>Buona navigazione!</strong></em></p>
<img src="http://jblog.it/?ak_action=api_record_view&id=28&type=feed" alt=" Bookmarks"  title="Bookmarks" />]]></content:encoded>
			<wfw:commentRss>http://jblog.it/bookmarks/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
