<?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>Olivier Balais &#187; Développement Web</title>
	<atom:link href="http://blog.overnetcity.com/categorie/developpement-web/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.overnetcity.com</link>
	<description>OvernetCity, blog d&#039;un auto-entrepreneur passionné par le développement Web et les NTIC</description>
	<lastBuildDate>Thu, 26 Jan 2012 13:08:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Failed opening required &#8216;phar://&#8230;</title>
		<link>http://blog.overnetcity.com/25-01-2012/failed-opening-required-phar/</link>
		<comments>http://blog.overnetcity.com/25-01-2012/failed-opening-required-phar/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 20:32:52 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[behat]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[include]]></category>
		<category><![CDATA[ioncube]]></category>
		<category><![CDATA[phar]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=513</guid>
		<description><![CDATA[Chez PMSIpilot, nous commençons à utiliser Behat pour nos tests fonctionnels. Je ne vais pas m&#8217;étendre sur toutes les belles choses que ce framework de bdd apportera au testing de votre projet, il vous suffit de vous rendre sur leur site officiel et de lire leur introduction rapide pour vous en persuader. Le problème auquel [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F25-01-2012%2Ffailed-opening-required-phar%2F' data-shr_title='Failed+opening+required+%27phar%3A%2F%2F...'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F25-01-2012%2Ffailed-opening-required-phar%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F25-01-2012%2Ffailed-opening-required-phar%2F' data-shr_title='Failed+opening+required+%27phar%3A%2F%2F...'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Chez <a href="http://www.pmsipilot.org/" title="Blog du service technique de PMSIpilot" target="_blank">PMSIpilot</a>, nous commençons à utiliser Behat pour nos tests fonctionnels.<br />
Je ne vais pas m&#8217;étendre sur toutes les belles choses que ce framework de bdd apportera au testing de votre projet, il vous suffit de vous rendre sur leur <a href="http://behat.org/" target="_blank">site officiel</a> et de lire leur <a href="http://docs.behat.org/quick_intro.html" target="_blank">introduction rapide</a> pour vous en persuader.</p>
<p>Le problème auquel j&#8217;ai immédiatement fait face en tentant d&#8217;inclure le Phar de Behat est le suivant :</p>
<p><code>Fatal error: require(): Failed opening required 'phar:///[...]/lib/vendor/behat/behat.phar'</code></p>
<p>La ligne incriminée ne pouvait pas être plus simple :</p>
<p><code>include 'phar:///[...]/lib/vendor/behat/behat.phar';</code></p>
<p>Après avoir interrogé dans toutes les langues et sous toutes les formes mon moteur de recherché préféré, difficile de trouver une explication rationnelle.<br />
Comme souvent, la réponse est venue par l&#8217;intermédiaire d&#8217;un collègue (merci <a href="https://fr.twitter.com/#!/jubianchi" target="_blank">@jubianchi</a> et <a href="https://fr.twitter.com/#!/ratibus" target="_blank">@ratibus</a> !) et il s&#8217;avère que c&#8217;est l&#8217;extension ioncube qui était en cause sur mon poste. Si vous avez ce problème, c&#8217;est donc peut-être une piste à suivre.</p>
<p>Pour tester si <a href="http://www.ioncube.com/" target="_blank">ioncube </a>est activé :</p>
<p><code>$ php -i | grep -i ioncube<br />
    with the ionCube PHP Loader v4.0.5, Copyright (c) 2002-2011, by ionCube Ltd., and<br />
ionCube Loader<br />
</code></p>
<p>Chez moi c&#8217;était la version ioncube <strong>4.0.5</strong> qui posait problème. Rassurez-vous néanmoins, une fois la dernière version de ioncube installée, plus de problème à noter ! Apparemment le problème est réglé au moins depuis la version 4.0.9.</p>
<p>Le lien direct pour télécharger la dernière version stable pour une distrib linux 32 bits : <a href="http://downloads2.ioncube.com/loader_downloads/ioncube_loaders_lin_x86.tar.gz">http://downloads2.ioncube.com/loader_downloads/ioncube_loaders_lin_x86.tar.gz</a></p>
<p>Une fois l&#8217;extension décompressée et placée au bon endroit, l&#8217;include passe sans encombre.</p>
<p><code>$ php -i | grep -i ioncube<br />
    with the ionCube PHP Loader v4.0.12, Copyright (c) 2002-2011, by ionCube Ltd., and<br />
ionCube Loader</code></p>
<div class="shr-publisher-513"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F25-01-2012%2Ffailed-opening-required-phar%2F' data-shr_title='Failed+opening+required+%27phar%3A%2F%2F...'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F25-01-2012%2Ffailed-opening-required-phar%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F25-01-2012%2Ffailed-opening-required-phar%2F' data-shr_title='Failed+opening+required+%27phar%3A%2F%2F...'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/25-01-2012/failed-opening-required-phar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passer de SVN à Git en préservant son historique de commits</title>
		<link>http://blog.overnetcity.com/14-11-2011/passer-de-svn-a-git-en-preservant-son-historique-de-commits/</link>
		<comments>http://blog.overnetcity.com/14-11-2011/passer-de-svn-a-git-en-preservant-son-historique-de-commits/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 09:24:59 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=483</guid>
		<description><![CDATA[Subversion (SVN) a eu une belle carrière parmi les outils de versionning mais il est aujourd&#8217;hui largement supplanté par Git. Plus souple, plus rapide, plus puissant, nombreux sont les développeurs qui souhaitent migrer leurs dépôts vers Git. Mais il serait dommage de perdre l&#8217;historique de son projet, surtout quand celui-ci remonte sur plusieurs mois / [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F14-11-2011%2Fpasser-de-svn-a-git-en-preservant-son-historique-de-commits%2F' data-shr_title='Passer+de+SVN+%C3%A0+Git+en+pr%C3%A9servant+son+historique+de+commits'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F14-11-2011%2Fpasser-de-svn-a-git-en-preservant-son-historique-de-commits%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F14-11-2011%2Fpasser-de-svn-a-git-en-preservant-son-historique-de-commits%2F' data-shr_title='Passer+de+SVN+%C3%A0+Git+en+pr%C3%A9servant+son+historique+de+commits'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Subversion (SVN) a eu une belle carrière parmi les outils de versionning mais il est aujourd&#8217;hui largement supplanté par Git. Plus souple, plus rapide, plus puissant, nombreux sont les développeurs qui souhaitent migrer leurs dépôts vers Git. Mais il serait dommage de perdre l&#8217;historique de son projet, surtout quand celui-ci remonte sur plusieurs mois / années.</p>
<p>Le sujet a déjà largement été abordé sur différents blogs, forums et mailing-list mais je vais simplement compléter les étapes classiques par celles que j&#8217;ai dû ajouter pour pouvoir migrer mes propres dépôts SVN qui n&#8217;avaient pas tous une structure standard (pas de Trunk par exemple&#8230;).<br />
Nous utiliserons la commande par défaut git-svn. Si besoin : <code>sudo apt-get install git-svn</code></p>
<p>Quelques étapes indispensables (pour plus de détails, se rendre à <a href="http://help.github.com/import-from-subversion/">cette adresse</a>, ou à <a href="http://www.albin.net/git/convert-subversion-to-git">celle-ci</a>) :</p>
<h2>Récupérer les différents commiters sur son dépôt SVN</h2>
<p><code>svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > commiters.txt</code></p>
<p>Il suffit ensuite de transformer chaque ligne du fichier généré vers quelque chose du genre :</p>
<p>obalais = Olivier Balais &lt;obalais@server.com&gt;</p>
<h2>Cloner votre dépôt SVN</h2>
<p>Ici on spécifie l&#8217;url de son dépôt SVN, le fichier à utiliser pour les logs de commit et un dossier dans lequel cloner le dépôt. L&#8217;option no-metadata supprime les notes que git-svn ajoute à chaque message de commit par défaut.</p>
<p><code>git svn clone URL_DEPOT --no-metadata -A commiters.txt --stdlayout ~/mon_depot</code></p>
<p>Certains de mes dépôts avaient une structure non standard. Par exemple, certains projets simples n&#8217;avaient tout simplement pas de trunk, branches et tags mais directement la structure du projet commitée à la racine du dépôt (oui c&#8217;est moche&#8230;). Pour se sortir de ce genre de galères on peut utiliser les options -T, -t et -b pour spécifier les URI des Trunk, Tag et Branches. Dans mon cas, j&#8217;ai utilisé la commande suivante :</p>
<p><code>git svn clone URL_DEPOT --no-metadata <strong>-T</strong> / -A authors.txt --stdlayout ~/mon_depot</code></p>
<p>Sur un projet, j&#8217;ai également souhaité récupérer tous les commits excepté le dernier. Pour cela, il suffit d&#8217;ajouter l&#8217;option <code>-r initial_revision:final_revision</code>. Exemple :</p>
<p><code>git svn clone URL_DEPOT --no-metadata -T / <strong>-r 1:99</strong> -A authors.txt --stdlayout ~/mon_depot</code></p>
<h2>Créer un dépôt vide pour y pusher le contenu de son ancien dépôt SVN</h2>
<p><code>git init --bare ~/mon_projet.git<br />
cd ~/mon_projet.git<br />
git symbolic-ref HEAD refs/heads/trunk</code></p>
<p>Pusher le contenu en faisant :</p>
<p><code>cd ~/mon_depot<br />
git remote add bare ~/mon_projet.git<br />
git config remote.bare.push 'refs/remotes/*:refs/heads/*'<br />
git push bare</code></p>
<p>Il ne reste désormais plus qu&#8217;à renommer la branche trunk en master&#8230;</p>
<h2>Renommer son trunk en master</h2>
<p><code>cd ~/mon_projet.git<br />
git branch -m trunk master</code></p>
<p>And you&#8217;re done!</p>
<div class="shr-publisher-483"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F14-11-2011%2Fpasser-de-svn-a-git-en-preservant-son-historique-de-commits%2F' data-shr_title='Passer+de+SVN+%C3%A0+Git+en+pr%C3%A9servant+son+historique+de+commits'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F14-11-2011%2Fpasser-de-svn-a-git-en-preservant-son-historique-de-commits%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F14-11-2011%2Fpasser-de-svn-a-git-en-preservant-son-historique-de-commits%2F' data-shr_title='Passer+de+SVN+%C3%A0+Git+en+pr%C3%A9servant+son+historique+de+commits'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/14-11-2011/passer-de-svn-a-git-en-preservant-son-historique-de-commits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Premiers pas avec Node.js &#8211; Installation de Node et Express</title>
		<link>http://blog.overnetcity.com/19-05-2011/premiers-pas-avec-node-js-installation-de-node-et-express/</link>
		<comments>http://blog.overnetcity.com/19-05-2011/premiers-pas-avec-node-js-installation-de-node-et-express/#comments</comments>
		<pubDate>Thu, 19 May 2011 12:03:01 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[serveur]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=400</guid>
		<description><![CDATA[Chez PMSIpilot, à chaque fin de Sprint, les équipes techniques organisent et participent à ce qu&#8217;on appelle les &#8220;ateliers&#8221;. Comme tout bon geek qui se respecte, j&#8217;ai une soif insatiable d&#8217;apprendre de nouvelles choses et je participe donc en général au plus grand nombre possible de ces ateliers. Un de ceux qui m&#8217;ont le plus [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F19-05-2011%2Fpremiers-pas-avec-node-js-installation-de-node-et-express%2F' data-shr_title='Premiers+pas+avec+Node.js+-+Installation+de+Node+et+Express'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F19-05-2011%2Fpremiers-pas-avec-node-js-installation-de-node-et-express%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F19-05-2011%2Fpremiers-pas-avec-node-js-installation-de-node-et-express%2F' data-shr_title='Premiers+pas+avec+Node.js+-+Installation+de+Node+et+Express'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p><img src="http://blog.overnetcity.com/wp-content/uploads/2011/05/logo.png" alt="" title="Node.js" width="420" height="111" class="alignnone size-full wp-image-402" /></p>
<p>Chez <a href="http://www.pmsipilot.org/2011/02/02/les-pmsiateliers/">PMSIpilot</a>, à chaque fin de Sprint, les équipes techniques organisent et participent à ce qu&#8217;on appelle les &#8220;ateliers&#8221;. Comme tout bon geek qui se respecte, j&#8217;ai une soif insatiable d&#8217;apprendre de nouvelles choses et je participe donc en général au plus grand nombre possible de ces ateliers. Un de ceux qui m&#8217;ont le plus marqué est sans aucun doute celui qui présentait le fonctionnement et l&#8217;utilisation de <strong>Node.js</strong>.</p>
<p>Je vais donc profiter de ce blog pour faire un retour au fur et à mesure de ma découverte de Node.js et de son écosystème.<br />
Ce premier billet résume l&#8217;installation de Node et Express et me servira de mémo pour retrouver facilement les commandes qui vont bien.</p>
<p>Node.js est un framework très en vogue qui consiste à utiliser le langage Javascript avec le moteur V8 de Google côté serveur pour servir les requêtes HTTP reçues.</p>
<p>Parmis les intérêts majeurs de ce type d&#8217;approche on retient notamment :</p>
<ul>
<li>L&#8217;approche évènementielle du framework (entrées / sorties non bloquantes&#8230;)</li>
<li>La possibilité d&#8217;utiliser un seul langage côté serveur et côté client pour les applications Full JS</li>
</ul>
<p>Ainsi, grâce à sa légèreté et à ses I/O non bloquants, Node.js permet de développer une application web capable de recevoir et de répondre à un nombre de requêtes infiniment plus conséquent qu&#8217;une même application développée avec une pile LAMP classique.<br />
C&#8217;est toute la philosophie du développement web qui se voit bouleversée par cette approche évènementielle.</p>
<p>Pour plus d&#8217;informations à ce sujet, je vous invite à lire les articles suivants :</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Nodejs">http://en.wikipedia.org/wiki/Nodejs</a></li>
<li><a href="http://anders.janmyr.com/2011/05/not-very-short-introduction-to-nodejs.html">http://anders.janmyr.com/2011/05/not-very-short-introduction-to-nodejs.html</a></li>
<li><a href="http://nodejs.org">http://nodejs.org</a></li>
</ul>
<p>Let&#8217;s get started!</p>
<p>Première étape, télécharger et installer Node.js. Pour se faire RDV sur le site officiel pour télécharger la dernière release en date : <a href="http://nodejs.org/#download">http://nodejs.org/#download</a>. Décompressez l&#8217;archive, rendez-vous dans le dossier et exécutez les commandes suivantes une par une :</p>
<p><code>mkdir ~/local<br />
./configure --prefix=$HOME/local/node<br />
make<br />
make install<br />
export PATH=$HOME/local/node/bin:$PATH<br />
</code></p>
<p>La commande make prend un certain temps à s&#8217;exécuter donc il faut s&#8217;armer de patience. Ensuite le reste est trivial.<br />
A noter que si au moment du lancement de <code>configure</code>, vous avez une erreur du type <code>Could not autodetect OpenSSL support. Make sure OpenSSL development packages are installed</code>, c&#8217;est qu&#8217;il vous manque la lib OpenSSL.<br />
Dans ce cas, un petit apt-get résoud le problème : </p>
<p><code>sudo apt-get install libssl-dev</code></p>
<p>Dans le même ordre d&#8217;idée, il se peut qu&#8217;un message vous avertisse qu&#8217;il manque un compilateur du type g++ / c++. Dans ce cas :</p>
<p><code>sudo apt-get install g++</code></p>
<p>Voilà une bonne chose de faite. Testez l&#8217;installation en exécutant la commande suivante :</p>
<p><code>obalais@server:~$ node -v<br />
v0.4.7</code></p>
<p>Même s&#8217;il est possible de créer une application web complète juste avec Node.js, nous allons installer des plugins qui vont nous faciliter le développement. Un framework MVC (<strong>Express</strong>) par exemple me semble plus que nécessaire, un moteur de template (<strong>Jade</strong>) ainsi qu&#8217;un ORM pour la base de données (<strong>Mongoose</strong> si on utilise une base MongoDb).<br />
Nous avons de la chance puisqu&#8217;un gestionnaire de paquets spécifique à Node.js est devenu plus ou moins un standard pour récupérer facilement les plugins qui existent, à savoir <strong>NPM</strong>.</p>
<p>Si vous n&#8217;avez pas curl :</p>
<p><code>sudo apt-get install curl</code></p>
<p>Ensuite, l&#8217;installation de NPM est on ne peut plus simple puisqu&#8217;il suffit d&#8217;une seule ligne :</p>
<p><code>curl http://npmjs.org/install.sh | sh</code></p>
<p>Et une fois de plus, vous pouvez tester si l&#8217;installation s&#8217;est bien déroulée en lançant la commande suivante :</p>
<p><code>obalais@server:~$ npm -v<br />
1.0.6<br />
</code></p>
<p>Nous allons tout de suite mettre à profit NPM en installant <a href="http://expressjs.com/">Express</a>, le framework de développement web le plus abouti actuellement pour Node.js.</p>
<p><img src="http://blog.overnetcity.com/wp-content/uploads/2011/05/express.png" alt="" title="Express" width="217" height="69" class="alignnone size-full wp-image-409" /></p>
<p>Voici la liste de ses features, directement récupérée depuis le site officiel :</p>
<ul>
<li>Robust routing</li>
<li>Redirection helpers</li>
<li>Dynamic view helpers</li>
<li>Application level view options</li>
<li>Content negotiation</li>
<li>Application mounting</li>
<li>Focus on high performance</li>
<li>View rendering and partials support</li>
<li>Environment based configuration</li>
<li>Session based flash notifications</li>
<li>Built on Connect</li>
<li>Executable for generating applications quickly</li>
<li>High test coverage</li>
</ul>
<p>Grâce à NPM, l&#8217;installation se fait encore une seule ligne toute simple :</p>
<p><code>npm install express</code></p>
<p>N&#8217;oubliez pas de rajouter express à votre PATH et de tester le résultat de l&#8217;installation :</p>
<p><code>obalais@server:~$ export PATH=$HOME/node_modules/express/bin:$PATH<br />
obalais@server:~$ express --version<br />
2.3.4<br />
</code></p>
<p><img src="http://blog.overnetcity.com/wp-content/uploads/2011/05/Jade1.png" alt="" title="Jade" width="600" height="341" class="alignnone size-full wp-image-430" /></p>
<p>Maintenant installez <a href="http://jade-lang.com/">Jade</a> :</p>
<p><code>npm install jade</code></p>
<p>Tout est en place. Il ne reste plus qu&#8217;à créer notre serveur avec Node.js + Express. Pour cela, créez un fichier helloworld.js contenant le code suivant :</p>
<pre class="brush: javascript; ">

var app = require(&#039;express&#039;).createServer();

app.get(&#039;/&#039;, function(req, res){
  res.send(&#039;&lt;h1&gt;another hello world&lt;/h1&gt;&#039;);
});

app.listen(3000);
</pre>
<p>On lance le serveur node.js avec la commande suivante :</p>
<p><code>node helloworld.js</code></p>
<p>Et on teste si tout fonctionne correctement en se rendant via son navigateur sur son localhost sur le port 3000.</p>
<p><img src="http://blog.overnetcity.com/wp-content/uploads/2011/05/hello_world.png" alt="" title="hello_world" width="790" height="332" class="alignnone size-full wp-image-417" /></p>
<p>Nous verrons dans un prochain article quels sont les principes fondamentaux du développement avec Express et Node.js.<br />
En attendant, je vous laisse visiter le site officiel d&#8217;Express qui contient toute la documentation nécessaire pour se lancer dans l&#8217;utilisation du Framework. Faites un tour sur <a href="http://expressjs.com/guide.html">cette page pour commencer</a>.</p>
<div class="shr-publisher-400"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F19-05-2011%2Fpremiers-pas-avec-node-js-installation-de-node-et-express%2F' data-shr_title='Premiers+pas+avec+Node.js+-+Installation+de+Node+et+Express'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F19-05-2011%2Fpremiers-pas-avec-node-js-installation-de-node-et-express%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F19-05-2011%2Fpremiers-pas-avec-node-js-installation-de-node-et-express%2F' data-shr_title='Premiers+pas+avec+Node.js+-+Installation+de+Node+et+Express'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/19-05-2011/premiers-pas-avec-node-js-installation-de-node-et-express/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>sfForms et valeurs par défaut. Pourquoi est-ce que getDefault me renvoie null ?</title>
		<link>http://blog.overnetcity.com/11-05-2011/sfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null/</link>
		<comments>http://blog.overnetcity.com/11-05-2011/sfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null/#comments</comments>
		<pubDate>Wed, 11 May 2011 16:15:32 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[bug symfony]]></category>
		<category><![CDATA[default values]]></category>
		<category><![CDATA[null]]></category>
		<category><![CDATA[sfForms]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=353</guid>
		<description><![CDATA[Les formulaires de symfony ont quelquefois des comportements surprenants pour le développeur. Tout le monde pense immédiatement aux embed forms mais ce n&#8217;est pas de ces derniers dont je vais parler ici. Je suis tombé sur le problème suivant : pourquoi après avoir passé une valeur par défaut à un des widgets de mon formulaire, [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Les formulaires de symfony ont quelquefois des comportements surprenants pour le développeur. Tout le monde pense immédiatement aux <strong>embed forms </strong>mais ce n&#8217;est pas de ces derniers dont je vais parler ici.</p>
<p>Je suis tombé sur le problème suivant : pourquoi après avoir passé une valeur par défaut à un des widgets de mon formulaire, je ne parviens pas à la récupérer dans mon action ou dans mon template ? L&#8217;appel à la méthode getDefault du sfForm me renvoie <em>null,</em> tout simplement.</p>
<p>Cas typique :</p>
<pre class="brush: php; ">

// Dans le code de mon formulaire :
$this-&gt;setWidgets(array(
  ...
  &#039;my_field&#039; =&gt; new sfMyWidget(array(&#039;default&#039; =&gt; &#039;my_value&#039;)),
));

// Dans le code de mon action :
if ($my_form-&gt;getDefault(&#039;my_field&#039;) == &#039;some_value&#039;)
{
  ...
}
</pre>
<p>Dans ce cas, la méthode getDefault() appelée sur mon formulaire me renvoie null alors que j&#8217;ai explicitement donné une valeur par défaut à mon widget. Pourtant, en lisant la doc de symfony sur le sujet je retiens ceci :</p>
<blockquote><p>The setDefault(), getDefault(), setDefaults(), and getDefaults() methods manages the default values for the embedded widgets. <span style="text-decoration: underline;">They are proxy methods </span>for the getDefault() and setDefault() widget methods.</p></blockquote>
<p>Les méthodes setDefault() et getDefault() au niveau de la classe sfForm sont censées êtres des raccourcis pour les méthodes setDefault() et getDefault() de la classe sfWidgetForm().</p>
<p>En fait il s&#8217;avère que ce n&#8217;est absolument pas le cas et que la méthode getDefault() du formulaire ne fait jamais appel à la méthode getDefault() du widget associé.</p>
<p>L&#8217;appel à <strong>$my_form-&gt;getDefault(&#8216;my_field&#8217;)</strong> n&#8217;est donc pas équivalent à <strong>$my_form['my_field']-&gt;getWidget()-&gt;getDefault()</strong>.</p>
<p>Par conséquent, il est important de bien comprendre quelle méthode appeler et dans quel cas.</p>
<p>A savoir, <strong>$my_form-&gt;getDefault(&#8216;my_field&#8217;)</strong> quand le setDefault a été utilisé<strong> au niveau du formulaire</strong>. Exemple :</p>
<pre class="brush: php; ">

// Valeurs passées dans mon formulaire :
$this-&gt;setWidgets(array(
  ...
  &#039;my_field&#039; =&gt; new sfMyWidget(),
));
$this-&gt;setDefault(&#039;my_field&#039;, &#039;my_value&#039;);

// Ou alors valeurs passées dans mon action :
$my_form = new myFormClass(array(
  ...
  &#039;my_field&#039; =&gt; &#039;my_value&#039;,
));
</pre>
<p>Et, <strong>$my_form['my_field']-&gt;getWidget()-&gt;getDefault()</strong> quand le setDefault() a été utilisé <strong>au niveau du widget</strong>. Exemple :</p>
<pre class="brush: php; ">

// Dans le code de mon formulaire :
$this-&gt;setWidgets(array(
  ...
  &#039;my_field&#039; =&gt; new sfMyWidget(array(&#039;default&#039; =&gt; &#039;my_value&#039;)),
));
</pre>
<p>Voilà, désormais vous êtes prévenus&#8230;</p>
<div class="shr-publisher-353"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F11-05-2011%2Fsfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null%2F' data-shr_title='sfForms+et+valeurs+par+d%C3%A9faut.+Pourquoi+est-ce+que+getDefault+me+renvoie+null+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/11-05-2011/sfforms-et-valeurs-par-defaut-pourquoi-est-ce-que-getdefault-me-renvoie-null/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Les ressources utiles du mois de Février (et +)</title>
		<link>http://blog.overnetcity.com/09-03-2011/les-ressources-utiles-du-mois-de-fevrier-et/</link>
		<comments>http://blog.overnetcity.com/09-03-2011/les-ressources-utiles-du-mois-de-fevrier-et/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 12:32:41 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery Mobile]]></category>
		<category><![CDATA[Ressources Utiles]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=315</guid>
		<description><![CDATA[Et ben&#8230; Moi qui pensais rédiger chaque mois un article regroupant les meilleur liens sur lesquels je tombe, je viens de constater que le dernier (et aussi le premier) posté dans cette rubrique date de&#8230; Juillet. Allez j&#8217;ai une excuse, pendant ce temps, je suis parti plusieurs mois en roadtrip à l&#8217;autre bout du monde&#8230; [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F09-03-2011%2Fles-ressources-utiles-du-mois-de-fevrier-et%2F' data-shr_title='Les+ressources+utiles+du+mois+de+F%C3%A9vrier+%28et+%2B%29'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F09-03-2011%2Fles-ressources-utiles-du-mois-de-fevrier-et%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F09-03-2011%2Fles-ressources-utiles-du-mois-de-fevrier-et%2F' data-shr_title='Les+ressources+utiles+du+mois+de+F%C3%A9vrier+%28et+%2B%29'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Et ben&#8230; Moi qui pensais rédiger chaque mois un article regroupant les meilleur liens sur lesquels je tombe, je viens de constater que le dernier (et aussi le premier) posté dans cette rubrique date de&#8230; Juillet.<br />
Allez j&#8217;ai une excuse, pendant ce temps, je suis parti plusieurs mois en roadtrip à l&#8217;autre bout du monde&#8230;</p>
<p>Depuis mon retour en France, j&#8217;ai repris les choses sérieuses et ai de nouveau le loisir de glaner ci et là de bonnes ressources pour le boulot (et pour ma culture).</p>
<p>Voici donc ma sélection pour le mois de Février.</p>
<h2>Isotope</h2>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2011/03/Isotope.png"><img title="Isotope" src="http://blog.overnetcity.com/wp-content/uploads/2011/03/Isotope-300x65.png" alt="" width="300" height="65" /></a></p>
<p>Isotope est un plugin jQuery fantastique. Il permet de réorganiser à la volée l&#8217;affichage d&#8217;éléments au sein d&#8217;une page Web en fonction de différents critères qu&#8217;il suffit au développeur de définir (ordre, type, taille de l&#8217;écran&#8230;).</p>
<p>Je vais très prochainement l&#8217;intégrer à l&#8217;un de mes projets pour faire un joli filtrage dynamique d&#8217;items.</p>
<p><strong>URL : </strong><a href="http://isotope.metafizzy.co/" target="_blank">http://isotope.metafizzy.co/</a></p>
<h2>Osez créer un site HTML5 et CSS3</h2>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2011/03/logo-alsacreations-com.png"><img title="Logo Alsacréations" src="http://blog.overnetcity.com/wp-content/uploads/2011/03/logo-alsacreations-com.png" alt="" width="290" height="80" /></a></p>
<p>Raphael Goetter du site Alsacréations nous démontre dans un très bon article qu&#8217;il est possible aujourd&#8217;hui de développer un site en HTML5 et CSS3. Il explique quels compromis il a dû faire pour les anciens navigateurs et quelles sont les parades pour ne pas rendre son site complètement inaccessible sur ces derniers.</p>
<p>Pour ma part, c&#8217;est cet article qui m&#8217;a convaincu de développer ma prochaine appli web en HTML5, malgré la part encore très importante de personnes utilisant IE6, 7 et 8.</p>
<p><strong>URL : </strong><a href="http://www.alsacreations.com/article/lire/947-osez-creer-site-html5-css3.html" target="_blank">http://www.alsacreations.com/article/lire/947-osez-creer-site-html5-css3.html</a></p>
<h2>Jquery Mobile DateBox</h2>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2011/03/jQuery-DateBox.png"><img title="jQuery Mobile DateBox" src="http://blog.overnetcity.com/wp-content/uploads/2011/03/jQuery-DateBox-300x83.png" alt="" width="300" height="83" /></a></p>
<p>Enfin, et parce que je m&#8217;intéresse tout particulièrement à l&#8217;actualité concernant jQuery Mobile, je vous signale l&#8217;apparition d&#8217;un petit widget pour vos webapp mobiles, vous permettant de renseigner un champs date de manière simple et efficace.</p>
<p>Une simple ligne de code dans votre template et le tour est joué :</p>
<p><code>&lt;input name="somedate" type="date" /&gt;</code></p>
<p><strong>URL : </strong><a href="http://dev.jtsage.com/jQM-DateBox/" target="_blank">http://dev.jtsage.com/jQM-DateBox/</a></p>
<h2>Formalize</h2>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2011/03/Capture.png"><img class="size-medium wp-image-324 alignnone" title="Formalize" src="http://blog.overnetcity.com/wp-content/uploads/2011/03/Capture-300x99.png" alt="" width="300" height="99" /></a></p>
<p>Formalize est un plugin jQuery (également disponible pour d&#8217;autres frameworks JS (Dojo, ExtJS, MooTools, Prototype et YUI) qui facilite la tâche du développeur lors de la création et de la mise en forme des formulaires. Il offre une mise en page standardisée sur tous les navigateurs de vos forms et offre le support de certaines propriétés CSS3 non implémentées dans les anciens navigateurs.</p>
<p><strong>URL</strong> : <a href="http://formalize.me/" target="_blank">http://formalize.me/</a></p>
<p><strong>Démo</strong> : <a href="http://formalize.me/demo.html" target="_blank">http://formalize.me/demo.html</a></p>
<h2>Quovolver</h2>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2011/03/quovolver_logo.png"><img title="Logo QUOVOLVER" src="http://blog.overnetcity.com/wp-content/uploads/2011/03/quovolver_logo.png" alt="" width="326" height="46" /></a></p>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2011/03/banner_img.png"><img title="Quote QUOVOLVER" src="http://blog.overnetcity.com/wp-content/uploads/2011/03/banner_img-300x73.png" alt="" width="300" height="73" /></a></p>
<p>Grâce à ce plugin, en une seule ligne de code, présentez joliment et efficacement un ensemble de quotes au sein d&#8217;un même bloc.</p>
<p><code>$('blockquote').quovolver();</code></p>
<p><strong>URL : </strong><a href="http://sandbox.sebnitu.com/jquery/quovolver/" target="_blank">http://sandbox.sebnitu.com/jquery/quovolver/</a></p>
<div class="shr-publisher-315"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F09-03-2011%2Fles-ressources-utiles-du-mois-de-fevrier-et%2F' data-shr_title='Les+ressources+utiles+du+mois+de+F%C3%A9vrier+%28et+%2B%29'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F09-03-2011%2Fles-ressources-utiles-du-mois-de-fevrier-et%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F09-03-2011%2Fles-ressources-utiles-du-mois-de-fevrier-et%2F' data-shr_title='Les+ressources+utiles+du+mois+de+F%C3%A9vrier+%28et+%2B%29'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/09-03-2011/les-ressources-utiles-du-mois-de-fevrier-et/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery Mobile sort en version Alpha</title>
		<link>http://blog.overnetcity.com/18-10-2010/jquery-mobile-sort-en-version-alpha/</link>
		<comments>http://blog.overnetcity.com/18-10-2010/jquery-mobile-sort-en-version-alpha/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 09:27:47 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=288</guid>
		<description><![CDATA[Samedi dernier, la version mobile du célébrissime Framework Javascript jQuery est sortie en version Alpha. Assez semblable à ce qu&#8217;offre jQTouch, jQuery Mobile s&#8217;annonce comme une future référence pour les développeurs web qui veulent adapter leur site aux navigateurs des différents smartphones du marché. Au menu, support cross-browser (iPhone, Androïd, Blackberry, &#8230;), graceful degradation pour [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F18-10-2010%2Fjquery-mobile-sort-en-version-alpha%2F' data-shr_title='jQuery+Mobile+sort+en+version+Alpha'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F18-10-2010%2Fjquery-mobile-sort-en-version-alpha%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F18-10-2010%2Fjquery-mobile-sort-en-version-alpha%2F' data-shr_title='jQuery+Mobile+sort+en+version+Alpha'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Samedi dernier, la version mobile du célébrissime Framework Javascript jQuery est sortie en version Alpha. Assez semblable à ce qu&#8217;offre jQTouch, jQuery Mobile s&#8217;annonce comme une future référence pour les développeurs web qui veulent adapter leur site aux navigateurs des différents smartphones du marché.</p>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2010/10/jQuery-Mobile.jpg"><img class="alignnone size-full wp-image-289" title="jQuery Mobile" src="http://blog.overnetcity.com/wp-content/uploads/2010/10/jQuery-Mobile.jpg" alt="" width="363" height="500" /></a></p>
<p>Au menu, support cross-browser (iPhone, Androïd, Blackberry, &#8230;), graceful degradation pour les navigateurs qui n&#8217;implémentent pas encore toutes les propriétés CSS3 ou HTML5, animations et transitions du type iPhone, boîtes de dialogues et boutons prêts à être utilisés, gestion des thèmes et encore beaucoup d&#8217;autres choses très prometteuses.</p>
<p>Il est explicitement spécifié sur le site officiel de jQuery Mobile qu&#8217;il ne faut pas considérer ce framework comme un simple moyen d&#8217;adapter son site aux navigateurs mobiles puisqu&#8217;il peut très facilement profiter des fonctionnalités de <a href="http://www.phonegap.com/" target="_blank">PhoneGap</a> pour créer de véritables clients lourds pour les différents Smartphones. Un bon moyen de coder une seule fois son application mobile pour la déployer ensuite sur les différents stores des constructeurs.</p>
<p>J&#8217;ai jeté un rapide coup d&#8217;oeil à l&#8217;application de démonstration qui s&#8217;annonce en effet très bien réalisée. Quelques bugs semblent persister mais je pense qu&#8217;ils devraient rapidement être résolus en fonction des retours de la communauté. Dès que j&#8217;aurai un peu plus de temps, je tâcherai de poster un petit tutoriel pour démarrer un projet symfony avec jQuery Mobile.</p>
<p>En attendant, n&#8217;hésitez pas à consulter le <a href="http://jquerymobile.com/" target="_blank">site officiel</a> et surtout la <a href="http://jquerymobile.com/demos/1.0a1/" target="_blank">démo en ligne</a> de ce projet.</p>
<div class="shr-publisher-288"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F18-10-2010%2Fjquery-mobile-sort-en-version-alpha%2F' data-shr_title='jQuery+Mobile+sort+en+version+Alpha'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F18-10-2010%2Fjquery-mobile-sort-en-version-alpha%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F18-10-2010%2Fjquery-mobile-sort-en-version-alpha%2F' data-shr_title='jQuery+Mobile+sort+en+version+Alpha'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/18-10-2010/jquery-mobile-sort-en-version-alpha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les ressources utiles du mois de Juillet</title>
		<link>http://blog.overnetcity.com/31-07-2010/les-ressources-utiles-du-mois-de-juillet/</link>
		<comments>http://blog.overnetcity.com/31-07-2010/les-ressources-utiles-du-mois-de-juillet/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 07:30:56 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Ressources Utiles]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[gallery]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[microdata]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[rdfa]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[slideshow]]></category>
		<category><![CDATA[temps réel]]></category>
		<category><![CDATA[tuto]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[xmpp]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=256</guid>
		<description><![CDATA[C&#8217;est une pratique assez récurrente chez les développeurs Web ou chez les web designers qui bloguent. Alors moi aussi je vais régulièrement (chaque mois) poster un article regroupant les ressources utiles sur lesquelles je suis tombé. Deux intérêts à cette démarche : D&#8217;une part pouvoir les retrouver le jour où j&#8217;en aurai besoin / re-besoin [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>C&#8217;est une pratique assez récurrente chez les développeurs Web ou chez les web designers qui bloguent. Alors moi aussi je vais régulièrement (chaque mois) poster un article regroupant les ressources utiles sur lesquelles je suis tombé. Deux intérêts à cette démarche :</p>
<ul>
<li>D&#8217;une part pouvoir les retrouver le jour où j&#8217;en aurai besoin / re-besoin</li>
<li>D&#8217;autre part, les partager avec vous amis lecteurs</li>
</ul>
<p>Je crée donc pour l&#8217;occasion une nouvelle catégorie d&#8217;articles sur OvernetCity intitulée sobrement : &#8220;Ressources Utiles&#8221;.</p>
<p>Pour ce mois de Juillet, un peu de jQuery, un peu de symfony et un peu de développement iPhone sont au programme. D&#8217;ailleurs, cela risque d&#8217;être souvent le cas&#8230;</p>
<h2>Interactive Photo Desk with jQuery and CSS3</h2>
<p><img class="alignnone size-medium wp-image-258" title="Photo Desk" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/photodesk-300x162.jpg" alt="" width="300" height="162" /></p>
<p>Les démonstrations concernant CSS 3 et HTML 5 ont le vent en poupe depuis quelques mois. Il ne se passe pas une journée sans qu&#8217;un tuto complet soit posté sur un des nombreux blogs que je suis, montrant à quel point l&#8217;arrivée de ces deux langages et leur support par l&#8217;ensemble des navigateurs modernes va changer notre façon d&#8217;interagir avec une application Web.</p>
<p>Ici, c&#8217;est l&#8217;alliance du CSS 3 et de jQuery qui permet de réaliser un chouette bureau sur lequel s&#8217;entassent quelques photos. L&#8217;utilisateur peut les déplacer avec un résultat d&#8217;une fluidité étonnante.</p>
<p>A consulter avec un navigateur moderne évidemment.</p>
<p><a href="http://tympanus.net/codrops/2010/07/01/interactive-photo-desk/">http://tympanus.net/codrops/2010/07/01/interactive-photo-desk/</a></p>
<h2>Minimalistic Slideshow Gallery with jQuery</h2>
<p><img class="alignnone size-medium wp-image-257" title="Minimalistic Slideshow Gallery" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/MinimalisticSlideshowGallery-300x162.jpg" alt="" width="300" height="162" /></p>
<p>Encore un tuto expliquant comment réaliser une mini gallerie pour afficher quelques photos. Celui-ci a le mérite d&#8217;être très clair et d&#8217;avoir un rendu vraiment pro.</p>
<p>Très facile à intégrer au sein d&#8217;une page existante !</p>
<p><a href="http://tympanus.net/codrops/2010/07/05/minimalistic-slideshow-gallery/">http://tympanus.net/codrops/2010/07/05/minimalistic-slideshow-gallery/</a></p>
<h2>Symfony 1.4 &#8211; Tri sur les colonnes étrangères dans l&#8217;admin generator</h2>
<p>L&#8217;admin generator de symfony est un outil merveilleusement pratique qui permet de créer en quelques minutes un backend parfaitement fonctionnel et adapté aux besoins du client.</p>
<p>Néanmoins, je me suis souvent demandé pourquoi il est impossible sans mettre les mains dans le cambouis de faire un tri sur les colonnes persos dans la liste générée par le Framework. Chaque colonne est par défaut cliquable ce qui entraine un tri ascendant ou descendant de la liste en fonction de cette colonne mais ce comportement est indisponible dès que la colonne en question n&#8217;est pas une colonne native en base et fait, par exemple, référence à l&#8217;attribut name d&#8217;un objet récupéré via une relation.</p>
<p>Les développeurs experts symfony de l&#8217;agence Elao nous montrent comment modifier le comportement de l&#8217;admin generator pour que, justement, ce tri soit possible sur les colonnes non natives. Très utile !</p>
<p><a href="http://www.elao.org/symfony/symfony-1-4-admin-generator-tris-sur-les-colonnes-etrangeres.html">http://www.elao.org/symfony/symfony-1-4-admin-generator-tris-sur-les-colonnes-etrangeres.html</a></p>
<h2>Introduction aux Métadonnées RDFa, Microdata et Microformats</h2>
<p><img class="alignnone size-medium wp-image-262" title="microdata-image1" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/microdata-image1-300x99.jpg" alt="" width="300" height="99" /></p>
<p>Je connais la technique depuis un moment mais n&#8217;ai pas encore eu l&#8217;occasion de la mettre en pratique au sein d&#8217;un projet. Ces métadonnées à destination des moteurs de recherche permettent de stocker de modifier la présentation d&#8217;une page au sein d&#8217;un moteur de recherche pour apporter de la valeur ajoutée à l&#8217;utilisateur. Les sites référençant des restaurants, par exemple, peuvent profiter de ces métadonnées pour afficher, directement au sein des résultats d&#8217;un moteur de recherche, la note associée à un restaurant sous forme d&#8217;étoiles.</p>
<p>Ces données sont de plus en plus utilisées et de mieux en mieux exploitées. Elles méritent donc qu&#8217;on s&#8217;y attarde un tout petit peu de manière à optimiser le référencement naturel d&#8217;une application web.</p>
<p>Cet article présente quelques exemples concrets d&#8217;utilisation de ces métadonnées et référence quelques liens utiles pour le développeur.</p>
<p><a href="http://spyrestudios.com/real-world-microformats-rdfa-microformats-and-microdata-practical-examples/">http://spyrestudios.com/real-world-microformats-rdfa-microformats-and-microdata-practical-examples/</a></p>
<h2>Tutoriel complet sur les Microdata de HTML5</h2>
<p><img class="alignnone size-full wp-image-269" title="nettuts_microdata" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/nettuts_microdata.png" alt="" width="200" height="200" /></p>
<p>Quand on pense à l&#8217;HTML 5, on ne pense pas forcément immédiatement à Microdata. Et pourtant c&#8217;est également une des grandes nouveauté que ce nouveau langage nous apporte et à laquelle tout bon développeur se doit de s&#8217;intéresser. Ce tutoriel très complet permet d&#8217;aller plus loin que l&#8217;article précédent en se basant sur un exemple concret.</p>
<p><a href="http://net.tutsplus.com/tutorials/html-css-techniques/html5-microdata-welcome-to-the-machine/">http://net.tutsplus.com/tutorials/html-css-techniques/html5-microdata-welcome-to-the-machine/</a></p>
<h2>Comment intégrer Google Analytics dans son application iPhone en 7 minutes ?</h2>
<p>Intégrer un script de tracking des visiteurs dans une application Web est aujourd&#8217;hui presque un réflexe pour le développeur. On peut faire la même chose pour une application lourde sur iPhone puisque l&#8217;API de Google est compatible avec plusieurs terminaux mobiles dont ce dernier.</p>
<p>Quel est l&#8217;intérêt ? Comment est-ce que ça marche ? Quels sont les pré-requis ? Autant de questions qui trouveront leurs réponses dans ce tutoriel très complet de iCodeBlog.</p>
<p><a href="http://icodeblog.com/2010/04/22/how-to-integrate-google-analytics-tracking-into-your-apps-in-7-minutes/">http://icodeblog.com/2010/04/22/how-to-integrate-google-analytics-tracking-into-your-apps-in-7-minutes/</a></p>
<h2>Premiers pas avec iPhone Core Data</h2>
<p><img class="alignnone size-full wp-image-273" title="Into_to_coredata_preview2" src="http://blog.overnetcity.com/wp-content/uploads/2010/07/Into_to_coredata_preview2.jpg" alt="" width="200" height="200" /></p>
<p>Ce tutoriel est une belle introduction au Framework Core Data de l&#8217;iPhone OS qui n&#8217;est pas très bien couvert par les livres que j&#8217;ai pu lire lors de ma formation au développement iPhone.</p>
<p>A parcourir pour comprendre quelles sont les possibilités offertes par ce Framework et surtout comment les mettre en oeuvre.</p>
<p><a href="http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/">http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/</a></p>
<h2>Afficher un flux RSS en temps réel avec XMPP</h2>
<p>Comment fait Google avec son GTalk pour afficher les messages envoyés en temps réel sur sa page web, sans sacrifier les ressources serveurs avec des requêtes Ajax envoyée chaque seconde ?</p>
<p>C&#8217;est une question que je me suis souvent posé et à laquelle j&#8217;ai trouvé une réponse aujourd&#8217;hui grâce à un tutoriel très complet posté sur le site d&#8217;IBM. GMail, Gtalk, Google Wave font tous usage du langage XMPP dédié à la notification en quasi temps réel pour les applications web. A lire d&#8217;urgence si le sujet vous intéresse&#8230;</p>
<p><a href="http://www.ibm.com/developerworks/xml/tutorials/x-realtimeXMPPtut/index.html">http://www.ibm.com/developerworks/xml/tutorials/x-realtimeXMPPtut/index.html</a></p>
<div class="shr-publisher-256"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F31-07-2010%2Fles-ressources-utiles-du-mois-de-juillet%2F' data-shr_title='Les+ressources+utiles+du+mois+de+Juillet'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/31-07-2010/les-ressources-utiles-du-mois-de-juillet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Warning: URL file-access is disabled in the server configuration&#8230;</title>
		<link>http://blog.overnetcity.com/12-07-2010/warning-url-file-access-is-disabled-in-the-server-configuration/</link>
		<comments>http://blog.overnetcity.com/12-07-2010/warning-url-file-access-is-disabled-in-the-server-configuration/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 11:46:08 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[1and1]]></category>
		<category><![CDATA[astuce]]></category>
		<category><![CDATA[php.ini]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=118</guid>
		<description><![CDATA[En voulant me servir de la fonction PHP getimagesize('http://un_serveur/une_image.jpg'), je suis tombé sur une erreur après la mise en ligne du code sur un hébergement mutualisé de 1and1 : Warning: getimagesize() [function.getimagesize]: URL file-access is disabled in the server configuration L&#8217;erreur vient tout simplement du fait que, par défaut, dans la version 5 de PHP, [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F12-07-2010%2Fwarning-url-file-access-is-disabled-in-the-server-configuration%2F' data-shr_title='Warning%3A+URL+file-access+is+disabled+in+the+server+configuration...'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F12-07-2010%2Fwarning-url-file-access-is-disabled-in-the-server-configuration%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F12-07-2010%2Fwarning-url-file-access-is-disabled-in-the-server-configuration%2F' data-shr_title='Warning%3A+URL+file-access+is+disabled+in+the+server+configuration...'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>En voulant me servir de la fonction PHP <code>getimagesize('http://un_serveur/une_image.jpg')</code>, je suis tombé sur une erreur après la mise en ligne du code sur un hébergement mutualisé de 1and1 :</p>
<p><code>Warning: getimagesize() [function.getimagesize]: URL file-access is disabled in the server configuration</code></p>
<p>L&#8217;erreur vient tout simplement du fait que, par défaut, dans la version 5 de PHP, la variable <code>allow_url_fopen</code> du <strong>php.ini</strong> est à <code>false</code>. Cette option active les versions étendues des fonctions d&#8217;accès aux fichiers, qui savent exploiter les URL.</p>
<p>Je me suis dit dans un premier temps que j&#8217;allais devoir basculer le site sur un serveur dédié mais, après quelques recherches, j&#8217;ai découvert que 1and1 autorise la modifications des valeurs du <strong>php.ini</strong>, même sur un hébergement mutualisé.</p>
<p>Pour ce faire, rien de plus simple ! Il suffit de créer un fichier <strong>php.ini</strong> avec les couples variables / valeurs souhaités et de le placer dans l&#8217;ensemble des répertoires contenant des scripts PHP sur le serveur.</p>
<p>Exemple de fichier <strong>php.ini</strong> :</p>
<p><code>upload_max_filesize = 10M<br />
post_max_size = 10M<br />
</code></p>
<p>En ce qui nous concerne, il faut créer le fichier suivant :</p>
<p><code>allow_url_fopen = 1<br />
</code></p>
<p>Si vous travaillez sur un projet symfony, il suffit de mettre le <strong>php.ini</strong> à la racine du dossier web, puisque toutes les actions s&#8217;exécutent à partir du contrôleur frontal.</p>
<p>Si vous n&#8217;êtes pas chez <strong>1and1</strong>, vérifiez si votre hébergeur vous propose la personnalisation du <strong>php.ini</strong>. De plus en plus le font afin de laisser un peu de souplesse aux développeurs. Et on ne va pas s&#8217;en plaindre&#8230;</p>
<div class="shr-publisher-118"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F12-07-2010%2Fwarning-url-file-access-is-disabled-in-the-server-configuration%2F' data-shr_title='Warning%3A+URL+file-access+is+disabled+in+the+server+configuration...'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F12-07-2010%2Fwarning-url-file-access-is-disabled-in-the-server-configuration%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F12-07-2010%2Fwarning-url-file-access-is-disabled-in-the-server-configuration%2F' data-shr_title='Warning%3A+URL+file-access+is+disabled+in+the+server+configuration...'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/12-07-2010/warning-url-file-access-is-disabled-in-the-server-configuration/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Comment créer un sprite pour optimiser le chargement de ses images ?</title>
		<link>http://blog.overnetcity.com/10-07-2010/comment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images/</link>
		<comments>http://blog.overnetcity.com/10-07-2010/comment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images/#comments</comments>
		<pubDate>Sat, 10 Jul 2010 08:34:33 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=108</guid>
		<description><![CDATA[Je m&#8217;occupe actuellement du développement du site myBonjour.fr qui permet le recensement et l&#8217;affichage de tous les blogs du type Bonjour Madame et Bonjour Poney. Pour optimiser la vitesse de chargement des pages, je me suis intéressé à la technique aujourd&#8217;hui très populaire des Sprites CSS. Un Sprite, qu&#8217;est-ce que c&#8217;est ? C&#8217;est une grande [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Je m&#8217;occupe actuellement du développement du site <a href="http://www.mybonjour.fr">myBonjour.fr</a> qui permet le recensement et l&#8217;affichage de tous les blogs du type Bonjour Madame et Bonjour Poney.</p>
<p>Pour optimiser la vitesse de chargement des pages, je me suis intéressé à la technique aujourd&#8217;hui très populaire des Sprites CSS.</p>
<p>Un Sprite, qu&#8217;est-ce que c&#8217;est ? C&#8217;est une grande image qui contient plusieurs petites images utilisées au sein de votre application web, via les feuilles de style. En utilisant la propriété background CSS, il est assez facile de dire quelle partie du sprite doit être affichée en image de fond.<br />
L&#8217;avantage de regrouper plusieurs petites images au sein d&#8217;un sprite est double. D&#8217;une part, l&#8217;image ainsi formée est souvent moins lourde que l&#8217;ensemble des petites images additionnées et, d&#8217;autre part, le nombre de requête HTTP pour charger les images est réduit à un. C&#8217;est ce dernier point qui est le plus important et le plus significatif en terme de gain de performances.</p>
<p>Voici un exemple de sprite :</p>
<p><img src="http://blog.overnetcity.com/wp-content/uploads/2010/07/buttons.gif" alt="Sprite de boutons" title="Sprite de boutons" width="121" height="14" class="alignnone size-full wp-image-109" /></p>
<p>De nombreuses applications Web apportent une aide intéressante pour la création de Sprite à partir d&#8217;un site existant non optimisé.<br />
J&#8217;ai retenu tout particulièrement le site http://spriteme.org qui offre un bouton à glisser dans sa barre de favoris et qui ouvre une popup en Javascript qui permet de créer un sprite à la volée et même de générer le CSS correspondant à partir du CSS existant.</p>
<p><a href="http://blog.overnetcity.com/wp-content/uploads/2010/07/Capture.jpg"><img src="http://blog.overnetcity.com/wp-content/uploads/2010/07/Capture-300x189.jpg" alt="Exemple avec SpriteMe" title="Exemple avec SpriteMe" width="300" height="189" class="alignnone size-medium wp-image-110" /></a></p>
<p>Maintenant, comment générer un Sprite soit même, directement dans son code symfony ? Vous allez voir ci-dessous le code que j&#8217;ai utilisé pour <a href="http://www.mybonjour.fr">myBonjour.fr</a>.</p>
<p>Pour cela, j&#8217;ai ajouté dans un premier temps une méthode privée dans mon modèle, s&#8217;occupant de générer le Sprite en question :</p>
<pre class="brush: php; ">

  private function makeSpriteForFavicons()
  {
    $items = Doctrine_Core::getTable(&#039;MyBonjourItem&#039;)-&amp;gt;getAllActiveItems();

    $width = 25;
    $height = 16;
    $space = 14;

    // On crée l&#039;image vide
    $image = imagecreatetruecolor($width, ($height+$space) * count($items));
    $background = imagecolorallocatealpha($image, 255, 255, 255, 127);
    imagefill($image, 0, 0, $background);
    imagealphablending($image, false);
    imagesavealpha($image, true);

    // Ajout de tous les favicons à l&#039;image
    $pos = 7;
    foreach($items as $item)
    {
      $tmp = imagecreatefrompng($item-&amp;gt;getItemFilePath());
      imagecopy($image, $tmp, 0, $pos, 0, 0, $width, $height);
      $pos += $height + $space;
      imagedestroy($tmp);
    }

    imagepng($image, sfConfig::get(&#039;sf_web_dir&#039;).&#039;/images/items_icons.png&#039;);
  }
</pre>
<p>Il suffit ensuite d&#8217;appeler cette méthode, quand la colonne correspondant à l&#8217;image est modifiée. Pour cela, on implémente la méthode save du modèle :</p>
<pre class="brush: php; ">

  public function save(Doctrine_Connection $conn = null)
  {
    if(in_array(&#039;favicon_url&#039;, array_keys($this-&amp;gt;getModified())))
    {
      $return = parent::save($conn);
      $this-&amp;gt;makeSpriteForFavicons();
    }
    else
      $return = parent::save($conn);

    return $return;
  }
</pre>
<p>Et enfin, on génère la partie correspondante dans le fichier CSS, à la volée :</p>
<pre class="brush: php; ">

// makeCSSSuccess.php
&amp;lt;?php $pos = 0; foreach($items as $item): ?&amp;gt;
div#&amp;lt;?php echo $item-&amp;gt;getSlug() ?&amp;gt; &amp;gt; h3{
  background: url(&amp;quot;/images/items_icons.png&amp;quot;) no-repeat scroll 5px -&amp;lt;?php echo $pos*$width ?&amp;gt;px;
}
&amp;lt;?php $pos++; endforeach; ?&amp;gt;
</pre>
<p>Le fichier CSS généré par une action symfony doit être mis en cache pour éviter toute chute des performances. Il suffit de déclencher ensuite une regénération du cache lorsqu&#8217;un item est ajouté en base.<br />
Sur myBonjour, j&#8217;ai ainsi supprimé le chargement de 60 requêtes HTTP, correspondant aux différents bonjours présents dans la liste.</p>
<div class="shr-publisher-108"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F10-07-2010%2Fcomment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images%2F' data-shr_title='Comment+cr%C3%A9er+un+sprite+pour+optimiser+le+chargement+de+ses+images+%3F'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/10-07-2010/comment-creer-un-sprite-pour-optimiser-le-chargement-de-ses-images/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lancer une tâche symfony depuis une action</title>
		<link>http://blog.overnetcity.com/02-07-2010/lancer-une-tache-symfony-depuis-une-action/</link>
		<comments>http://blog.overnetcity.com/02-07-2010/lancer-une-tache-symfony-depuis-une-action/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 07:24:02 +0000</pubDate>
		<dc:creator>Olivier Balais</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[tâche]]></category>
		<category><![CDATA[task]]></category>

		<guid isPermaLink="false">http://blog.overnetcity.com/?p=88</guid>
		<description><![CDATA[How to launch a symfony task from action code? Ou comment appeler une tâche symfony depuis une action, sans passer par le CLI ? Symfony permet depuis la version 1.3 / 1.4 d&#8217;appeler une tâche directement depuis une autre tâche via le code suivant : $this-&#62;runTask(&#039;mydomain:mytask&#039;); On peut par exemple très facilement créer une tâche [...]]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetTop Automatic --><p>How to launch a symfony task from action code? Ou comment appeler une tâche symfony depuis une action, sans passer par le CLI ?</p>
<p>Symfony permet depuis la version 1.3 / 1.4 d&#8217;appeler une tâche directement depuis une autre tâche via le code suivant :</p>
<pre class="brush: php; ">

$this-&gt;runTask(&#039;mydomain:mytask&#039;);
</pre>
<p>On peut par exemple très facilement créer une tâche au cours de laquelle un appel à symfony cc sera déclenché :</p>
<pre class="brush: php; ">

&lt;?php

class testTask extends sfBaseTask
{
  protected function configure()
  {
    // // add your own arguments here
    // $this-&gt;addArguments(array(
    //   new sfCommandArgument(&#039;my_arg&#039;, sfCommandArgument::REQUIRED, &#039;My argument&#039;),
    // ));
    $this-&gt;addOptions(array(
    new sfCommandOption(&#039;application&#039;, null, sfCommandOption::PARAMETER_REQUIRED, &#039;The application name&#039;),
    new sfCommandOption(&#039;env&#039;, null, sfCommandOption::PARAMETER_REQUIRED, &#039;The environment&#039;, &#039;dev&#039;),
    new sfCommandOption(&#039;connection&#039;, null, sfCommandOption::PARAMETER_REQUIRED, &#039;The connection name&#039;, &#039;doctrine&#039;),
    // add your own options here
    ));
    $this-&gt;namespace        = &#039;&#039;;
    $this-&gt;name             = &#039;test&#039;;
    $this-&gt;briefDescription = &#039;&#039;;
    $this-&gt;detailedDescription = &lt;&lt;
The [test|INFO] task does things.
Call it with:
[php 1=&quot;test|INFO&quot; language=&quot;symfony&quot;][/php][/php]
EOF;
  }
  protected function execute($arguments = array(), $options = array())
  {
    // initialize the database connection
    $databaseManager = new sfDatabaseManager($this-&gt;configuration);
    $connection = $databaseManager-&gt;getDatabase($options[&#039;connection&#039;])-&gt;getConnection();
    // here is our code
    // we do something
    // and we clear cache
    $this-&gt;runTask(&#039;cc&#039;);
  }
}
</pre>
<p>En revanche, rien n&#8217;est actuellement prévu pour appeler cette même tâche depuis une action. Il est pourtant très utile de pouvoir appeler la tâche d&#8217;envoi des emails directement depuis une action de son backend. Ou même de vider le cache sans avoir à passer par la ligne de commandes.<br />
Le plugin <a href="http://www.symfony-project.org/plugins/ybRunTaskPlugin">ybRunTaskPlugin</a> a été développé justement pour palier à ce manque. Une fois le plugin installé, il est possible d&#8217;appeler directement au sein de son action une tâche symfony, de la même manière qu&#8217;on pouvait le faire en standard au sein d&#8217;une autre tâche :</p>
<pre class="brush: php; ">

class myActions extends sfActions
{
  public function executeRuntask(sfWebRequest $request)
  {
    $ret = $this-&gt;runTask(&#039;myDomain:myTask&#039;, &#039;myArguments&#039;);
    if(null != $ret)
    {
      $this-&gt;msg = $ret-&gt;getMessage();
    }
    else
    {
      $this-&gt;msg = &#039;everything went OK&#039;;
    }
  }
}
</pre>
<p>Malheureusement, le plugin ne gère actuellement pas l&#8217;affichage des logs ou d&#8217;une quelconque valeur de retour si l&#8217;exécution s&#8217;est passé correctement. Peut-être dans une prochaine version ?<br />
En attendant, vous pouvez réaliser un petit hack du plugin en fonction de vos besoins&#8230;</p>
<div class="shr-publisher-88"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a><a class='shareaholic-fbsend' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fblog.overnetcity.com%2F02-07-2010%2Flancer-une-tache-symfony-depuis-une-action%2F' data-shr_title='Lancer+une+t%C3%A2che+symfony+depuis+une+action'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://blog.overnetcity.com/02-07-2010/lancer-une-tache-symfony-depuis-une-action/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

