<?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>piouPiouM&#039;s dev&#187; Archives de la catégorie Développement Web &#8211; piouPiouM&#039;s dev</title>
	<atom:link href="http://pioupioum.fr/developpement/feed/" rel="self" type="application/rss+xml" />
	<link>http://pioupioum.fr</link>
	<description>Bloc-note d&#039;un développeur web</description>
	<lastBuildDate>Mon, 30 Apr 2012 09:42:02 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Compass au quotidien</title>
		<link>http://pioupioum.fr/developpement/compass-usage-quotidien-cheatsheet.html</link>
		<comments>http://pioupioum.fr/developpement/compass-usage-quotidien-cheatsheet.html#comments</comments>
		<pubDate>Sun, 29 Apr 2012 15:31:39 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[astuces]]></category>
		<category><![CDATA[compass]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[méthodologie]]></category>
		<category><![CDATA[productivité]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=625</guid>
		<description><![CDATA[Sass et Compass éveillent de plus en plus la curiosité des intégrateurs Web et développeurs front-end français. Malheureusement je ne peux que constater une certaine réticence de leur part à sauter le pas.
La faute en incombe généralement à une frayeur démesurée de la ligne de commande et, il est vrai, 
à un manque de ressources [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Sass et Compass éveillent de plus en plus la curiosité des intégrateurs Web et développeurs front-end français. Malheureusement je ne peux que constater une certaine réticence de leur part à sauter le pas.<br />
La faute en incombe généralement à une <strong>frayeur démesurée</strong> de la ligne de commande et, il est vrai, 
à un manque de ressources francophones qui expliquent comment intégrer l&#8217;outil dans son processus métier.</p>

<p>Je vous propose ici la méthode de travail générique que j&#8217;utilise depuis maintenant 2 ans 
dans mon environnement professionnel. Je précise bien <em>générique</em> parce que certains projetss peuvent 
imposer une organisation différente.</p>

<p><div id="attachment_624" class="wp-caption aligncenter" style="width: 620px"><a href="/developpement/compass-usage-quotidien-stylesheet.html"><img src="http://assets1.pioupioum.fr/uploads/2012/04/post_it_marilyn-by-peter_hellberg.jpg" alt="Post-it Marilyn par Peter Hellberg" title="Compass au quotidien" width="610" height="300" class="size-medium wp-image-600" /></a><p class="wp-caption-text">Crédits&#160;: <a href="http://www.flickr.com/photos/peterhellberg/4625578444">Post-it Marilyn</a> par <a href="http://www.flickr.com/people/peterhellberg/">Peter Hellberg</a> sous licence <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.fr">CC BY-SA 2.0</a></p></div>
<span id="more-625"></span></p>

<h2>Initialiser un nouveau projet Compass</h2>

<p>Mon projet est généralement contenu dans un projet plus conséquent, comme par exemple un thème Drupal pour lequel j&#8217;ai déjà créé son répertoire. Il me suffit ainsi d&#8217;initialiser un nouveau <strong>projet Compass</strong>, chose aisée grâce à sa commande <code>init</code>&#160;:</p>

<pre><code>$ compass init --prepare --sass-dir sass --css-dir css --images-dir img --relative-assets
directory css/ 
directory sass/ 
   create config.rb
</code></pre>

<p>Puisque je ne souhaite pas que Compass me génère de feuilles de styles par défaut, 
j&#8217;utilise ici l&#8217;option <code>--prepare</code> qui limitera son action à créer&#160;:</p>

<ul>
<li>le fichier de configuration du projet <code>config.rb</code>&#160;;</li>
<li>le répertoires accueillant les sources SCSS nommé ici <code>sass</code>&#160;;</li>
<li>le dossier de destination des feuilles de styles générées <code>css</code>.</li>
</ul>

<p>Cela fait, j&#8217;édite le fichier de configuration pour paramétrer les 2 environnements de déployement 
(<code>development</code> et <code>production</code>, sachant que <code>development</code> est celui par défaut) et pour empêcher 
Compass d&#8217;ajouter un éventuel <a href="http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html" title="Compass : supprimer le cache buster des sprites &#8211; Remove sprite hash – piouPiouM&#039;s dev">cache buster</a>&#160;:</p>

<pre><code>if environment == :production
  output_style = :compressed
else
  output_style = :expanded
  sass_options = { :debug_info =&gt; true }
end

# Désactiver l'ajout du cache buster sur les images appelées via la fonction image-url().
asset_cache_buster :none
</code></pre>

<p><strong>Note&#160;:</strong><br />
La ligne qui contient <code>:debug_info</code> me permet d&#8217;utiliser le plugin pour Firefox <a href="https://addons.mozilla.org/fr/firefox/addon/firesass-for-firebug/">FireSass</a>.</p>

<p>Ok, mon projet Compass est presque prêt. Il ne me manque plus qu&#8217;à créer quelques répertoires et 
fichiers que j&#8217;utilise habituellement&#160;:</p>

<pre><code>$ mkdir -p sass/partials/{reset,ui}
$ touch sass/{style,reset,partials/_{base,reset,ui}}.scss
</code></pre>

<p>Mon arborescence finale&#160;:</p>

<pre><code>$ tree -F
.
├── config.rb
├── css/
└── sass/
    ├── partials/
    │   ├── _base.scss
    │   ├── _reset.scss
    │   ├── _ui.scss
    │   ├── reset/
    │   └── ui/
    ├── reset.scss
    └── style.scss
</code></pre>

<h2>Méthodologie de travail avec Compass</h2>

<p>Après toute modification qui nécessite une vérification du résultat de ma part<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>, je lance une 
compilation des sources Sass par une simple commande&#160;:</p>

<pre><code>$ compass compile
</code></pre>

<p>Comme aucun fichier de configuration n&#8217;est précisé, la commande <code>compile</code> lit le fichier de 
configuration <code>config.rb</code> (ou <code>compass.rb</code>).</p>

<p>Lorsque mon fichier de configuration n&#8217;est pas <em>standard</em>, je précise son emplacement avec l&#8217;argument -c&#160;:
    $ compass compile -c sass/theme.rb</p>

<p>Il est aussi possible de ne compiler qu&#8217;une seule feuille de styles, en précisant simplement
son équivalent Sass&#160;:</p>

<pre><code>$ compass compile sass/styles.scss
</code></pre>

<p>Cette opération pouvant être répétitive, Compass offre une commande <code>watch</code> qui possède les même options
que sa sœur <code>compile</code> mais qui se charge de surveiller mon projet et lancer la compilation 
dès que cela est nécessaire&#160;:</p>

<pre><code>$ compass watch
</code></pre>

<p>Un petit <kbd>Ctrl+C</kbd> stoppera la surveillance.</p>

<h2>Partager son projet Compass</h2>

<p>Jusqu&#8217;ici je ne travaillai qu&#8217;en local. Il me faut maintenant pousser mon travail sur le dépôt 
centralisé pour permettre à mes collègues d&#8217;en bénéficier.<br />
Oui, je pourrai pousser le travail en l&#8217;état, mais non je ne le fait pas. Puisque ces mêmes ressources 
sont destinée à être déployées sur le serveur de production je relance une compilation en précisant 
l&#8217;environnement <code>production</code>&#160;:</p>

<pre><code>$ compass compile -e production --force
</code></pre>

<p>L&#8217;argument <code>--force</code> m&#8217;assure que toutes les ressources seront bien compilées.</p>

<p>J&#8217;obtiens ainsi des feuilles de styles compressées, idéales pour les <strong>webperf</strong> et décourageantes pour 
la personne qui souhaiterait directement les éditer en se cognant du projet Compass parce que ça 
l&#8217;emmerde de s&#8217;y mettre<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> <img src='http://pioupioum.fr/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<blockquote>
  <p>Webperf un jour, webperf toujours&#160;!</p>
</blockquote>

<p>Dernière opération avant de pousser mon travail&#160;: j&#8217;optimise les sprites modifiés depuis la dernière fois. Évoluant sous MacOSX, j&#8217;utilise l&#8217;excellent <a href="http://imageoptim.com/" title="ImageOptim — make websites and apps load faster (Mac app)">ImageOptim</a>. Sous Linux vous pouvez vous tourner vers son équivalent <a href="http://trimage.org/" title="Trimage (lossless) image compressor">Trimage</a> et <a href="http://pnggauntlet.com/" title="PNGGauntlet - PNG Compression Software | BenHollis.net">PNGGauntlet</a> sous Windows.</p>

<h2><em>Au secours, j&#8217;ai un conflit&#160;!</em></h2>

<p>Après un <code>svn up</code> ou <code>git pull</code> il peut arriver un conflit . Il y a 98% de chances pour qu&#8217;il porte sur 
un fichier généré par Compass, à savoir une feuille de styles ou une image de sprite.<br />
Pas de problème, j&#8217;accepte la version entrante ou supprime ma version locale. Je peux ainsi visualiser dans un navigateur la dernière version récupérée et dans tous les cas il me suffit de lancer une compilation pour que mon travail soit à nouveau pris en compte (puisque les modifications entrantes des sources Sass ont été correctement fusionnées).</p>

<h2>En résumé</h2>

<p>Finalement, une fois le projet initialisé, travailler avec Compass revient à exécuter un ridicule
jeux de commandes&#160;:</p>

<pre><code>$ compass watch
CTRL+C
$ compass compile -e production --force
$ open -a "ImageOptim" img/*.png
</code></pre>

<p>Rien de sorcier, n&#8217;est-ce pas&#160;? <img src='http://pioupioum.fr/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<h2>Bonus de Compass</h2>

<p>Il peut arriver que je souhaite supprimer tout fichier généré par Compass&#160;: fichiers de cache, sprites et feuilles de styles. Rien de plus simple à l&#8217;aide de la commande <code>clean</code>&#160;:</p>

<pre><code>$ compass clean
</code></pre>

<p>Parce que les statistiques sont toujours révélatrices de points forts ou faiblesses d&#8217;un projet&#160;:</p>

<pre><code>$ compass stats
</code></pre>

<p><strong>Notes&#160;:</strong><br />
N&#8217;oubliez pas de préciser le fichier de configuration s&#8217;il n&#8217;est pas standard.</p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html' title='Compass : supprimer le cache buster des sprites'>Compass&#160;: supprimer le cache buster des sprites</a></li><li><a href='http://pioupioum.fr/developpement/compass-rvm-multiple-instances.html' title='Instances multiples de Compass avec Ruby Version Manager (rvm)'>Instances multiples de Compass avec Ruby Version Manager (rvm)</a></li><li><a href='http://pioupioum.fr/developpement/git-alias-productivite.html' title='Git : des alias pour aller plus vite'>Git&#160;: des alias pour aller plus vite</a></li><li><a href='http://pioupioum.fr/developpement/drupal-iframe-page.html' title='Drupal 6 : utiliser une iframe comme contenu de page'>Drupal 6&#160;: utiliser une iframe comme contenu de page</a></li><li><a href='http://pioupioum.fr/developpement/optimiser-rapidite-chargement-adsense-jquery.html' title='Optimiser le chargement des AdSense'>Optimiser le chargement des AdSense</a></li></ul>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>sans déconner, vous avez vraiment besoin d&#8217;une solution comme <a href="http://livereload.com/" title="LiveReload">LiveReload</a>&#160;? Vous avez si peu confiance en vos compétences&#160;? :-/<br />
Sans parler du fait que c&#8217;est un coup à faire ramer votre machine lorsque le projet à rafraîchir est une
page complexe d&#8217;un CMS…&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p>mes collègues de <a href="http://www.clever-age.com/" title="Clever Garden, Clever Age, Clever Presence - 100% digital">Clever Age</a> Lyon sont géniaux&#160;: aucun n&#8217;a émit d&#8217;objection quand je leur ai 
proposé d&#8217;utiliser Compass dans leurs projets. Au contraire, ils ont été friands de nouveauté \o/&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/compass-usage-quotidien-cheatsheet.html/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Les angoisses du theming sous Drupal 7</title>
		<link>http://pioupioum.fr/developpement/drupal7-angoisse-theming.html</link>
		<comments>http://pioupioum.fr/developpement/drupal7-angoisse-theming.html#comments</comments>
		<pubDate>Thu, 19 Apr 2012 22:23:33 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal 7]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=595</guid>
		<description><![CDATA[Le système de theming de Drupal 7 est 
un gâchis. Jacine Luisi, co-auteure du livre The Definitive Guide to Drupal 7, résume dans son article Let’s Do Something About Drupal’s Theme System le fond de ma pensée. Au lieu de retranscrire son article ici même, je vais plutôt vous présenter de quoi il retourne.



Pourquoi le [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><strong>Le système de theming de <a href="http://drupal.org/" title="Drupal - Open Source CMS | drupal.org">Drupal 7</a> est 
un gâchis.</strong> <a href="http://jacine.net/" title="jacine">Jacine Luisi</a>, co-auteure du livre <a href="http://amazon.com/dp/1430231351" title="Amazon.com: The Definitive Guide to Drupal 7 (Definitive Guide Apress) (9781430231356): Benjamin Melancon, Jacine Luisi, Karoly Negyesi, Bojhan Somers, Stephane Corlosquet, Stefan Freudenberg, Ryan Szrama, Dan Hakimzadeh, Amye Scavarda, Allie Micka, Roy Scholten, Kasey Dolin, Sam Boyer, Mike Gifford: Books">The Definitive Guide to Drupal 7</a>, résume dans son article <a href="http://jacine.net/post/19652705220/theme-system">Let’s Do Something About Drupal’s Theme System</a> le fond de ma pensée. Au lieu de retranscrire son article ici même, je vais plutôt vous présenter de quoi il retourne.</p>

<p><div id="attachment_600" class="wp-caption aligncenter" style="width: 620px"><a href="/developpement/drupal7-angoisse-theming.html"><img src="http://assets1.pioupioum.fr/uploads/2012/04/kaos-ii.jpg" alt="Kaos - Chaos paiting (ii)" title="Pourquoi le theming Drupal est-il si compliqué ?" width="610" height="300" class="size-medium wp-image-600" /></a><p class="wp-caption-text">Crédits&#160;: <a href="http://www.flickr.com/photos/kalexanderson/6113247118/">Kaos - Chaos paiting (ii)</a> par <a href="http://www.flickr.com/people/kalexanderson/">Kristina Alexanderson</a> sous licence <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.fr">CC BY-NC-SA 2.0</a></p></div></p>

<p><span id="more-595"></span></p>

<h2>Pourquoi le theming Drupal est-il si compliqué&#160;?</h2>

<p>Depuis que je travaille sur <strong>Drupal 7</strong>, il ne se passe pas une semaine sans que j&#8217;ai à pester contre son <strong>système de thème</strong>. Comme le souligne Jacine, les nombreux points d&#8217;entrées et la multiplicité de niveaux d’interactions font qu&#8217;il est souvent <strong>difficile de trouver où intervenir</strong>.</p>

<blockquote>
  <p>Quel <em>preprocess</em> appeler&#160;? Celui-ci&#160;?<br />
  Perdu. Testons dans un autre ou dans un <em>hook_alter</em>.<br />
  Toujours rien. Peut-être dans un <em>hook_process</em>&#160;?<br />
  Finalement, il me faut surcharger un <em>hook_theme</em> parce que je ne peux agir sur ce <em>pre-render</em>…</p>
</blockquote>

<p>J&#8217;exagère un peu, quoique, pas tant que ça finalement.<br />
Vous allez me dire qu&#8217;avec Drupal 6 nous étions habitué à cette gymnastique mentale, ce à quoi je réponds oui, mais. Mais, c&#8217;était moins anarchique.  Exemple.</p>

<h2>Un exemple tout bête</h2>

<p>Pour un type de contenu spécifique, un client demande à pouvoir insérer librement du code JavaScript et des styles CSS depuis l&#8217;espace de contribution. Pas de problème, il me suffit de récupérer le contenu des champs et de les attacher à la page à l&#8217;aide des fonctions 
<a href="http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_add_js/7" title="drupal_add_js | Drupal 7 API"><code>drupal_add_js</code></a> et <a href="http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_add_css/7" title="drupal_add_css | Drupal 7 API"><code>drupal_add_css</code></a> en précisant un type <code>inline</code> et les scopes appropriés. Ni une ni deux, je m&#8217;exécute et fais le nécessaire dans une implémentation de <code>hook_preprocess_node()</code> et, sans surprise, cela fonctionne.</p>

<p><strong>Note&#160;:</strong> les extraits de codes qui suivent sont simplifiés pour se focaliser sur le sujet.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * @file template.php
 */</span>
<span style="color: #009933; font-style: italic;">/**
 * Implements hook_preprocess_node().
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> MYTHEME_preprocess_node<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$vars</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// Nous utilisons la propriété `value` au lieu de `safe_value` qui encode les quotes.</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$vars</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'field_inline_css'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    drupal_add_css<span style="color: #009900;">&#40;</span><span style="color: #000088;">$vars</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'field_inline_css'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'type'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'inline'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'group'</span>      <span style="color: #339933;">=&gt;</span> CSS_THEME<span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'every_page'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'media'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'all'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'preprocess'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">// ne pas aggréger avec les autres styles</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #666666; font-style: italic;">// -- snip --</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<p>Malheureusement le markup HTML des champs est malgré tout généré dans le flux du contenu. Ok, il me suffit de les masquer (au sens Drupal 7 du terme). Je regarde pour appliquer un coup de <a href="http://api.drupal.org/api/drupal/includes%21common.inc/function/hide/7" title="hide | Drupal 7 API"><code>hide()</code></a> sur mes champs depuis mon implémentation du <code>preprocess_node</code>. Mince, ces derniers sont déjà marqués comme rendus, leurs contenu calculé, etc. Pas mieux depuis un <a href="http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_page_alter/7" title="hook_page_alter | Drupal 7 API"><code>hook_page_alter()</code></a>, ni depuis le fichier de template dédié. Pourtant la documentation officielle ne cesse de montrer comme il est facile de gérer la visibilité des champs.</p>

<p>Que faire&#160;? Dois-je perdre du temps pour rendre un à un tous les champs à afficher pour ce type de contenu, ou est-ce que je pousse un peu l&#8217;investigation&#160;? J&#8217;opte pour la seconde option tellement cette situation me paraît ridicule.</p>

<p>Rapidement, je trouve que je peux masquer mes champs en implémentant le <a href="http://api.drupal.org/api/drupal/modules%21node%21node.api.php/function/hook_node_view_alter/7" title="hook_node_view_alter | Drupal 7 API"><code>hook_node_view_alter()</code></a>. Tout fonctionne.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * @file template.php
 */</span>
<span style="color: #009933; font-style: italic;">/**
 * Implements hook_node_view_alter().
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> MYTHEME_node_view_alter<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$build</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  hide<span style="color: #009900;">&#40;</span><span style="color: #000088;">$build</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'field_inline_css'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  hide<span style="color: #009900;">&#40;</span><span style="color: #000088;">$build</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'field_inline_js'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<p>Cependant, gérer ces champs à deux endroits n&#8217;est pas des plus lisible. Je rapatrie donc le code ajouté dans l&#8217;implémentation du <code>hook_preprocess_node()</code> dans mon <code>hook_node_view_alter</code>.<br />
Déconfiture&#160;: seule l&#8217;injection du JavaScript est prise en compte. Celle des styles CSS est tout bonnement ignorée ;!</p>

<p><strong>WTF Drupal (╯°□°）╯︵ ┻━┻</strong></p>

<p>Et c&#8217;est ainsi que je me suis résigné à scinder cette étape de theming en 2 emplacements distincts. Le tout agrémenté d&#8217;explications en commentaires pour ne pas m&#8217;y perdre dans quelques mois ou tout simplement pour aider mes collègues à s&#8217;y retrouver.</p>

<h2>Comment en est-on arrivé là&#160;?</h2>

<p>La faute en incombe en partie à une structure de données non normalisée couplée à un système de <em><a href="http://drupal.org/node/930760" title="Render Arrays in Drupal 7 | drupal.org">render array</a></em> alléchant mais qui ne tient pas ses promesses. Tout module gère ses données à transmettre à l&#8217;<a href="http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_render/7" title="drupal_render | Drupal 7 API">API render</a> comme bon lui chante. De ce fait il existe presque autant de cas de figure qu&#8217;il y a de modules :-/ Au niveau des fichiers de template, nous avons le droit à une soupe de variables au type simple et de <em>render array</em>.</p>

<p>Également, les modules peuvent transformer la structure des <em>render array</em> et nous mettre des bâtons dans les roues pour le theming (les modules <a href="http://drupal.org/project/field_group" title="Field group | drupal.org">Field Group</a> et <a href="http://drupal.org/project/ds" title="Display Suite | drupal.org">Display Suite</a> en sont de bons exemples).</p>

<p>Pour finir, bien des situations complexes pourraient être évités si le core de Drupal exploitait systématiquement les <em>render array</em>. Il arrive toujours un moment où, alors que nous cherchons à modifier le <code>#prefix</code> d&#8217;un élément, l&#8217;on tombe sur du pur HTML. Tout ça parce qu&#8217;une implémentation du <a href="http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7" title="hook_theme | Drupal 7 API"><code>hook_theme()</code></a> ne retourne pas de <em>render array</em>, comme <a href="http://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_links/7" title="theme_links | Drupal 7 API"><code>theme_links()</code></a> par exemple…</p>

<h2>L&#8217;avenir du theming avec Drupal 8</h2>

<p>FIXME. C&#8217;est l&#8217;idée <img src='http://pioupioum.fr/wp/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> <br />
Jacine propose une <a href="http://jacine.github.com/drupal/">standardisation de composant</a> qui aura le bénéfice de simplifier le templating en rationnalisant la construction d&#8217;une page et, <strong>surtout</strong>, chaque module pourra arrêter de nous noyer sous des kilomètres de classes CSS <em>&#8220;au cas où…&#8221;</em>.</p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/drupal-iframe-page.html' title='Drupal 6 : utiliser une iframe comme contenu de page'>Drupal 6&#160;: utiliser une iframe comme contenu de page</a></li></ul>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/drupal7-angoisse-theming.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compass&#160;: supprimer le cache buster des sprites</title>
		<link>http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html</link>
		<comments>http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html#comments</comments>
		<pubDate>Wed, 15 Jun 2011 18:22:54 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[astuces]]></category>
		<category><![CDATA[compass]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=543</guid>
		<description><![CDATA[Le générateur de sprites de Compass 0.11.31 crée des images dont le nom a pour format &#60;map>-&#60;hash>.png où &#60;map> correspond au nom du répertoire qui contient les images du sprite et -&#60;hash> à un hash qui&#160;:


assure l&#8217;unicité du fichier généré&#160;;
fait office de cache buster.


Seulement voilà, chaque modification de sprite (par un ajout ou décalage d&#8217;image [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Le générateur de <strong>sprites de Compass 0.11.3</strong><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> crée des images dont le nom a pour format <code>&lt;map>-&lt;hash>.png</code> où <code>&lt;map></code> correspond au nom du répertoire qui contient les images du sprite et <code>-&lt;hash></code> à un hash qui&#160;:</p>

<ul>
<li>assure l&#8217;unicité du fichier généré&#160;;</li>
<li>fait office de <strong><span lang="en">cache buster</span></strong>.</li>
</ul>

<p>Seulement voilà, chaque modification de sprite (par un ajout ou décalage d&#8217;image par exemple) va générer une image avec un hash différent<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>, ce qui rend la gestion du dépôt d&#8217;un projet versionné assez prise de tête.<br />
Heureusement, il est possible de ruser.<span id="more-543"></span></p>

<p>Pour ce faire, il suffit d&#8217;implémenter les <span lang="en">callbacks <strong><code>on_sprite_saved</code></strong> et <strong><code>on_stylesheet_saved</code></strong></span> dans le fichier de configuration du projet, comme suit&#160;:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># config.rb</span>
<span style="color:#008000; font-style:italic;">#</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Réaliser une copie des sprites avec un nom dépourvu du hash d'unicité.</span>
on_sprite_saved <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>filename<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC00FF; font-weight:bold;">FileUtils</span>.<span style="color:#9900CC;">cp</span> filename, filename.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">%</span>r<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">-</span>s<span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#125;</span>\.<span style="color:#9900CC;">png</span>$<span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#996600;">'.png'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Remplacer dans les feuilles de styles générés les références aux sprites par</span>
<span style="color:#008000; font-style:italic;"># leurs équivalents dépourvus du hash d'unicité.</span>
on_stylesheet_saved <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>filename<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>
    css = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">read</span> filename
    <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename, <span style="color:#996600;">'w+'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
      f <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> css.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">%</span>r<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">-</span>s<span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#125;</span>\.<span style="color:#9900CC;">png</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#996600;">'.png'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>


<p>Ainsi, après chaque génération de sprite par <a href="http://compass-style.org/" title="Compass Home | Compass Documentation">Compass</a>, une copie de l&#8217;image dépourvue du hash d&#8217;unicité est réalisée. Cela s&#8217;accompagne bien évidemment par un remplacement de leurs appels dans les feuilles de styles.<br />
Il ne reste plus qu&#8217;à ignorer les images ayant un hash au niveau de votre <span lang="en">repository</span> pour ne pas polluer ce dernier.</p>

<p>Je suis conscient qu&#8217;il y aurait plus <span lang="en">secure</span> (je pense notamment aux substitutions dans les feuilles de style), mais disons que cela me convient dans l&#8217;immédiat, et qu&#8217;accessoirement je ne fais pas de ruby <img src='http://pioupioum.fr/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/compass-usage-quotidien-cheatsheet.html' title='Compass au quotidien'>Compass au quotidien</a></li><li><a href='http://pioupioum.fr/developpement/compass-rvm-multiple-instances.html' title='Instances multiples de Compass avec Ruby Version Manager (rvm)'>Instances multiples de Compass avec Ruby Version Manager (rvm)</a></li><li><a href='http://pioupioum.fr/developpement/drupal-iframe-page.html' title='Drupal 6 : utiliser une iframe comme contenu de page'>Drupal 6&#160;: utiliser une iframe comme contenu de page</a></li><li><a href='http://pioupioum.fr/developpement/optimiser-rapidite-chargement-adsense-jquery.html' title='Optimiser le chargement des AdSense'>Optimiser le chargement des AdSense</a></li><li><a href='http://pioupioum.fr/snippets/wordpress-autoriser-upload-media-format-inconnu.html' title='WordPress : autoriser l&#8217;upload de fichiers au format non-supporté'>WordPress&#160;: autoriser l&#8217;upload de fichiers au format non-supporté</a></li></ul>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p><strong>attention&#160;:</strong> les versions de Compass inférieures à 0.11.3 souffrent de bugs qui empêchent cette astuce de fonctionner.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p>les fichiers obsolètes étants automatiquement supprimés, à moins que la variable de configuration <code>$&lt;map&gt;-clean-up</code> soit positionnée à <code>false</code>.&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Drupal 6&#160;: utiliser une iframe comme contenu de page</title>
		<link>http://pioupioum.fr/developpement/drupal-iframe-page.html</link>
		<comments>http://pioupioum.fr/developpement/drupal-iframe-page.html#comments</comments>
		<pubDate>Sun, 29 May 2011 18:17:22 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[astuces]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=529</guid>
		<description><![CDATA[Vous devez intégrer sous Drupal 6 des pages en provenance d&#8217;un site externe. Le web scraping est à exclure et de ce fait le chargement en iframe des pages externes a été retenu.
Marche à suivre.

Déclarer un menu de type callback

En premier lieu, il vous faut créer la page virtuelle qui aura la charge de faire [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Vous devez intégrer sous <strong><a href="http://drupal.org/" title="Drupal - Open Source CMS | drupal.org">Drupal</a> 6</strong> des pages en provenance d&#8217;un site externe. Le <strong><a href="http://fr.wikipedia.org/wiki/Web_scraping" title="Web scraping - Wikipédia">web scraping</a></strong> est à exclure et de ce fait le <strong>chargement en iframe</strong> des pages externes a été retenu.<br />
Marche à suivre.<span id="more-529"></span></p>

<h2>Déclarer un menu de type callback</h2>

<p>En premier lieu, il vous faut créer la page virtuelle qui aura la charge de faire appel au service externe <em>via</em> une iframe. Cela se fait en implémentant le <a href="http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_menu/6" title="hook_menu | Drupal API">hook_menu</a> pour y déclarer une entrée de type <a href="http://api.drupal.org/api/drupal/includes--menu.inc/constant/MENU_CALLBACK/6" title="MENU_CALLBACK | Drupal API">MENU_CALLBACK</a>. La fonction callback associée, <code>_mytheme_load_iframe()</code> ici<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>, prendra 3 arguments&#160;:</p>

<ol>
<li><strong>url</strong>&#160;: l&#8217;URL de la ressource externe à charger dans l&#8217;iframe&#160;;</li>
<li><strong>width</strong>&#160;: la largeur en pixels de l&#8217;iframe, de <strong>type <code>String</code> obligatoirement</strong>&#160;;</li>
<li><strong>height</strong>&#160;: la hauteur en pixels de l&#8217;iframe, obligatoirement de type <code>String</code>.</li>
</ol>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * template.php
 */</span>
<span style="color: #009933; font-style: italic;">/**
 * @implements hook_menu()
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> mytheme_menu<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'drupal/page/path'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'title'</span>            <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Mon contenu externe'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'page callback'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'_mytheme_load_iframe'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'page arguments'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
              <span style="color: #0000ff;">'url'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'http://example.com/service'</span><span style="color: #339933;">,</span>
              <span style="color: #0000ff;">'width'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'700'</span><span style="color: #339933;">,</span>
              <span style="color: #0000ff;">'height'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'1000'</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'access arguments'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'access content'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'type'</span>             <span style="color: #339933;">=&gt;</span> MENU_CALLBACK<span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Loads an external resource into an iframe.
 *
 * @param string $url   URL to load in the iframe.
 * @param string $width The width of the iframe.
 * @param string $height The height of the iframe.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> _mytheme_load_iframe<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$width</span><span style="color: #339933;">,</span> <span style="color: #000088;">$height</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> theme<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mytheme_simple_iframe'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$iframe_url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$width</span><span style="color: #339933;">,</span> <span style="color: #000088;">$height</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>


<p>Comme vous pouvez le lire, la méthode de callback fait appel à la fonction <a href="http://api.drupal.org/api/drupal/includes--theme.inc/function/theme/6" title="theme | Drupal API">theme()</a> sur un hook <code>mytheme_simple_iframe</code> qui n&#8217;existe pas.</p>

<h2>Création d&#8217;un hook de thème</h2>

<p>La création d&#8217;un hook permettant de faire appel à un fichier template est des plus simple, grâce au <a href="http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_theme/6" title="hook_theme | Drupal API">hook_theme</a>. Définissez dans votre fichier <code>template.php</code> (ou dans un fichier de module) le hook <code>mytheme_simple_iframe</code>&#160;:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * template.php
 */</span>
<span style="color: #009933; font-style: italic;">/**
 * @implements hook_theme()
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> mytheme_theme<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'mytheme_simple_iframe'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'template'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'simple_iframe'</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'arguments'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'url'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'width'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'700'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'height'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'500'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>


<p>Simple de compréhension, on déclare un fichier de template <code>simple_iframe</code> auquel 3 variables seront passées. Les arguments <code>width</code> et <code>height</code> ont une valeur par défaut de précisée, ce qui permet de les omettre dans la définition de la ressource externe dans le hook_menu.</p>

<p>Enfin, créez le fichier de template qui affichera une iframe.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * simple_iframe.tpl.php
 */</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;div class=&quot;iframe&quot;&gt;
  &lt;iframe src=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">print</span> <span style="color: #000088;">$url</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; width=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">print</span> <span style="color: #000088;">$width</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; height=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">print</span> <span style="color: #000088;">$height</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; frameborder=&quot;0&quot; align=&quot;left&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;</pre></td></tr></table></div>


<p>Désormais, tout accès à l&#8217;URL <code>/drupal/page/path</code> chargera le template <code>simple_iframe.tpl.php</code> lorsque <strong>Drupal</strong> effectuera le rendu de la variable <code>$content</code> du fichier <code>page.tpl.php</code>.</p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/compass-usage-quotidien-cheatsheet.html' title='Compass au quotidien'>Compass au quotidien</a></li><li><a href='http://pioupioum.fr/developpement/drupal7-angoisse-theming.html' title='Les angoisses du theming sous Drupal 7'>Les angoisses du theming sous Drupal 7</a></li><li><a href='http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html' title='Compass : supprimer le cache buster des sprites'>Compass&#160;: supprimer le cache buster des sprites</a></li><li><a href='http://pioupioum.fr/developpement/optimiser-rapidite-chargement-adsense-jquery.html' title='Optimiser le chargement des AdSense'>Optimiser le chargement des AdSense</a></li><li><a href='http://pioupioum.fr/snippets/wordpress-autoriser-upload-media-format-inconnu.html' title='WordPress : autoriser l&#8217;upload de fichiers au format non-supporté'>WordPress&#160;: autoriser l&#8217;upload de fichiers au format non-supporté</a></li></ul>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>où <code>my_hook</code> correspond au nom du thème ou du module qui sert à enregistrer ces définitions.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/drupal-iframe-page.html/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Instances multiples de Compass avec Ruby Version Manager (rvm)</title>
		<link>http://pioupioum.fr/developpement/compass-rvm-multiple-instances.html</link>
		<comments>http://pioupioum.fr/developpement/compass-rvm-multiple-instances.html#comments</comments>
		<pubDate>Mon, 23 May 2011 19:56:22 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[compass]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=519</guid>
		<description><![CDATA[Dans le cadre de mon travail à Clever Age j&#8217;utilise dans plusieurs projets Compass, le framework Sass, dans sa version 0.10.6. Mais voilà, cette version a laissé place à la branche 0.11 qui, malheureusement, s&#8217;accompagne de son lot de mixins obsolètes voire de bugs avec certaines extensions.

Mes nouveaux projets feront appels à la dernière version [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Dans le cadre de mon travail à <a href="http://www.clever-age.com/" title="Clever Age, digital architecture">Clever Age</a> j&#8217;utilise dans plusieurs projets <strong><a href="http://compass-style.org/" title="Compass Home | Compass Documentation">Compass</a>, le framework <a href="http://sass-lang.com/" title="Sass - Syntactically Awesome Stylesheets">Sass</a></strong>, dans sa version 0.10.6. Mais voilà, cette version a laissé place à la branche 0.11 qui, malheureusement, s&#8217;accompagne de son lot de mixins obsolètes voire <a href="https://github.com/chriseppstein/compass/issues/306">de bugs</a> avec certaines extensions.</p>

<p>Mes nouveaux projets feront appels à la dernière version en date de Compass mais il me faut conserver une branche 0.10 sur mon poste pour assurer le support des anciens projets. Il est actuellement inconcevable de proposer aux clients une mise à jour des fichiers SCSS vers la branche 0.11.</p>

<p>Comment faire cohabiter les deux versions de Compass et leurs dépendances&#160;? C&#8217;est là qu&#8217;intervient <strong><a href="https://rvm.beginrescueend.com/" title="RVM: Ruby Version Manager">Ruby Version Manager</a></strong>, un gestionnaire d&#8217;environnements pour <a href="http://www.ruby-lang.org/fr/" title="Le langage Ruby">Ruby</a>.<span id="more-519"></span></p>

<h2>Installer RVM</h2>

<p>L&#8217;<a href="http://www.clever-age.com/veille/blog/ruby-version-manager-rvm.html" title="Ruby Version Manager (RVM) - Blog - Veille - Clever Age">installation de RVM</a> est des plus simples&#160;: il suffit de suivre la documentation.<br />
Je préfère installer RVM pour l&#8217;utilisateur courant (moi) et non pour tous les utilisateurs du poste, qui n&#8217;auront pas les mêmes besoins. Accessoirement, cela me permet de manipuler les gem sans invoquer <code>sudo</code>.</p>

<pre><code>$ cd
$ bash &lt; &lt;(curl -sk https://rvm.beginrescueend.com/install/rvm)
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;&amp; . "$HOME/.rvm/scripts/rvm" # Load RVM function' &gt;&gt; ~/.bash_profile
$ source .bash_profile
$ type rvm | head -1
rvm is a function
</code></pre>

<p>J&#8217;en profite pour installer la dernière version stable de Ruby&#160;:</p>

<pre><code>$ rvm install 1.9.2
Installing Ruby from source to: /Users/mehdi/.rvm/rubies/ruby-1.9.2-p180, this may take a while depending on your cpu(s)...

ruby-1.9.2-p180 - #fetching 
ruby-1.9.2-p180 - #downloading ruby-1.9.2-p180, this may take a while depending on your connection...
…
Installing rubygems dedicated to ruby-1.9.2-p180...
…
Installation of rubygems completed successfully.
ruby-1.9.2-p180 - adjusting #shebangs for (gem irb erb ri rdoc testrb rake).
ruby-1.9.2-p180 - #importing default gemsets (/Users/mehdi/.rvm/gemsets/)
Install of ruby-1.9.2-p180 - #complete 
</code></pre>

<p>À ce point, la version de Ruby active sur le système est pourtant celle fournie par Apple (je suis toujours sous OSX :p)&#160;:</p>

<pre><code>$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
</code></pre>

<p>En effet, RVM a bien réalisé l&#8217;installation de Ruby 1.9.2 mais il faut déclarer explicitement notre souhait de l&#8217;utiliser en remplacement de la version système<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>&#160;:</p>

<pre><code>$ rvm use 1.9.2 --default
Using /Users/mehdi/.rvm/gems/ruby-1.9.2-p180
$ ruby -v
ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0]
</code></pre>

<h2>Installation de la dernière version en date de Compass</h2>

<p>Classique, l&#8217;installation de Compass se fait <em>via</em> gem&#160;:</p>

<pre><code>$ gem install compass
Fetching: sass-3.1.1.gem (100%)
Fetching: chunky_png-1.2.0.gem (100%)
Fetching: fssm-0.2.7.gem (100%)
Fetching: compass-0.11.1.gem (100%)
Successfully installed sass-3.1.1
Successfully installed chunky_png-1.2.0
Successfully installed fssm-0.2.7
Successfully installed compass-0.11.1
4 gems installed
Installing ri documentation for sass-3.1.1...
Installing ri documentation for chunky_png-1.2.0...
Installing ri documentation for fssm-0.2.7...
Installing ri documentation for compass-0.11.1...
Installing RDoc documentation for sass-3.1.1...
Installing RDoc documentation for chunky_png-1.2.0...
Installing RDoc documentation for fssm-0.2.7...
Installing RDoc documentation for compass-0.11.1...
$ gem list

*** LOCAL GEMS ***

chunky_png (1.2.0)
compass (0.11.1)
fssm (0.2.7)
rake (0.9.0)
sass (3.1.1)
</code></pre>

<p>Une petite vérification d&#8217;usage&#160;:</p>

<pre><code>$ compass version 
Compass 0.11.1 (Antares)
Copyright (c) 2008-2011 Chris Eppstein
Released under the MIT License.
Compass is charityware.
Please make a tax deductable donation for a worthy cause: http://umdf.org/compass
</code></pre>

<p>Ok, mon environnement par défaut est prêt. Voyons comment faire cohabiter une ancienne version de Compass.</p>

<h2>Création d&#8217;un Gemset dédié à l&#8217;ancienne version de Compass</h2>

<p>En premier lieu, je me positionne sur l&#8217;environnement ruby voulu. Ici, il s&#8217;agit du Ruby que j&#8217;ai défini par défaut.</p>

<pre><code>$ rvm default
$ rvm gemset name
/Users/mehdi/.rvm/gems/ruby-1.9.2-p180
</code></pre>

<p>Recherchons la dernière version de la branche qui m&#8217;intéresse<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> (0.10 pour rappel)&#160;:</p>

<pre><code>$ gem query -ran ^compass$

*** REMOTE GEMS ***

compass (0.11.1, 0.11.0, 0.10.6, 0.10.5, 0.10.4, 0.10.3, 0.10.2, 0.10.1, 0.10.0, 0.8.17, 0.8.16)
</code></pre>

<p>Ok, il me faut la 0.10.6.<br />
RVM donne accès à des <strong>gemsets</strong> qui sont des espaces cloisonnés de gems pour une version de Ruby donnée. Pratique, j&#8217;ai justement besoin d&#8217;isoler les gems de la version 0.10.6 de Compass à celles de la dernière version en date.</p>

<p>Je crée un gemset au nom assez explicite et l&#8217;utilise&#160;:</p>

<pre><code>$ rvm gemset create compass0.10.6
$ rvm gemset use !$
$ rvm gemset name
compass0.10.6
</code></pre>

<p>La création d&#8217;un gemset fourni un nouvel environnement vierge de gems (ou presque, rake restant disponible)&#160;:</p>

<pre><code>$ gem list

*** LOCAL GEMS ***

rake (0.9.0)
</code></pre>

<p>Je peux maintenant installer Compass 0.10.6<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup>, ses dépendances et autres extensions en toute tranquillité.</p>

<pre><code>$ gem install compass --version 0.10.6 --no-rdoc --no-ri
Fetching: haml-3.1.1.gem (100%)
Fetching: compass-0.10.6.gem (100%)
Successfully installed haml-3.1.1
Successfully installed compass-0.10.6
2 gems installed
$ gem list

*** LOCAL GEMS ***

compass (0.10.6)
haml (3.1.1)
rake (0.9.0)
</code></pre>

<p>La petite vérification d&#8217;usage&#160;:</p>

<pre><code>$ compass version
Compass 0.10.6
Copyright (c) 2008-2009 Chris Eppstein
Released under the MIT License.
</code></pre>

<h3>Installer l&#8217;extension Lemonade pour Compass 0.10.6</h3>

<p>Il ne me reste plus  qu&#8217;à installer l&#8217;extension <a href="http://www.hagenburger.net/BLOG/Lemonade-CSS-Sprites-for-Sass-Compass.html" title="Generate CSS Sprites on the Fly with Lemonade">lemonade</a> que j&#8217;utilise dans mes projets&#160;:</p>

<pre><code>$ gem install lemonade --version '&lt; 0.3.5' --no-rdoc --no-ri
…
4 gems installed
</code></pre>

<p>J&#8217;installe ici la version strictement inférieur à 0.3.5 de lemonade car cette dernière lève directement une erreur pour indiquer que la gem lemonade est désormais dépréciée au profit de Compass Sprites. Le hic étant que ce dernier n&#8217;existe pas dans Compass 0.10.6.</p>

<p>Malheureusement, la gem de lemonade ne précise pas les bonnes versions de ses dépendances, et, de ce fait, on se retrouve avec un environnement incapable de générer les images des sprites. Pour corriger cela, on commence par downgrader la version de <strong><a href="http://rubygems.org/gems/chunky_png">chunky_png</a></strong>&#160;:</p>

<pre><code>$ gem uninstall chunky_png --version 1.2.0
$ gem install chunky_png --version '&lt; 1.0.0' --no-rdoc --no-ri
…
1 gem installed  
</code></pre>

<p>La gem <strong>haml</strong> installée avec l&#8217;extension <em>lemonade</em> est incompatible avec Compass 0.10.6 et risque de générer une erreur du genre&#160;:</p>

<pre><code>compile scss/screen.scss
  error scss/screen.scss (Line 2087: Not a valid color stop: #bcd712 74%)
</code></pre>

<p>Il suffit donc d&#8217;installer la dernière version de la branche 3.0&#160;:</p>

<pre><code>$ gem install haml --version '&lt; 3.1' --no-rdoc --no-ri
$ gem uninstall haml --version 3.1.1
$ gem list

*** LOCAL GEMS ***

chunky_png (0.12.0)
compass (0.10.6)
fssm (0.2.7)
haml (3.0.25)
lemonade (0.3.4)
rake (0.9.0)
sass (3.1.1)
</code></pre>

<h2>Utilisation</h2>

<p>Par défaut, en ouvrant un shell, Compass sera disponible en version 0.11. Si j&#8217;ai à travailler sur un projet en 0.10 il me suffit d&#8217;ouvrir un nouveau shell et d&#8217;activer temporairement le <strong>gemset compass0.10.6</strong>&#160;:</p>

<pre><code>$ rvm gemset use compass0.10.6
</code></pre>

<p>À l&#8217;avenir, je maintiendrai à jour la version de Compass dans l&#8217;environnement par défaut et, si besoin est, je figerai dans un nouveau gemset la version de Compass devenu obsolète.</p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html' title='Compass : supprimer le cache buster des sprites'>Compass&#160;: supprimer le cache buster des sprites</a></li><li><a href='http://pioupioum.fr/developpement/compass-usage-quotidien-cheatsheet.html' title='Compass au quotidien'>Compass au quotidien</a></li><li><a href='http://pioupioum.fr/snippets/php-installer-apc-macosx.html' title='PHP : installer APC sous Mac OS X Leopard'>PHP&#160;: installer APC sous Mac OS X Leopard</a></li><li><a href='http://pioupioum.fr/snippets/apache-rotation-logs.html' title='Rotation des logs Apache'>Rotation des logs Apache</a></li><li><a href='http://pioupioum.fr/outils-astuces/textmate-css-selection-unicode.html' title='TextMate : bundle CSS, commande &quot;Convertir la sélection en Unicode&quot;'>TextMate&#160;: bundle CSS, commande &quot;Convertir la sélection en Unicode&quot;</a></li></ul>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>vous pouvez activer ponctuellement (le temps de vie du shell) un autre environnement à l&#8217;aide de la commande <code>rvm use</code> en omettant l&#8217;option <code>--default</code>. Pour revenir à l&#8217;environnement par défaut, un petit <code>rvm default</code> suffit.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p>j&#8217;aurai très bien pu directement invoquer la commande <code>gem install compass --version '&lt; 0.11'</code> et me passer de la recherche <em>via</em> <code>gem query</code>. Je laisse en l&#8217;état pour donner un exemple d&#8217;utilisation de la commande <code>query</code>.&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:3">
<p>Je fais l&#8217;impasse sur l&#8217;installation des documentations pour ce gemset, d&#8217;où les arguments <code>--no-rdoc</code> et <code>--no-ri</code>.&#160;<a href="#fnref:3" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/compass-rvm-multiple-instances.html/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Photon&#160;: guide d&#8217;installation sur Mac OS X Snow Leopard</title>
		<link>http://pioupioum.fr/developpement/photon-php-installer-mac-os-x-snow-leopard.html</link>
		<comments>http://pioupioum.fr/developpement/photon-php-installer-mac-os-x-snow-leopard.html#comments</comments>
		<pubDate>Sun, 27 Feb 2011 18:58:43 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Photon]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=507</guid>
		<description><![CDATA[Créé par Loïc d&#8217;Anterroches, Photon1 est un micro framework PHP distribué sous licence LGPL qui fonctionne au-dessus du serveur web Mongrel2 et du service de messagerie asynchrone ØMQ2.
Voici un petit guide d&#8217;installation pour ce framework PHP pas comme les autres.

Pré-requis

Je considère que vous disposez sur votre système d&#8217;une version de PHP 5.3 installée via macports, [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Créé par <a href="http://xhtml.net/" title="XHTML.net by Loïc d'Anterroches">Loïc d&#8217;Anterroches</a>, <strong><a href="http://www.photon-project.com/" title="Photon, High Performance PHP Framework">Photon</a></strong><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> est un <strong>micro framework PHP</strong> distribué sous licence <a href="http://www.gnu.org/licenses/lgpl.html" title="GNU Lesser General Public License v3.0 - GNU Project - Free Software Foundation (FSF)">LGPL</a> qui fonctionne au-dessus du serveur web <strong><a href="http://mongrel2.org/" title="Mongrel2: The Language Agnostic Web Server">Mongrel2</a></strong> et du service de messagerie asynchrone <strong><a href="http://www.zeromq.org/" title="Less is More - zeromq">ØMQ</a></strong><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>.<br />
Voici un petit guide d&#8217;installation pour ce framework PHP pas comme les autres.<span id="more-507"></span></p>

<h2>Pré-requis</h2>

<p>Je considère que vous disposez sur votre système d&#8217;une version de <strong>PHP 5.3</strong> installée <em>via</em> <strong>macports</strong>, à l&#8217;aide du port <code>php5</code>.</p>

<p>Photon effectue des contrôles de processus. Pour ce faire, la présence de l&#8217;extension PHP <a href="http://www.php.net/manual/fr/book.pcntl.php">PCNTL</a> est obligatoire.<br />
Vérifiez que vous la possédez&#160;:</p>

<pre><code>$ php -i | grep pcntl
/opt/local/var/db/php5/pcntl.ini,
pcntl
pcntl support =&gt; enabled
</code></pre>

<p>Si ce n&#8217;est pas le cas, lancez une installation macports&#160;:</p>

<pre><code>$ sudo port install php5-pcntl
</code></pre>

<p><strong>Mongrel2</strong> requiert SQLite et ZeroMQ. Aussi, s&#8217;il n&#8217;est pas encore présent dans votre environnement de développement, il sera bon d&#8217;installer XDebug.<br />
Vérifiez la présence de ces pré-requis sur votre poste&#160;:</p>

<pre><code>$ port installed sqlite3 zmq php5-xdebug
The following ports are currently installed:
  php5-xdebug @2.1.0_0 (active)
  sqlite3 @3.7.5_0 (active)
  zmq @2.0.10_0 (active)
</code></pre>

<p>S&#8217;il vient à manquer des ports dans la liste ainsi générée, installez-les avec la commande <code>port install</code>&#160;:</p>

<pre><code>sudo port install zmq
</code></pre>

<p>Dans le cas où vous ne possédez aucune de ces libraires, vous pouvez les installer en une unique commande</p>

<pre><code>sudo port install sqlite3 zmq php5-xdebug php5-pcnt
</code></pre>

<h2>Installer Mongrel2 sous Mac OS X Snow Leopard</h2>

<p>Contre toute attente, au moment où cet article est rédigé, <strong>Mongrel2</strong> n&#8217;est pas disponible dans <strong>macports</strong>. Qu&#8217;à cela ne tienne, procédez à son installation depuis les sources&#160;:</p>

<pre><code>sudo port install wget
wget http://mongrel2.org/static/downloads/mongrel2-1.5.tar.bz2
tar xjvf mongrel2-1.5.tar.bz2
cd mongrel2-1.5/
sudo make clean macports install
</code></pre>

<p>L&#8217;option <code>macports</code> du Makefile ne signifie par que <strong>Mongrel2</strong> s&#8217;installera dans l&#8217;environnement de macports, mais qu&#8217;il va utiliser les libraires disponibles depuis cet environnement (soit généralement <code>/opt/local/</code>). Le binaire est généré dans le répertoire <code>/usr/local/bin/</code>&#160;:</p>

<pre><code>which m2sh
/usr/local/bin/m2sh
</code></pre>

<h2>Installer Photon</h2>

<p>L&#8217;installation de <strong>Photon</strong> est des plus simple. En effet, tout passe par <a href="http://dist.photon-project.com/" title="Photon Distribution Channel">PEAR</a>.</p>

<p>Commencez par déclarer les canaux du projet Photon, de l&#8217;extension PHP pour <strong>ØMQ</strong> puis ceux de PHPUnit
et ses dépendances&#160;:</p>

<pre><code>sudo pear channel-discover dist.photon-project.com
sudo pear channel-discover pear.zero.mq
sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover pear.symfony-project.com
sudo pear channel-discover components.ez.no
</code></pre>

<p>N&#8217;ayez aucune inquiétude quant à la présence des dépendances Symfony et eZ Publish. Ces dernières sont requises par <strong>PHPUnit</strong> qui n&#8217;y récupérera qu&#8217;un nombre limité de composants (comme le parser YAML de Symfony) et n&#8217;ira pas vous installer les 2 solutions dans leur intégralité.</p>

<p>Il ne vous reste plus qu&#8217;à lancer l&#8217;installation proprement dite de <strong>Photon</strong>&#160;:</p>

<pre><code>sudo pear install --alldeps photon/photon-alpha
sudo sh -c 'echo "extension=http.so" &gt; /opt/local/var/db/php5/http.ini'
sudo sh -c 'echo "extension=zmq.so" &gt; /opt/local/var/db/php5/zmq.ini'    
</code></pre>

<h3>Tester votre installation de Photon</h3>

<p>L&#8217;installation terminée, Photon est accessible par la commande <code>hnu</code><sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup>. Afin de vous en assurer, lancez simplement sa propre batterie de tests unitaires, comme suit&#160;:</p>

<pre><code>hnu selftest
</code></pre>

<h3>Could not open input file: /usr/share/php/photon.php</h3>

<p>Si vous rencontrez l&#8217;erreur <code>Could not open input file: /usr/share/php/photon.php</code> c&#8217;est que vous utilisez une version de Photon inférieure ou égale à 0.0.5. Si à l&#8217;heure où je rédige ces lignes la version 0.0.6 de Photon n&#8217;est pas disponible, exécutez l&#8217;ensemble des commandes ci-dessous pour fixer le problème&#160;:</p>

<pre><code>cd ~/Downloads/
wget -O hnu.diff http://projects.ceondo.com/p/photon/source/ddiff/9acba649ae355aaf4b365a1f639961336ae6a323/
sudo patch --no-backup-if-mismatch -i hnu.diff `pear config-get bin_dir`/hnu
rm hnu.diff
cd -
</code></pre>

<h2>Mettre à jour Photon</h2>

<p>Encore une fois, la procédure est des plus simple grâce à PEAR&#160;:</p>

<pre><code>$ sudo pear update-channels
Update of Channel "dist.photon-project.com" succeeded
$ sudo pear upgrade photon/photon-alpha
downloading photon-0.0.5.tgz ...
Starting to download photon-0.0.5.tgz (3,937,334 bytes)
...........................................................................done: 3,937,334 bytes
upgrade ok: channel://dist.photon-project.com/photon-0.0.5
</code></pre>

<h2>Accéder aux sources de Photon</h2>

<p>Vous pouvez accéder en local aux sources de Photon dans le répertoire <code>/opt/local/lib/php</code>. Avec TextMate par exemple&#160;:</p>

<pre><code>mate -a `pear config-get php_dir`/photon*
</code></pre>

<p>Autrement, vous pouvez directement accéder aux sources du projet par la <a href="http://projects.ceondo.com/p/photon/source/tree/develop/" title="Photon Git Source Tree - The High Speed PHP Framework">forge Indefero du projet</a>.</p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/snippets/php-installer-apc-macosx.html' title='PHP : installer APC sous Mac OS X Leopard'>PHP&#160;: installer APC sous Mac OS X Leopard</a></li><li><a href='http://pioupioum.fr/snippets/wordpress-create-shortcode-class.html' title='WordPress : une classe abstraite pour aider la création de shortcodes'>WordPress&#160;: une classe abstraite pour aider la création de shortcodes</a></li><li><a href='http://pioupioum.fr/snippets/textmate-commande-exporter-mots-word-wrap.html' title='TextMate : commande &laquo;&nbsp;Export words&nbsp;&raquo;'>TextMate&#160;: commande &laquo;&nbsp;Export words&nbsp;&raquo;</a></li><li><a href='http://pioupioum.fr/snippets/php-convertir-datetime-unix-timestamp.html' title='PHP : convertir un DATETIME en un timestamp UNIX'>PHP&#160;: convertir un DATETIME en un timestamp UNIX</a></li><li><a href='http://pioupioum.fr/snippets/php-uncamel-fonction-convertir-camel-case.html' title='PHP : fonction uncamel() pour inverser une notation en CamelCase'>PHP&#160;: fonction uncamel() pour inverser une notation en CamelCase</a></li></ul>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Pour la petite histoire, j&#8217;ai donné son petit nom au framework \o/&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p>Lire ZeroMQ. S&#8217;écrit également ZeroMQ, 0MQ ou ZMQ.&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:3">
<p>le nom de la commande <code>hnu</code> vient de &#x210E;&nu;, la notation des <a href="http://fr.wikipedia.org/wiki/Photon" title="Photon - Wikipédia">photons</a> en chimie et en optique.&#160;<a href="#fnref:3" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/photon-php-installer-mac-os-x-snow-leopard.html/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>JavaScript&#160;: optimiser le calcul de l&#8217;intersection de tableaux de grandes tailles</title>
		<link>http://pioupioum.fr/developpement/javascript-array-intersection.html</link>
		<comments>http://pioupioum.fr/developpement/javascript-array-intersection.html#comments</comments>
		<pubDate>Tue, 13 Jul 2010 13:31:38 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[licence MIT]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=408</guid>
		<description><![CDATA[Trouver sur la toile une fonction JavaScript de calcul d&#8217;intersection de tableaux qui soit efficace sur des tableaux dépassant les 50 entrées relève de l&#8217;impossible. C&#8217;est bien simple, les différentes solutions que j&#8217;ai pu rencontrer réalisent des calculs linéaires donc autant dire qu&#8217;à partir d&#8217;un certain seuil leurs performances deviennent catastrophiques.

C&#8217;est pourquoi je vous propose [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Trouver sur la toile une fonction <strong>JavaScript</strong> de calcul d&#8217;<strong>intersection de tableaux</strong> qui soit efficace sur des tableaux dépassant les 50 entrées relève de l&#8217;impossible. C&#8217;est bien simple, les différentes solutions que j&#8217;ai pu rencontrer réalisent des calculs linéaires donc autant dire qu&#8217;à partir d&#8217;un certain seuil <em>leurs performances deviennent catastrophiques</em>.</p>

<p>C&#8217;est pourquoi je vous propose ici une fonction de recherche des intersections pour un nombre arbitraire de grands tableaux plus efficace que ce que j&#8217;ai pu tester,  <a href="http://pioupioum.fr/sandbox/javascript-array-intersect-benchmark/" title="JavaScript Big Arrays Intersection - JSpeedmus Benchmark Suite">benchmarks</a> à l&#8217;appui. Est également disponible la suite des <a href="http://pioupioum.fr/sandbox/javascript-array-intersect-benchmark/qunit.html" title="JavaScript Big Arrays Intersection - Unit tests">tests unitaires</a>.</p>

<p><div id="attachment_418" class="wp-caption aligncenter" style="width: 620px"><a href="http://assets1.pioupioum.fr/uploads/2010/07/JavaScript-Big-Arrays-Intersection-JSpeedmus-Benchmark-Suite.png"><img src="http://assets1.pioupioum.fr/uploads/2010/07/JavaScript-Big-Arrays-Intersection-JSpeedmus-Benchmark-Suite-610x238.png" alt="Benchmark réalisé sous Google Chrome 5.0.375.99 / Mac Pro 2 x 3 Ghz Quad-Core Intel Xeon / Mac OS X 10.5.8" title="JavaScript Big Arrays Intersection - JSpeedmus Benchmark Suite" width="610" height="238" class="size-medium wp-image-418" /></a><p class="wp-caption-text">Benchmark réalisé sous Google Chrome 5.0.375.99 / Mac Pro 2 x 3 Ghz Quad-Core Intel Xeon sous Mac OS X 10.5.8</p></div>
<span id="more-408"></span></p>

<h2>La fonction array_big_intersect()</h2>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
 * Compute the intersection of big arrays.
 *
 * @author  Mehdi Kabab &lt;http://pioupioum.fr/&gt;
 * @license http://www.opensource.org/licenses/mit-license.php MIT License.
 * @see     http://pioupioum.fr/developpement/javascript-array-intersection.html
 * @version 1.0.1
 *
 * @param  {Array} arr1 First array.
 * @param  {Array} arr2 Second array.
 * @param  {Array} [arr3[, arr4[, ...]]] Optional arrays.
 * @return {Array} A new array containing elements common to the arrays passed
 *                 in arguments, with no duplicates.
 */</span>
<span style="color: #003366; font-weight: bold;">function</span> array_big_intersect <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> args <span style="color: #339933;">=</span> Array.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">slice</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      aLower <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      aStack <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      count<span style="color: #339933;">,</span>
      i<span style="color: #339933;">,</span>
      nArgs<span style="color: #339933;">,</span>
      nLower<span style="color: #339933;">,</span>
      oRest <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      oTmp <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      value<span style="color: #339933;">,</span>
      compareArrayLength <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>a.<span style="color: #660066;">length</span> <span style="color: #339933;">-</span> b.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      indexes <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>array<span style="color: #339933;">,</span> oStack<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
            value<span style="color: #339933;">,</span>
            nArr <span style="color: #339933;">=</span> array.<span style="color: #660066;">length</span><span style="color: #339933;">,</span>
            oTmp <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> nArr <span style="color: #339933;">&gt;</span> i<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          value <span style="color: #339933;">=</span> array<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
          <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>oTmp<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            oStack<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>oStack<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span> <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// counter</span>
            oTmp<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">return</span> oStack<span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
  args.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span>compareArrayLength<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  aLower <span style="color: #339933;">=</span> args.<span style="color: #660066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  nLower <span style="color: #339933;">=</span> aLower.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span> <span style="color: #339933;">===</span> nLower<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> aStack<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  nArgs <span style="color: #339933;">=</span> args.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
  i <span style="color: #339933;">=</span> nArgs<span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    oRest <span style="color: #339933;">=</span> indexes<span style="color: #009900;">&#40;</span>args.<span style="color: #660066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> oRest<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> nLower <span style="color: #339933;">&gt;</span> i<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    value <span style="color: #339933;">=</span> aLower<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    count <span style="color: #339933;">=</span> oRest<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>oTmp<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>nArgs <span style="color: #339933;">===</span> count<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        aStack.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        oTmp<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> aStack<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<h2>Un gain de performances</h2>

<p>Le gain de performances tient à peu de choses. En premier lieu, l&#8217;ordre d&#8217;analyse des tableaux est un point à ne pas négliger. Par définition, l&#8217;ensemble des valeurs constituant l&#8217;intersection se retrouve dans le plus petit des tableaux. De ce fait, je me base sur le plus petit d&#8217;entre-eux pour effectuer les comparaisons de présence d&#8217;une valeur dans les ensembles restants.</p>

<p>Aussi, la fonction crée un Hash de toutes les valeurs uniques et stocke leur fréquence d&#8217;apparition. Si une valeur apparaît autant de fois qu&#8217;il y a de tableaux, c&#8217;est qu&#8217;une intersection est trouvée.</p>

<p>Et c&#8217;est tout <img src='http://pioupioum.fr/wp/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<p>Petit avertissement, si vous avez à travailler sur des tableaux de petites tailles, je vous conseille plutôt d&#8217;utiliser la fonction <a href="http://www.jslab.dk/library/Array.intersect" title="JavaScript Lab - Library - Array.intersect">Array#intersect()</a> de la librairie <a href="http://www.jslab.dk/library/" title="JavaScript Lab - Library">JSLab</a> qui s&#8217;avère être des plus performantes.</p>

<h2>Anecdote</h2>

<p>Anecdote (ou pas), mon benchmark met en évidence des erreurs de calcul de la part des librairies <a href="http://prototypejs.org/" title="Prototype JavaScript framework: Easy Ajax and DOM manipulation for dynamic web applications">Prototype</a> et <a href="http://www.thegrubbsian.com/2009/01/25/useful-javascript-extensions/" title="Useful JavaScript Extensions &mdash; The Grubbsian">Extensions</a>. La seconde ayant moins d&#8217;impact car peu propagée, il en est tout autre pour Prototype. En effet, cette dernière exclue <strong>systématiquement</strong> la valeur <code>0</code> (zéro) du tableau résultant. Ce qui est plus qu&#8217;embarrassant, pourtant le <a href="https://prototype.lighthouseapp.com/projects/8886/tickets/841-arrayintersect-return-wrong-result-if-array-values-has-0">bug</a> est connu depuis fin 2009.</p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/jslint-console-rhino.html' title='Une console JSLint pour aider vos validations JavaScript'>Une console JSLint pour aider vos validations JavaScript</a></li><li><a href='http://pioupioum.fr/developpement/optimiser-rapidite-chargement-adsense-jquery.html' title='Optimiser le chargement des AdSense'>Optimiser le chargement des AdSense</a></li><li><a href='http://pioupioum.fr/outils-astuces/facebook-application-add-page-tab-bookmarklet.html' title='Page Fan : ajout simplifié d&#8217;application onglet à vos pages fan Facebook'>Page Fan&#160;: ajout simplifié d&#8217;application onglet à vos pages fan Facebook</a></li><li><a href='http://pioupioum.fr/snippets/wordpress-forcer-chargement-jquery-footer.html' title='WordPress : forcer le chargement de jQuery en bas de page'>WordPress&#160;: forcer le chargement de jQuery en bas de page</a></li><li><a href='http://pioupioum.fr/outils-astuces/license-helper-textmate-bundle.html' title='Bundle License Helper pour TextMate'>Bundle License Helper pour TextMate</a></li></ul>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/javascript-array-intersection.html/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Une console JSLint pour aider vos validations JavaScript</title>
		<link>http://pioupioum.fr/developpement/jslint-console-rhino.html</link>
		<comments>http://pioupioum.fr/developpement/jslint-console-rhino.html#comments</comments>
		<pubDate>Thu, 03 Jun 2010 20:07:49 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JSLint]]></category>
		<category><![CDATA[licence MIT]]></category>
		<category><![CDATA[Rhino]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=395</guid>
		<description><![CDATA[J&#8217;ai pris l&#8217;habitude de valider mon code JavaScript à l&#8217;aide de JSLint. Outil d&#8217;analyse statique de code, JSLint permet de m&#8217;assurer du niveau de qualité de mon code avant toute déploiement en production.

Cependant la console accompagnant l&#8217;outil ne me convenait pas, et ce pour plusieurs raisons&#160;:


L&#8217;élément window n&#8217;est pas défini via les options passées à [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>J&#8217;ai pris l&#8217;habitude de valider mon code <a href="http://pioupioum.fr/tag/javascript/" title="Archives pour le tag JavaScript – piouPiouM&#039;s dev">JavaScript</a> à l&#8217;aide de <strong><a href="http://www.jslint.com/" title="JSLint, The JavaScript Code Quality Tool">JSLint</a></strong>. Outil d&#8217;<a href="http://fr.wikipedia.org/wiki/Analyse_statique_de_programmes" title="Analyse statique de programmes - Wikipédia">analyse statique</a> de code, <strong>JSLint</strong> permet de m&#8217;assurer du niveau de qualité de mon code avant toute déploiement en production.</p>

<p>Cependant la <a href="http://www.jslint.com/rhino/rhino.js">console</a> accompagnant l&#8217;outil ne me convenait pas, et ce pour plusieurs raisons&#160;:</p>

<ol>
<li>L&#8217;élément <code>window</code> n&#8217;est pas défini <em>via</em> les options passées à <code>JSLINT</code> ce qui m&#8217;oblige à le déclarer, à l&#8217;aide de l&#8217;instruction <code>/*@global</code>, dans une majorité de mes scripts.</li>
<li>Dans le même esprit, j&#8217;utilise couramment certaines options — comme <code>browser: true</code> — non présentes dans l&#8217;appel à <code>JSLINT</code>.</li>
<li>La présentation du résultat ne me convient guère.</li>
</ol>

<p>Vous trouverez dans les lignes qui suivent la console que j&#8217;utilise en remplacement.</p>

<p><span id="more-395"></span></p>

<h2>Table des matières</h2>

<ol>
<li><a href="#source">Code source</a></li>
<li><a href="#prerequis">Prérequis</a></li>
<li><a href="#usage">Usage</a></li>
<li><a href="changelog">Historique des versions et changelog</a></li>
</ol>

<h2 id="source">Code source</h2>

<div class="box file-js">
    <a href="http://static.pioupioum.fr/code/jslint-console.js" title="Télécharger"><span>jslint-console.js (4&nbsp;Ko)</span></a>
</div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/*global JSLINT */</span>
<span style="color: #009966; font-style: italic;">/*jslint white: true, rhino: true */</span>
<span style="color: #006600; font-style: italic;">/**
 * @fileOverview Provides a JSLint console for Rhino.
 * &lt;p&gt;Usage: &lt;code&gt;java -jar lib/js.jar lib/jslint-console.js lib/fulljslint.js src/testFile1.js src/testFile2.js&lt;/code&gt;&lt;/p&gt;
 * @author Mehdi Kabab &lt;http://pioupioum.fr/&gt;
 * @version 0.1.1 (2010-06-24)
 */</span>
<span style="color: #006600; font-style: italic;">/**
 * @license Copyright (c) 2010 Mehdi Kabab &lt;http://pioupioum.fr/&gt;.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the &quot;Software&quot;), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Loads the JSLint script given as first argument.</span>
load<span style="color: #009900;">&#40;</span>arguments.<span style="color: #660066;">splice</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>scripts<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span>
        indentLen <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/**
     * Returns the string repeated multiplier times.
     * @param {Number} multiplier Number of time the string should be repeated.
     * @this {String}
     * @return Returns the repeated string.
     * @type String
     * @addon
     */</span>
    String.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">repeat</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>multiplier<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span> <span style="color: #339933;">&gt;</span> multiplier<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            multiplier <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">+</span> multiplier<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/**
     * Cleans evidence message and assign &lt;code&gt;identLen&lt;/code&gt;.
     * @private
     * @param {String} str The full message.
     * @param {String} p1 Possible identation.
     * @param {String} p2 The message content.
     * @returns The message content
     * @type String
     */</span>
    <span style="color: #003366; font-weight: bold;">function</span> cleanEvidence<span style="color: #009900;">&#40;</span>str<span style="color: #339933;">,</span> p1<span style="color: #339933;">,</span> p2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        indentLen <span style="color: #339933;">=</span> p1.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> p2<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #006600; font-style: italic;">// cleanEvidence</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/**
     * Check quality code of the given script.
     * @private
     * @param {String} jsfile File to check.
     * @requires JSLINT
     * @requires String#repeat()
     */</span>
    <span style="color: #003366; font-weight: bold;">function</span> lint<span style="color: #009900;">&#40;</span>jsfile<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span>
            input<span style="color: #339933;">,</span>
            e<span style="color: #339933;">,</span>
            errLen<span style="color: #339933;">,</span>
            errTag <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;[ERROR] &quot;</span><span style="color: #339933;">,</span>
            found <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Running JSLint on: &quot;</span> <span style="color: #339933;">+</span> jsfile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        input <span style="color: #339933;">=</span> readFile<span style="color: #009900;">&#40;</span>jsfile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>input<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span>errTag <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;Couldn't open file.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            quit<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>JSLINT<span style="color: #009900;">&#40;</span>input<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> browser<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> rhino<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> laxbreak<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
            onevar<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> undef<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> nomen<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> eqeqeq<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> bitwise<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
            regexp<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> newcap<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
            predef<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'window'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'escape'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'unescape'</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> errLen <span style="color: #339933;">=</span> JSLINT.<span style="color: #660066;">errors</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> errLen<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                e <span style="color: #339933;">=</span> JSLINT.<span style="color: #660066;">errors</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    found <span style="color: #339933;">+=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;% scanned).&quot;</span> <span style="color: #339933;">!==</span> e.<span style="color: #660066;">reason</span>.<span style="color: #660066;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span><span style="color: #CC0000;">11</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span>errTag <span style="color: #339933;">+</span> e.<span style="color: #660066;">reason</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\.$/</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span>
                            <span style="color: #3366CC;">&quot; on line &quot;</span> <span style="color: #339933;">+</span> e.<span style="color: #660066;">line</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; character &quot;</span> <span style="color: #339933;">+</span> e.<span style="color: #660066;">character</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&quot;</span> <span style="color: #339933;">!==</span> e.<span style="color: #660066;">evidence</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                            <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &quot;</span>.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#40;</span>errTag.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span>
                                <span style="color: #009900;">&#40;</span>e.<span style="color: #660066;">evidence</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^(\s*)(\S*(\s+\S+)*)\s*$/</span><span style="color: #339933;">,</span> cleanEvidence<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                            <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &quot;</span>.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#40;</span>errTag.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span>
                                <span style="color: #3366CC;">&quot;.&quot;</span>.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#40;</span>e.<span style="color: #660066;">character</span> <span style="color: #339933;">-</span> indentLen <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;^&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span>errTag <span style="color: #339933;">+</span> e.<span style="color: #660066;">reason</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;=&gt; &quot;</span> <span style="color: #339933;">+</span> found <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; error(s) found.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            quit<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;OK<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #006600; font-style: italic;">// lint</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>scripts<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Usage: jslint-console.js fulljslint.js file1.js[ file2.js]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        quit<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> scripts.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        lint<span style="color: #009900;">&#40;</span>scripts<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<h2 id="prerequis">Prérequis</h2>

<p>Les prérequis sont simples&#160;:</p>

<ul>
<li><a href="http://www.mozilla.org/rhino/download.html" title="Rhino Downloads">Télécharger Rhino</a> et récupérer le fichier <code>js.jar</code>.</li>
<li>Récupérer la version <a href="http://www.jslint.com/rhino/fulljslint.js">complète</a> ou <a href="http://www.jslint.com/rhino/jslint.js">minifiée</a> de JSLint. Attention cependant, il vous faudra supprimer la fonction anonyme embarquée <code>rhino.js</code> (en fin de script).</li>
</ul>

<h2 id="usage">Usage</h2>

<p>Dans un shell, exécutez <code>jslint-console.js</code> à l&#8217;aide de <strong><a href="http://www.mozilla.org/rhino/" title="Rhino - JavaScript for Java">Rhino</a></strong>, comme suis&#160;:</p>

<pre>$ java -jar lib/rhino/js.jar lib/jslint/jslint-console.js lib/jslint/fulljslint.js src/*.js</pre>

<p>Ici, deux arguments sont passés à la <strong>console jslint</strong>&#160;:</p>

<ul>
<li>Le script JSLint, <code>lib/jslint/fulljslint.js</code>, à fournir en premier argument. Je ne le charge pas en dur dans <code>jslint-console.js</code> afin de conserver une souplesse d&#8217;implémentation (<em>via</em> une tâche <a href="http://pioupioum.fr/tag/ant/" title="Archives pour le tag ant – piouPiouM&#039;s dev">Ant</a> par exemple).</li>
<li>La liste des fichiers sources <strong>JavaScript</strong> à analyser.</li>
</ul>

<p>Voici un exemple de sortie de la console&#160;:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="" style="font-family:monospace;">$ java -jar lib/rhino/js-1.7R2.jar lib/jslint/jslint-console.js lib/jslint/fulljslint.js src/*.js
Running JSLint on: src/jsfile1.js
OK
&nbsp;
Running JSLint on: src/jsfile2.js
<span class="br0">&#91;</span>ERROR<span class="br0">&#93;</span> Expected '===' and instead saw '==' on line <span style="">52</span> character 23.
        if <span class="br0">&#40;</span>false == test<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        ..........^
<span class="br0">&#91;</span>ERROR<span class="br0">&#93;</span> Unexpected dangling '_' in '_ob' on line <span style="">74</span> character 17.
        var _ob = window.ob;
        ....^
<span class="br0">&#91;</span>ERROR<span class="br0">&#93;</span> 'ob' is not defined on line <span style="">80</span> character 39.
        if <span class="br0">&#40;</span>'function' !== typeof ob.getVariables<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        ..........................^
<span class="br0">&#91;</span>ERROR<span class="br0">&#93;</span> 'ob' is not defined on line <span style="">83</span> character 26.
        params = ob.getVariables<span class="br0">&#40;</span><span class="br0">&#41;</span>.sequence;
        .........^
=&gt; <span style="">4</span> error<span class="br0">&#40;</span>s<span class="br0">&#41;</span> found.</pre></td></tr></table></div>


<h2 id="changelog">Historique des versions et changelog</h2>

<h3>0.1.1 (2010-06-24)</h3>

<ul>
<li>Forcer un multiplieur positif dans String.prototype.repeat</li>
</ul>

<h3>0.1 (2010-06-03)</h3>

<ul>
<li>Version initiale.</li>
</ul>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/javascript-array-intersection.html' title='JavaScript : optimiser le calcul de l&#8217;intersection de tableaux de grandes tailles'>JavaScript&#160;: optimiser le calcul de l&#8217;intersection de tableaux de grandes tailles</a></li><li><a href='http://pioupioum.fr/outils-astuces/facebook-application-add-page-tab-bookmarklet.html' title='Page Fan : ajout simplifié d&#8217;application onglet à vos pages fan Facebook'>Page Fan&#160;: ajout simplifié d&#8217;application onglet à vos pages fan Facebook</a></li><li><a href='http://pioupioum.fr/outils-astuces/license-helper-textmate-bundle.html' title='Bundle License Helper pour TextMate'>Bundle License Helper pour TextMate</a></li><li><a href='http://pioupioum.fr/snippets/textmate-commande-exporter-mots-word-wrap.html' title='TextMate : commande &laquo;&nbsp;Export words&nbsp;&raquo;'>TextMate&#160;: commande &laquo;&nbsp;Export words&nbsp;&raquo;</a></li><li><a href='http://pioupioum.fr/outils-astuces/textmate-convertir-couleur-hexadecimale-html-rgba.html' title='TextMate : convertir une couleur hexadécimale en notation RGBA'>TextMate&#160;: convertir une couleur hexadécimale en notation RGBA</a></li></ul>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/jslint-console-rhino.html/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Optimiser le chargement des AdSense</title>
		<link>http://pioupioum.fr/developpement/optimiser-rapidite-chargement-adsense-jquery.html</link>
		<comments>http://pioupioum.fr/developpement/optimiser-rapidite-chargement-adsense-jquery.html#comments</comments>
		<pubDate>Thu, 11 Mar 2010 16:48:57 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[astuces]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[optimiser]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=357</guid>
		<description><![CDATA[Il n&#8217;y a rien de plus horripilant que d&#8217;attendre que des publicités chargent pour accéder au contenu d&#8217;un article. C&#8217;est malheureusement une situation que l&#8217;on rencontre fréquemment. La faute en incombe au fonctionnement des blocs AdSense des publicitaires.

En effet, ils nécessitent que nous insérerions le code correspondant à un bloc à l&#8217;endroit où il sera [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Il n&#8217;y a rien de plus horripilant que d&#8217;attendre que des publicités chargent pour accéder au contenu d&#8217;un article. C&#8217;est malheureusement une situation que l&#8217;on rencontre fréquemment. La faute en incombe au fonctionnement des blocs <strong>AdSense</strong> des publicitaires.</p>

<p>En effet, ils nécessitent que nous insérerions le code correspondant à un bloc à l&#8217;endroit où il sera affiché. Cela pour deux raisons notamment&#160;:</p>

<ol>
<li>Des variables globales identifiants l&#8217;annonce sont déclarées.</li>
<li>Le script qui va charger l&#8217;annonce est immédiatement exécuté et fait appel à des actions d&#8217;écriture dans le flux <em>via</em> <a href="https://developer.mozilla.org/fr/DOM/document.write">write</a>.</li>
</ol>

<p>Le deuxième point oblige le navigateur à traiter le code de l&#8217;adsense dès qu&#8217;il le rencontre puisque ce dernier n&#8217;utilise pas de gestionnaire de chargement. En plus d&#8217;écrire dans le flux courant, le système du publicitaire va charger des éléments extérieurs. Pour peu que la latence des réponses soit élevée, l&#8217;impression de <strong>ralentissement du chargement de la page</strong> augmente.</p>

<p>S&#8217;est ainsi que si un article est précédé d&#8217;un encart publicitaire, l&#8217;utilisateur devra patiemment attendre le chargement de ce dernier avant de pouvoir accéder au contenu désiré.<br />
L&#8217;expérience utilisateur s&#8217;en trouve dégradée.</p>

<h2>En finir avec les ralentissements de chargement des pages</h2>

<p>Vous l&#8217;aurez peut-être remarqué, mais sur <a href="http://pioupioum.fr/" title="piouPiouM&#8217;s dev : bloc-note d&#8217;un développeur web. PHP, git, shell, plugins WordPress, SPIP, jQuery">piouPiouM&#8217;s dev</a>, le <strong>chargement des blocs publicitaires</strong> est comme <strong>temporisé</strong>, ne gênant ainsi en rien la navigation sur le site.<br />
Voyons dans la suite du billet comment y parvenir, en prenant pour exemple le service <a href="https://www.google.com/adsense/">Google Adsense</a>.
<span id="more-357"></span></p>

<h2 id="integration-maquette">Intégration dans une maquette</h2>

<p>On commence par définir les emplacements des encarts publicitaires. Cela vous permet ainsi d&#8217;intégrer les annonces dans vos maquettes <abbr title="Hyper Text Markup Language">HTML</abbr>, tout en vous assurant que cette apparence sera conservée pour les utilisateurs n&#8217;ayant pas JavaScript d&#8217;activé, ou qui bloquent les annonces publicitaires.<br />
Je prend ici le parti d&#8217;annoncer la couleur, en précisant la mention <em>Publicité</em>.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;ads-[ads_id]&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ads [ads_format]&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    Publicité
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>


<p>En sommes, il s&#8217;agit d&#8217;un simple élément <code>&lt;div&gt;</code> ayant pour attributs&#160;:</p>

<ul>
<li>un identifiant <strong>[ads_id]</strong>&#160;: un identifiant unique qui va servir de point d&#8217;ancrage au contenu de l&#8217;adsense. Vous pouvez par exemple, dans le cas de Google Adsense, utiliser le nom du critère personnalisé en notation CamelCase.</li>
<li>une classe <strong>ads</strong>&#160;: le style des encarts de pub lorsque celles-ci sont en attente de chargement.</li>
<li>une classe <strong>[ads_format]</strong>&#160;: le format de l&#8217;encart publicitaire. Par exemple, <code>square250</code> pour une annonce de 250px de côtés ou encore <code>banner468</code> pour une bannière au format 468 x 60.</li>
</ul>

<p>Appliquez les styles <abbr title="Cascading Style Sheets">CSS</abbr> qui suivent.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="css" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* @group Tools */</span>
&nbsp;
<span style="color: #6666ff;">.hide</span> <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* @end   Tools */</span>
<span style="color: #808080; font-style: italic;">/* @group Adsense */</span>
&nbsp;
<span style="color: #6666ff;">.ads</span> <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#F4F4F4</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#666666</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">11px</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">text-align</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">center</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">text-transform</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">uppercase</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #6666ff;">.square250</span> <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">250px</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">line-height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">250px</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">250px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #6666ff;">.banner468</span> <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">60px</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">line-height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">60px</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">468px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* @end   Adsense */</span></pre></td></tr></table></div>


<h2 id="ads-code-annonceur">Insertion du code de l&#8217;annonceur</h2>

<p>Insérez en fin de page les différents codes donnés par votre annonceur (ici, Google Adsense).</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;hide&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Ads --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;adsref-[ads_id]&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
google_ad_client = &quot;pub-[client_id]&quot;;
google_ad_slot   = &quot;[slot_id]&quot;;
google_ad_width  = 250;
google_ad_height = 250;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>


<p><strong>Chaque annonce</strong> est incluse dans un élément ayant pour identifiant <code>adsref-[ads_id]</code> (voir <a href="#integration-maquette">Intégration de la maquette</a>) qui fait le lien avec l&#8217;emplacement final de la publicité.</p>

<p>Le tout étant masqué à l&#8217;aide d&#8217;un <code>div.hide</code>. Il serait en effet désagréable d&#8217;afficher les annonces publicitaires en bas de page, même si ce n&#8217;est que pour une poignée de [micro]secondes.</p>

<h2 id="jquery-ads-loader">Un Adsense Loader avec jQuery</h2>

<p>Il ne reste plus qu&#8217;à déplacer à l&#8217;aide de JavaScript les blocs AdSense aux endroits souhaités. Avec <a href="http://pioupioum.fr/tag/jquery/" title="Archives pour le tag jQuery – piouPiouM&#039;s dev">jQuery</a> cela donne&#160;:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> $ads<span style="color: #339933;">;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div[id^=&quot;adsref-&quot;]'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>          <span style="color: #006600; font-style: italic;">// pour chaque bloc d'annonce #adsref-[ads_id]</span>
        $ads <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#ads-'</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span>.<span style="color: #660066;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">7</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// supprimer de #ads-[ads_id] tout éventuel contenu</span>
        $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ins:first'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span>$ads<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>           <span style="color: #006600; font-style: italic;">// déplacer l'annonce dans #ads-[ads_id]</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<p>Bien évidemment, et comme vous êtes sensible aux bonnes pratiques liées à la <a href="http://performance.survol.fr/" title="Performance web">performance web</a>, vous insérerez naturellement ce code en fin de page <img src='http://pioupioum.fr/wp/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/javascript-array-intersection.html' title='JavaScript : optimiser le calcul de l&#8217;intersection de tableaux de grandes tailles'>JavaScript&#160;: optimiser le calcul de l&#8217;intersection de tableaux de grandes tailles</a></li><li><a href='http://pioupioum.fr/developpement/compass-usage-quotidien-cheatsheet.html' title='Compass au quotidien'>Compass au quotidien</a></li><li><a href='http://pioupioum.fr/outils-astuces/facebook-application-add-page-tab-bookmarklet.html' title='Page Fan : ajout simplifié d&#8217;application onglet à vos pages fan Facebook'>Page Fan&#160;: ajout simplifié d&#8217;application onglet à vos pages fan Facebook</a></li><li><a href='http://pioupioum.fr/developpement/compass-sprites-supprimer-cache-buster.html' title='Compass : supprimer le cache buster des sprites'>Compass&#160;: supprimer le cache buster des sprites</a></li><li><a href='http://pioupioum.fr/developpement/drupal-iframe-page.html' title='Drupal 6 : utiliser une iframe comme contenu de page'>Drupal 6&#160;: utiliser une iframe comme contenu de page</a></li></ul>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/optimiser-rapidite-chargement-adsense-jquery.html/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Du RGBA dans vos animations avec le plugin jQuery Color</title>
		<link>http://pioupioum.fr/developpement/jquery-color-plugin-animation-rgba-support.html</link>
		<comments>http://pioupioum.fr/developpement/jquery-color-plugin-animation-rgba-support.html#comments</comments>
		<pubDate>Sat, 20 Feb 2010 14:13:32 +0000</pubDate>
		<dc:creator>piouPiouM</dc:creator>
				<category><![CDATA[Développement Web]]></category>
		<category><![CDATA[couleur]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rgba]]></category>

		<guid isPermaLink="false">http://pioupioum.fr/?p=332</guid>
		<description><![CDATA[J&#8217;ai récemment eu à (ré)utiliser le plugin jQuery Color mais je me suis heurté à une limitation. Je travaillais sur un jeu de couleurs RGBA et malheureusement le plugin ne supportait pas ce mode colorimétrique (il se contente de travailler sur des couleurs RGB).

Qu&#8217;à cela ne tienne, en attendant que ma modification soit intégrée1 au [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>J&#8217;ai récemment eu à (ré)utiliser le plugin <a href="http://plugins.jquery.com/project/color" title="Plugins Color Animations | jQuery Plugins">jQuery Color</a> mais je me suis heurté à une limitation. Je travaillais sur un jeu de couleurs RGBA et malheureusement le plugin ne supportait pas ce mode colorimétrique (il se contente de travailler sur des couleurs RGB).</p>

<p>Qu&#8217;à cela ne tienne, en attendant que <a href="http://github.com/piouPiouM/jquery-color/commit/92ee455320d7e32e0bccdd09166087c1ba5555e2" title="Voir le commit sur mon fork GitHub">ma modification</a> soit intégrée<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> au plugin, voici une version de <strong>jQuery Color</strong> pourvu du <strong><a href="http://pioupioum.fr/developpement/javascript-detecter-support-rgba.html" title="JavaScript : tester le support des couleurs RGBA &#8211; DOM, jQuery CSS3 RGBA &#8211; piouPiouM&#039;s dev">support des couleurs RGBA</a></strong>&#160;:</p>

<div class="box file-js">
    <a href="http://static.pioupioum.fr/code/jquery.color.js" title="Télécharger"><span>jquery.color.js (6&#160;Ko)</span></a>
</div>

<p>La <a href="http://pioupioum.fr/sandbox/jquery-color/" title="RBGA support for jQuery Color – jQuery Color test page – piouPiouM’s dev">page de démonstration</a> qui va bien.</p>

<h3 class='related_post_title'>Continuez votre lecture sur des sujets similaires</h3>

<ul class='related_post'><li><a href='http://pioupioum.fr/developpement/javascript-detecter-support-rgba.html' title='JavaScript : tester le support des couleurs RGBA'>JavaScript&#160;: tester le support des couleurs RGBA</a></li><li><a href='http://pioupioum.fr/outils-astuces/textmate-convertir-couleur-hexadecimale-html-rgba.html' title='TextMate : convertir une couleur hexadécimale en notation RGBA'>TextMate&#160;: convertir une couleur hexadécimale en notation RGBA</a></li><li><a href='http://pioupioum.fr/plugins-wordpress/wordpress-jquery-ui-effects.html' title='WordPress jQuery UI Effects'>WordPress jQuery UI Effects</a></li><li><a href='http://pioupioum.fr/outils-astuces/supprimer-neige-scripts-greasemonkey.html' title='Supprimer les effets de neige avec Greasemonkey'>Supprimer les effets de neige avec Greasemonkey</a></li><li><a href='http://pioupioum.fr/outils-astuces/facebook-application-add-page-tab-bookmarklet.html' title='Page Fan : ajout simplifié d&#8217;application onglet à vos pages fan Facebook'>Page Fan&#160;: ajout simplifié d&#8217;application onglet à vos pages fan Facebook</a></li></ul>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>enfin, je l&#8217;espère :]&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://pioupioum.fr/developpement/jquery-color-plugin-animation-rgba-support.html/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

