<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Frailers.net</title>
    <link>http://www.frailers.net/articles.rss</link>
    <description>Ressources Ruby on Rails en Français</description>
    <pubDate>Wed, 22 Jul 2009 00:00:00 +0000</pubDate>
    <lastBuildDate>Wed, 22 Jul 2009 00:00:00 +0000</lastBuildDate>
    <language>fr</language>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/FrailersArticles" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>Une interface d'administration en 2 secondes : Typus</title>
      <description>&lt;p&gt;Pour la plupart des projets, il est nécessaire d&amp;#8217;avoir une interface d&amp;#8217;administration. Dans la majeure partie des cas, il s&amp;#8217;agit simplement d&amp;#8217;un accès aux objets. Permettre à l&amp;#8217;administrateur de créer, d&amp;#8217;éditer ou de supprimer certains objets. Au lieu de recréer vos  contrôleurs et vues pour chaque projets, je vous propose une petite introduction à Typus, qui va nous générer tout ça comme un grand à partir de nos modèles :D&lt;/p&gt; &lt;h2&gt;Etape 1 : Installer Typus&lt;/h2&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; script/plugin install git://github.com/fesplugas/typus.git&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; script/generate typus&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Une fois les fichiers créés il suffit d&amp;#8217;exécuter la migration. Elle ajoute une table contenant les utilisateurs de typus à votre base de donnée. Typus a donc son propre système de gestion d&amp;#8217;utilisateurs.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; rake db:migrate&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Et voilà, il ne vous reste plus qu&amp;#8217;a vous rendre à l&amp;#8217;adresse&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; http&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;localhost:&lt;span class="Constant"&gt;3000&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;admin
&lt;/pre&gt;
&lt;p&gt;Pour accéder à votre nouvelle interface d&amp;#8217;administration !&lt;/p&gt;
&lt;p&gt;&lt;img src="http://frailers.net/uploads/typus.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Mieux que la tente Quechua&amp;#8230;&lt;/p&gt;
&lt;h2&gt;Etape 2 : Configurer Typus&lt;/h2&gt;
&lt;p&gt;Evidement, dans sa forme actuelle, même si Typus nous a fait gagner du temps, il reste quelques petits problèmes. Nous voudrions par exemple :&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Empêcher l&amp;#8217;édition des objets d&amp;#8217;un modèle précis&lt;/li&gt;
	&lt;li&gt;Empêcher la création d&amp;#8217;un type d&amp;#8217;objet&lt;/li&gt;
	&lt;li&gt;Enlever un champ particulier du formulaire d&amp;#8217;édition&lt;/li&gt;
	&lt;li&gt;Rendre un champ &amp;#8216;read-only&amp;#8217; dans le formulaire&lt;/li&gt;
	&lt;li&gt;etc&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pas de panique c&amp;#8217;est possible, il suffit d&amp;#8217;aller dans les fichiers :&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;config/typus/application.yml&lt;/li&gt;
	&lt;li&gt;config/typus/application_roles.yml&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prenons un exemple, un blogpost, dans application.yml on aura :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Variable"&gt;Post&lt;/span&gt;:
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   fields:
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;     list: id, blog, user, content, status, created_at
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;     form: blog, user, content
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;     show: id, blog, user, content, status, updated_at, created_at
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;  options:
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;     read_only: blog, user
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;   export: csv, xml
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;   order_by: user
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;   filters: created_at
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt;   search: content
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;   application: exampleblog
&lt;/pre&gt;
&lt;p&gt;Fields permet de définir, pour les vues générées, les champs qui y seront présents. On peut également spécifier quels champs seront &amp;#8216;read-only&amp;#8217; grâce à &amp;#8216;options &amp;gt; read-only&amp;#8217; comme aux lignes 6 et 7.&lt;/p&gt;
&lt;p&gt;Export permet de spécifier dans quel format la liste des éléments sera exportable, xml, csv et pdf sont disponibles.&lt;/p&gt;
&lt;p&gt;Order_by est suffisement explicite. Filters crée, sur le côté droit de la liste, une boîte qui permet de filtrer les éléments. Si on prend l&amp;#8217;exemple du created_at on aura une série de liens (Today, Past 7 days, This month, This year) qui permettent de filtrer notre liste.&lt;/p&gt;
&lt;p&gt;Search ajoute également une boîte sur la droite, une zone de recherche. On peut rechercher sur plusieurs champs.&lt;/p&gt;
&lt;p&gt;Si vous souhaitez modifier complètement une des vues générées, c&amp;#8217;est simple, si on prend notre exemple et qu&amp;#8217;on souhaite modifier le formulaire, il suffit de créer le fichier app/view/admin/posts/edit.html.erb, d&amp;#8217;en écrire le contenu et l&amp;#8217;affaire est dans le sac !&lt;/p&gt;
&lt;p&gt;Le fichier application_roles.yml permet de spécifier, pour chaque rôle, les actions qu&amp;#8217;il pourra effectuer sur tel ou tel objet.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; admin:
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   &lt;span class="Variable"&gt;Post&lt;/span&gt;: create, read, delete, update
&lt;/pre&gt;
&lt;p&gt;Le layout de typus est également modifiable a souhait, et il existe encore d&amp;#8217;autres options non détaillées dans ce post. Consultez la doc pour plus d&amp;#8217;infos.&lt;/p&gt;
&lt;p&gt;Dorénavant, vous n&amp;#8217;avez plus d&amp;#8217;excuses pour ne pas faire des interfaces d&amp;#8217;administration qui en jettent en très peu de temps ;)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://intraducibles.com/projects/typus/"&gt;http://intraducibles.com/projects/typus/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://github.com/fesplugas/typus/tree/master"&gt;http://github.com/fesplugas/typus/tree/master&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/aF8ri1o_lwM" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 22 Jul 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/aF8ri1o_lwM/65-une-interface-d-administration-en-2-secondes-typus</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/65-une-interface-d-administration-en-2-secondes-typus</guid>
    <feedburner:origLink>http://www.frailers.net/articles/65-une-interface-d-administration-en-2-secondes-typus</feedburner:origLink></item>
    <item>
      <title>Deuxième edition d'ArrrrCamp</title>
      <description>&lt;p&gt;&lt;a href="http://arrrrcamp.be"&gt;ArrrrCamp&lt;/a&gt; &amp;#8211; &amp;#8220;About Ruby, Rails, Radiant and Rum&amp;#8221;-Camp, le rendez-vous Ruby en Belgique. Après une première edition le 8 mai dernier, les organisateurs d&amp;#8217; &lt;a href="http://arrrrcamp.be"&gt;ArrrrCamp&lt;/a&gt; remettent le couvert. Rendez-vous le 16 Octobre 2009.&lt;/p&gt; &lt;p&gt;&lt;a href="http://arrrrcamp.be"&gt;ArrrrCamp&lt;/a&gt; tente de rassembler toute les personnes qui, en Belgique (et ailleurs), ont un intérêt pour Ruby et ses dérivés. La première edition fût un succès. Pour en savoir plus, le site d&amp;#8217; &lt;a href="http://arrrrcamp.be"&gt;ArrrrCamp&lt;/a&gt; reprend les slides/videos des différentes présentations qui ont eu lieu lors de la première edition.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://arrrrcamp.be"&gt;http://arrrrcamp.be&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Les inscriptions pour la deuxième edition ont commencé, déjà 11 inscrits ! Venez grossir les rangs des participants !&lt;/p&gt;
