<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Tout sur Rien</title><link>http://blog.fruitsoftware.com</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ToutSurRien" /><description>Un blog sur Tout sur Rien</description><language>en</language><lastBuildDate>Sun, 11 Mar 2012 11:21:33 PDT</lastBuildDate><generator>http://wordpress.org/?v=3.3.1</generator><sy:updatePeriod xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">hourly</sy:updatePeriod><sy:updateFrequency xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">1</sy:updateFrequency><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ToutSurRien" /><feedburner:info uri="toutsurrien" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>gRaphael, axes et graduations – tips</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/RuWSPWCXrms/</link><category>Non classé</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Sat, 10 Mar 2012 21:52:14 PST</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=320</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Je cherchais à personnaliser les textes de l&#8217;axe des x d&#8217;un graphique de type &laquo;&nbsp;linechart&nbsp;&raquo; fait en <a href="http://g.raphaeljs.com/" target="_blank">gRaphael</a>.</p>
<p>En effet, il n&#8217;est pas possible de personnaliser les textes affichées sur les différents axes. Or je voulais pouvoir avoir un graphique pour lequel j&#8217;avais des données journalières, mais pouvoir afficher des graduation toutes les semaines.</p>
<p>N&#8217;ayant rien trouvé sur les tubes, j&#8217;ai donc décidé de creuser un peu dans le code, et voici ce que j&#8217;ai trouvé. Ceci est donc plus une note personnelle&#8230; En espérant que cela pourra aussi servir à quelqu&#8217;un.</p>
<p>Bon, je commence par la fin: <a href="http://jsfiddle.net/saadtazi/vpGyL/" target="_blank">voici un jsFiddle</a> illustrant le résultat. Vous voyez comment les graduations de l&#8217;axe des y est pas beau? Les nombres affichés ne sont pas très &laquo;&nbsp;ronds&nbsp;&raquo;&#8230; J&#8217;ai ici corriger le tir pour l&#8217;axe des x.</p>
<p><iframe style="width: 100%; height: 300px;" src="http://jsfiddle.net/saadtazi/vpGyL/embedded/result/" frameborder="0" width="320" height="240"></iframe></p>
<p>J&#8217;ai utilisé une fonction utilitaire de graphael, Raphael.g.axis. J&#8217;ai noté que il y avait un paramètre label! Et en utilisant le debugger, la version non-minifiée de graphael, et en regardant comment g.line.js utilise cette foncction , j&#8217;ai pu comprendre son fonctionnement et voici ce qu&#8217;il faut faire pour avoir un axe des x avec des textes sous forme de texte:</p>
<pre class="brush: jscript; title: ; notranslate">
var r = Raphael('testGraph', 320, 220);

// Creates a simple line chart at 10, 10
// width 300, height 200
var x = 10
,    y = 10
,    xlen = 300
,    ylen = 200
,    gutter = 20
, xdata = [0,2,4,6,8,10]
;
var chrt = r.linechart(x,y,xlen,ylen,xdata,[30,10,20,15,35,30], { gutter: gutter, nostroke: false, axis: &quot;0 0 0 1&quot;, symbol: &quot;circle&quot;, smooth: true });
// default gutter: 10
              //x, y, length, from, to, steps, orientation, labels, type, dashsize, paper
Raphael.g.axis(
    x + gutter, // 10 + gutter
    y + ylen - gutter, //y pos
    xlen - 2*gutter,
    null, null, // used to pass the initial value and last value (number) if no labels are provided
    xdata.length - 1, // number of steps
    0,
    ['0', '-2-', '-4-', '-6-', '-8-', '-10-'], // the labels
    r // you need to provide the Raphael object
);
</pre>
<p>Donc vous pouvez facilement controler le nombre de graduations et les textes affichés sur les axes. Pas pire, non?</p>
<p>Bon, si vous voulez aller plus loin (changer la police de caractères par exemple), il va falloir que vous fassiez votre propre fonction axis&#8230;</p>
<h2>Bonus</h2>
<h3>documentation graphael</h3>
<p>Si vous cherchez un peu de documentation sur graphael, voici quelques liens:</p>
<ul>
<li>Documentation pas encore ajoutée au repo officiel: <a href="https://github.com/kennyshen/g.raphael/tree/master/docs" target="_blank">https://github.com/kennyshen/g.raphael/tree/master/docs</a></li>
<li><a href="http://jburrows.wordpress.com/2011/02/21/documentation-for-graphael-g-line-js/" target="_blank">http://jburrows.wordpress.com/2011/02/21/documentation-for-graphael-g-line-js/</a></li>
<li>Une autre librairie raphael pour faire des graphiques: <a href="http://alexyoung.github.com/ico/" target="_blank">http://alexyoung.github.com/ico/</a></li>
</ul>
<h3>Documentation (manque de)</h3>
<p>(en date du 11 mars 2012) Le code d&#8217;exemple sur la page d&#8217;accueil n&#8217;est pas bon:</p>
<pre class="brush: jscript; title: ; notranslate">
// il y a ça:
// r.g.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2]);
// mais ça devrait être ça
r.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2]);
</pre>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/RuWSPWCXrms" height="1" width="1"/>]]></content:encoded><description>Je cherchais à personnaliser les textes de l&amp;#8217;axe des x d&amp;#8217;un graphique de type &amp;#171;&amp;#160;linechart&amp;#160;&amp;#187; fait en gRaphael. En effet, il n&amp;#8217;est pas possible de personnaliser les textes affichées sur les différents axes. Or je voulais pouvoir avoir un graphique &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2012/03/graphael-axes-et-graduations-tips/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2012/03/graphael-axes-et-graduations-tips/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2012/03/graphael-axes-et-graduations-tips/</feedburner:origLink></item><item><title>Node, functions asynchones et async</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/325L590x9a4/</link><category>programmation</category><category>async</category><category>javascript</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Fri, 10 Feb 2012 19:58:03 PST</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=294</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Ces derniers temps, je fais beaucoup de javascript&#8230; vraiment beaucoup&#8230;. et j&#8217;aime ça!</p>
<p>Il y a un &laquo;&nbsp;shift&nbsp;&raquo; de mentalité à faire lorsqu&#8217;on n&#8217;est pas habitué à utiliser des callbacks tous les jours&#8230; Mais en en faisant plus, on se rend compte de la puissance de la chose. Et j&#8217;aime ça! Mes vieux réflexes sont parfois encore là mais &laquo;&nbsp;je me soigne&nbsp;&raquo;, et ça va de mieux en mieux.</p>
<p>J&#8217;ai eu un problème dernièrement, où il fallait que plusieurs callbacks de fonctions soient executés avant de passer à la suite. </p>
<p>Veuillez noter dans les exemples qui suivent, je vais utiliser la fonction setTimeout pour illustrer le code, mais vous pouvez remplacer setTimeout par toute autre function qui accepte un callback comme paramètre. En utilisant setTimeout, on ne se rend pas bien compte qu&#8217;on recherche à recevoir un résultat (en paramètre du callback), mais bon&#8230;</p>
<p>Une première approche, qui fonctionne, est la suivante:</p>
<pre class="brush: jscript; title: ; notranslate">
setTimeout(function(
    // with &quot;real functions with callbacks,
    // the &quot;result&quot; is passed as params of the callback function
    ) {
    console.log('in function 1 callback');
    // ok, now run function2
        setTimeout(function() {
        console.log('in function 2 callback');
        // ok, I'm done
        // now, do what you have to do...
        // ...
    }, 100);
}, 200);

