<?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>DEVBLOG :: Le blog d'Alexandre BALMES, jeune chef de projet &#187; Développement</title>
	<atom:link href="http://dev.pockyworld.com/category/developpement/feed" rel="self" type="application/rss+xml" />
	<link>http://dev.pockyworld.com</link>
	<description>Enfin j'essaie</description>
	<lastBuildDate>Wed, 01 Dec 2010 22:24:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Peanut Semaine&#8230; peanutPosts disponible en téléchargement !</title>
		<link>http://dev.pockyworld.com/developpement/php/peanut-semaine-peanutposts-disponible-en-telechargement.html</link>
		<comments>http://dev.pockyworld.com/developpement/php/peanut-semaine-peanutposts-disponible-en-telechargement.html#comments</comments>
		<pubDate>Fri, 30 Jul 2010 10:37:43 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[peanut]]></category>
		<category><![CDATA[projet]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=243</guid>
		<description><![CDATA[Et non le projet n&#8217;est pas mort Ceux qui me suivent sur Twitter ont pu voir que les choses c&#8217;étaient un peu compliqués ces derniers temps même si tout est revenu dans l&#8217;ordre pour le moment. Le plugin peanutPosts a été ajouté à son propre repository Git et est utilisable en l&#8217;état. Au passage, un [...]]]></description>
			<content:encoded><![CDATA[<p>Et non le projet n&#8217;est pas mort <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>Ceux qui me suivent sur Twitter ont pu voir que les choses c&#8217;étaient un peu compliqués ces derniers temps même si tout est revenu dans l&#8217;ordre pour le moment. Le plugin peanutPosts a été ajouté <a href="http://github.com/pocky/peanutPostsPlugin">à son propre repository Git</a> et est utilisable en l&#8217;état.</p>

<p>Au passage, un grand nettoyage a été effectué <a href="http://github.com/pocky/peanut">sur le repository principal</a> au niveau des branches et le readme a été mis à jour (avec des fautes d&#8217;orthographes).</p>

<p>A noter que vous pouvez utiliser ce plugin indépendamment de peanut sans aucun problème puisqu&#8217;il n&#8217;a que deux pré-requis : <a href="http://github.com/pocky/sfDoctrineGuardPlugin">sfDoctrineGuardPlugin</a> (<a href="http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin">version officielle</a>) et <a href="http://www.symfony-project.org/plugins/sfDoctrineActAsTaggablePlugin">sfDoctrineActAsTaggablePlugin</a>.</p>

<p>Le validateur du formulaire de contact <a href="http://github.com/pocky/sfValidatorSimpleCaptcha">sfValidatorSimpleCaptcha</a> a également son repository et sera prochainement remplacé sur le formulaire de contact par un autre validateur sfValidatorHiddenCaptcha.</p>

<p>Et pour finir, parce que je ne le dirait jamais assez, Symfony est un régal à pratiquer !
A bientôt !</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/php/peanut-semaine-peanutposts-disponible-en-telechargement.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Peanut : Semaine 7 &#8211; peanutPosts</title>
		<link>http://dev.pockyworld.com/developpement/php/peanut-semaine-7-peanutposts.html</link>
		<comments>http://dev.pockyworld.com/developpement/php/peanut-semaine-7-peanutposts.html#comments</comments>
		<pubDate>Mon, 31 May 2010 21:22:48 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[peanut]]></category>
		<category><![CDATA[projet]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=236</guid>
		<description><![CDATA[Bonsoir ! Itération 7 cette semaine avec la création de la branche peanutPosts. Cette branche contient non pas un mais trois modules qui sont en cours de préparation : Le module peanutCategories : gestion des catégories Le module peanutPosts : gestion des articles dynamiques Le module tag : via le behavior Taggable Il y a [...]]]></description>
			<content:encoded><![CDATA[<p>Bonsoir !</p>

<p>Itération 7 cette semaine avec la création de <a href="http://github.com/pocky/peanut">la branche peanutPosts</a>. Cette branche contient non pas un mais trois modules qui sont en cours de préparation :</p>

<ul>
<li>Le module peanutCategories : gestion des catégories</li>
<li>Le module peanutPosts : gestion des articles dynamiques</li>
<li>Le module tag : via le behavior Taggable</li>
</ul>

<p>Il y a donc pas mal de travail à faire et tout avance au fur et à mesure dans l&#8217;ordre précédent. La création de ce module m&#8217;a également permit de découvrir le behavior Doctrine nestedSet permettant de gérer un arbre et ainsi éviter beaucoup de problèmes de récursivité (avec une gestion des catégories plus classique). Je compte d&#8217;ailleurs bien utiliser ce behavior sur le module peanutPage lors de sa refactorisation</p>

<p>Cette itération a également connue un petit bug avec le module Doctrine sfGuardForgotPassword alors vous pouvez remercier tight qui a apporté une réponse au <a href="http://github.com/pocky/peanut/issues/closed#issue/1">ticket de bug</a>.</p>

<p>La semaine dernière, un site de présentation a été mis en ligne à l&#8217;adresse suivante <a href="http://www.peanut.fr">http://www.peanut.fr</a>. Une personne c&#8217;est déjà amusée avec le formulaire de contact et vous pouvez faire de même. Vous n&#8217;aurez cependant pas accès au backoffice pour le moment, je l&#8217;ouvrirais un peu plus tard sur un site de demo. Ce site sera bien entendu amené à évoluer avec les différents modules.</p>

<p>Et pour conclure, je suis toujours aussi motivé par ce projet alors n&#8217;hésitez pas à me faire part de vos bugs ou envie, j&#8217;essaierai de faire le plus d&#8217;heureux possible !</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/php/peanut-semaine-7-peanutposts.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Peanut : Semaine 6 &#8211; peanutPage (fin et bonus)</title>
		<link>http://dev.pockyworld.com/developpement/php/peanut-semaine-6-peanutpage-fin-et-bonus.html</link>
		<comments>http://dev.pockyworld.com/developpement/php/peanut-semaine-6-peanutpage-fin-et-bonus.html#comments</comments>
		<pubDate>Tue, 25 May 2010 20:40:02 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[peanut]]></category>
		<category><![CDATA[contact]]></category>
		<category><![CDATA[page]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=232</guid>
		<description><![CDATA[Bonjour à tous, Pour cette sixième semaine, la fin de la version 1.0 du module peanutPage. Ce module est donc fonctionnel et vous pouvez d&#8217;ors et déjà l&#8217;utiliser. Un petit passage en intégration (sur un vrai-faux site) m&#8217;à même permis d&#8217;ajouter quelques fonctions bien utiles pour le commun des mortels. Avec ce module, le plugin [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour à tous,</p>

<p>Pour cette sixième semaine, la fin de la version 1.0 du module peanutPage. Ce module est donc fonctionnel et vous pouvez d&#8217;ors et déjà l&#8217;utiliser. Un petit passage en intégration (sur un vrai-faux site) m&#8217;à même permis d&#8217;ajouter quelques fonctions bien utiles pour le commun des mortels.</p>

<p>Avec ce module, le plugin <a href="http://www.symfony-project.org/plugins/csDoctrineActAsSortablePlugin">csDoctrineActAsSortable</a> a été ajouté ainsi que le plugin <a href="http://www.symfony-project.org/plugins/sfCKEditorPlugin">sfCKEditorPlugin</a>.</p>

<p>Quelques ajouts xHTML/CSS ont été faits afin d&#8217;améliorer un peu le tout au niveau graphique et rendre le backend un peu plus sexy.</p>

<p>Bonus, le module contact a également été ajouté. Rien de bien exceptionnel à ce niveau puisque le formulaire de contact met tout simplement en place le <a href="http://www.symfony-project.org/forms/1_4/fr/">tutoriel symfony forms in action</a>. J&#8217;ai tout de même créé un petit validateur au passage baptisé sfValidatorSimpleCaptcha permettant de valider un captcha simple (sur la base d&#8217;un addition avec deux opérateurs).</p>

<p>Le module contact est donc également en version 1.0</p>

<p>Le plus important étant que maintenant, vous pouvez utiliser peanut pour créer un site simple de quelques pages même si cela reviendra à utiliser une grosse berline pour aller acheter votre pain.</p>

<h3>Le wiki</h3>

<p>J&#8217;ai ajouté quelques pages au <a href="http://wiki.github.com/pocky/peanut/">wiki</a> github afin de vous donner quelques informations sur la suite et le programme en perspective. Si vous repérez des bugs mais que vous ne voulez pas forcément proposer une solution, n&#8217;hésitez pas à utiliser <a href="http://github.com/pocky/peanut/issues">la gestion de ticket github</a>. Tout est bon à prendre pour moi avec ce projet.</p>

<h3>Modification de l&#8217;utilisation de Git</h3>

<p>J&#8217;ai décidé d&#8217;utiliser <a href="http://book.git-scm.com/5_submodules.html">les submodules git</a> afin de gérer les plugins dans le projet. Les submodules Git sont un peu l&#8217;équivalent des externals de SVN. Concrètement cela permet d&#8217;ajouter des projets git à l&#8217;intérieur même d&#8217;un superprojet git et donc de pouvoir faciliter les updates.</p>

<p>Dans notre cas, cela permettra de gérer les plugins du projet en offrant à tous la possibilité de télécharger directement le plugin (ou proposer des modifications) sur le repository associé.</p>

<p>Deux submodules ont été ajoutés pour le moment, <a href="http://github.com/vjousse/symfony-1.4">symfony</a> et mon fork de <a href="http://github.com/pocky/sfDoctrineGuardPlugin">sfDoctrineGuardPlugin</a>.</p>

<h3>Oups!</h3>

<p>J&#8217;ai fait une &laquo;&nbsp;petite&nbsp;&raquo; erreur de manipulation avec mes branches Git suite à l&#8217;utilisation des submodules. Git a en effet quelques problèmes pour gérer l&#8217;ajout de submodule sur une branche lors d&#8217;un checkout sur une branche sans submodules (d&#8217;après ce que j&#8217;ai compris). Résultat des courses, une fausse manip en essayant de faire fonctionner le tout et ma branche master disparait. Il m&#8217;a donc fallu la recréer et&#8230; Il faut forger pour être forgeron <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>

<p>Un cours de Git m&#8217;attends vendredi soir pour régler les petits problèmes associés à cette erreur (rien de méchant). J&#8217;aurais donc tendance à vous conseiller d&#8217;attendre samedi pour faire une mise à jour (ou alors de ne pas oublier de créer un répertoire &laquo;&nbsp;cache&nbsp;&raquo; à la racine du projet. Au passage, peanut sera tagué en version 1 et un site demo sera mis en ligne dans la semaine.</p>

<h3>Modification de la roadmap</h3>

<p>Etant donné que j&#8217;ai besoin d&#8217;utiliser peanut pour un projet, je vais un peu modifier la roadmap annoncé la semaine dernière.  Le projet va donc évoluer de la façon suivante :</p>

<ul>
<li>Création du module peanutCategories</li>
<li>Création du module peanutPosts</li>
<li>Création du plugin peanutPosts</li>
<li>Création du module peanutComments</li>
<li>Création du plugin peanutComments</li>
<li>Création du module peanutSEO</li>
<li>Création du plugin peanutSEO</li>
</ul>

<p>Si tout se passe bien, le tout devrait prendre de 3 à 4 itérations pour les v1 de ses modules/plugins.</p>

<p>Je passerais ensuite au refactoring/amélioration/debug de l&#8217;ensemble des modules. Chacun de ses modules (à travers leurs plugins) auront leurs propres repository Git et seront intégrés sous la forme de submodules dans le projet principal. Cela permettra au passage de pouvoir profiter d&#8217;un ou plusieurs plugins de son choix sans utiliser la base (même si certains plugins comme le module peanutSEO seront dépendants d&#8217;autres plugins).</p>

<p>Ce sera tout pour cette semaine !
A la semaine prochaine <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>Et pour rappel, vous pouvez récupérer le projet <a href="http://github.com/pocky/peanut">sur Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/php/peanut-semaine-6-peanutpage-fin-et-bonus.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Peanut : Semaine 4 &#8211; sfDoctrineGuardPlugin</title>
		<link>http://dev.pockyworld.com/developpement/php/peanut-semaine-4-sfdoctrineguardplugin.html</link>
		<comments>http://dev.pockyworld.com/developpement/php/peanut-semaine-4-sfdoctrineguardplugin.html#comments</comments>
		<pubDate>Sun, 09 May 2010 19:57:50 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projets]]></category>
		<category><![CDATA[peanut]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[projet]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=216</guid>
		<description><![CDATA[Il c&#8217;est passé un peu de temps depuis le dernier article et je continue tranquillement à avancer au rythmefixé (au moins un lot de fonctionnalités par semaine) mais j&#8217;ai eu énormément de travail ces derniers temps et donc&#8230; Aucune nouvelle. Semaine 3 &#8211; template, template, template La semaine dernière a essentiellement servie à créer le [...]]]></description>
			<content:encoded><![CDATA[<p>Il c&#8217;est passé un peu de temps depuis le dernier article et je continue tranquillement à avancer au rythmefixé (au moins un lot de fonctionnalités par semaine) mais j&#8217;ai eu énormément de travail ces derniers temps et donc&#8230; Aucune nouvelle.</p>

<h3>Semaine 3 &#8211; template, template, template</h3>

<p>La semaine dernière a essentiellement servie à créer le layout du backend. Pas grand chose à dire à ce niveau, j&#8217;ai essayé de me faire un peu plaisir avec un peu de CSS3, un peu de jQuery et du xHTML (et oui, pas de HTML5 pour le backend). Je n&#8217;ai par contre pas encore pris le temps de valider les pages. Il peut donc y avoir quelques erreurs d&#8217;intégration. Le backoffice n&#8217;a également pas été testé sur la famille Internet Explorer mais je m&#8217;en occuperais dans quelques itérations au maximum car inutile de vous le cacher, mon prochain blog tournera bel et bien sur peanut (quitte à devoir évoluer avec).</p>

<h3>Semaine 4 &#8211; spéciale sfDoctrineGuardPlugin</h3>

<p>Comme je l&#8217;avais dis au début du projet, je comptais bien modifier sfDoctrineGuardPlugin. Lors de la création du projet, je suis parti sur la base du <a href="http://svn.symfony-project.com/plugins/sfDoctrineGuardPlugin/trunk/">trunk de sfDoctrineGuardPlugin</a> qui ajoute certaines fonctionnalités avec deux modules : sfGuardForgotPassword et sfGuardRegister permettant respectivement de récupérer son mot de passe et de se créer un compte.</p>

<p>Malheureusement, les process utilisés lors de ces étapes ne sont pas &laquo;&nbsp;corrects&nbsp;&raquo; dans le sens ou si effectivement ils fonctionnent, ils ne font pas forcément les choses correctement. Je me suis donc efforcé de modifier ces éléments afin de corriger un peu le tir, tout du moins à mon sens. Rassurez-vous, les modifications ne sont pas nombreuses mais en voici quelques unes.</p>

<p><strong>sfGuardAuth</strong></p>

<ul>
<li>Possibilité via le fichier app.yml d&#8217;autoriser ou non la connection via le nom d&#8217;utilisateur et le mot de passe</li>
</ul>

<p><strong>sfGuardUser</strong></p>

<ul>
<li>Modification du fichier schema.yml afin qu&#8217;un utilisateur ne soit pas actif par défaut</li>
</ul>

<p><strong>sfGuardRegister</strong></p>

<ul>
<li>Modification de la route afin de pouvoir gérer le process d&#8217;inscription</li>
<li>Lors de la création de compte, un email est envoyé à l&#8217;utilisateur afin de confirmer la création du compte</li>
<li>Modification du process d&#8217;inscription qui va se charger de vérifier certains points importants avant d&#8217;activer le compte</li>
</ul>

<p><strong>sfGuardForgotPassword</strong></p>

<ul>
<li>L&#8217;email envoyé par défaut indique un délai de 24H pour valider son compte mais le code n&#8217;imposait pas de limite et n&#8217;enregistrait même pas la limite correctement</li>
<li>Ajout d&#8217;une tache permettant via cronjob de supprimer tous les utilisateurs n&#8217;ayant pas validé leur compte</li>
</ul>

<p><strong>De façon générale</strong>
- Ajout de traductions (uniquement en français)</p>

<h4>Parce qu&#8217;il faut tout de même le dire</h4>

<p>Ce qui est actuellement en place est bien entendu perfectible. Le process d&#8217;inscription par exemple va générer une chaine sha1 basée sur le nom d&#8217;utilisateur, son adresse email et le csrf token de l&#8217;application et comme vous pouvez vous en douter&#8230; Il y a mieux (mais il y a aussi largement pire).</p>

<p>Pour moi, il faudrait créer une nouvelle table permettant de stocker les utlisateurs en cours d&#8217;inscription avec une clé unique en base de donnée afin de vraiment garantir la sécurité à ce niveau. L&#8217;autre option pourrait être de générer le sha1 sur la base du timestamp de création du compte qui pourrait ainsi (puisque stocké en bdd via created_at) servir de base un peu plus fiable. Autre solution, enregistrer l&#8217;utilisateur, récupérer l&#8217;objet utilisateur et générer quelque chose d&#8217;unique basé sur le salt par exemple.</p>

<p>Ceci dit je préfère attendre quelqu&#8217;uns de vos retours et mettre tout ça dans ma todolist pour un (éventuel et certains) refactoring dans le futur.</p>

<p>Autre chose, l&#8217;ensemble de ce travail a directement été fait dans le plugin sfDoctrineGuard car cela fais vraiment parti pour moi des fonctions à assurer au minimum et non à rajouter à la volée suivant les besoins de chaques projets (contrairement à la personnalisation des templates par exemple). Vous pouvez donc très bien surcharger ce qui est fait mais par défaut, une personne s&#8217;inscrit, reçoit un email de confirmation puis confirme son compte et cela tiens quand même plus la route qu&#8217;une inscription directe sans plus de vérification que ça.</p>

<p>Enfin, les tests unitaires ne sont pas complets et il faut vraiment que je m&#8217;y mette. Cela me dépasse encore un peu pour le moment. Je vois bien le principe mais je ne sais pas si c&#8217;est parce que j&#8217;ai l&#8217;habitude de chercher à faire tout de suite compliqué mais la&#8230; Je ne serais pas contre un petit cours à l&#8217;oral avec démo et questions connes en direct.</p>

<p>Ceci dit et si jamais j&#8217;arrive (ou nous arrivons via vos éventuelles contributions) à améliorer le plugin sfDoctrineGuard, j&#8217;aimerais le proposer afin qu&#8217;il soit intégré aux plugins (voir remplacer la version actuelle). Certaines conversations lues sur IRC me font dire que ce ne serait pas une mauvaise chose.</p>

<p>Petit détail d&#8217;importance, il faut que vous sachiez que mon anglais est encore moins bon que mon français à l&#8217;écrit en ce moment. Si jamais vous voulez modifier ça parce que&#8230; Hum&#8230; Okay mais bon il y a mieux, n&#8217;hésitez pas. Il faudrait également s&#8217;occuper de la traduction espagnole (puisqu&#8217;il y en a une pour le plugin) pour ne pas faire de malheureux mais la&#8230; Je vous laisse faire.</p>

<h4>A quoi peut servir peanut actuellement ?</h4>

<p>Si jamais vous vous posez la question, peanut peut vous servir (dans l&#8217;état actuel) à tout et à rien puisqu&#8217;il n&#8217;assure rien d&#8217;autre que la gestion de vos utilisateurs, groupes et permissions. Il est donc envisageable de faire n&#8217;importe quoi autour de ça : Réseau social, trombinoscope, intranet, extranet&#8230; Et j&#8217;en passe.</p>

<p>J&#8217;essaierai de vous donner ce genre d&#8217;exemples à chaque itération.</p>

<h4>Le débat de la semaine</h4>

<p>Le débat de la semaine porte sur la traduction i18n pour les setFlash(). <a href="http://gist.github.com/395109">Un gist</a> a donc été créé et de la même façon que lors de la précédente question ouverte, je vous invite à l&#8217;enrichir via vos différentes méthodes afin de trouver les différentes façons de faire. Vous en trouverez actuellement trois, plus ou moins sexy mais qui fonctionnent toutes.</p>

<h4>A venir</h4>

<p>Le premier module du CMS permettant tout simplement de créer des &laquo;&nbsp;pages&nbsp;&raquo; (comprendre pages dynamiques peu modifiées du type CGU/CGV/&#8230;) pour votre site Internet.</p>

<h4>Et pour finir</h4>

<p>J&#8217;ai activé le système de donation sur le projet. A défaut d&#8217;aller directement dans mes poches, tout sera stocké sur un compte paypal dédié dans le but de m&#8217;offrir certaines formations dispensées par <a href="http://trainings.sensiolabs.com/fr">SensioLabs Trainings</a> qui seraient à priori :</p>

<ul>
<li>PHP niveau 1 : bases</li>
<li>PHP niveau 2 : POO</li>
<li>Symfony 1.4 + Doctrine</li>
<li>Symfony et REST</li>
<li>Doctrine</li>
</ul>

<p>Bien entendu, cela pourra évoluer (je l&#8217;espère bien) avec ce projet puisque le but pour moi est de pratiquer encore et encore  afin de m&#8217;améliorer jusqu&#8217;au moment où je pourrais trashtalk sur PHP <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>

<p>Et pour rappel, <a href="http://github.com/pocky/peanut">un lien vers le projet</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/php/peanut-semaine-4-sfdoctrineguardplugin.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Question ouverte : Le meilleur moyen de tester le contenu d&#8217;un objet Doctrine ?</title>
		<link>http://dev.pockyworld.com/developpement/php/question-ouverte-le-meilleur-moyen-de-tester-le-contenu-dun-objet-doctrine.html</link>
		<comments>http://dev.pockyworld.com/developpement/php/question-ouverte-le-meilleur-moyen-de-tester-le-contenu-dun-objet-doctrine.html#comments</comments>
		<pubDate>Wed, 21 Apr 2010 19:31:10 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[question]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=203</guid>
		<description><![CDATA[Le problème avec les questions ouvertes, c&#8217;est que l&#8217;on ne sait pas toujours comment formuler correctement la question. Alors de mieux qu&#8217;un peu de code pour illustrer mes propos. Le contexte Nous avons une table post dans laquelle nous n&#8217;avons pas encore d&#8217;articles. On va donc faire les choses simplement sans se poser trop de [...]]]></description>
			<content:encoded><![CDATA[<p>Le problème avec les questions ouvertes, c&#8217;est que l&#8217;on ne sait pas toujours comment formuler correctement la question. Alors de mieux qu&#8217;un peu de code pour illustrer mes propos.</p>

<h3>Le contexte</h3>

<p>Nous avons une table <em>post</em> dans laquelle nous n&#8217;avons pas encore d&#8217;articles. On va donc faire les choses simplement sans se poser trop de questions. À la wordpress <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>

<h3>Le code</h3>

<p><strong>/lib/model/doctrine/postsTable.class.php</strong></p>

<pre><code>&lt;?php

  class postsTable extends Doctrine_Table
  {

    public function getPosts()
    {
      $t = $this-&gt;createQuery('c')
        -&gt;where('c.status = ?', 'publish');

      return $t-&gt;execute();
    }

  }
</code></pre>

<p><strong>/apps/frontend/modules/posts/actions/actions.class.php</strong></p>

<pre><code>&lt;?php

  /**
   * posts actions
   */

   class postsActions extends sfActions
   {

     public function executeIndex(sfWebRequst $request)
     {
       $this-&gt;entries = Doctrine::getTable('Posts')-&gt;getPosts();

       $this-&gt;forward404Unless($this-&gt;entries);
     }

   }
}
</code></pre>

<p>Et enfin dans notre template : <strong>/apps/frontend/modules/posts/templates/indexSuccess.php</strong></p>

<pre><code>[...]

&lt;?php if($entries) {

  foreach($entries as $entry) { ?&gt;

    &lt;h2&gt;&lt;?php echo $entry-&gt;getTitle() ?&gt;&lt;/h2&gt;
    [...]

  &lt;?php }

} else { ?&gt;

  &lt;h2&gt;Oups! Aucun article n'a été trouvé&lt;/h2&gt;

&lt;?php } ?&gt;
</code></pre>

<h3>Le résultat</h3>

<p>La première fois que j&#8217;ai fait ce code, je m&#8217;attendais vraiment à trouver mon &laquo;&nbsp;Oups&#8230;&nbsp;&raquo;. Ca me paraissait logique, table vide, la requête ne peut pas renvoyer de résultats à l&#8217;action et donc dans la vue mais non. Toujours et encore toujours du vide et aucun &laquo;&nbsp;Oups&#8230;&nbsp;&raquo;.</p>

<p>Et je ne comprends pas.</p>

<p>Je me suis donc &laquo;&nbsp;amusé&nbsp;&raquo; (c&#8217;est vite dit sur Doctrine) avec un <em>var_dump</em> afin de voir ce qui pouvait bien être stocké dans ma variable <em>$entries</em>. Après avoir décortiqué la soupe issue du <em>var_dump</em>, j&#8217;ai pu voir que ma variable contenait un <em>Doctrine_collection</em> vide et donc au final quelque chose &laquo;&nbsp;plein de vide&nbsp;&raquo;.</p>

<p>C&#8217;est donc la que l&#8217;on peut commencer à réfléchir.</p>

<h3>Version 1 &#8211; getFirst</h3>

<p>La première solution consiste à tester via Doctrine si il y a au moins un enregistrement :</p>

<p>Dans <strong>/apps/frontend/modules/posts/templates/indexSuccess.php</strong></p>

<pre><code>[...]

&lt;?php if($entries-&gt;getFirst()) {

  foreach($entries as $entry) { ?&gt;

    &lt;h2&gt;&lt;?php echo $entry-&gt;getTitle() ?&gt;&lt;/h2&gt;
    [...]

  &lt;?php }

} else { ?&gt;

  &lt;h2&gt;Oups! Aucun article n'a été trouvé&lt;/h2&gt;

&lt;?php } ?&gt;
</code></pre>

<h3>Version 2 &#8211; count()</h3>

<p>Seconde solution, compter avec un bon vieux <em>count()</em> en PHP :</p>

<p>Dans <strong>/apps/frontend/modules/posts/templates/indexSuccess.php</strong></p>

<pre><code>[...]

&lt;?php if(count($entries) &gt; 0)) {

  foreach($entries as $entry) { ?&gt;

    &lt;h2&gt;&lt;?php echo $entry-&gt;getTitle() ?&gt;&lt;/h2&gt;
    [...]

  &lt;?php }

} else { ?&gt;

  &lt;h2&gt;Oups! Aucun article n'a été trouvé&lt;/h2&gt;

&lt;?php } ?&gt;
</code></pre>

<h3>Analyse des versions 1 et 2</h3>

<p>Les deux solutions fonctionnent mais la méthode ne me semble pas correcte. Si je donne le tout à intégrateur++ qui peut intégrer n&#8217;importe quel template WordPress, saura-t&#8217;il faire la même chose avec le mien ?</p>

<p>Réponse négative à mon sens, on ne va pas penser à un <em>count()</em> ou un <em>getFirst()</em> de Doctrine. C&#8217;est encore plus vrai dans le sens où venant de cet univers, je n&#8217;ai absolument pas pensé à faire cette &laquo;&nbsp;opération&nbsp;&raquo;. Il faut donc trouver autre chose.</p>

<h3>Version 3 &#8211; count() dans l&#8217;action</h3>

<pre><code>&lt;?php

  /**
   * posts actions
   */

   class postsActions extends sfActions
   {

     public function executeIndex(sfWebRequst $request)
     {
       $entries = Doctrine::getTable('Posts')-&gt;getPosts();

       if(count($entries) &gt; 0)
       {
         $this-&gt;entries = $entries;
       }

       else
       {
         $this-&gt;entries = false;
       }

       $this-&gt;forward404Unless($entries);
     }

   }
}
</code></pre>

<h3>Version 4 &#8211; count() dans le model</h3>

<pre><code>&lt;?php

  class postsTable extends Doctrine_Table
  {

    public function getPosts()
    {
      $t = $this-&gt;createQuery('c')
        -&gt;where('c.status = ?', 'publish')
        -&gt;execute();

      if(count($t) &gt; 0)
      {
        return $t;
      }

      else
      {
        return NULL;         
      }

    }

  }
</code></pre>

<h3>Analyse des versions 3 et 4</h3>

<p>Avec ces deux versions, je peux renvoyer <em>NULL</em> et tester ma variable beaucoup plus simplement (et pour tout le monde). La question est donc de savoir si cela doit être fait dans l&#8217;action ou dans le model.</p>

<p>J&#8217;y ai donc réfléchis un peu et je trouve que le faire dans le model est plus simple car permet également de vérifier le contenu d&#8217;une requête plus rapidement et avec moins de ligne de code dans l&#8217;action. De plus, on peut mettre en place des tests comme <em>is_object()</em> ou <em>is_null()</em> à tous les niveaux ce qui ne me semble pas plus mal.</p>

<p>Mais vous, qu&#8217;en pensez-vous ? Où avez-vous d&#8217;autres moyens ?</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/php/question-ouverte-le-meilleur-moyen-de-tester-le-contenu-dun-objet-doctrine.html/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Réflexion autour de l&#8217;admin-generator symfony</title>
		<link>http://dev.pockyworld.com/developpement/php/reflexion-autour-de-ladmin-generator-de-symfony.html</link>
		<comments>http://dev.pockyworld.com/developpement/php/reflexion-autour-de-ladmin-generator-de-symfony.html#comments</comments>
		<pubDate>Wed, 31 Mar 2010 22:36:11 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[admin-generator]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=148</guid>
		<description><![CDATA[Chose promise, chose due. Voici la premier article d’une longue série sur les différentes approches de développement et le web en général. Cette article fait suite à trois événements : La conférence BeZend et une réflexion sur l’admin-generator Un article publié chez Maxime Un sujet interne à Crumblr Comme vous pouvez vous en douter, cet [...]]]></description>
			<content:encoded><![CDATA[<p>Chose promise, chose due. Voici la premier article d’une longue série sur les différentes approches de développement et le web en général.</p>

<p>Cette article fait suite à trois événements :</p>

<ul>
    <li>La conférence <a title="Accéder au site" href="http://www.be-zend.org/">BeZend</a> et une réflexion sur l’admin-generator</li>
    <li>Un article publié chez <a title="Faille SQL : LoL Guru, je LIKE." href="http://maxime.sh/2010/03/faille-sql-lol-guru-je-like/">Maxime</a></li>
    <li>Un sujet interne à <a title="Accéder au site" href="http://www.crumblr-project.com">Crumblr</a></li>
</ul>

<p>Comme vous pouvez vous en douter, cet article tournera essentiellement autour de l’admin-generator de <a title="Accéder au site" href="http://www.symfony-project.com">symfony</a>.</p>

<h3 id="1_prsentation_de_l8217admin_generator">1. Présentation de l’admin-generator</h3>

<p>Faisons simple pour cette explication, l’admin-generator vous permet très simplement via le biais d’une simple commande symfony de créer une interface d’administration pour votre site. Cela se passe de la façon suivante dans votre terminal. Je pars du principe que vous avez déjà généré votre projet et que vous avez déjà construit votre base de donnée, formulaires, votre model…</p>

<h4 id="11_cration_d8217un_module_avec_l8217admin_generator">1.1 Création d’un module avec l’admin-generator</h4>

<p>Première étape, nous allons créer une application pour le backoffice :</p>

<p><code>php symfony generate:app backend</code></p>

<p>Puis après créer un module géré par l’admin-generator</p>

<p><code>php symfony doctrine:generate-admin backend <em>matable</em> --module=<em>le nom du module</em></code></p>

<p>Et voila, tout est créé. Comme vous pourrez le constater, la démarche est relativement simple.
Le résultat obtenu sera proche de l’exemple ci-dessous :</p>

<p><a href="http://dev.pockyworld.com/wp-content/uploads/2010/03/look_and_feel.png"><img class="alignnone size-full wp-image-193" title="look_and_feel" src="http://dev.pockyworld.com/wp-content/uploads/2010/03/look_and_feel.png" alt="" width="500" height="268" /></a></p>

<p><em>D’autres exemples sur le tutoriel <a title="Jour 12 : L'Admin Generator" href="http://www.symfony-project.org/jobeet/1_4/Doctrine/fr/12">Jobeet</a></em></p>

<h4 id="12_les_fonctionnalits_de_l8217admin_generator">1.2 Les fonctionnalités de l’admin-generator</h4>

<p>L’admin-generator vous créer donc une interface graphique complète avec un certains nombres de fonctionalitées attendues dans un backoffice :</p>

<ul>
    <li>Une interface graphique complète</li>
    <li>Un CRUD complet (Create &#8211; Read &#8211; Update &#8211; Delete)</li>
    <li>Des filtres</li>
    <li>Des actions batchs/lists</li>
    <li>Des messages de validations/erreurs</li>
    <li>Une pagination</li>
</ul>

<p>Ajoutez ensuite à cette liste la possibilité de personnaliser très simplement les différents éléments de l’interface via un fichier <em>generator.yml</em>.</p>

<h4 id="13_conclusion">1.3 Conclusion</h4>

<p>Rapidement, nous pouvons tirer une première conclusion : l’admin-generator est très simple de création. Rien à redire à ce niveau.</p>

<p>Mais l’admin-gen est-il une solution idéale ?</p>

<h3 id="2_l8217aspet_graphique">2. L’aspet graphique</h3>

<p><em>Une petite pensée pour ce cher LoL Guru</em></p>

<p>Il est très facile pour une personne technique de négliger un backoffice sur le plan graphique. Personnellement, tous mes backoffice sont accessible par mes clients. Il faut donc pouvoir livrer quelque chose de correct graphiquement à ce niveau et il m’a donc fallu me pencher très rapidement sur ce problème.</p>

<p>Graphiquement, il faut tout d’abord distinguer deux éléments : le template global de l’application et le template de chacun des modules. Il est donc possible dans un premier temps d’appliquer un style graphique via le fichier <em>apps/backend/templates/layout.php</em>. Cela permettra déjà d’offrir une cure de jouvence à l’interface créée par l’admin-generator.</p>

<p>De la même façon, vous pouvez personnaliser l’admin-generator via le fichier <em>apps/backend/config/view.yml</em> en ajoutant un fichier css qui viendrais remplacer certaines propriétés. Par exemple pour déplacer les filtres en haut du document et pour agrandir les champs input text, il vous suffira très simplement d’appliquer les styles suivants :</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#sf_admin_bar</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">20px</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#sf_admin_container</span> input<span style="color: #00AA00;">&#91;</span>type<span style="color: #00AA00;">=</span><span style="color: #993333;">text</span><span style="color: #00AA00;">&#93;</span> <span style="color: #00AA00;">&#123;</span>
<span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">400px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>


<p>La encore, rien de bien compliqué. Vous pourrez donc personnaliser un certains nombres d’éléments de cette façon.</p>

<h4 id="21_oui_mais_moi_je_veux_vraiment_tout_personnaliser_">2.1 Oui mais moi, je veux vraiment tout personnaliser !</h4>

<p>C’est un peu la que tout commence à se gâter. Si l’envie vous prenais de commencer à vouloir personnaliser les templates, vous pourriez vous apercevoir d’une chose : Il n’y a aucun fichier dans le repertoire templates des modules générés.</p>

<p>wow.</p>

<p>Mais ils sont ou alors ?</p>

<p>Et voila, nous venons de poser le doigt sur le principal inconvénient de l’admin-generator. La simplicité a donc bel et bien un revers. Il vous faudra en effet surcharger un certain nombre d’éléments de l’admin-generator pour pouvoir en profiter pleinement. Et pour retrouver tout ses fichiers, il vous faudra aller dans le repertoire cache de votre application et les ouvrir tour à tour pour mettre le doigt sur le contenu de l’élément concerné.</p>

<p>Cela peut être très simple, la personnalisation minimale étant à mon sens étant celle du fichier <em>generator.yml</em> dans le module concerné afin de réorganiser l’affichage.</p>

<p>Autre exemple avec un plugin <em>must-have</em>. Pour personnaliser le formulaire d’authentification de <a title="Voir le plugin" href="http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin">sfDoctrineGuardPlugin</a>, il vous faudra créer un répertoire <em>templates</em> dans un module <em>sfGuardAuth</em> pour enfin faire un fichier <em>signinSuccess.php</em> qui vous permettra de reprendre le code.</p>

<p>Heureusement pour nous, il existe une liste de tous les templates utilisés :</p>

<ul>
    <li><strong>_assets.php</strong> Rendre lees CSS et les JS pour les utiliser dans les Templates</li>
    <li><strong>_filters.php</strong> Rendre la zone des filtres</li>
    <li><strong>_filtersfield.php</strong> Rendre un seul champ du filtre</li>
    <li><strong>_flashes.php</strong> Rendre les messages flash</li>
    <li><strong>_form.php</strong> Afficher le formulaire</li>
    <li><strong>_form_actions.php</strong> Afficher les actions du formulaire</li>
    <li><strong>_form_field.php</strong> Afficher un seul champ du formulaire</li>
    <li><strong>_form_fieldset.php</strong> Afficher un jeu de champs du formulaire</li>
    <li><strong>_form_footer.php</strong> Afficher le formulaire pied de page</li>
    <li><strong>_form_header.php</strong> Afficher le formulaire d’entête</li>
    <li><strong>_list.php</strong> Afficher la liste</li>
    <li><strong>_list_actions.php</strong> Afficher les actions de la liste</li>
    <li><strong>_list_batch_actions.php</strong> Afficher les actions batch de la liste</li>
    <li><strong>_list_field_boolean.php</strong> Afficher un seul champ booléen dans la liste</li>
    <li><strong>_list_footer.php</strong> Afficher le pied de page de la liste</li>
    <li><strong>_list_header.php</strong> Afficher l’entête de la liste</li>
    <li><strong>_list_td_actions.php</strong> Afficher les actions d’un objet pour une ligne</li>
    <li><strong>_list_td<em>batch</em>actions.php</strong> Afficher le checkbox pour une ligne</li>
    <li><strong>_list_td_stacked.php</strong> Afficher le layout stacked pour une ligne</li>
    <li><strong>_list_td_tabular.php</strong> Afficher un seul champ pour la liste</li>
    <li><strong>_list_th_stacked.php</strong> Afficher un seul nom de colonne pour l’entête</li>
    <li><strong>_list_th_tabular.php</strong> Afficher un seul nom de colonne pour l’entête</li>
    <li><strong>_pagination.php</strong> Afficher la pagination de la liste</li>
    <li><strong>editSuccess.php</strong> Afficher la vue edit</li>
    <li><strong>indexSuccess.php</strong> Afficher la vue list</li>
    <li><strong>newSuccess.php</strong> Afficher la vue new</li>
</ul>

<p>Cela représente donc un certain nombre de fichiers et il vous faudra prendre en compte la problématique qui pour faire simple sera la suivante :</p>

<ul>
    <li>Est-ce que j’ai un ou plusieurs templates à surcharger ?</li>
    <li>Est-ce que cette modification est redondante à l’ensemble des modules ?</li>
</ul>

<p>Enfin et pour conclure avec cette partie, ce travail de personnalisation complète du backoffice n’est fondamentalement pas plus complexe que pour le backoffice d’un Joomla, d’un Drupal, d’un WordPress et j’en passe. Si vous savez intégrer pour votre front-office, vous saurez le faire pour le back-office.</p>

<h3 id="3_cot_code_maintenant">3. Coté code maintenant</h3>

<p>N’y allons pas par quatre chemins, la encore vous aurez le bonheur de trouver des fichiers actions.class.php complètement vide qui vous permettront de surcharger tout ce que vous pourrez retrouver dans les fichiers stockés dans le cache.</p>

<p>La liste complète des actions est la suivante (attention les traductions sont un peu aléatoires <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) :</p>

<ul>
    <li><strong>executeIndex()</strong> Action de la vue list</li>
    <li><strong>executeFilter()</strong> Mettre à jour les filtres</li>
    <li><strong>executeNew()</strong> Action de la vue new</li>
    <li><strong>executeCreate()</strong> Création d’un enregistrement</li>
    <li><strong>executeEdit()</strong> Edition d’un enregistrement</li>
    <li><strong>executeUpdate()</strong> Mise à jour d’un enregistrement</li>
    <li><strong>executeDelete()</strong> Supprimer un enregistrement</li>
    <li><strong>executeBatch()</strong> Executer une action batch</li>
    <li><strong>executeBatchDelete()</strong> Executer l’action batch _delete</li>
    <li><strong>processForm()</strong> Processer le formulaire emploi</li>
    <li><strong>getFilters()</strong> Retourner le filtre actuel</li>
    <li><strong>setFilters()</strong> Définir le filtre</li>
    <li><strong>getPager()</strong> Retourner la pagination de la liste</li>
    <li><strong>getPage()</strong> Obtenir la page de la pagination</li>
    <li><strong>setPage()</strong> Définir la page de la pagination</li>
    <li><strong>buildQuery()</strong> Construire la requête pour la liste</li>
    <li><strong>addSortQuery()</strong> Ajouter la requête de tri pour la liste</li>
    <li><strong>getSort()</strong> Retourner la colonne triée actuelle</li>
    <li><strong>setSort()</strong> Définit la colonne triée actuelle</li>
</ul>

<p>La encore, beaucoup d’éléments à prendre en compte.</p>

<h4 id="31_les_form_ulaires_et_relations">3.1 Les formulaires et relations</h4>

<p>Qui dit backoffice dit interraction avec la base de donnée et donc beaucoup de formulaires ce qui me permet de répondre à l’une des plus belles idioties entendue au Be-Zend sur l’admin-generator : Non, un module créé avec l’admin-generator n’intérragie pas forcément avec une seule des tables de votre base de donnée. Je tairais même le nom de l’auteur de cette remarque afin de préserver sa réputation <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (jusqu’à ce que les vidéos arrivent).</p>

<p>Créer un module via la commande doctrine:generate-admin c’est très basiquement créer un module avec un template généré et des fonctions prédéfinies. Vous pouvez donc intéragir de la même façon qu’avec un module classique et vous pourrez avec un seul formulaire “en apparence” travailler avec un nombre X de tables avec autant de formulaires. Je vous conseille d’ailleurs d’aller lire un article de <a title="Embedding relations in Forms" href="http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine">Niko</a> expliquant les embedForms et embedRelations.</p>

<p>Un embedForm pourra donc être intégré via le <em>generator.yml</em> en l’appelant tout simplement par son nom. Tous les champs seront appelés et vous pourrez très simplement les exploiter. Une même page d’édition/création pourra par exemple vous permettre de travailler sur votre table <em>post</em> et votre table <em>seo</em> pour une plus grande souplesse. La limite étant uniquement humaine : est-ce que vos formulaires à ralonge ne vont pas déstabiliser l’utilisateur ? (ce qui sera d’autant plus vrai dans le cadre de l’utilisation de plusieurs langue via I18n)</p>

<p>Inutile de le préciser, l’ensemble des champsdes formulaire sont bien évidemment personnalisable via les fichiers correpondant dans <em>/lib/form/doctrine/xxxForm.class.php</em></p>

<h4 id="32_les_actions_batch_et_list">3.2 Les actions batch et list</h4>

<p>La encore, tout est très simple. Nous retrouvons vraiment une philosophie symfony dans l’admin generator. Créer une action batch/list consiste donc en un minimum de deux étapes :</p>

<ol>
    <li>Ajout d’un batch dans le fichier generator.yml</li>
    <li>Création de l’action correpondante dans le fichier actions.class.php de type : public function executeBatchXXX(sfWebRequest $request) { } OU public function executeListXXX(sfWebRequest $request) { }</li>
</ol>

<p>Cerise sur le gateau, le code que vous ferez à travers vos batchs/lists pourra être utilisé pour créer une tache symfony avec très peu de code à modifier. Cela permettra par exemple de pouvoir appeler une tache automatiquement via Cron tout en offrant la possibilité à l’utilisateur de faire la même chose via une action batch/list.</p>

<h4 id="33_et_ce_n8217est_pas_fini">3.3 Et ce n’est pas fini</h4>

<p>Vous pouvez rapidement faire un tour de l’ensemble des possibilités dans le chapitre dédié à l’<a href="http://www.symfony-project.org/jobeet/1_4/Doctrine/fr/12">admin-generator</a> du tutoriel Jobeet.</p>

<h3 id="4_alors_l8217admin_generator_killer_admin_">4. Alors l’admin-generator killer admin ?</h3>

<p>Par moments oui tandis que d’autres non.</p>

<p>Comme vous avez pu le remarquer, un nombre conséquent de possibilités sont facilement accessible via l’admin-generator mais cela implique un nombre plus ou moins important de changements. Il faudra donc avant tout chose peser le pour et le contre vis à vis du projet.</p>

<ul>
    <li>A quoi va me servir l’admin-generator (interaction complète avec le front comme un CMS ou partielle comme Jobeet par exemple)</li>
    <li>Quel va être le niveau de personnalisation graphique ?</li>
    <li>Quel sont les attentes en terme de fonctionnalités à surcharger ?</li>
</ul>

<p>Les réponses à ces différentes questions vous permettront d’établir un pourcentage variable allant (à mon niveau) de 10% à presque 70% d’éléments à surcharger. L’utilisation de l’admin-generator doit donc être un élément réfléchi dont il faut peser l’impact et penser l’utilisation. Dans le cadre d’applications simples, l’admin-generator sera un outil idéal vous permettant de gagner énormément de temps mais si vous devez commencer à ajouter des fonctionnalités importantes ou de l’AJAX par exemple, les surcharges pourront devenir très importantes et le routage pourra même être impacté. Dans ce cas, un backoffice créé de toute pièce sera donc plus adapté.</p>

<p>Quant à la mixité admin-generator/module classique, j’ai un peu de mal à y croire car il faudra expliquer les différences graphiques entre les templates maison et ceux générés. Pour mettre à niveau le tout, il faudra donc prévoir la personnalisation de l’ensemble et donc la encore un certain nombre d’heures de travail.</p>

<p>Quoi qu’il en soit, l’admin-generator n’est pas à sous-estimer car il peut rendre service dans de nombreux cas en vous permettant de gagner énormément de temps. Après tout, c’est exactement ce à quoi il destiné.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/php/reflexion-autour-de-ladmin-generator-de-symfony.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Installation d&#8217;un serveur de développement COMPLET sur MacOS X avec MacPorts</title>
		<link>http://dev.pockyworld.com/developpement/installation-dun-serveur-de-developpement-complet-sur-macos-x-avec-macports.html</link>
		<comments>http://dev.pockyworld.com/developpement/installation-dun-serveur-de-developpement-complet-sur-macos-x-avec-macports.html#comments</comments>
		<pubDate>Mon, 23 Nov 2009 22:41:31 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[macos]]></category>
		<category><![CDATA[macport]]></category>
		<category><![CDATA[php mysql]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=129</guid>
		<description><![CDATA[Quand on a rien à dire (ou pas le temps) on ne dit rien. Heureusement, tout à une fin alors aujourd&#8217;hui nous parlerons de l&#8217;installation complète d&#8217;un serveur d&#8217;environnement de développement sur Mac. Ce tutoriel se base sur la dernière version de chacun des logiciels et vous expliquera step-by-step comment installer et configurer votre serveur [...]]]></description>
			<content:encoded><![CDATA[<p><center><em>Quand on a rien à dire (ou pas le temps) on ne dit rien.</em></center></p>

<p>Heureusement, tout à une fin alors aujourd&#8217;hui nous parlerons de l&#8217;installation complète d&#8217;un serveur d&#8217;environnement de développement sur Mac. Ce tutoriel se base sur la dernière version de chacun des logiciels et vous expliquera step-by-step comment installer et configurer votre serveur afin d&#8217;obtenir un environnement sain en évitant le maximum de manipulations.</p>

<h3>Pré-requis</h3>

<p>Le système d&#8217;Apple n&#8217;ayant pas de gestionnaire de package digne de ce nom, le pré-requis indispensable est l&#8217;installation de <a href="http://www.macports.org/install.php">macports</a>. Il vous faudra télécharger le programme correspondant à votre système qui vous demandera lui-même d&#8217;installer <a href="http://developer.apple.com/tools/xcode/">Xcode</a> afin de pouvoir compiler tous les binaires.</p>

<h3>Première étape : La mise à jour de MacPort</h3>

<p>Une fois MacPort installé, la première étape consiste en la mise à jour du programme. Pour cela, rien de bien compliqué puisqu&#8217;il vous suffira de taper la commande suivante :</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo port selfupdate</pre></div></div>


<p>MacPort devrait se mettre à jour ainsi que sa liste de package. Cela permettra de pouvoir mettre en place les dernières versions des différents serveurs.</p>

<h3>Seconde étape : Installation d&#8217;Apache</h3>

<p>Passons à l&#8217;installation d&#8217;Apache, à partir de ce moment soyez un peu patient car l&#8217;installation ne se fait pas forcément en 5 minutes alors prenez une bière (ou un coca) et profitez un peu des flocons de neige en hiver ou de votre voisine en maillot de bain en été.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo port install apache2
sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist</pre></div></div>


<h3>Troisième étape : Installation de MySQL</h3>

<p>MySQL maintenant, un peu plus d&#8217;étapes de configuration mais cela devrait plutôt bien se passer.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo port install mysql5-server
sudo -u mysql mysql_install_db5
sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
/opt/local/lib/mysql5/bin/mysql_secure_installation</pre></div></div>


<p>La dernière commande vous invitera à rentrer votre identifiant et mot de passe, soyons clair, même en environnement de développement, il faut toujours un mot de passe à votre compte root. Vous pourrez au passage supprimer les tables test lorsque le script vous le demandera.</p>

<h3>Quatrième étape : Installation de PHP</h3>

<p>L&#8217;étape qui fait mal puisque la moins bien documenté pour MacPort depuis le changement de version. Heureusement tout devrait bien se passer pour nous. Tous les modules que vous allez installer dans la suite ne sont pas forcément indispensables mais disons que vous serez bien équipé pour la suite.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo port install php5 +apache2 +pear
sudo port install php5-mysql
sudo port install php5-eaccelerator
sudo port install php5-exif
sudo port install php5-gd
sudo port install php5-gettext
sudo port install php5-iconv
sudo port install php5-imagick
sudo port install php5-mbstring
sudo port install php5-mcrypt
sudo port install php5-openssl
sudo port install php5-sqlite
sudo port install php5-xmlrpc
sudo port install php5-xsl
sudo port install php5-zip</pre></div></div>


<h3>Configuration de PHP</h3>

<p>Maintenant que tout est installé, l&#8217;étape de configuration grâce à laquelle nous allons pouvoir bientôt travailler.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;"><span style="color: #b1b100; font-weight: bold;">cd</span> /opt/local/etc/php5/
sudo cp php.ini-production php.ini</pre></div></div>


<p>Pourquoi copier le fichier php.ini de production ? Tout simplement car c&#8217;est le plus restrictif et je préfère pour ma part modifier un fichier restrictif qu&#8217;un fichier de configuration trop permissif. Travaillant en plus avec Symfony, je n&#8217;ai pas trop à me soucier de ça <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>Nous allons donc éditer notre fichier php.ini. Il vous faudra rechercher la ligne suivante, j&#8217;utilise pour ma part vi dont voici les commandes principales :</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">Ouvrir un fichier : <span style="color: #b100b1; font-weight: bold;">vi &lt;nom du fichier&gt;</span>
Rechercher dans le fichier : <span style="color: #b100b1; font-weight: bold;">&lt;appuyer sur echap puis faire&gt; /&lt;occurrence à rechercher&gt;</span>
Editer un fichier : <span style="color: #b100b1; font-weight: bold;">&lt;appuyer sur la touche i&gt;</span>
Enregistrer un fichier : <span style="color: #b100b1; font-weight: bold;">&lt;appuyer sur echap puis faire&gt;:w</span>
Quitter un fichier : <span style="color: #b100b1; font-weight: bold;">&lt;appuyer sur echap puis faire&gt;:q</span>
Forcer un quit sur un fichier modifié : <span style="color: #b100b1; font-weight: bold;">&lt;appuyer sur echap puis faire&gt;:q!</span></pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo vi /opt/local/apache2/conf/httpd.conf
&lt;Rechercher&gt; DirectoryIndex index.html
&lt;Modifier par&gt; DirectoryIndex index.php index.html
&nbsp;
&lt;Rechercher&gt;Include conf/extra/
&lt;Ajouter&gt;Include conf/extra/mod_php.conf
&lt;Enregister&gt;
&nbsp;
sudo vi /opt/local/etc/php5/php.ini
&lt;Rechercher&gt;mysql.default_socket
&lt;Modifier par&gt;mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock
&nbsp;
&lt;Rechercher&gt;mysqli.default_socket
&lt;Modifier par&gt;mysqli.default_socket = /opt/local/var/run/mysql5/mysqld.sock
&nbsp;
&lt;Rechercher&gt;pdo_mysql.default_socket
&lt;Modifier par&gt;pdo_mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock
&nbsp;
&lt;Rechercher&gt;date.timezone
&lt;Modifier par&gt;date.timezone = Europe/Paris
&nbsp;
&lt;enregister&gt;
sudo /opt/local/apache2/bin/apachectl -k restart</pre></div></div>


<p>Votre environnement devrait être prêt !</p>

<h3>Création d&#8217;un fichier phpinfo</h3>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo vi /opt/local/apache2/htdocs/phpinfo.php
&lt;Ajouter&gt;&lt;?php phpinfo<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; ?&gt;
&lt;Enregister&gt;</pre></div></div>


<p>Votre fichier devrait être accessible à l&#8217;adresse <a href="http://localhost/phpinfo.php">http://localhost/phpinfo.php</a>
Vous pourrez à ce moment la vérifier vos différents modules et vérifier que vos drivers mysql fonctionnent correctement (ils devraient apparaitre dans la liste, recherchez simplement &laquo;&nbsp;pdo&nbsp;&raquo;).</p>

<h3>Installation de phpMyAdmin</h3>

<p>Afin de faciliter votre maintenance MySQL, installons phpMyAdmin.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo port install phpmyadmin
sudo vi /opt/local/apache2/conf/httpd.conf
&nbsp;
&lt;Rechercher&gt;Include conf/extra/
&lt;Ajouter&gt;Include conf/extra/httpd-phpmyadmin.conf
&nbsp;
sudo vi /opt/local/apache2/conf/extra/httpd-phpmyadmin.conf
&nbsp;
&lt;Ajouter les éléments suivants&gt;
&nbsp;
AliasMatch ^/phpmyadmin<span style="color: #66cc66;">&#40;</span>?:/<span style="color: #66cc66;">&#41;</span>?<span style="color: #66cc66;">&#40;</span>/.*<span style="color: #66cc66;">&#41;</span>?$ &quot;/opt/local/www/phpmyadmin$<span style="color: #cc66cc;">1</span>&quot;
&nbsp;
&lt;Directory &quot;/opt/local/www/phpmyadmin&quot;&gt;
  Options -Indexes
  AllowOverride None
  Order allow,deny
  Allow from all
&nbsp;
  LanguagePriority en de es fr ja ko pt-br ru 
  ForceLanguagePriority Prefer Fallback
&lt;/Directory&gt;
&nbsp;
&lt;Enregister&gt;
sudo /opt/local/apache2/bin/apachectl -k restart</pre></div></div>


<h3>Utilisations de vhosts</h3>

<p>N&#8217;importe qui vous le dira, les vhosts, c&#8217;est le bonheur. Cette étape est cependant facultative.
Nous allons donc mettre le tout en place pour en bénéficier.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo vi /opt/local/apache2/conf/httpd.conf
&lt;Rechercher&gt; Include conf/extra/
&lt;Ajouter&gt; Include conf/extra/httpd-vhosts.conf
&lt;Supprimer la ligne&gt; Include conf/extra/httpd-phpmyadmin.conf
&lt;Enregister&gt;
&nbsp;
sudo vi /opt/local/apache2/conf/extra/httpd-vhosts.conf</pre></div></div>


<p>Nous allons ajouter deux vhosts principaux afin de pouvoir utiliser le répertoire Sites de l&#8217;arborescence Mac. Au passage, modifions le vhost pour phpMyAdmin.</p>

<p>Attention, il s&#8217;agit de ma propre configuration, à vous de la personnaliser.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">&lt;VirtualHost *:<span style="color: #cc66cc;">80</span>&gt;
    ServerAdmin pocky<span style="color: #33cc33;">@</span>pockyworld.com
    DocumentRoot &quot;/Users/Alexandre/Sites/&quot;
    ServerName www.pockyworld.local
&nbsp;
    &lt;Directory &quot;/Users/Alexandre/Sites/&quot;&gt;
        Options Indexes FollowSymLinks Includes ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from All
    &lt;/Directory&gt;
&nbsp;
&lt;/VirtualHost&gt;
&nbsp;
&lt;VirtualHost *:<span style="color: #cc66cc;">80</span>&gt;
    ServerAdmin pocky<span style="color: #33cc33;">@</span>pockyworld.com
    DocumentRoot &quot;/opt/local/www/phpmyadmin/&quot;
    ServerName sql.pockyworld.local
&nbsp;
    &lt;Directory &quot;/opt/local/www/phpmyadmin&quot;&gt;
       Options -Indexes
       AllowOverride None
       Order allow,deny
       Allow from all
&nbsp;
       LanguagePriority en de es fr ja ko pt-br ru
       ForceLanguagePriority Prefer Fallback
    &lt;/Directory&gt;
&nbsp;
&lt;/VirtualHost&gt;</pre></div></div>


<p>N&#8217;oubliez pas de relancer Apache après avoir effectué cet ajout de vhost.</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo /opt/local/apache2/bin/apachectl -k restart</pre></div></div>


<h3>Le petit plus : Installation de GIT</h3>

<p>Le petit extra spécial geek fan du versioning</p>


<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">sudo port install git-core +svn
&nbsp;
git config --global user.name &quot;Votre nom&quot;
git config --global user.email &quot;Votre adresse mail&quot;</pre></div></div>


<p>Attention pour Git, tout n&#8217;a pas directement fonctionné du premier coup, n&#8217;hésitez pas à relancer la commande d&#8217;installation.</p>

<h3>Conclusion</h3>

<p>Votre environnement de travail devrait fonctionner et être idéal pour pouvoir travailler. N&#8217;oubliez pas de personnaliser votre fichier de configuration de php (le php.ini) suivant vos besoins. Celui livré par défaut dans ce tutorial n&#8217;affichera par exemple pas les erreurs PHP ce qui peut être embêtant en phase de développement <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>

<p>Vous ne devriez pas (avec les vhosts) avoir de problème d&#8217;autorisations d&#8217;écriture dans votre répertoire Sites car il est créé par le système lors de l&#8217;installation de MacOS. Dans le cas ou vous utilisiez le répertoire par défaut (sans vhost) il vous faudra modifier les autorisations (pomme + i sur le répertoire) pour vous autoriser l&#8217;écriture de fichiers.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/installation-dun-serveur-de-developpement-complet-sur-macos-x-avec-macports.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Gestion des polices exotiques avec CSS3, jQuery et Cufon</title>
		<link>http://dev.pockyworld.com/developpement/css/gestion-des-polices-exotiques-avec-css3-jquery-et-cufon.html</link>
		<comments>http://dev.pockyworld.com/developpement/css/gestion-des-polices-exotiques-avec-css3-jquery-et-cufon.html#comments</comments>
		<pubDate>Sun, 07 Jun 2009 15:23:53 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[cufon]]></category>
		<category><![CDATA[fontavailable]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[sifr]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=109</guid>
		<description><![CDATA[Cette semaine nous aborderons le problème de la gestion des polices exotiques (comprendre les polices non-standard) suivant les différents navigateurs. La solution proposée ci-dessous n&#8217;est pas forcément la meilleure sur la question du &#171;&#160;poids de la page&#160;&#187; mais c&#8217;est celle qui d&#8217;après mes essais couvre le plus de navigateurs et cause le moins de problèmes. [...]]]></description>
			<content:encoded><![CDATA[<p>Cette semaine nous aborderons le problème de la gestion des polices exotiques (comprendre les polices non-standard) suivant les différents navigateurs. La solution proposée ci-dessous n&#8217;est pas forcément la meilleure sur la question du &laquo;&nbsp;poids de la page&nbsp;&raquo; mais c&#8217;est celle qui d&#8217;après mes essais couvre le plus de navigateurs et cause le moins de problèmes.</p>

<h3>Qu&#8217;est-ce qu&#8217;une police exotique ?</h3>

<p>Une police exotique est tout simplement une police non-standard. D&#8217;accord, vous n&#8217;êtes pas plus avancé alors qu&#8217;est-ce qu&#8217;une police standard ? C&#8217;est tout simplement une police présente sur tous les systèmes d&#8217;exploitation et prise en charge par tous les navigateurs. La police <em>Arial</em> est une police standard, à contrario la police <em>Helvetica</em> n&#8217;est pas une police standard quant à la police <em>Helvetica Neue</em>, ne cherchez pas à la trouver sur un système d&#8217;exploitation autre que Mac OS.</p>

<p>En partant de ce principe, le webdesigner et l&#8217;intégrateur doivent donc trouver comment faire avec les polices standards et les polices exotiques dans le but d&#8217;atteindre le Saint-Graal, un affichage identique sur tous les navigateurs.</p>

<h3>Les différentes solutions</h3>

<p>Les différentes solutions sont donc relativement simple. Tout d&#8217;abord du coté du webdesigner, il faudra faire au maximum avec les polices standards en ne gardant les polices exotiques que pour les éléments &laquo;&nbsp;statiques&nbsp;&raquo; de votre maquette : logo et navigation par exemple. Seulement cette limite peut être forte pour ceux qui souhaiteraient avoir le titre d&#8217;un article affiché avec une police exotique.</p>

<p>Du coté de l&#8217;intégrateur maintenant, il faudra faire avec la maquette du webdesigner. Tous les éléments statiques pourront être transformés en images et gérés via les sous propriétés de la balise a : a:link, a:visited, a:hover, a:active, &#8211; mémotechnique : LoVe HAte.</p>

<p>Seulement voila, que faire de nos titres utilisant une police exotique et pourtant dynamique ? La aussi plusieurs solutions existent, le remplacement du texte par une image générée via une libraire de type GD ou encore ImageMagick, l&#8217;utilisation de propriétés CSS ou encore le recours à Flash et/ou Javascript. Le tout étant de trouver le moyen convenant au maximum de monde.</p>

<p>Écartons directement l&#8217;utilisation de GD/ImageMagick, cela implique un peu de travail coté développement et l&#8217;intégrateur n&#8217;est pas forcément développeur. Au niveau de CSS, @font-face est une solution proposée du coté de CSS3. Enfin, du coté de flash et de JS, beaucoup d&#8217;entre-vous connaissent la solution sIFR mais beaucoup d&#8217;entre-vous savent aussi que sIFR à quelques problèmes relavant par moment du mysticisme.</p>

<h3>Ma solution : CSS3, jQuery et Cufon</h3>

<p>Passons maintenant à ma solution, elle utilise CSS3 via @font-face, jQuery pour la détection de la présence des polices et Cufon pour le remplacement. Le but, rendre la chose compatible avec le maximum de navigateurs. Pour les détracteurs, oui, si jamais une personne arrive avec Internet Explorer 6 et le javascript désactivé, cela ne fonctionnera pas.</p>

<h4>Première étape : @font-face et CSS3</h4>

<p>La première étape de la solution consiste en l&#8217;utilisation de @font-face. @font-face est une propriété CSS3, cette première étape ne s&#8217;appliquera donc qu&#8217;au navigateur supportant cette propriété CSS3.</p>

<blockquote>Pour information @font-face est en fait une propriété CSS 2 complètement délaissé à l&#8217;époque de CSS 2.1 puis réintroduite via CSS3.</blockquote>

<p>Nous allons donc prendre notre fichier de police, l&#8217;envoyer dans un dossier précis (soyons fou, il se nommera /font/) puis l&#8217;inclure dans notre feuille de style de la façon suivante.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #a1a100;">@font-face { font-family : 'Ma police exotique';</span>
src<span style="color: #00AA00;">:</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'font/mapoliceexotique.ttf'</span><span style="color: #00AA00;">&#41;</span> format<span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'truetype'</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></pre></div></div>


<p>Seconde étape, appeler notre police de la façon la plus basique qui soit via la propriété CSS font-family. Nous l&#8217;appellerons pour nos titres h3 dans le div avec l&#8217;identifiant article.</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#article</span> h3 <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">font-family</span><span style="color: #00AA00;">:</span> <span style="color: #ff0000;">&quot;Ma police exotique&quot;</span><span style="color: #00AA00;">,</span> arial<span style="color: #00AA00;">,</span> <span style="color: #993333;">sans-serif</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></pre></div></div>


<h4>Seconde étape : cufon</h4>

<p>Passons maintenant aux autres navigateurs, nous utiliserons cufon car après beaucoup d&#8217;essais en condition de production, cufon est la meilleure alternative à sIFR.</p>

<blockquote>Le fonctionnement de cufon : cufon est composé de deux fichiers, le premier est un fichier yui (interface) chargé de traiter le fichier de police en javascript créé via une interface web. cufon s&#8217;implémente via VME sur les vieux navigateurs et via canvas sur les navigateurs plus récents.</blockquote>

<p>Tout d&#8217;abord, télécharger <a href="http://cufon.shoqolate.com/js/cufon-yui.js">le fichier YUI de cufon</a> puis se rendre sur <a href="http://cufon.shoqolate.com/generate/">le site internet de cufon</a> afin de générer un fichier javascript de police. Une fois cela fait, envoyer le tout sur votre serveur dans le repertoire de votre choix (disons /js/).</p>


<div class="wp_syntax"><div class="code"><pre class="html4" style="font-family:monospace;">&lt;script src=&quot;js/cufon-yui.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/mapoliceexotique.font.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;</pre></div></div>


<h4>Troisième étape : jQuery</h4>

<p>Une fois l&#8217;étape 3 terminée, nous pourrions très simplement nous arrêter la mais cela serait un peu bête car l&#8217;étape 1 n&#8217;aurait donc aucun sens. Nous allons donc très simplement utiliser <del datetime="2009-06-07T13:06:47+00:00">notre</del> ma librairie javascript favorite à savoir jQuery ainsi qu&#8217;un plugin pour tester la présence du fichier de police sur l&#8217;ordinateur du visiteur.</p>

<p>Pour cela <a href="http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.3.2.min.js">télécharger jQuery</a> (si vous ne l&#8217;utiliser pas déjà pour tous vos effets javascript) puis le plugin <a href="http://jquery-fontavailable.googlecode.com/files/jquery.fontavailable-1.1.min.js">fontavailable</a>. Enfin, envoyer le tout dans votre repertoire /js/ puis inclure le tout.</p>


<div class="wp_syntax"><div class="code"><pre class="html4" style="font-family:monospace;">&lt;script src=&quot;js/jquery-1.3.2.min.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/jquery.fontavailable-1.1.min.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;</pre></div></div>


<p>Passons maintenant au bout de code javascript à intégrer pour utiliser le tout.</p>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">	&lt;script type=&quot;text/javascript&quot;&gt;
	$(document).ready(function() {
	    if(!$.fontAvailable('Ma police exotique')) {
	      Cufon.replace('#article h3');
	    }
	});
	&lt;/script&gt;</pre></div></div>


<h3>Conclusion</h3>

<p>Passons maintenant au cheminement complet de cette technique :</p>

<ol>
    <li>Le visiteur arrive sur votre site, le dom se charge, la feuille de style css est appelé et essaie d&#8217;appliquer votre police exotique
    <li>Votre visiteur n&#8217;a pas la police exotique
        <ol>
            <li>Il est sur un navigateur supportant @font-face, la police se télécharge.</li>
            <li>Il n&#8217;est pas sur un navigateur supportant @font-face, le document se charge, fontavailable teste la présence de la police et l&#8217;intègre</li>
        </ol>
    </li>
    <li>Votre visiteur a votre police exotique
        <ol>
            <li>Rien ne se passe</li>
        </ol>
    </li>
</ol>

<p>Au final et pour revenir à mon introduction, certains d&#8217;entre-vous pourrons s&#8217;étonner de l&#8217;armada déployée pour l&#8217;occasion (qui n&#8217;est d&#8217;ailleurs pas plus importante que celle utilisée pour une intégration correcte de sIFR) mais le modèle peut être optimisé via fontavailable en ne limitant plus le test au changement de la police mais aussi au téléchargement de cufon-yui.js  et votre fichier *.font.js.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/css/gestion-des-polices-exotiques-avec-css3-jquery-et-cufon.html/feed</wfw:commentRss>
		<slash:comments>78</slash:comments>
		</item>
		<item>
		<title>Le mémento Microformats est disponible</title>
		<link>http://dev.pockyworld.com/developpement/xhtml/le-memento-microformats-est-disponible.html</link>
		<comments>http://dev.pockyworld.com/developpement/xhtml/le-memento-microformats-est-disponible.html#comments</comments>
		<pubDate>Sat, 23 May 2009 12:50:23 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[xHTML]]></category>
		<category><![CDATA[hAtom]]></category>
		<category><![CDATA[hCalendar]]></category>
		<category><![CDATA[hCard]]></category>
		<category><![CDATA[hReview]]></category>
		<category><![CDATA[mémento]]></category>
		<category><![CDATA[Microformat]]></category>
		<category><![CDATA[sémantique]]></category>
		<category><![CDATA[XFN]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=90</guid>
		<description><![CDATA[C&#8217;est entre deux projets personnels et beaucoup d&#8217;autres professionnels que j&#8217;ai enfin pris le temps d&#8217;écrire ce mémento sur les microformats. Avant d&#8217;aller plus loin, les quelques informations. Qu&#8217;est ce qu&#8217;un mémento ? Un mémento est une sorte de brochure contenant l&#8217;essentiel des informations sur un sujet. En tant que travailleurs ou intéressés par le [...]]]></description>
			<content:encoded><![CDATA[<p>C&#8217;est entre deux projets personnels et beaucoup d&#8217;autres professionnels que j&#8217;ai enfin pris le temps d&#8217;écrire ce mémento sur les microformats. Avant d&#8217;aller plus loin, les quelques informations.</p>

<h3>Qu&#8217;est ce qu&#8217;un mémento ?</h3>

<p>Un mémento est une sorte de brochure contenant l&#8217;essentiel des informations sur un sujet. En tant que travailleurs ou intéressés par le web, vous connaissez probablement les mémentos publiés aux <a href="http://www.eyrolles.com/Informatique/Recherche/index.php?q=m%E9mento&#038;themes=INF" title="Les différents mémentos">éditions Eyrolles</a>. Si ce n&#8217;est pas le cas, intéressez-vous y sérieusement, ces petits ouvrages sont tout simplement indispensable en cas de doute et/ou trou de mémoire.</p>

<h3>Pourquoi un mémento microformat ?</h3>

<p>J&#8217;avais commencé à écrire un mémento microformats il y a presque deux ans. L&#8217;idée était intéressante, la sémantique sur Internet est un sujet passionnant en ce qui me concerne. Les obligations professionnelles aidant, le projet était donc sagement resté dans un dossier sous la forme de brouillon. <a href="http://googlewebmastercentral.blogspot.com/2009/05/introducing-rich-snippets.html" "annonce du support sur le blog de Google">L&#8217;annonce de Google</a> d&#8217;il y a maintenant deux semaines concernant le support des microformats et de RDFa dans le moteur de recherche ayant relancé la vague, c&#8217;était donc maintenant ou jamais.</p>

<h3>Précisions</h3>

<p>Avant de vous proposer le document en téléchargement, quelques précisions. Le mémento contiens les microformats les plus utilisés à l&#8217;instant T qu&#8217;ils soient définitifs ou encore au format brouillon. Le mémento ne contiens malgré tout pas le microformat XOXO, je vous invite à vous y intéresser mais il est très peu implémenté à l&#8217;heure actuelle car beaucoup de personnes n&#8217;y voient pas d&#8217;intérêt.</p>

<p>Au cours de la lecture, vous vous apercevrez également que certains microformats peuvent être intégrés à d&#8217;autres microformats. Le mémento détaille une bonne partie du microformat hCard mais ne fais pas la même chose pour hCalendar qui peut intégrer hCard ou hAtom qui peut intégrer hCalendar en plus de hCard. Si j&#8217;avais tout intégré, il n&#8217;y aurait quasiment que du code d&#8217;exemple et ce n&#8217;est pas forcément l&#8217;objectif d&#8217;un mémento.</p>

<p>Le mémento est donc estampillé révision 1.</p>

<p><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.0/fr/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-nd/2.0/fr/88x31.png" /></a><br /><span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Text" property="dc:title" rel="dc:type">Le M&#233;mento Microformats</span> par <a xmlns:cc="http://creativecommons.org/ns#" href="http://dev.pockyworld.com" property="cc:attributionName" rel="cc:attributionURL">Alexandre BALMES</a> est mis &#224; disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.0/fr/">licence Creative Commons Paternit&#233; &#8211; Pas d&#8217;Utilisation Commerciale &#8211; Pas de Modification 2.0 France</a>.<br />Les autorisations au-del&#224; du champ de cette licence peuvent &#234;tre obtenues par <a xmlns:cc="http://creativecommons.org/ns#" href="mailto:contact@alexandrebalmes.fr" rel="cc:morePermissions">mail</a>.</p>

<h3>La suite</h3>

<p>N&#8217;hésitez pas à laisser vos commentaires pour demander des précisions qui pourraient également être intégrés au mémento. Souhaitez-vous plus d&#8217;exemples, de nouveaux microformats ou d&#8217;autres choses ? N&#8217;hésitez pas à le dire.</p>

<h3>Téléchargement</h3>

<p>Le mémento microformat est <a href="http://dev.pockyworld.com/wp-content/uploads/2009/05/microformats2.pdf">disponible au format PDF</a> (4Mo)</p>

<h3>Faire un don</h3>

<p>Vous pouvez faire un don si vous avez aimé ce mémento. Petit indice, cela devrait me permettre de m&#8217;offrir PHP5 avancé <img src='http://dev.pockyworld.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> 
<center>
        <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_xclick" />
    <input type="hidden" name="business" value="ab@pockyworld.com" /><input type="hidden" name="item_name" value="" /><input type="hidden" name="currency_code" value="EUR" /><span style="font-size:10.0pt"><strong> </strong></span><br /><br /><select id="amount" name="amount" class=""><option value="1">Un café - 1 euros</option><option value="2">Une bière - 2 euros</option><option value="5">Un mémento - 5 euros</option></select><br /><br /><strong> Your Email Address :</strong><input type="hidden" name="on0" value="Reference" /><br /><br /><input type="text" name="os0" maxlength="60" />
        <br /><br />
        <input type="hidden" name="no_shipping" value="2" />
        <input type="hidden" name="no_note" value="1" />
        <input type="hidden" name="mrb" value="3FWGC6LFTMTUG" />
        <input type="hidden" name="bn" value="IC_Sample" />
    <input type="hidden" name="return" value="http://dev.pockyworld.com" /><input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but11.gif" name="submit" alt="Make payments with payPal - it's fast, free and secure!" /></form></center></p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/xhtml/le-memento-microformats-est-disponible.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Comment créer sa carte de visite web #1 : le .tel</title>
		<link>http://dev.pockyworld.com/developpement/comment-creer-sa-carte-de-visite-web-1-le-tel.html</link>
		<comments>http://dev.pockyworld.com/developpement/comment-creer-sa-carte-de-visite-web-1-le-tel.html#comments</comments>
		<pubDate>Wed, 29 Apr 2009 12:57:29 +0000</pubDate>
		<dc:creator>Alexandre</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[annuaire]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[rdfa]]></category>
		<category><![CDATA[ressource]]></category>
		<category><![CDATA[sémantique]]></category>

		<guid isPermaLink="false">http://dev.pockyworld.com/?p=86</guid>
		<description><![CDATA[Beaucoup d&#8217;entre vous ont entendu parler du .tel. Ce nouveau tld vous permet de créer votre carte d&#8217;identité sur Internet. Petite analyse du système. Tout le monde en a plus ou moins rêver, pouvoir créer un véritable annuaire sur Internet. Nombre de services s&#8217;y sont essayés et se sont affrontés par la même occasion avec [...]]]></description>
			<content:encoded><![CDATA[<p>Beaucoup d&#8217;entre vous ont entendu parler du .tel. Ce nouveau tld vous permet de créer votre carte d&#8217;identité sur Internet. Petite analyse du système.</p>

<p>Tout le monde en a plus ou moins rêver, pouvoir créer un véritable annuaire sur Internet. Nombre de services s&#8217;y sont essayés et se sont affrontés par la même occasion avec plus ou moins de succès mais aucun n&#8217;est vraiment sortit du lot. Il faut dire que l&#8217;internaute confirmés ou non devant le panel d&#8217;offre peut être rapidement dépassé, ne reste donc que le technophile avec deux possibilités : choisir un service et l&#8217;utiliser au maximum ou les utiliser tous au tiers de leurs possibilités.</p>

<p>C&#8217;est la que le .tel arrive avec ses gros sabots, une extension avec un seul objectif, vous permettre de créer votre identité en ligne de manière formatée. De ce point de vue, le .tel est donc un véritable succès et représente enfin la solution à la fois acceptable en tant qu&#8217;annuaire et pourquoi pas le standard en devenir.</p>

<p>La ou le bas blesse, c&#8217;est sur la technique. Le .tel à plusieurs inconvénients, le premier et le plus évident est celui de l&#8217;hébergement puisque vous ne pourrez qu&#8217;acheter un .tel et utiliser la plateforme .tel pour l&#8217;héberger. L&#8217;avantage pour l&#8217;inconvénient du standard. Second point, la sécurité des données, l&#8217;ensemble des informations étant diffusées de la même manière et en clair, il est très facile de créer un parseur récupérant l&#8217;ensemble des informations disponibles sur les domaines .tel pour créer un véritable petit annuaire pour spammeur. Nous assistons donc à deux types de comportement vis à vis de l&#8217;extension, les premiers achètent un .tel et l&#8217;utilise en conscience plus ou moins évidentes des risques tandis que les seconds ne font qu&#8217;acheter le domaine, protection de l&#8217;identité numérique oblige.</p>

<p>Enfin et pour terminer avec les problèmes techniques, le .tel ne fait à mon sens que le travail à moitié. Un petit affichage du code source de la page vous permettra de mettre en avant un problème, le .tel n&#8217;utilise aucune des technologies de sémantisation de l&#8217;information. N&#8217;essayez donc pas de trouver de microformats ou encore de RDFa, il n&#8217;y en a tout simplement pas. Nous avons donc devant nous un outil sémantiquement formidable qui n&#8217;utilise aucun des moyens sémantiques en devenir &#8211; non je n&#8217;alimenterai pas le débat microformats vs RDFa.</p>

<p>Cette suite d&#8217;article, la première du devblog, va donc vous permettre de créer un équivalent du .tel version sémantique et personnalisable. Cette suite d&#8217;articles prendra donc la forme suivante et aura pour but de sortir une carte d&#8217;identité optimisé pour l&#8217;iPhone et le web &#8211; ou l&#8217;inverse c&#8217;est au choix &#8211; :</p>

<ul>
    <li>La création d&#8217;une interface simple et adaptée aux mobiles.</li>
    <li>Comment faire une intégration sémantique à la fois en microformats et en RDFa afin de faciliter l&#8217;export d&#8217;informations.</li>
    <li>comment ajouter quelques effets javascript afin de créer une touche d&#8217;interactivité.</li>
</ul>

<p>Et parce que je ne suis pas complètement contre le .tel, <a href="http://www.toutpointtel.fr/">un lien vers le site Internet</a> dans lequel vous retrouverez tous les renseignements pour vous en procurer votre .tel ainsi que tous les webservices ou applications développés pour en améliorer l&#8217;utilisation.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.pockyworld.com/developpement/comment-creer-sa-carte-de-visite-web-1-le-tel.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