&lt;p&gt;&lt;a href="http://arrrrcamp.be/participants/new"&gt;http://arrrrcamp.be/participants/new&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Voilà une bonne occasion de parler de votre passion, le tout autour d&amp;#8217;un bon verre ;)&lt;/p&gt;
&lt;p&gt;Si vous souhaitez sponsoriser l&amp;#8217;évènement, il suffit de vous rendre sur le site d&amp;#8217; &lt;a href="http://arrrrcamp.be"&gt;ArrrrCamp&lt;/a&gt; et de contacter l&amp;#8217;équipe.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/5ABzVWuFigQ" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 26 Jun 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/5ABzVWuFigQ/64-deuxie-me-edition-d-arrrrcamp</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/64-deuxie-me-edition-d-arrrrcamp</guid>
    <feedburner:origLink>http://www.frailers.net/articles/64-deuxie-me-edition-d-arrrrcamp</feedburner:origLink></item>
    <item>
      <title>Importez vos contacts avec le plugin Contacts</title>
      <description>&lt;p&gt;Si vous travaillez sur des réseaux sociaux, ou si simplement vous souhaitez que votre application permette à vos utilisateurs d&amp;#8217;inviter un maximum de personnes, alors Contacts peut vous aider. Ce plugin vous permettra de récupérer la liste des contacts de vos utilisateurs, à partir d&amp;#8217;un compte &lt;strong&gt;Hotmail&lt;/strong&gt;, &lt;strong&gt;Gmail&lt;/strong&gt;, &lt;strong&gt;Yahoo&lt;/strong&gt; ou &lt;strong&gt;Plaxo&lt;/strong&gt;.&lt;/p&gt; &lt;h2&gt;Etape 1 : Installer Contacts&lt;/h2&gt;
&lt;p&gt;Contacts a été initialement créé par &lt;a href="http://github.com/cardmagic"&gt;cardmagic&lt;/a&gt; mais les versions que j&amp;#8217;ai eu l&amp;#8217;occasion d&amp;#8217;utiliser ne fonctionnaient plus avec Hotmail. Je vous conseille donc d&amp;#8217;utiliser le fork de &lt;a href="http://github.com/waheedi"&gt;waheedi&lt;/a&gt; qui règle le problème.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;plugin install git&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;github.&lt;span class="Entity"&gt;com&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;waheedi&lt;span class="Keyword"&gt;/&lt;/span&gt;contacts.git
&lt;/pre&gt;
&lt;h2&gt;Etape 2 : Récupérer les contacts&lt;/h2&gt;
&lt;p&gt;L&amp;#8217;utilisation de contacts est ridiculement simple.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; vous connaissez la plateforme concernée&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Support"&gt;Contacts&lt;/span&gt;::&lt;span class="Entity"&gt;Hotmail&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(login, password).&lt;span class="Entity"&gt;contacts&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Support"&gt;Contacts&lt;/span&gt;::&lt;span class="Entity"&gt;Yahoo&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(login, password).&lt;span class="Entity"&gt;contacts&lt;/span&gt;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; &lt;span class="Support"&gt;Contacts&lt;/span&gt;::&lt;span class="Entity"&gt;Gmail&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(login, password).&lt;span class="Entity"&gt;contacts&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;   
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; &lt;span class="Support"&gt;Contacts&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;gmail&lt;/span&gt;, login, password).&lt;span class="Entity"&gt;contacts&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt; &lt;span class="Support"&gt;Contacts&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;hotmail&lt;/span&gt;, login, password).&lt;span class="Entity"&gt;contacts&lt;/span&gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt; &lt;span class="Support"&gt;Contacts&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;yahoo&lt;/span&gt;, login, password).&lt;span class="Entity"&gt;contacts&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; laisser contacts deviner de quel type de compte il s'agit&lt;/span&gt;
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt; &lt;span class="Support"&gt;Contacts&lt;/span&gt;.&lt;span class="Entity"&gt;guess&lt;/span&gt;(login, password).contacts
&lt;/pre&gt;
&lt;p&gt;Vous récupérez alors un tableau de contacts de la forme :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; [[&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;name&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;foo@bar.com&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;], [&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;name2&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;foo2@bar2.com&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]]
&lt;/pre&gt;
&lt;p&gt;A vous de jouer !&lt;/p&gt;
&lt;p&gt;Plus d&amp;#8217;infos sur le fork de contacts par waheedi ici :&lt;br /&gt;
&lt;a href="http://github.com/waheedi/contacts/tree/master"&gt;http://github.com/waheedi/contacts/tree/master&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/kTt4Mxuc8NA" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 24 Jun 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/kTt4Mxuc8NA/63-importez-vos-contacts-avec-le-plugin-contacts</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/63-importez-vos-contacts-avec-le-plugin-contacts</guid>
    <feedburner:origLink>http://www.frailers.net/articles/63-importez-vos-contacts-avec-le-plugin-contacts</feedburner:origLink></item>
    <item>
      <title>Babilu : I18n dans votre javascript !</title>
      <description>&lt;p&gt;Babilu est un plugin très facile à utiliser qui copie littéralement votre configuration I18n en &lt;span class="caps"&gt;JSON&lt;/span&gt; et Javascript. Cela vous permet d&amp;#8217;utiliser vos traductions côté client, et c&amp;#8217;est parfois assez pratique&amp;#8230;&lt;/p&gt; &lt;h2&gt;Etape 1 : Installer Babilu et ses dépendances&lt;/h2&gt;