console.log('the end!');
</pre>
<p>Le résultat:</p>
<pre class="brush: plain; title: ; notranslate">
the end!
in function 1 callback
in function 2 callback
</pre>
<p>Cela fonctionne, mais on voit vite le problème: si on a une 3ème fonction à exécuter, on rajoute un autre niveau&#8230; De plus en plus difficile à lire, pas super élégant (à mon goût)&#8230; Donc plus d&#8217;erreurs en cas de modification future.<br />
En plus, une telle approche exécute les differentes fonctions en série, les unes après les autres.</p>
<p>Donc, après une rapide recherche, j&#8217;ai découvert la librairie <a href="https://github.com/caolan/async" target="_blank">async</a> de <a title="site web de caolan" href="http://caolanmcmahon.com" target="_blank">caolan</a> (que je ne connaissais pas, mais qui est probablement connu de tout développeur nodejs (?)), initialement développé pour nodejs mais également disponible dans le browser. Cette librairie semble très populaire. Elle est notamment dans le top 6 des packages npm dont dépendent le plus d&#8217;autres <a href="http://search.npmjs.org/" target="_blank">packages npm</a>.</p>
<p>async contient de nombreuses fonctions qui permettent de resoudre le genre de problèmes décrits plus haut.<br />
Voici un exemple d&#8217;utilisation de aync.parallel:</p>
<pre class="brush: jscript; title: ; notranslate">
// this example uses nodejs module loading system
var async = require('async');

async.parallel([
    function(callback){
    	// any function with callback
        setTimeout(function(){
        	console.log('in function 1 callback');
        	// when you have what you want, call &quot;callback&quot;
        	// to notify async that the function 1 is done
        	// note: we are in the setTimeout callback function,
        	// that is the beauty!!
            callback(null, 'function 1 result');
        }, 200);
    },
    function(callback){
        setTimeout(function(){
            console.log('in function 2 callback');
            callback(null, 'function 2 result');
        }, 100);
    },
],
// optional callback
function(err, results){
	// we are here only if function 1 and 2 called callback
	// or if one callback param 1 (err) is not null
    console.log('test 1 - in final callback - err:', err, ' - results: ', results);
});

console.log('the end!');
</pre>
<p>Le résultat (exécuté en ligne de commande &laquo;&nbsp;node test-async.js&nbsp;&raquo;):</p>
<pre class="brush: plain; title: ; notranslate">
the end!
in function 2 callback
in function 1 callback
test 1 - in final callback - err: undefined  - results:  [ 'function 1 result', 'function 2 result' ]
</pre>
<p>C&#8217;est certain que le code est plus long (mais j&#8217;ai aussi mis plus de commentaires&#8230;), mais on a des avantages:</p>
<ul>
<li>les functions sont exécutées en parallèle. Veuillez noter qu&#8217;il y a de nombreuses autres stratégies de &laquo;&nbsp;flow&nbsp;&raquo; (en série, waterfall, &#8230;) disponible avec async. Une de plus avancée je trouve (mais je n&#8217;ai pas encore trouvé une utilité) est auto</li>
<li>on a aussi accès à des fonctions permettant d&#8217;appliquer la même fonction à des collections (comme async.forEach(), async.map() &#8230;)</li>
</ul>
<p>Le README du projet sur github est complet et décrit très bien toutes les fonctions offertes par la librarie.</p>
<p>Voici un 2ème exemple de callback qui illustre une génération d&#8217;erreur:</p>
<pre class="brush: jscript; title: ; notranslate">
// test #2 - error
var async = require('async');

async.parallel({
    func3: function(callback){
    	// any function with callback
        setTimeout(function(){
            console.log('in function 3 callback');
            callback('error returned by function 3');
        }, 200);
    },
    func3: function(callback){
        setTimeout(function(){
            console.log('in function 4 callback');
            callback(null, 'function 4 result');
        }, 100);
    },
},
// optional callback
function(err, results){
	// we are here only if func3 and 4 called callback
	// or if one callback first param (err) is not null
	// not that results may contain some values (if some functions have ended)
        // only only one error, 0 to functionCount results
        // note: because we used the parallel map notation, result is a map
    console.log('test 2 - in final callback - err:', err, ' - results: ', results);
});