&lt;p&gt;Babilu a besoin de &lt;a href="http://github.com/toretore/lucy"&gt;Lucy&lt;/a&gt; pour fonctionner.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;plugin install git&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;github.&lt;span class="Entity"&gt;com&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;toretore&lt;span class="Keyword"&gt;/&lt;/span&gt;lucy.&lt;span class="Entity"&gt;git&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;plugin install git&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;github.&lt;span class="Entity"&gt;com&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;toretore&lt;span class="Keyword"&gt;/&lt;/span&gt;babilu.git
&lt;/pre&gt;
&lt;h2&gt;Etape 2 : Ajouter Babilu a notre application&lt;/h2&gt;
&lt;p&gt;Il vous suffit alors simplement d&amp;#8217;ajouter&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;head&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;script type&lt;span class="Keyword"&gt;=&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;text/javascript&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; src&lt;span class="Keyword"&gt;=&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;/javascripts/locales.js&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;gt;&lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;script&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;head&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;dans l&amp;#8217;en-tête de votre layout pour charger le fichier généré. Et d&amp;#8217;utilisez directement&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Variable"&gt;I18n&lt;/span&gt;.&lt;span class="Entity"&gt;t&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;string1&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;) 
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Variable"&gt;I18n&lt;/span&gt;.&lt;span class="Entity"&gt;t&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;messages.invalid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, {scope:[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;activerecord&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;errors&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]})
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Variable"&gt;I18n&lt;/span&gt;.&lt;span class="Entity"&gt;t&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;activerecord.errors.template.header&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, {count:&lt;span class="Constant"&gt;2&lt;/span&gt;, &lt;span class="Support"&gt;model&lt;/span&gt;&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:'&lt;/span&gt;user&lt;span class="Constant"&gt;'&lt;/span&gt;&lt;/span&gt;}) 
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;   &lt;span class="String"&gt;&lt;span class="String"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;2 erreurs empêchent la sauvegarde de User&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;dans votre javascript.&lt;/p&gt;
&lt;p&gt;Et voilà !&lt;/p&gt;
&lt;p&gt;Le fichier javascript contenant les traductions est régénéré à chaque requête en développement et à chaque démarrage du serveur en production.&lt;/p&gt;
&lt;p&gt;Pour plus de détails sur babilu :&lt;br /&gt;
&lt;a href="http://github.com/toretore/babilu/tree/master"&gt;http://github.com/toretore/babilu/tree/master&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/7RnR4kwores" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 16 Jun 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/7RnR4kwores/62-babilu-i18n-dans-votre-javascript</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/62-babilu-i18n-dans-votre-javascript</guid>
    <feedburner:origLink>http://www.frailers.net/articles/62-babilu-i18n-dans-votre-javascript</feedburner:origLink></item>
    <item>
      <title>Un form_builder pour afficher les erreurs d'un champ autrement</title>
      <description>&lt;p&gt;Si vous avez déjà travaillé au développement de plusieurs applications Rails, il est possible qu&amp;#8217;un jour, vous vous soyez dit : &amp;#8220;J&amp;#8217;en ai marre de cette tartine que me génère error_messages_for&amp;#8221;.&lt;/p&gt;
&lt;p&gt;A force de bidouille par-ci par là vous êtes parvenu à un résultat qui vous convenait. Mais comment afficher les erreurs d&amp;#8217;un champ de manière élégante, par exemple, juste à côté du champ ? Le FormBuilder est votre ami !&lt;/p&gt; &lt;p&gt;On aimerait arriver à ce résultat là :&lt;br /&gt;
&lt;img src="http://www.frailers.net/uploads/email_validation.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Créons notre Builder lib/error_form_builder.rb qui étend le FormBuilder de &amp;#8216;base&amp;#8217;&lt;br /&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;ErrorFormBuilder&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; ActionView::Helpers::FormBuilder&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Dans ce builder, on va surdéfinir les helpers pour les éléments d&amp;#8217;un formulaire. Nous ne ferons le détail que pour le textfield, pour les autres éléments, il suffit de suivre le même exemple en analysant bien la structure de l&amp;#8217;objet dans le FormBuilder de base.&lt;/p&gt;
&lt;p style="errors.is_a?(Array) ? errors.first : errors;"&gt;C&amp;#8217;est partit :&lt;br /&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;text_field&lt;/span&gt;(&lt;span class="Variable"&gt;method&lt;span class="Variable"&gt;,&lt;/span&gt; options &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;{&lt;/span&gt;&lt;span class="Variable"&gt;}&lt;/span&gt;&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;       object &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;template&lt;/span&gt;.&lt;span class="Entity"&gt;instance_variable_get&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;@&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;&lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;object_name&lt;/span&gt;&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;       &lt;span class="Keyword"&gt;unless&lt;/span&gt; object.&lt;span class="Entity"&gt;nil?&lt;/span&gt; &lt;span class="Keyword"&gt;||&lt;/span&gt; options[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;hide_errors&lt;/span&gt;]
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;         errors &lt;span class="Keyword"&gt;=&lt;/span&gt; object.&lt;span class="Entity"&gt;errors&lt;/span&gt;.&lt;span class="Entity"&gt;on&lt;/span&gt;(method.&lt;span class="Entity"&gt;to_sym&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;         &lt;span class="Keyword"&gt;if&lt;/span&gt; errors
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;           text &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt; &amp;lt;span class=&lt;span class="Constant"&gt;\&amp;quot;&lt;/span&gt;error&lt;span class="Constant"&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt; &lt;span class="String"&gt;              &lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;errors&lt;span class="String"&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;is_a?&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;(&lt;/span&gt;&lt;span class="Variable"&gt;Array&lt;/span&gt;&lt;span class="String"&gt;)&lt;/span&gt; &lt;span class="Keyword"&gt;?&lt;/span&gt; errors&lt;span class="String"&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;first&lt;/span&gt;&lt;/span&gt; &lt;span class="String"&gt;:&lt;/span&gt; errors&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;&amp;lt;/span&amp;gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;         &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;       &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;       &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;template&lt;/span&gt;.&lt;span class="Entity"&gt;text_field&lt;/span&gt;(&lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;object_name&lt;/span&gt;, method, 
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt;          &lt;span class="Entity"&gt;objectify_options&lt;/span&gt;(options))&lt;span class="Keyword"&gt;+&lt;/span&gt;text.&lt;span class="Entity"&gt;to_s&lt;/span&gt;
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;La première chose que l&amp;#8217;on fait dans ce nouveau helper text_field, c&amp;#8217;est récupérer l&amp;#8217;objet. Ensuite on vérifie s&amp;#8217;il contient des erreurs relatives à la méthode que l&amp;#8217;on passe en paramètre. Et si il y a des erreurs relatives à cette méthode, on vient concaténer un bloc span contenant le premier message d&amp;#8217;erreur.&lt;/p&gt;
&lt;p&gt;Un peu de css :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; span.&lt;span class="Entity"&gt;error&lt;/span&gt; {
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   color:&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;c30;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;   float&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;left&lt;/span&gt;;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;   display&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;block&lt;/span&gt;;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;   font&lt;span class="Keyword"&gt;-&lt;/span&gt;size:&lt;span class="Constant"&gt;1.&lt;/span&gt;1em;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;   font&lt;span class="Keyword"&gt;-&lt;/span&gt;weight&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;bold&lt;/span&gt;;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;   line&lt;span class="Keyword"&gt;-&lt;/span&gt;height:14px;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;   text&lt;span class="Keyword"&gt;-&lt;/span&gt;align&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;left&lt;/span&gt;;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;   padding:0px &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; 5px;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;   width:190px;
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt; }
&lt;/pre&gt;
&lt;p&gt;Et voilà ! Une toute nouvelle manière d&amp;#8217;ajouter les erreurs dans vos formulaires, et pour pas des masses d&amp;#8217;effort ;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/ks3C-E5lf0Q" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 18 Mar 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/ks3C-E5lf0Q/60-un-form-builder-pour-afficher-les-erreurs-d-un-champ-autrement</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/60-un-form-builder-pour-afficher-les-erreurs-d-un-champ-autrement</guid>
    <feedburner:origLink>http://www.frailers.net/articles/60-un-form-builder-pour-afficher-les-erreurs-d-un-champ-autrement</feedburner:origLink></item>
    <item>
      <title>Exporter ses données dans un tableur</title>
      <description>&lt;p&gt;Il arrive souvent que l&amp;#8217;on aie besoin d&amp;#8217;exporter un ensemble d&amp;#8217;informations pour y accéder de manière plus conviviale dans un tableur.&lt;/p&gt;
&lt;p&gt;Dans cet article, je vais vous montrer deux manières d&amp;#8217;exporter un ensemble de données, ou plutôt deux formats différents pour cette exportation.&lt;/p&gt; &lt;h2&gt;Partie 1 : Exporter en csv&lt;/h2&gt;
&lt;p&gt;Le premier format qui me vient à l&amp;#8217;esprit quand on me parle de tableur, est bien évidemment le format csv (Comma Separated Values) qui, pour ceux qui ne le sauraient pas encore, sépare chaque valeur d&amp;#8217;une colonne par une virgule.&lt;/p&gt;
&lt;p&gt;La première chose à faire c&amp;#8217;est d&amp;#8217;installer la gem fastercsv.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; sudo gem install fastercsv
&lt;/pre&gt;
&lt;p&gt;Puis d&amp;#8217;installer le plugin to_csv d&amp;#8217;Ary Djmal dans votre application.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;plugin install git&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;github.&lt;span class="Entity"&gt;com&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;arydjmal&lt;span class="Keyword"&gt;/&lt;/span&gt;to_csv.git
&lt;/pre&gt;
&lt;p&gt;La suite est encore plus simple. Pas besoin de &amp;#8216;builder&amp;#8217;, il suffit, dans le bloc respond_to de l&amp;#8217;action de votre contrôleur et pour le format csv, d&amp;#8217;appeler la méthode to_csv sur votre tableau de données, elle est pas belle la vie ? :-)&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;UsersController&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; ApplicationController&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;index&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;     &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;users&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;User&lt;/span&gt;.&lt;span class="Entity"&gt;find&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;all&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;     respond_to &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;format&lt;/span&gt;|
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;       format.&lt;span class="Entity"&gt;html&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;       format.&lt;span class="Entity"&gt;csv&lt;/span&gt; { send_data &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;users&lt;/span&gt;.&lt;span class="Entity"&gt;to_csv&lt;/span&gt; }
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;     &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Il suffit alors d&amp;#8217;ajouter dans votre vue un lien du style :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;%=&lt;/span&gt; link_to &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Exporter en csv&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="Entity"&gt;formatted_users_path&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;format&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;csv&lt;/span&gt;) &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Et le tour est joué !&lt;/p&gt;
&lt;h2&gt;Partie 2 : Exporter en xls&lt;/h2&gt;
&lt;p&gt;Mais je vois déjà venir les mauvaises langues avec leurs gros sabots :&lt;/p&gt;
&lt;p&gt;&amp;#8220;Haaaa mais môôôsieur, le csv c&amp;#8217;est bien beau mais mon Excel(lent) tableur préféré ne gère pas les caractères en &lt;span class="caps"&gt;UTF&lt;/span&gt;-8 dans un csv&amp;#8221;&lt;/p&gt;
&lt;p&gt;&amp;#8220;Pas de bol&amp;#8221;, vous dirais-je, mais pas de panique Ary a pensé à vous, pauvres utilisateurs de MS Excel.&lt;/p&gt;
&lt;p&gt;Première étape, il nous faut ajouter ce nouveau type de fichier obscur dans notre initializer mime_types que vous trouverez à config/initializers/mime_types.rb&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Support"&gt;Mime&lt;/span&gt;::&lt;span class="Entity"&gt;Type&lt;/span&gt;.&lt;span class="Entity"&gt;register&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;application/vnd.ms-excel&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;xls&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Et d&amp;#8217;installer un second plugin, to_xls&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;plugin install git&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;github.&lt;span class="Entity"&gt;com&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;arydjmal&lt;span class="Keyword"&gt;/&lt;/span&gt;to_xls.git
&lt;/pre&gt;
&lt;p&gt;Ouf ! Le plus dur est fait :-)&lt;/p&gt;
&lt;p&gt;La suite est à peu de choses près exactement la même que pour to_csv, sauf qu&amp;#8217;il s&amp;#8217;agit maintenant de to_xls, donc, au risque de me répéter, elle est pas belle la vie ?&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;UsersController&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; ApplicationController&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;index&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;     &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;users&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;User&lt;/span&gt;.&lt;span class="Entity"&gt;find&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;all&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;     respond_to &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;format&lt;/span&gt;|
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;       format.&lt;span class="Entity"&gt;html&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;       format.&lt;span class="Entity"&gt;xls&lt;/span&gt; { send_data &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;users&lt;/span&gt;.&lt;span class="Entity"&gt;to_xls&lt;/span&gt; }
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;     &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Il suffit alors d&amp;#8217;ajouter un lien dans notre vue qui fait appel au bon format :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;%=&lt;/span&gt; link_to &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Exporter en xls&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="Entity"&gt;formatted_users_path&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;format&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;xls&lt;/span&gt;) &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;La méthode to_xls crée en fait un fichier &lt;span class="caps"&gt;XML&lt;/span&gt; lisible par Excel. Attention cependant, cela ne marchera que pour les versions d&amp;#8217;Excel 2003 et plus.&lt;/p&gt;
&lt;p&gt;Quelques liens de référence:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://arydjmal.com/2008/6/11/to_csv-plugin-better-excel-compatibility"&gt;to_csv plugin: Better Excel compatibility&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://arydjmal.com/2009/1/11/to_xls-plugin-export-to-excel-in-rails-the-easy-way"&gt;to_xls plugin: Export to Excel in Rails the easy way&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://arydjmal.com/2008/6/8/export-to-excel-in-rails-2"&gt;Export to Excel in Rails 2&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/qlVmgKjmKhY" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 06 Mar 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/qlVmgKjmKhY/59-exporter-ses-donne-es-dans-un-tableur</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/59-exporter-ses-donne-es-dans-un-tableur</guid>
    <feedburner:origLink>http://www.frailers.net/articles/59-exporter-ses-donne-es-dans-un-tableur</feedburner:origLink></item>
    <item>
      <title>Recherche "Full text" avec xapian</title>
      <description>&lt;p&gt;Une recherche &amp;#8220;Full text&amp;#8221; devient souvent une nécessité lorsqu&amp;#8217;on travaille sur des projets  ayant beaucoup de contenu. Différents outils permettent de réaliser ce genre de recherches avec plus ou moins d&amp;#8217;efficacité. Pour Rails, il existe bien évidement Ferret, probablement le plus connu, mais aussi Solr basé sur Lucene, Sphinx et enfin, Xapian.&lt;/p&gt;