console.log('the end!');
</pre>
<p>Le résultat:</p>
<pre class="brush: plain; title: ; notranslate">
the end!
in function 4 callback
in function 3 callback
test 2 - in final callback - err: error returned by function 3  - results:  { func2: 'function 4 result', func1: undefined }
</pre>
<p>Voilà, j&#8217;apprends, doucement&#8230; Et, au cas où vous ne l&#8217;auriez pas compris&#8230; j&#8217;aime ça!!</p>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/325L590x9a4" height="1" width="1"/>]]></content:encoded><description>Ces derniers temps, je fais beaucoup de javascript&amp;#8230; vraiment beaucoup&amp;#8230;. et j&amp;#8217;aime ça! Il y a un &amp;#171;&amp;#160;shift&amp;#160;&amp;#187; de mentalité à faire lorsqu&amp;#8217;on n&amp;#8217;est pas habitué à utiliser des callbacks tous les jours&amp;#8230; Mais en en faisant plus, on se &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2012/02/node-functions-asynchones-et-async/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2012/02/node-functions-asynchones-et-async/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2012/02/node-functions-asynchones-et-async/</feedburner:origLink></item><item><title>Du nouveau sur geoquity</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/FGtPhbgxxWc/</link><category>Projet</category><category>Symfony</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Sun, 23 Oct 2011 16:49:13 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=287</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Je vous ai déjà parlé de mon projet personnel <a title="projet: geoquity" href="http://blog.fruitsoftware.com/2011/10/projet-geoquity/">geoquity</a>. Je viens d&#8217;ajouter un petit &laquo;&nbsp;mashup&nbsp;&raquo; qui utilise Google Maps API, et tout un tas d&#8217;API geolocalisé:</p>
<ul>
<li>wikipedia (via <a title="geonames.org" href="http://www.geonames.org/export/ws-overview.html" target="_blank">geonames.org</a>)</li>
<li><a title="twitter api" href="https://dev.twitter.com/docs" target="_blank">twitter</a></li>
<li><a title="facebook graph api" href="https://developers.facebook.com/docs/reference/api/" target="_blank">facebook</a></li>
<li><a title="flickr api" href="http://www.flickr.com/services/api/" target="_blank">flickr</a></li>
<li><a title="google places api" href="http://code.google.com/apis/maps/documentation/places/" target="_blank">google places</a></li>
<li><a title="yelp api" href="http://www.yelp.com/developers/documentation/v2/overview" target="_blank">yelp</a></li>
<ul>
<li>plus compliqué à appeler, mais facile une fois qu&#8217;on trouve les <a href="https://github.com/Yelp/yelp-api/tree/master/v2/php" target="_blank">exemples de yelp sur github</a></li>
</ul>
<li><a href="http://code.google.com/apis/youtube/overview.html" target="_blank">youtube</a></li>
<li><a title="lastfm api" href="http://www.last.fm/api" target="_blank">lastfm</a></li>
</ul>
<p>J&#8217;ai aussi utilisé pour récupérer certaines statistiques sur Google Analytics la librairie <a href="http://code.google.com/p/gapi-google-analytics-php-interface/" target="_blank">ga:pi</a>, que j&#8217;affiche sur <a title="geo stat page" href="http://demo.saadtazi.com/fr/geo/stats" target="_blank">cette page</a> en utilisant le bundle <a href="https://github.com/saadtazi/SaadTaziGChartBundle" target="_blank">SaadTaziGChartBundle</a>.</p>
<p>Toujours du <a href="http://symfony.com">Symfony2</a> (parfait), du <a href="http://documentcloud.github.com/backbone/" target="_blank">backbone</a> (parfait aussi).</p>
<p>Je sais, la carte est trop chargée, trop d&#8217;icones&#8230; C&#8217;est un peu &laquo;&nbsp;brut&nbsp;&raquo; encore&#8230;</p>
<p>Des questions, remarques, commentaires? N&#8217;hésitez pas à poster un commentaire.</p>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/FGtPhbgxxWc" height="1" width="1"/>]]></content:encoded><description>Je vous ai déjà parlé de mon projet personnel geoquity. Je viens d&amp;#8217;ajouter un petit &amp;#171;&amp;#160;mashup&amp;#160;&amp;#187; qui utilise Google Maps API, et tout un tas d&amp;#8217;API geolocalisé: wikipedia (via geonames.org) twitter facebook flickr google places yelp plus compliqué à appeler, &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2011/10/du-nouveau-sur-geoquity/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/10/du-nouveau-sur-geoquity/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/10/du-nouveau-sur-geoquity/</feedburner:origLink></item><item><title>Projet: SaadTaziOEmbedBundle</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/o15ByKYsYcc/</link><category>Projet</category><category>Symfony</category><category>bundle</category><category>oembed</category><category>symfony2</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Wed, 05 Oct 2011 05:42:06 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=277</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>J&#8217;ai rendu disponible sur github le bundle <a href="https://github.com/saadtazi/SaadTaziOEmbedBundle" target="_blank">SaadTaziOEmbedBundle</a> pour <a href="http://symfony.com">Symfony2</a> qui permet de récupérer des données <a href="http://oembed.com">oembed</a>, pour aller chercher des informations sur des images, vidéos&#8230; lorsque celles-ci sont diffusées par un fournisseur (provider) qui met à disposition les données oembed, comme youtube.com, vimeo.com, flickr.com (la longue liste des fournisseurs est disponible <a href="http://oembed.com/#section7" target="_blank">ici</a>)&#8230;</p>
<p>Une utilisation possible: aller chercher le thumbnail de vidéos youtube ou vimeo (sans avoir à utiliser les différentes apis des différents fournisseurs&#8230;)</p>
<p>Pour en savoir plus sur oembed, lisez la spécification <a href="http://oembed.com/">ici</a>.</p>
<p>J&#8217;ai en fait créé une librairie <a href="https://github.com/saadtazi/simple-oembed" target="_blank">simple-oembed</a> qui est indépendante de Symfony2 (php 5.3+ et curl nécessaires). Le bundle ne fait qu&#8217;exposer le service oembed grâce au DIC de Symfony2. Vous pouvez bien entendu utiliser cette librairie sans utiliser le bundle.</p>
<p>La documentation est dans le README github. Si vous avez des questions/bugs/commentaires, n&#8217;hésitez pas (via ce blog ou github).</p>
<p>En espérant que cela serve à quelqu&#8217;un&#8230;</p>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/o15ByKYsYcc" height="1" width="1"/>]]></content:encoded><description>J&amp;#8217;ai rendu disponible sur github le bundle SaadTaziOEmbedBundle pour Symfony2 qui permet de récupérer des données oembed, pour aller chercher des informations sur des images, vidéos&amp;#8230; lorsque celles-ci sont diffusées par un fournisseur (provider) qui met à disposition les données oembed, &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2011/10/projet-saadtazioembedbundle/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/10/projet-saadtazioembedbundle/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/10/projet-saadtazioembedbundle/</feedburner:origLink></item><item><title>Projet: Geoquity</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/jwmCpW44Mik/</link><category>Projet</category><category>Symfony</category><category>assetic</category><category>backbone</category><category>doctrine</category><category>lesscss</category><category>symfony2</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Mon, 03 Oct 2011 20:53:23 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=270</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Je viens de lancer <a href="http://demo.saadtazi.com/fr/geo" target="_blank">un nouveau projet personnel, geoquity,</a> qui utilise différentes méthodes de géolocalisation, et les compare (bientôt).<br />
Ce projet est dans la lignée d&#8217;un autre projet que j&#8217;avais <a href="http://blog.fruitsoftware.com/2010/04/geolocalisation/" target="_blank">lancé il y a 2 ans et demi</a> http://geo.fruitsoftware.com/. Mais chaque utilisateur est invité à soumettre les données récupérées par les différentes méthodes de géolocalisations, afin de pouvoir comparer les résultats (js geolocation api est super performant pour moi, et pour vous?&#8230;).<br />
Toutes les statistiques collectées restent anonymes bien sûr!</p>
<p>Ça a été pour moi l&#8217;occasion d&#8217;essayer <a href="http://symfony.com/" target="_blank">Symfony 2</a> et de tester plus en détail <a href="http://documentcloud.github.com/backbone/" target="_blank">backbone</a>. Voici un résumé de mon expérience:</p>
<h2>Symfony</h2>
<p>J&#8217;ai beaucoup aimé l&#8217;expérience. Le framework nous force à être organisé, et de plus facilement faire des bundles réutilisables.</p>
<p>Assetic a été très facile d&#8217;utilisation: j&#8217;ai mis en place les filtres lesscss et yui compressors très rapidement, mais j&#8217;ai perdu un peu de temps sur le serveur de production, car j&#8217;avais oublié d&#8217;exécuter:</p>
<pre class="brush: plain; title: ; notranslate">php  app/console assetic:dump --env=prod</pre>
<p>Au niveau de Doctrine (ORM), là aussi, assez simple et facile à mettre en place.</p>
<p>Par contre, du côté des formulaires, j&#8217;ai eu un peu plus de difficulté pour sauvegarder des entités avec une relation one-to-many&#8230; Mais une fois fini, on se rend compte que c&#8217;était &laquo;&nbsp;évident&nbsp;&raquo;, et que &#8216;&nbsp;&raquo;il suffisait de le savoir&nbsp;&raquo;&#8230;</p>
<p>Une note par rapport aux namespaces et à l&#8217;autoloading: Attention au nom des fichiers et des classes PHP: ils doivent être identiques, et la casse doit être la même. Disons que si j&#8217;avais été plus vigilant, j&#8217;aurais sauvé une couple de minutes&#8230; J&#8217;aime mon Mac Book Pro, mais disons que si le filesystem était &laquo;&nbsp;case-sensitive&nbsp;&raquo;, la vie serait plus simple&#8230;</p>
<h2>Backbone</h2>
<p>Là encore, assez simple d&#8217;utilisation, et ce framework nous force à séparer les choses. Mais je crois que je verrai la puissance si j&#8217;utilisais un api RESTful et les collections.</p>
<p>Aussi, je trouve que la séparation Model et View est moins évidente en Javscript (pour moi en tout cas). Je suis pas mal certain que je ferai les choses différemment maintenant que j&#8217;en sais un peu plus sur backbone&#8230;</p>
<h2>Autres affaires</h2>
<h3>html5 boilerplate</h3>
<p>(vraiment rien à dire, dans le bon sens du terme&#8230;)</p>
<h3>the semantic grid</h3>
<p><a href="http://semantic.gs/" target="_blank">The semantic grid</a> est un beau projet, qui permet d&#8217;utiliser la puissance de lesscss pour réaliser des grids très flexibles sans avoir à utiliser des classes css obscures. Ça rend le html très propre.</p>
<h2>Ce qu&#8217;il me reste à faire (un jour&#8230;)</h2>
<ul>
<li><del>Ajouter les statistiques et les rendre publiques</del></li>
<li>Configurer <a href="http://jenkins-ci.org/" target="_blank">Jenkins</a> (je débute en configuration de jenkins&#8230;) pour rouler <a href="http://jenkins-php.org/" target="_blank">les tests et d&#8217;autres outils d&#8217;asurance qualité</a>, et faire le deploiement sur mon serveur <a href="http://webfaction.com" target="_blank">webfaction</a>.</li>
<li><del>Ajouter un mashup qui collecte des données de différentes API géolocalisées (foursquare, facebook&#8230;)</del></li>
</ul>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/jwmCpW44Mik" height="1" width="1"/>]]></content:encoded><description>Je viens de lancer un nouveau projet personnel, geoquity, qui utilise différentes méthodes de géolocalisation, et les compare (bientôt). Ce projet est dans la lignée d&amp;#8217;un autre projet que j&amp;#8217;avais lancé il y a 2 ans et demi http://geo.fruitsoftware.com/. Mais &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2011/10/projet-geoquity/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/10/projet-geoquity/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/10/projet-geoquity/</feedburner:origLink></item><item><title>Passage à Webfaction</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/SkJDIIUuois/</link><category>Non classé</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Sat, 02 Jul 2011 22:03:50 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=255</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Oui, je l&#8217;avoue, je suis encore sur du shared hosting&#8230; Mais je viens de passer à du shared hosting amélioré&#8230;</p>
<p>Cela faisait quelques temps que je voulais migrer vers un nouveau &laquo;&nbsp;hosting&nbsp;&raquo;, pour pouvoir facilement expérimenter des nouvelles technologies, sans devoir me poser la question: &laquo;&nbsp;est-ce que mon hosting supporte ça?&nbsp;&raquo;</p>
<p>Mon soucis: je ne voulais pas faire le saut à un VPS:</p>
<ul>
<li>plus cher généralement,</li>
<li>plus de soucis à installer,</li>
<li>il faut constamment mettre à jour, mais pas forcément tout&#8230;</li>
</ul>
<p>Je me suis donc pris du hosting chez <a href="http://webfaction.com">webfaction.com</a>, et voici mon retour sur l&#8217;expérience &laquo;&nbsp;à date&nbsp;&raquo;.</p>
<h2>Création du compte</h2>
<p>Cela leur a pris 50 minutes pour me donner accès à mon serveur (je pense qu&#8217;on est 2 dessus&#8230; pour l&#8217;instant&#8230;). Pas pire&#8230;</p>
<h2>Tickets</h2>
<p>Cela leur a pris 11 minutes pour répondre et donner une solution qui fonctionnent. Bon, je l&#8217;avoue, c&#8217;est probablement une question qu&#8217;ils doivent se faire poser souvent: version php 5.3 pour une symlink app&#8230;</p>
<h2>Version php</h2>
<p>Bon, ils supportent mieux php 5.2 que php 5.3, mais ils supportent les 2.</p>
<p>En créant une app php (qui créée un répertoire dans webapps), on peut choisir quelle version de php 5.2(.11) ou php 5.3(.5). Mais les choses se corsent avec les app &laquo;&nbsp;symbolic links&nbsp;&raquo; (voir plus bas).</p>
<p><strong>Update: </strong></p>
<ol>
<li>Les symbolic links peuvent être soient 5.2 soient 5.3, donc pas besoin modification du .htaccess.</li>
<li>Mmm, pas de apc ou autre accélérateurs php, à moins d&#8217;installer une version apache et php custom (&laquo;&nbsp;coûte&nbsp;&raquo; de l&#8217;<a href="http://www.webfaction.com/services/hosting" target="_blank">application memory</a>)</li>
</ol>
<h2>Structures</h2>
<p>Comment ça fonctionne: dans une interface d&#8217;admin web, on créée un domaine ou sous-domaine, une application (php, ruby, python&#8230;) et on créée finalement un site web qui lie un sous-domaine à une ou plusieurs apps (donc &laquo;&nbsp;http://monsite.com/&nbsp;&raquo; peut rouler du php, &laquo;&nbsp;htpp://monsite.com/testnode&nbsp;&raquo; peut rouler nodejs&#8230;). Rien de neuf sous le soleil, mais facile et intuitif.</p>
<p>Mais comme il faut bien quelques irritants&#8230; Il faut créer une webapp dans leur panneau de contrôle pour pouvoir faire quelque chose. Donc comme la majorité des apps que j&#8217;ai sont en <a href="http://symfony.com" target="_blank">Symfony</a> 1 ou 2 (mais le problème se poserait aussi pour cakePHP et Zend framework je pense), il ne faut qu&#8217;exposer un répertoire web/ (qui contient le front controller), et tout le reste du code se trouve au même niveau que web/ (app(s)/ ou lib/ ou src/&#8230;</p>
<p>En cherchant un peu, je trouve qu&#8217;il est possible de faire de &laquo;&nbsp;symbolic link&nbsp;&raquo; app: parfait! &#8230; mais il faut créer quand même une app (que j&#8217;ai appelé web_apps) pour déposer tout le code,  que je ne vais jamais linker à un site web pour pouvoir déposer mes apps qui ont besoin d&#8217;un répertoire web/.</p>
<p><del>Seul hic: les apps &laquo;&nbsp;symbolic link&nbsp;&raquo; ne sont possible (pour l&#8217;instant, d&#8217;après le support) qu&#8217;avec php 5.2&#8230; Le trick est d&#8217;ajouter la directive suivante dans le .htaccess (j&#8217;aime pas trop mais ça fonctionne&#8230;):</del></p>
<p><del></p>
<blockquote><p>AddHandler php53-cgi .php</p></blockquote>
<p></del></p>
<p><del>Pas top mais ça ne semble pas ralentir le site.</del></p>
<p>Ceci n&#8217;est plus nécessaire: 2 mode symbolic links maintenant.</p>
<h2>Installation de node</h2>
<p>Alors là, trop facile. 15 minutes et c&#8217;était fait&#8230; Une petite recherche sur google et &#8230; J&#8217;ai utilisé une méthode très similaire à celle décrite par <a href="http://www.ravelrumba.com/blog/how-to-install-node-js-on-webfaction/" target="_blank">Rob Flaherty</a> sur son blog, sauf que:</p>
<ul>
<li>j&#8217;ai mis les sources de node dans mon app web_apps pour la compilation</li>
<li>ce n&#8217;est qu&#8217;après que :
<ul>
<li>j&#8217;ai créée l&#8217;app custom (qui roule sur un port),</li>
<li>associer l&#8217;app à un site</li>
<li>et que je me suis loggé ssh créer le fichier app.js et pour l&#8217;exécuter</li>
</ul>
</li>
</ul>
<p>Avantage: les sources node ne pollue pas mon app node&#8230;</p>
<h2>Configuration Google email (google apps)</h2>
<p>Depuis l&#8217;interface d&#8217;admin my.webfaction.com, très facile: il suffit de créer les MX records&#8230;</p>
<h2>Conclusion</h2>
<p>Pour l&#8217;instant, je suis très satisfait.</p>
<p>J&#8217;espère juste qu&#8217;ils vont améliorer le support de php 5.3, notamment pour les &laquo;&nbsp;symbolic link apps&nbsp;&raquo;.</p>
<p>Autre point positif: beaucoup de documentation, même si l&#8217;ancien forum pollue parfois google&#8230;</p>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/SkJDIIUuois" height="1" width="1"/>]]></content:encoded><description>Un feedback à chaud de webfaction... &lt;a href="http://blog.fruitsoftware.com/2011/07/passage-a-webfaction/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/07/passage-a-webfaction/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/07/passage-a-webfaction/</feedburner:origLink></item><item><title>GChart Bundle – un bundle Symfony pour utiliser Google Chart</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/D9FQO7VYKvI/</link><category>Projet</category><category>Symfony</category><category>bundle</category><category>chart</category><category>google</category><category>symfony</category><category>symfony2</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Sun, 29 May 2011 10:52:04 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=241</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Je viens de <a title="GChartBundle sur github.com" href="https://github.com/saadtazi/SaadTaziGChartBundle" target="_blank">rendre disponible sur github.com</a> GChartBundle, un bundle Symfony (Symfony2 donc&#8230;) qui &laquo;&nbsp;wrappe&nbsp;&raquo; le <a title="Google Chart Tool" href="http://code.google.com/apis/chart/interactive/docs/index.html" target="_blank">Google Chart Tool</a> et quelques charts (mais surtout le QrCode) de <a title="Google Image Chart API" href="http://code.google.com/apis/chart/image/" target="_blank">Google Image Chart API</a>.</p>
<p>Ce que j&#8217;ai appris en faisant ce bundle:</p>
<h2>La puissance du DIC</h2>
<p>La puissance du Dependency Injection Container&#8230; ou comment permettre à l&#8217;utilisateur de redéfinir des paramètres du Bundle, passer des services aux services que l&#8217;on créée&#8230;</p>
<h2>La puissance des Twig Extensions</h2>
<p>&#8230; ou comment définir ses propres fonctions Twig, qui elles-même peuvent appeler &laquo;&nbsp;render&nbsp;&raquo; sur un template.</p>
<p>J&#8217;ai passé un peu de temps à trouver comment faire, mais l&#8217;idée est d&#8217;utiliser la méthode initRunTime() pour garder une référence d&#8217;un Twig_Environment:</p>
<pre class="brush: plain; title: ; notranslate">
    //in Twig/TwigExtension.php
    public function initRuntime(\Twig_Environment $environment)
    {
        $this-&gt;environment = $environment;
    }
</pre>
<p>J&#8217;aurais pu aussi de la même manière utiliser un template php (en passant 2 resources dans le DIC par exemple&#8230;), mais un manque de motivation m&#8217;a gagné (je n&#8217;utilise pas les templates php de toute façon).</p>
<p>Cette partie (=le &laquo;&nbsp;rendering&nbsp;&raquo; d&#8217;un template dans l&#8217;extension Twig) pourrait être plus &laquo;&nbsp;propre aussi&#8230; Dans une version ultérieure peut-être?</p>
<p>Malheureusement, je n&#8217;ai pas de démo live. Mais voici tout de même un <a href="http://blog.fruitsoftware.com/demo-gchartbundle/" target="_blank">démo</a> statique (copier coller du code html généré localement) de ce que génère l&#8217;action Demo.</p>
<p>En espérant que ça aide quelqu&#8217;un&#8230;</p>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/D9FQO7VYKvI" height="1" width="1"/>]]></content:encoded><description>Je viens de rendre disponible sur github.com GChartBundle, un bundle Symfony (Symfony2 donc&amp;#8230;) qui &amp;#171;&amp;#160;wrappe&amp;#160;&amp;#187; le Google Chart Tool et quelques charts (mais surtout le QrCode) de Google Image Chart API. Ce que j&amp;#8217;ai appris en faisant ce bundle: La &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2011/05/gchart-bundle-un-bundle-symfony-pour-utiliser-google-chart/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/05/gchart-bundle-un-bundle-symfony-pour-utiliser-google-chart/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/05/gchart-bundle-un-bundle-symfony-pour-utiliser-google-chart/</feedburner:origLink></item><item><title>Symfony et l’AdminBundle – ça fonctionne!</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/it9b-rWVVFU/</link><category>programmation</category><category>Symfony</category><category>tips</category><category>adminBundle</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Sat, 07 May 2011 19:40:01 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=229</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>&laquo;&nbsp;Ça ne marche pas, ça fonctionne&nbsp;&raquo; &#8211; <em>JF</em></p>
<p>Excellente nouvelle, l&#8217;AdminBundle a été modifié pour fonctionner avec la version beta1 de Symfony.</p>
<p>Grâce à <a href="http://rabaix.net/AdminBundle/html/index.html" target="_blank">la documentation</a> mise en ligne par <a href="http://twitter.com/#!/th0masr" target="_blank">Thomas Rabaix</a> , j&#8217;ai assez facilement réussi à obtenir ça:</p>
<p><a href="http://blog.fruitsoftware.com/wp-content/uploads/2011/05/adminBundle.png"><img class="alignnone size-full wp-image-230" title="adminBundle" src="http://blog.fruitsoftware.com/wp-content/uploads/2011/05/adminBundle.png" alt="" width="800" /></a></p>
<p>(oui, les datas ne sont pas très réaliste, car loadées rapidement avec <a href="https://github.com/symfony/DoctrineFixturesBundle">DoctrineFixturesBundle</a>)</p>
<p>Mon seul &laquo;&nbsp;soucis&nbsp;&raquo; a été de comprendre la configuration à insérer dans config.yml, ne sachant pas trop les préfixes &laquo;&nbsp;sonata&nbsp;&raquo; qu&#8217;il fallait garder. Donc voici ce que j&#8217;ai mis dans mon fichier:</p>
<pre class="brush: plain; title: ; notranslate">
services:
  sonata.blog.admin.post:
    class: SaadTazi\BlogBundle\Admin\PostAdmin
    tags:
      - { name: sonata.admin, manager_type: orm, group: saadtazi_blog, label: post }
    arguments: [null, SaadTazi\BlogBundle\Entity\Post, BlogBundle:PostAdmin]
  sonata.blog.admin.author:
    class: SaadTazi\BlogBundle\Admin\AuthorAdmin
    tags:
      - { name: sonata.admin, manager_type: orm, group: saadtazi_blog, label: author }
    arguments: [null, SaadTazi\BlogBundle\Entity\Author, BlogBundle:AuthorAdmin]
</pre>
<p>(oui, je sais, j&#8217;ai fait un mini système de blog, pas très original, et il existe déjà un NewsBundle&#8230; mais c&#8217;est assez simple comme objectif&#8230;)</p>
<h2>À noter</h2>
<ul>
<li>La documentation: j&#8217;ai déjà donné le lien de la documentation, mais la revoici, juste au cas où vous n&#8217;avez pas compris que c&#8217;est ce qui m&#8217;a permis d&#8217;y arriver&#8230; <a href="http://rabaix.net/AdminBundle/html/index.html" target="_blank">http://rabaix.net/AdminBundle/html/index.html</a></li>
<li>La possibilité d&#8217;ajouter un enregistrement relié par une foreign key directement depuis (depuis une modal jQuery). Un exemple:</li>
</ul>
<p style="text-align: center;"><img class="aligncenter size-large wp-image-231" title="adminBundleAssoc" src="http://blog.fruitsoftware.com/wp-content/uploads/2011/05/adminBundleAssoc-1024x451.png" alt="" width="573" height="253" /></p>
<ul>
<li>Par rapport à l&#8217;admin generator de symfony 1 (une ligne de commande et on avait un module), là il y a un plus de chose à faire pour le développeur: une classe Controller (super simple), une classe Admin, de la configuration dans config.yml (ou xml ou &#8230;)</li>
<li>Reste à trouver comment customiser les menus (xliff i18n?)&#8230;</li>
<li>Il m&#8217;a fallu appliquer <a href="https://github.com/deoxxa/AdminBundle/commit/eb44b7652ffa2ae6ef59b467e96ab086e50e3bc2" target="_blank">ce patch</a> afin de supprimer un problème de &laquo;&nbsp;invalid CSRF token&nbsp;&raquo; à chaque fois que je voulais sauvegarder quelque chose (pas encore accepté&#8230;). Donc ce n&#8217;est probablement pas super stable encore&#8230; Mais je pense que c&#8217;est une fonctionnalité essentielle pour l&#8217;adoption de Symfony par la communauté&#8230;</li>
</ul>
<h2>Merci, Merci, Merci, Merci!!!</h2>
<p>Ça ressemble étrangement à django, vous ne trouvez pas <img src='http://blog.fruitsoftware.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ? Bravo en tout cas en gens autours de <a href="https://github.com/sonata-project" target="_blank">sonata-project</a>.</p>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/it9b-rWVVFU" height="1" width="1"/>]]></content:encoded><description>&amp;#171;&amp;#160;Ça ne marche pas, ça fonctionne&amp;#160;&amp;#187; &amp;#8211; JF Excellente nouvelle, l&amp;#8217;AdminBundle a été modifié pour fonctionner avec la version beta1 de Symfony. Grâce à la documentation mise en ligne par Thomas Rabaix , j&amp;#8217;ai assez facilement réussi à obtenir ça: &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2011/05/symfony-et-ladminbundle-ca-fonctionne/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/05/symfony-et-ladminbundle-ca-fonctionne/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/05/symfony-et-ladminbundle-ca-fonctionne/</feedburner:origLink></item><item><title>Symfony2 beta1 – Notes</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/-w-9wwxw_68/</link><category>programmation</category><category>Symfony</category><category>tips</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Sun, 01 May 2011 20:19:09 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=218</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Maintenant que <a href="http://symfony.com/" target="_blank">Symfony 2</a> est disponible en <a href="http://symfony.com/blog/symfony2-beta1-available" target="_blank">beta 1</a>, je n&#8217;ai pas pu résister, il fallait que je fasse quelques tests.<br />
J&#8217;ai joué avec Doctrine2 ORM, les formulaires, les formats (_format json ou html), la gestions des erreurs (404, 500). J&#8217;ai aussi utilisé <a href="http://documentcloud.github.com/backbone/" target="_blank">backbone.js</a> (YESS!!! Me like!!!) et <a href="http://www.aloha-editor.org/" target="_blank">Aloha Editor</a>, peut-être que j&#8217;En parlerai un jour&#8230;</p>
<p>La seule chose qui n&#8217;a pas fonctionnée (et il m&#8217;a fallu moins d&#8217;une minute pour trouver la solutions &#8211; merci Google!): la version courte du tag Twig &laquo;&nbsp;trans&nbsp;&raquo; n&#8217;est plus supportée.<br />
Dans tous les cas, il faut garder un oeil sur la liste des updates qui brise la compatibilité: <a href="https://github.com/symfony/symfony/blob/master/UPDATE.md">https://github.com/symfony/symfony/blob/master/UPDATE.md</a><br />
Wow!</p>
<h2>Notes intéressantes</h2>
<h3>Autoload et Bundle Registration</h3>
<p>Plus de magie: il faut déclarer toutes les librairies que vous utiliser dans autoload.php. En espérant que la librairie que vous voulez utiliser utilise la convention <a href="http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1" target="_blank">PSR-0</a> ou PEAR (qui voudrait inclure une librairie non-PSR-0 anyway <img src='http://blog.fruitsoftware.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).</p>
<p>En fait, j&#8217;aime ça: on sait ce qui est utilisé dans le projet.</p>
<h3>AdminBundle</h3>
<p>Ça fait 2 fois que j&#8217;essaie d&#8217;installer ce Bundle (remplace l&#8217;admin-generator de symfony1), mais encore une fois sans succès&#8230; En espérant que maintenant que Symfony 2 est en beta, les développeurs vont updater ce Bundle (oui, je sais, j&#8217;aurais pu essayer de le fixer, au moins un peu&#8230; Pas le temps!)</p>
<h3>Doctrine 2</h3>
<p>Toute en douceur, même si je n&#8217;ai pas fait des choses intensives (2 tables simples simples simples&#8230;). J&#8217;ai aimé le fait que la classe du modèle soit uniquement responsable de ce qu&#8217;elle doit être responsable (au revoir active record, bonjour Data Mapper).</p>
<p>Par contre, les behaviours de Doctrine 2 étaient vraiment pratique. Même si il y a quelques plugins qui existent (pas eu le temps de les tester, comme <a href="http://www.gediminasm.org/article/timestampable-behavior-extension-for-doctrine-2" target="_blank">ça</a>), il va falloir attendre les traits (php 5.4?) pour avoir quelque chose de facile à utiliser. Ca va nous forcer à monter des solides hiérarchies de classes probablement (une bonne chose), ou à utiliser les events&#8230;</p>
<p>Ah, aussi, l&#8217;article sur les fixtures Doctrine dans le cookbook fonctionne bien. Du php pur, pas de yaml&#8230; Ok avec ça, sauf pour les gens de QA&#8230; Donc ca va être su deéveloppeur de se monter quelque chose&#8230; ou le Bundle pour les fixtures va être améliorer (mais problème de naming convention: avec les setters et getters des modèles vs les attributs  qui devraient normalement être <em>private</em> ou au moins <em>protected </em>si vous avez du &laquo;&nbsp;coeur&nbsp;&raquo;, quoique le Form Component demande de suivre des &laquo;&nbsp;naming convention&nbsp;&raquo; &#8211; lorsqu&#8217;on passe un objet à un formulaire&#8230;).</p>
<h4>Ajout par rapport à Doctrine (2011-05-07):</h4>
<p>Après quelques tests un peu plus poussés (mais pas trop&#8230;), je me suis demandé s&#8217;il y  avait un mécanisme similaire aux classes XxxxTable.class.php de Doctrine 1.2. Et oui!! Cela existe heureusement, et cela s&#8217;appelle un Repository. Merci à Richard McIntyre pour <a href="http://mackstar.com/blog/2010/10/04/using-repositories-doctrine-2" target="_blank">son article</a>. Voir aussi la <a href="http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html#custom-repositories" target="_blank">documentation Doctrine officielle correspondante</a> (un peu caché et un peu court, non?).</p>
<h3>error template</h3>
<p>- les templates 404 et 500 supporte les templates Twig (symfony 1 offrait la possibilité d&#8217;avoir une page 500 mais elle n&#8217;était pas prise en charge par le framework (ce qui se comprend bien&#8230; ) et peuvent hériter d&#8217;un autre template. Mais attention: trop de logique et de code peut générer une autre erreur. Et là, vous n&#8217;obtiendrai qu&#8217;une page toute blanche&#8230;</p>
<p>- c&#8217;est le même template (error.html.twig pour la version html) qui est utilisé pour les 404 et 500 &#8211; c&#8217;est au développeur de mettre en place une logique &laquo;&nbsp;switch&nbsp;&raquo; sur le status_code s&#8217;il veut avoir différentes pages 404 et 500. Mais peut-être qu&#8217;il y a une autre manière de gérer la page 404 dans le routing, à la Sinatra par exemple? Histoire à suivre&#8230; Update (probablement disponible en beta2): C&#8217;est maintenant <a href="https://github.com/symfony/symfony-docs/commit/736fc4c6ecf88c7d4e7779851400b48a4c7e63c5" target="_blank">possible</a>: Il suffit d&#8217;avoir un template errorXXX.html.twig par exemple, ou XXX est le status code http (404, 500, 403&#8230;). Si ce template n&#8217;existe pas, alors error.html.twig sera utilisé.</p>
<h3>&laquo;&nbsp;app.yml is gone&nbsp;&raquo;</h3>
<p>Je n&#8217;ai pas trouvé de recommendation dans le &laquo;&nbsp;book&nbsp;&raquo; pour conserver les settings et paramètres d&#8217;une application, par environnement. J&#8217;imagine que &laquo;&nbsp;import&nbsp;&raquo; dans config.yml et le Yaml component permettent de faire ça très facilement.</p>
<p>Dans le même ordre d&#8217;idée, je n&#8217;ai pas trouvé de détails sur config.yml dans le profiler&#8230;</p>
<h3>Conclusion</h3>
<p>Bon, en un mot, j&#8217;ai bien hâte de l&#8217;utiliser sur un vrai projet! Je vous en reparlerai à ce moment-là&#8230; Histoire à suivre donc&#8230;</p>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/-w-9wwxw_68" height="1" width="1"/>]]></content:encoded><description>Maintenant que Symfony 2 est disponible en beta 1, je n&amp;#8217;ai pas pu résister, il fallait que je fasse quelques tests. J&amp;#8217;ai joué avec Doctrine2 ORM, les formulaires, les formats (_format json ou html), la gestions des erreurs (404, 500). &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2011/05/symfony2-beta1-notes/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/05/symfony2-beta1-notes/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/05/symfony2-beta1-notes/</feedburner:origLink></item><item><title>Symfony 2 et AsseticBundle – tips</title><link>http://feedproxy.google.com/~r/ToutSurRien/~3/WWQ8eYUl69Y/</link><category>programmation</category><category>Symfony</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Saad Tazi</dc:creator><pubDate>Sun, 24 Apr 2011 16:44:52 PDT</pubDate><guid isPermaLink="false">http://blog.fruitsoftware.com/?p=206</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Je suis vraiment impressionné par <a href="https://github.com/kriswallsmith/assetic" target="_blank">Assetic</a>, la librairie PHP écrite par Kris Wallsmith.</p>
<p>Elle permet pour tout projet PHP de gérer les &laquo;&nbsp;assets&nbsp;&raquo; javascript et css, en utilisant des techniques modernes tel que: less, sass, coffeescript&#8230;</p>
<p>La documentation étant encore un peu sommaire, notamment pour l&#8217;Intégration avec <a href="http://symfony.com" target="_blank">Symfony 2</a>, voici quelques notes afin de ne pas oublier comment faire (pour la prochaine fois hein&#8230;)</p>
<h2>Less</h2>
<p>Config.yml</p>
<pre class="brush: plain; title: ; notranslate">
# Assetic Configuration
assetic:
    debug:          %kernel.debug%
    use_controller: %kernel.debug%
    read_from:      %kernel.root_dir%/../web/bundles
    write_to:       %kernel.root_dir%/../web/assets
    filters:
        cssrewrite: ~
        less: ~
#...
parameters:
  assetic.node.bin: /usr/local/bin/node
  #ca m'a pris longtemps pour trouver la config
  #  pour loader les packages npm par exemple
  assetic.node.paths:
    - /usr/local/lib/node
</pre>
<p>Puis dans routing_dev.yml (nécessaire là où use_controller est true), j&#8217;ai ajouté la route:</p>
<pre class="brush: plain; title: ; notranslate">
_assetic:
    resource: .
    type: assetic
</pre>
<p>Puis il suffit d&#8217;inclure dans le template (Twig):</p>
<pre class="brush: plain; title: ; notranslate">
{% stylesheets
		filter='less'
		output='css/all.css'
		'@SaadTestBundle/Resources/public/less/main.less'
%}
&lt;link href=&quot;{{asset_url}}&quot; rel=&quot;stylesheet&quot;/&gt;
{% endstylesheets %}
</pre>
<p>Cela produira:</p>
<pre class="brush: plain; title: ; notranslate">
&lt;link href=&quot;/app_dev.php/css/all_main1.css&quot; rel=&quot;stylesheet&quot;/&gt;
</pre>
<img src="http://feeds.feedburner.com/~r/ToutSurRien/~4/WWQ8eYUl69Y" height="1" width="1"/>]]></content:encoded><description>Je suis vraiment impressionné par Assetic, la librairie PHP écrite par Kris Wallsmith. Elle permet pour tout projet PHP de gérer les &amp;#171;&amp;#160;assets&amp;#160;&amp;#187; javascript et css, en utilisant des techniques modernes tel que: less, sass, coffeescript&amp;#8230; La documentation étant encore un &amp;#8230; &lt;a href="http://blog.fruitsoftware.com/2011/04/symfony-2-et-asseticbundle-tips/"&gt;Lire la suite &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.fruitsoftware.com/2011/04/symfony-2-et-asseticbundle-tips/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">6</slash:comments><feedburner:origLink>http://blog.fruitsoftware.com/2011/04/symfony-2-et-asseticbundle-tips/</feedburner:origLink></item></channel></rss>