&lt;p&gt;Je n&amp;#8217;ai pas la prétention de dire que je suis un expert en la matière mais ayant utilisé Xapian durant le dernier projet sur lequel j&amp;#8217;ai travaillé, je me suis dit qu&amp;#8217;un petit partage de connaissances s&amp;#8217;imposait. Histoire de vous donner les moyens de tester tout ça par vous-même.&lt;/p&gt; &lt;h2&gt;Etape 1 : Installer Xapian&lt;/h2&gt;
&lt;p&gt;Suivant votre OS il existe plusieurs manières d&amp;#8217;installer Xapian. Tout est expliqué sur le &lt;a href="http://www.xapian.org"&gt;site de Xapian&lt;/a&gt;. Choisissez la manière qui vous convient le mieux. Pour l&amp;#8217;exemple on partira des fichiers source !&lt;/p&gt;
&lt;p&gt;Télécharger les sources de xapian :&lt;br /&gt;
&lt;a href="http://oligarchy.co.uk/xapian/1.0.10/xapian-core-1.0.10.tar.gz"&gt;http://oligarchy.co.uk/xapian/1.0.10/xapian-core-1.0.10.tar.gz&lt;/a&gt;&lt;br /&gt;
Et les bindings qui nous permettrons de l&amp;#8217;utiliser avec Ruby :&lt;br /&gt;
&lt;a href="http://oligarchy.co.uk/xapian/1.0.10/xapian-bindings-1.0.10.tar.gz"&gt;http://oligarchy.co.uk/xapian/1.0.10/xapian-bindings-1.0.10.tar.gz&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il est bien évidement conseillé d&amp;#8217;utiliser la même version pour xapian et ses &amp;#8220;bindings&amp;#8221;.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; tar xvzf xapian&lt;span class="Keyword"&gt;-&lt;/span&gt;core&lt;span class="Keyword"&gt;-&lt;/span&gt;version.&lt;span class="Entity"&gt;tar&lt;/span&gt;.&lt;span class="Entity"&gt;gz&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; tar xvzf xapian&lt;span class="Keyword"&gt;-&lt;/span&gt;bindings&lt;span class="Keyword"&gt;-&lt;/span&gt;version.&lt;span class="Entity"&gt;tar&lt;/span&gt;.&lt;span class="Entity"&gt;gz&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; cd xapian&lt;span class="Keyword"&gt;-&lt;/span&gt;core&lt;span class="Keyword"&gt;-&lt;/span&gt;version
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; .&lt;span class="Keyword"&gt;/&lt;/span&gt;configure
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; make
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt; sudo make install
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt; cd xapian&lt;span class="Keyword"&gt;-&lt;/span&gt;bindings&lt;span class="Keyword"&gt;-&lt;/span&gt;version
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt; .&lt;span class="Keyword"&gt;/&lt;/span&gt;configure
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt; make
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt; sudo make install
&lt;/pre&gt;
&lt;h2&gt;Etape 2 : Installer acts_as_xapian&lt;/h2&gt;
&lt;p&gt;La première chose à faire est de récupérer acts_as_xapian sur github.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;plugin install git&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;github.&lt;span class="Entity"&gt;com&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;frabcus&lt;span class="Keyword"&gt;/&lt;/span&gt;acts_as_xapian.git
&lt;/pre&gt;
&lt;p&gt;Ensuite, d&amp;#8217;exécuter les migrations associées.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;generate acts_as_xapian
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; rake db&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;migrate&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Voilà, nous sommes prêts !&lt;/p&gt;
&lt;h2&gt;Etape 3 : Tous dans le bac à sable&lt;/h2&gt;
&lt;p&gt;Dans tous les modèles ou vous souhaitez utiliser une recherche &amp;#8220;Full text&amp;#8221; ajoutez la ligne suivante :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;Stuff&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; ActiveRecord:Base&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;  acts_as_xapian &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;texts&lt;/span&gt; =&amp;gt; [&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;title&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;description&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;tags&lt;/span&gt;]
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;En remplaçant, bien évidement :title, :description et :tags par les champs de votre modèle dans lesquels vous souhaitez faire la recherche.&lt;/p&gt;
&lt;p&gt;Ajoutez quelques objets en db et construisez l&amp;#8217;index de recherche en prenant soin de spécifier les modèles (séparés par un espace) pour lesquels il est nécessaire de construire cet index.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; rake xapian&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;build_index&lt;/span&gt; models&lt;span class="Keyword"&gt;=&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Stuff AutreModel1 AutreModel2&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;On peut alors tester la recherche en console :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; rake xapian&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;query&lt;/span&gt; models&lt;span class="Keyword"&gt;=&lt;/span&gt;“&lt;span class="Variable"&gt;Stuff&lt;/span&gt; &lt;span class="Variable"&gt;AutreModel1&lt;/span&gt; &lt;span class="Variable"&gt;AutreModel2&lt;/span&gt;” query&lt;span class="Keyword"&gt;=&lt;/span&gt;“test”
&lt;/pre&gt;
&lt;p&gt;Qui aura pour effet de rechercher &amp;#8220;test&amp;#8221; dans les champs renseignés dans le paramètre :texts de acts_as_xapian des trois modèles spécifiés.&lt;/p&gt;
&lt;h2&gt;Etape 4 : Et dans mon contrôleur ça donne quoi ?&lt;/h2&gt;
&lt;p&gt;C&amp;#8217;est tout simple :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;query&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;ActsAsXapian&lt;/span&gt;::&lt;span class="Entity"&gt;Search&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;([&lt;span class="Variable"&gt;Stuff&lt;/span&gt;], &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;query_params&lt;/span&gt;)
&lt;/pre&gt;
&lt;p&gt;On cherche dans le modèle Stuff avec pour paramètres de recherche @query_params (la chaîne de caractères que l&amp;#8217;on veut rechercher).&lt;/p&gt;
&lt;p&gt;Pour obtenir les résultats il suffit de faire :&lt;br /&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;results&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;query&lt;/span&gt;.results
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Attention ! @results n&amp;#8217;est pas un tableau d&amp;#8217;objets d&amp;#8217;un modèle ActiveRecord ! Pour ça, il faut repasser le tout à la moulinette :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;stuffs&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;results&lt;/span&gt;.&lt;span class="Entity"&gt;collect&lt;/span&gt;{|&lt;span class="Variable"&gt;r&lt;/span&gt;| r[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;model&lt;/span&gt;]}
&lt;/pre&gt;
&lt;p&gt;Ou pour faire simple et en une seule ligne :&lt;br /&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;stuffs&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;ActsAsXapian&lt;/span&gt;::&lt;span class="Entity"&gt;Search&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;([&lt;span class="Variable"&gt;Stuff&lt;/span&gt;], &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;query_params&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;              .&lt;span class="Entity"&gt;results&lt;/span&gt;.&lt;span class="Entity"&gt;collect&lt;/span&gt;{|&lt;span class="Variable"&gt;r&lt;/span&gt;| r[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;model&lt;/span&gt;]}
&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;Etape 5 : Et si mes données changent ?&lt;/h2&gt;
&lt;p&gt;Le seul petit problème d&amp;#8217;acts_as_xapian est qu&amp;#8217;il ne propose pas de mise à jour automatique de l&amp;#8217;index lorsqu&amp;#8217;il y a un changement dans les données. Si changement il y a, cette modification est ajoutée à la table acts_as_xapian_jobs que nous avons créée grâce à la migration de l&amp;#8217;étape 2. Et ce n&amp;#8217;est que lorsque l&amp;#8217;on exécute&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; rake xapian&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;update_index&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;que les changements sont pris en compte. Vous trouverez plus d&amp;#8217;explications en suivant le premier lien à la fin de cet article. Qu&amp;#8217;avons-nous fait dans notre dernier projet ? Une simple tâche cron, qui est appelée toutes les x minutes et qui met à jour l&amp;#8217;index. Une autre qui s&amp;#8217;exécute une fois par jour pour reconstruire complètement l&amp;#8217;index.&lt;/p&gt;
&lt;h2&gt;Etape 6 : Et maintenant ?&lt;/h2&gt;
&lt;p&gt;Plusieurs autres possibilités sont présentes dans acts_as_xapian, comme la recherche par &amp;#8216;terms&amp;#8217;, ou encore la possibilité de proposer des corrections ou des alternatives à la recherche effectuée.&lt;/p&gt;
&lt;p&gt;Notre introduction s&amp;#8217;arrête malheureusement là, mais les quelques liens suivants vous serons sûrement très utiles :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.locomotivation.com/blog/2008/07/23/simple-ruby-on-rails-full-text-search-using-xapian.html"&gt;Simple Ruby on Rails Full Text Search Using Xapian&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://xapian.org/"&gt;The Xapian project&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.locomotivation.com/blog/2008/07/15/mulling-over-our-ruby-on-rails-full-text-search-options.html"&gt;Mulling over our Ruby on Rails full text search options&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/i3PoRfltquA" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 04 Mar 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/i3PoRfltquA/58-recherche-full-text-avec-xapian</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/58-recherche-full-text-avec-xapian</guid>
    <feedburner:origLink>http://www.frailers.net/articles/58-recherche-full-text-avec-xapian</feedburner:origLink></item>
    <item>
      <title>Une application pas à pas - My Tag Cloud - épisode 3</title>
      <description>&lt;p&gt;Dans mon dernier article, nous avions passé en revue les éléments nécessaires à notre concept de &amp;#8216;tag cloud&amp;#8217;. Cette semaine, on replonge dans facebooker.&lt;/p&gt;
&lt;p&gt;Au menu, mise en place d&amp;#8217;une profile box et du &lt;em&gt;Publisher&lt;/em&gt; qui va avec.&lt;/p&gt; &lt;p&gt;A l&amp;#8217;image de Rails qui propose ActionMailer, une interface claire pour l&amp;#8217;envoi d&amp;#8217;emails, facebooker propose l&amp;#8217;interface &lt;em&gt;Publisher&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Dans ce Publisher, on peut définir des méthodes pour envoyer des notifications, des feeds, ou du contenu à une profile box.&lt;/p&gt;
&lt;p&gt;Commençons par générer notre publisher.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; script&lt;span class="Keyword"&gt;/&lt;/span&gt;generate facebook_publisher facebook
&lt;/pre&gt;
&lt;p&gt;Nous voilà maintenant avec un &lt;em&gt;Publisher&lt;/em&gt; vide et les migrations qui vont avec, migrations qui nous seront utiles lorsque nous voudrons publier des feeds.&lt;/p&gt;
&lt;p&gt;Commençons simplement par ajouter le helper de notre application à notre publisher.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;FacebookPublisher&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; Facebooker::Rails::Publisher&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   &lt;span class="Support"&gt;helper&lt;/span&gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;application&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ajoutons ensuite une méthode profile_update.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;profile_update&lt;/span&gt;(&lt;span class="Variable"&gt;user&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;  send_as &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;profile&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;  recipients user
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;  profile &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Testing...&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Il suffit alors d&amp;#8217;aller ajouter la ligne suivante dans le bas du layout de l&amp;#8217;application&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;%=&lt;/span&gt; fb_add_profile_section &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Qui a pour effet d&amp;#8217;ajouter un bouton &amp;#8216;Add to profile&amp;#8217;. Lorsqu&amp;#8217;on clique dessus, on voit apparaître une boîte de dialogue nous demandant notre accord.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://frailers.net/uploads/fb3x2.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Et voilà ce que ça donne dans l&amp;#8217;onglet &amp;#8216;Boîtes&amp;#8217; !&lt;/p&gt;
&lt;p&gt;&lt;img src="http://frailers.net/uploads/fb3x1.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Comme vous le savez peut-être déjà, une profile box peut se placer à plusieurs endroits et avoir plusieurs tailles. Un onglet &amp;#8216;Boîtes&amp;#8217; a été ajouté dans le nouveau profil, qui permet de stocker des &amp;#8216;profile boxes&amp;#8217; de deux largeurs, 380 pixels pour les larges et 180 pixels pour les petites.&lt;/p&gt;
&lt;p&gt;Mais cette boîte peut aussi être ajoutée à votre wall. La taille est, ici, encore différente, 250 pixels de hauteur maximum, la largeur étant également de 180 pixels.&lt;/p&gt;
&lt;p&gt;Les tags &lt;span class="caps"&gt;FBML&lt;/span&gt; suivants permettent de définir un contenu spécifique pour chaque largeur.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;fb&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;wide&lt;/span&gt;&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;fb&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;narrow&lt;/span&gt;&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Dans notre exemple, nous ne différencierons pas les différentes tailles, étant donné que ce que nous devons afficher prend peu de place&amp;#8230;&lt;/p&gt;
&lt;p&gt;Nous pourrions définir le contenu de notre profile box directement après le mot clé &amp;#8220;profile&amp;#8221; dans notre méthode profile_update, mais un partiel semble plus approprié.&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;profile_update&lt;/span&gt;(&lt;span class="Variable"&gt;user&lt;/span&gt;)
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;  send_as &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;profile&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;  recipients user
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;  &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;friend&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Friend&lt;/span&gt;.&lt;span class="Entity"&gt;find_by_facebook_id&lt;/span&gt; user.&lt;span class="Entity"&gt;id&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;  profile &lt;span class="Support"&gt;render&lt;/span&gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;partial&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;profile.fbml.erb&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;locals&lt;/span&gt; =&amp;gt; {&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;user&lt;/span&gt; =&amp;gt; &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;friend&lt;/span&gt;}
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Nous envoyons au partiel les informations concernant l&amp;#8217;utilisateur. De cette manière on pourra récupérer les tags dudit utilisateur dans le partiel.&lt;/p&gt;
&lt;p&gt;Dans le dossier apps/views/facebook_publisher/ fraîchement créé, nous ajoutons notre partiel _profile.fbml.erb :&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt; &lt;span class="Keyword"&gt;if&lt;/span&gt; user.&lt;span class="Entity"&gt;tag_list&lt;/span&gt;.&lt;span class="Entity"&gt;empty?&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; &lt;span class="String"&gt; &amp;lt;p&lt;span class="String"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Variable"&gt;No&lt;/span&gt; tags yet...&lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;p&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt; &lt;span class="Keyword"&gt;else&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; &lt;span class="String"&gt; &amp;lt;% tag_cloud user.tag_counts(:order =&lt;span class="String"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;name&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;), 
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;     &lt;span class="String"&gt;&lt;span class="String"&gt;%w(&lt;/span&gt;css1 css2 css3 css4&lt;span class="String"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;tag&lt;/span&gt;, &lt;span class="Variable"&gt;css_class&lt;/span&gt;| &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; &lt;span class="String"&gt;  &amp;lt;span class=&amp;lt;%= css_class %&lt;span class="String"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;gt;&lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;%=&lt;/span&gt; tag.&lt;span class="Entity"&gt;name&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&amp;lt;/span&lt;span class="String"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;  &lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt; &lt;span class="String"&gt;&amp;lt;% end %&lt;span class="String"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Les pages de profils sont mises en cache par les serveurs de Facebook, il est donc nécessaire de forcer la mise à jour de contenu dans une profile box, d&amp;#8217;où l&amp;#8217;importance du &lt;em&gt;Publisher&lt;/em&gt;. Nous devons donc, à un instant dans le processus d&amp;#8217;utilisation de notre application, faire un &amp;#8220;push&amp;#8221; du contenu.&lt;/p&gt;
&lt;p&gt;Il suffit alors de faire l&amp;#8217;appel suivant lorsque quelqu&amp;#8217;un vous a taggé ou lorsque vous taggez quelqu&amp;#8217;un, en prenant soin bien sûr de donner en paramètre le bon utilisateur. Pour les besoins de l&amp;#8217;article et pour voir un résultat directement nous allons placer cet appel dans notre contrôleur Friends, dans l&amp;#8217;action show par exemple. Je rappelle que ce n&amp;#8217;est que pour les besoins de cet article, dans ce cas la profile box ne sera mise à jour que lorsque l&amp;#8217;utilisateur consultera son tag cloud dans l&amp;#8217;application, ce qui n&amp;#8217;a pas grand intérêt&amp;#8230;&lt;/p&gt;
&lt;pre class="blackboard"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Support"&gt;FacebookPublisher&lt;/span&gt;.&lt;span class="Entity"&gt;deliver_profile_update&lt;/span&gt;(&lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;facebook_session&lt;/span&gt;.&lt;span class="Entity"&gt;user&lt;/span&gt;)
&lt;/pre&gt;
&lt;p&gt;Ce qui donne sur notre profil :&lt;/p&gt;
&lt;p&gt;&lt;img src="http://frailers.net/uploads/fb3x3.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Et voilà le travail ! Dans le prochain article, nous nous attarderons sur les feeds.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/rr-nY61hzEc" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 05 Feb 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/rr-nY61hzEc/57-une-application-pas-a-pas-my-tag-cloud-e-pisode-3</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/57-une-application-pas-a-pas-my-tag-cloud-e-pisode-3</guid>
    <feedburner:origLink>http://www.frailers.net/articles/57-une-application-pas-a-pas-my-tag-cloud-e-pisode-3</feedburner:origLink></item>
    <item>
      <title>Frailers.net passe à l'open source!</title>
      <description>&lt;p&gt;Après un an et demi d&amp;#8217;activité sur Frailers.net, nous avons décidé de rendre son code source publiquement disponible sur GitHub. Nous en avons profité pour le remettre un peu au goût du jour. Vous trouverez tout ici:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://github.com/belighted/frailers"&gt;http://github.com/belighted/frailers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Comme mentionné dans le &lt;span class="caps"&gt;README&lt;/span&gt;, quelques points forts du code:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;basé sur Rails 2.3&lt;/li&gt;
	&lt;li&gt;utilisation du framework i18n de Rails pour le français&lt;/li&gt;
	&lt;li&gt;mise en évidence de la syntaxe dans le blog (via ultraviolet/oniguruma)&lt;/li&gt;
	&lt;li&gt;100% RESTful&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nous espérons que cela permettra aux débutants (et aux autres!) de voir comment fonctionne une application &amp;#8220;réelle&amp;#8221;, sachant que nous allons continuer à mettre le code à jour au fur et à mesure que de nouvelles fonctionnalités (et bugs ;-)) apparaîtront.&lt;/p&gt;
&lt;p&gt;N&amp;#8217;hésitez bien entendu pas à télécharger et commenter le code. Bon amusement!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/b5MYW_gCtTg" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 03 Feb 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/b5MYW_gCtTg/55-frailers-net-passe-a-l-open-source</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/55-frailers-net-passe-a-l-open-source</guid>
    <feedburner:origLink>http://www.frailers.net/articles/55-frailers-net-passe-a-l-open-source</feedburner:origLink></item>
    <item>
      <title>Ruby on Rails Dev Room au FOSDEM '09 ce dimanche</title>
      <description>&lt;p&gt;Ce week-end se tiendra à Bruxelles le célèbre &lt;a href="http://www.fosdem.org"&gt;&lt;span class="caps"&gt;FOSDEM&lt;/span&gt;&lt;/a&gt; (Free and Open Source Software Developers&amp;#8217; European Meeting), un ensemble de conférences organisées chaque année autour du logiciel libre.&lt;/p&gt;
&lt;p&gt;Comme l&amp;#8217;an passé, une des &amp;#8220;developer rooms&amp;#8221; est consacrée le dimanche à &lt;a href="http://fosdem.org/2009/schedule/devrooms/rubyandrails"&gt;Ruby on Rails&lt;/a&gt; et vos dévoués serviteurs y auront d&amp;#8217;ailleurs l&amp;#8217;occasion de faire 2 présentations (en english):&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Jean-Baptiste, à 14h45, sur le thème &lt;a href="http://fosdem.org/2009/schedule/events/ror_ruby_and_java"&gt;Ruby and Java: What are the differences?&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Nicolas, à 15h30, sur le thème &lt;a href="http://fosdem.org/2009/schedule/events/ror_i18n_rails_2_2"&gt;Internationalization in Rails 2.2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour la liste complète des présentations, reportez vous à la &lt;a href="http://fosdem.org/2009/schedule/devrooms/rubyandrails"&gt;page officielle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Si vous comptez y être présent, n&amp;#8217;hésitez pas à le signaler via Frailers sur notre page liée à l&amp;#8217;événement: &lt;a href="http://frailers.net/events/5-fosdem-09-ror-devroom"&gt;&lt;span class="caps"&gt;FOSDEM&lt;/span&gt; &amp;#8217;09 &amp;#8211; RoR DevRoom&lt;/a&gt; &amp;#8230; et bien sûr, passez nous dire bonjour!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FrailersArticles/~4/oefHyKObjUw" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 03 Feb 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/FrailersArticles/~3/oefHyKObjUw/56-ruby-on-rails-dev-room-au-fosdem-09-ce-dimanche</link>
      <guid isPermaLink="false">http://www.frailers.net/articles/56-ruby-on-rails-dev-room-au-fosdem-09-ce-dimanche</guid>
    <feedburner:origLink>http://www.frailers.net/articles/56-ruby-on-rails-dev-room-au-fosdem-09-ce-dimanche</feedburner:origLink></item>
  </channel>
</rss>
