<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Vicent Gozalbes [Weblog] - Home</title>
  <id>tag:www.vicentgozalbes.com,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://www.vicentgozalbes.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.vicentgozalbes.com/" rel="alternate" type="text/html"/>
  <updated>2008-05-14T15:11:49Z</updated>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-05-14:2590</id>
    <published>2008-05-14T15:04:00Z</published>
    <updated>2008-05-14T15:11:49Z</updated>
    <category term="Rails"/>
    <category term="rails"/>
    <link href="http://www.vicentgozalbes.com/2008/5/14/rails-2-1-0" rel="alternate" type="text/html"/>
    <title>rails 2.1.0</title>
<content type="html">
            En los próximos artículos voy a comentar las novedades de Rails que más me han impresionado de su última versión 2.1.0 y que próximamente será estable, por ejemplo:

&lt;pre&gt;
vicent_route = User.find_by_name('vicent').routes.find(:first)
pepe_route = vicent_route.clone
&lt;/pre&gt;

Y eso también se podría abreviar como:

&lt;pre&gt;
vicent_route = User.find_by_name('vicent').routes.first (ó last)
pepe = vicent_route.clone
&lt;/pre&gt;

¡Bonito de verdad!
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-04-14:80</id>
    <published>2008-04-14T08:13:00Z</published>
    <updated>2008-04-14T14:53:31Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/4/14/passenger-rails-apache-made-easy" rel="alternate" type="text/html"/>
    <title>Passenger, Rails + Apache made easy</title>
<content type="html">
            &lt;p&gt;Needless to say, you only have to view the screencast of the new &lt;a href=&quot;http://www.modrails.com&quot;&gt;Passenger&lt;/a&gt;. I’m sure that you will cry ;)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-04-09:79</id>
    <published>2008-04-09T18:17:00Z</published>
    <updated>2008-04-16T07:02:26Z</updated>
    <category term="Proyectos"/>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/4/9/erun-new-design" rel="alternate" type="text/html"/>
    <title>eRun, new design</title>
<content type="html">
            &lt;p&gt;I&#8217;m currently working hard to launch officially my new project eRun &#8211; &lt;a href=&quot;http://www.mientrenamiento.com&quot;&gt;mientrenamiento.com&lt;/a&gt;. For new people, eRun is an online community of Runners. Using this tool, you will be able to manage and share your diary trainings, and handle the kilometers made with each of your pair of running shoes. Here you are some of the new views:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://farm3.static.flickr.com/2318/2400769123_71a92a0224.jpg?v=0&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2318/2400769123_71a92a0224_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://farm4.static.flickr.com/3096/2400768609_6b9a460dbd.jpg?v=0&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3096/2400768609_6b9a460dbd_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://farm3.static.flickr.com/2169/2400763789_bc9d91c1fa.jpg?v=0&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2169/2400763789_bc9d91c1fa_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-04-04:78</id>
    <published>2008-04-04T08:08:00Z</published>
    <updated>2008-04-16T07:02:22Z</updated>
    <category term="Debian"/>
    <link href="http://www.vicentgozalbes.com/2008/4/4/setting-up-a-samba-server-in-few-steps" rel="alternate" type="text/html"/>
    <title>Setting up a Samba Server in few steps</title>
<content type="html">
            &lt;p&gt;I will try to explain here the work we have done for implementing a linux-samba server with several users and folder privileges, of course, for server issues, we are going to use Debian distribution.&lt;/p&gt;


	&lt;p&gt;First at all, we need to install the samba packages as follow:&lt;/p&gt;


&lt;pre&gt;
boxroom:# apt-get install samba samba-common
&lt;/pre&gt;

	&lt;p&gt;The next step is creating the users:&lt;/p&gt;


&lt;pre&gt;
boxroom:# useradd -s /usr/sbin/nologin pini
boxroom:# smbpasswd -a pini
boxroom:# useradd -s /usr/sbin/nologin pon
boxroom:# smbpasswd -a pon
&lt;/pre&gt;

	&lt;p&gt;And the groups, for example:&lt;/p&gt;


&lt;pre&gt;
boxroom:# groupadd cartoons
&lt;/pre&gt;

	&lt;p&gt;The group cartoons will include both users:&lt;/p&gt;


&lt;pre&gt;
boxroom:# usermod -a -G cartoons pini
boxroom:# usermod -a -G cartoons pon
&lt;/pre&gt;

	&lt;p&gt;Now, we need to share one folder, in my case the /intranet one:&lt;/p&gt;


&lt;pre&gt;
boxroom:# chmod 775 /intranet
&lt;/pre&gt;

	&lt;p&gt;And finally we edit the /etc/samba/smb.conf:&lt;/p&gt;


&lt;pre&gt;
[global]
   workgroup = factory
   server string = Intranet

 # In my case I have a WINS Server in my network, so I use it, why not…
   wins support = no
   wins server = 192.168.100.2

####### Authentication #######
   security = user
   encrypt passwords = true
   invalid users = root

[Intranet]
   comment = Intranet
   path = /intranet
   guest ok = no
   browseable = yes
   writable = yes
   create mask = 6770
   directory mask = 6770
&lt;/pre&gt;

	&lt;p&gt;Now, we are going to create three folders for showing you how the permissions work:&lt;/p&gt;


&lt;pre&gt;
boxroom:# cd /intranet
warehouse:/intranet# mkdir fpini
warehouse:/intranet# mkdir fpon
warehouse:/intranet# mkdir public
&lt;/pre&gt;

	&lt;p&gt;And we set the permissions:&lt;/p&gt;


&lt;pre&gt;
warehouse:/intranet# chmod –R 6770 fpini fpon
warehouse:/intranet# chown pini:pini fpini
warehouse:/intranet# chown pon:pon fpon
warehouse:/intranet# chmod –R 6775 public
warehouse:/intranet# chown -R pini:cartoons public
&lt;/pre&gt;

	&lt;p&gt;In this case, Pini can access to fpini and public folders and Pon to fpon and public. Also, Pini can’t write in Pon folder and vice versa. In the case of plublic folder, all the users can see it, but only Pini or the users that belongs to cartoons group can write or delete files.&lt;/p&gt;


	&lt;p&gt;So that’s all, I hope you have enough information for setting your own intranet,
bye.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-03-21:50</id>
    <published>2008-03-21T18:17:00Z</published>
    <updated>2008-04-16T07:02:16Z</updated>
    <category term="Proyectos"/>
    <link href="http://www.vicentgozalbes.com/2008/3/21/men-u-horizontal-al-estilo-flickr-o-facebook" rel="alternate" type="text/html"/>
    <title>Men&#250; horizontal al estilo Flickr o Facebook</title>
<content type="html">
            &lt;p&gt;I write my own similar Facebook horizontal menu using &lt;a href=&quot;http://en.wikipedia.org/wiki/Document_Object_Model&quot;&gt;&lt;span class=&quot;caps&quot;&gt;DOM&lt;/span&gt;&lt;/a&gt; (Document Object Model). The advantage of &lt;span class=&quot;caps&quot;&gt;DOM&lt;/span&gt; is that the menu doesn&#8217;t depend of any external library such as jQuery or Scriptaculous. You can download the code pressing &lt;a href=&quot;http://rapidshare.com/files/102845482/menu.zip&quot;&gt;here&lt;/a&gt;. If you found any incompatibility, please let me know.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.vicentgozalbes.com/images/files/menu.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


&lt;pre&gt;
// fMenu v1.0.2
// By Vicent Gozalbes [vigosan@gmail.com]

var imgs = [];

function init() {
  if (!document.getElementsByTagName || !document.getElementById) { return; }
  var uls = document.getElementsByTagName('ul');

  for (var u=0; u &amp;lt; uls.length; u++) {
    if (uls[u].className.search(/\bmenu\b/) == -1) { continue; }
    var lis = uls[u].getElementsByTagName('li')
    for (var l=0; l &amp;lt; lis.length; l++) {
      var spans = lis[l].getElementsByTagName('span');
      for (var s=0; s &amp;lt; spans.length; s++) {
        var node = spans[s];
        if(node.className == 'head_menu' &#38;&#38; lis[l].getElementsByTagName('ul').length &amp;gt; 0) {
          var image = node.childNodes[1];
          addEvent(image, 'mouseover', getMoverFor(image), false);
          addEvent(image, 'mouseout', getMoutFor(image), false);
          addEvent(image, 'click', getMclickFor(image), false);
          addEvent(document, 'click', getMclickFor(document), false);
          image.topul = lis[l].getElementsByTagName('ul')[0];
          image.topul.isOpen = false;
          imgs.push(image);
        }
      }
    }
  }
}

function addEvent(elm, evType, fn, useCapture) {
  if(elm.addEventListener) {
    elm.addEventListener(evType, fn, useCapture);
    return true;
  } else if (elm.attachEvent) {
    var r = elm.attachEvent('on' + evType, fn);
    return r;
  } else {
    elm['on' + evType] = fn;
  }
}

function stopEvent(e) {
  if(!e) var e = window.event;

  //e.cancelBubble is supported by IE 
  e.cancelBubble = true;

  //e.stopPropagation works only in Firefox.
  if (e.stopPropagation) {
    e.stopPropagation();
    }
  return false;
}

function closeUls() {        
  for (var i = 0; i &amp;lt; imgs.length; i++) {
    imgs[i].topul.style.display = 'none';
    imgs[i].src = 'images/arrow.png';
    imgs[i].topul.isOpen = false;
  }
}

function setMover(e, targetElement) {
  var el = window.event ? targetElement : e ? e.currentTarget : null;
  if (!el) return;
  el.src = 'images/arrow_hover.png';
}

function setMout(e, targetElement) {
  var el = window.event ? targetElement : e ? e.currentTarget : null;
  if (!el) return;
  el.src = el.topul.isOpen ? 'images/arrow_select.png' : 'images/arrow.png';
}

function setMclick(e, targetElement) {
  stopEvent(e);
   var el = window.event ? targetElement : e ? e.currentTarget : null;
  if (!el) return;

  if(el.nodeName.toLowerCase() != 'img' &#38;&#38; !el.topul) {
    closeUls();
    return;
  } else if (el.topul.isOpen) {
    el.src = 'images/arrow.png';
    el.topul.style.display = 'none';
    el.topul.isOpen = false;
  } else {
    closeUls();
    el.src = 'images/arrow_select.png';
    el.topul.style.display = 'block';
    el.topul.isOpen = true;
  }
}

function getMoverFor(node) {
  return function(e) { setMover(e, node); };
}

function getMoutFor(node) {
  return function(e) { setMout(e, node); };
}

function getMclickFor(node) {
  return function(e) { setMclick(e, node); };
}

addEvent(window, 'load', init, false);
&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:21</id>
    <published>2008-02-25T11:28:00Z</published>
    <updated>2008-04-16T07:02:02Z</updated>
    <category term="Proyectos"/>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/erun-mi-nuevo-proyecto-rails" rel="alternate" type="text/html"/>
    <title>eRun, mi nuevo proyecto Rails</title>
<content type="html">
            &lt;p&gt;Últimamente ando un poco desaparecido, pero la realidad es que estoy liado con un proyecto bastante interesante, se llama &lt;a href=&quot;http://www.mientrenamiento.com&quot;&gt;eRun&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;¿Qué es eRun?&lt;/h3&gt;


	&lt;p&gt;eRun es una herramienta Web gratuita, que te permite registrar tus entrenamientos diarios de atletismo, así como llevar un control de los kilómetros realizados con cada par de tus zapatillas.&lt;/p&gt;


	&lt;h3&gt;Funcionalidad&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;Registrar entrenamientos, indicando el tipo de entrenamiento, distancia recorrida, sensaciones, ppm, calorías, zapatillas utilizadas, etc.&lt;/li&gt;
		&lt;li&gt;Registrar zapatillas, modelos, precio, etc. La aplicación llevará la suma del kilometraje realizado y aconsejará su cambio.&lt;/li&gt;
		&lt;li&gt;Gráficas semanales, mensuales de km, ppm, distancias etc.&lt;/li&gt;
		&lt;li&gt;“Amigos” con los que compartir la información de nuestros entrenamientos y con los que poder compararnos y competir.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;La funcionalidad de mañana&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;Crear y compartir planes de entrenamiento.&lt;/li&gt;
		&lt;li&gt;Gestión de carreras. Puedes anunciar una carrera que estás organizando y si participas en alguna darla de alta como un entrenamiento con puesto. ¡Y a ver quien ha llegado antes de tu grupo de amigos!&lt;/li&gt;
		&lt;li&gt;OpenId para hacer más sencilla la validación, así no es necesario tener que recordar tantos usuarios y contraseñas.&lt;/li&gt;
		&lt;li&gt;El log como un pequeño twitter para compartir tus comentarios sobre tus entrenamientos con tus amigos y contigo mismo.&lt;/li&gt;
		&lt;li&gt;Retos, será la parte más divertida, por ejemplo ver quien corre más km en una semana, o quien hace una marathon en menos de 3h45 etc.&lt;/li&gt;
		&lt;li&gt;Compra de zapatillas con recomendación por parte de la aplicación en base a a tu peso, tipo de pisada, distancias medias recorrida.&lt;/li&gt;
		&lt;li&gt;Entrenador personal (cualificado) y planes de entrenamiento a medida (previo pago al entrenador).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Características diferenciadoras&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;Creado por corredores para corredores&lt;/li&gt;
		&lt;li&gt;Proyecto dinámico. Realease early / release often. Una funcionalidad nueva por semana.&lt;/li&gt;
		&lt;li&gt;Total atención a las necesidades / peticiones de los usuarios&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:20</id>
    <published>2008-02-25T11:25:00Z</published>
    <updated>2008-04-16T07:01:56Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/rails-2-0-y-como-enviar-correos-a-trav-es-de-gmail" rel="alternate" type="text/html"/>
    <title>Rails 2.0 y como enviar correos a trav&#233;s de Gmail</title>
<content type="html">
            &lt;p&gt;Aquípongo un receta rápida de como enviar correos a través de Gmail.&lt;/p&gt;


	&lt;p&gt;Primero en el directorio /lib creamos un fichero llamado smtp_tls.rb que contenga:&lt;/p&gt;


&lt;pre&gt;
require 'openssl'
require 'net/smtp'

Net::SMTP.class_eval do
  private
  def do_start(helodomain, user, secret, authtype)
    raise IOError, 'SMTP session already started' if @started
    check_auth_args user, secret, authtype if user or secret

    sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
    @socket = Net::InternetMessageIO.new(sock)
    @socket.read_timeout = 60 #@read_timeout

    check_response(critical { recv_response() })
    do_helo(helodomain)

    raise 'openssl library not installed' unless defined?(OpenSSL)
    starttls
    ssl = OpenSSL::SSL::SSLSocket.new(sock)
    ssl.sync_close = true
    ssl.connect
    @socket = Net::InternetMessageIO.new(ssl)
    @socket.read_timeout = 60 #@read_timeout
    do_helo(helodomain)

    authenticate user, secret, authtype if user
    @started = true
  ensure
    unless @started
      # authentication failed, cancel connection.
      @socket.close if not @started and @socket and not @socket.closed?
      @socket = nil
    end
  end

  def do_helo(helodomain)
    begin
      if @esmtp
        ehlo helodomain
      else
        helo helodomain
      end
    rescue Net::ProtocolError
      if @esmtp
        @esmtp = false
        @error_occured = false
        retry
      end
      raise
    end
  end

  def starttls
    getok('STARTTLS')
  end

  def quit
    begin
      getok('QUIT')
    rescue EOFError
    end
  end
end
&lt;/pre&gt; 

	&lt;p&gt;Al final del fichero config/environment.rb añadimos:&lt;/p&gt;


&lt;pre&gt;
require 'lib/smtp_tls'

yaml_contents = File.open(&quot;#{RAILS_ROOT}/config/mailer.yml&quot;) 
mailer_options = YAML.load(yaml_contents) 
ActionMailer::Base.smtp_settings = mailer_options 
&lt;/pre&gt;

	&lt;p&gt;Y por último la configuración de la cuenta en config/mailer.yml:&lt;/p&gt;


&lt;pre&gt;
:address: &quot;smtp.gmail.com&quot; 
:port: 587 
:domain: &quot;tudominio.com&quot; 
:user_name: &quot;usuario@gmail.com&quot; 
:password: &quot;contraseña&quot; 
:authentication: :plain 
&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:19</id>
    <published>2008-02-25T11:24:00Z</published>
    <updated>2008-04-16T07:01:49Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/men-us-din-amicos" rel="alternate" type="text/html"/>
    <title>Men&#250;s din&#225;micos</title>
<content type="html">
            &lt;p&gt;No se si el título refleja exactamente lo que pretendo hacer, pero de lo que se trata es de ayudarnos de algún helper para tener nuestro propio constructor de menús; voy a comentaros mi idea y si alguien tiene alguna mejor que la comente.&lt;/p&gt;


	&lt;p&gt;Primero en application.rb he defino la estructura que tendrá el menú, utilizando arrays, y en los que indico el nombre del enlace y la url. Además, mostrará un menú diferente dependiendo si el usuario está validado o no.&lt;/p&gt;


&lt;pre&gt;
# application.rb
  helper_method navigation_links

  def navigation_links
    if logged_in?
      return [
        [ &quot;Logout&quot;, &quot;#{logout_path}&quot; ]
      ]
    else
      return [
        [ &quot;Home&quot;, &quot;#{root_path}&quot; ],
        [ &quot;Log in&quot;, &quot;#{login_path}&quot; ],
        [ &quot;Signup&quot;, &quot;#{signup_path}&quot; ]
      ]
    end
  end
&lt;/pre&gt; 

	&lt;p&gt;Ahora application_helper.rb escribo las funciones que generarán el menú:&lt;/p&gt;


&lt;pre&gt;
  def link_for(label, path = {})
    if controller.controller_name == path.split(&quot;/&quot;).last
      content_tag :li, link_to(label, path, { &quot;class&quot;=&amp;gt; &quot;current&quot; })
    else
      content_tag :li, link_to(label, path)
    end
  end

  def links_for_navigation(options = {})
    class_name = options[:class] || &quot;navigation_links&quot; 
    code = &quot;&amp;lt;ul class=\&quot;#{class_name}\&quot;&amp;gt;\n&quot; 
    links = []
    navigation_links.each do |label, path|
      links.push link_for(label, path)
    end
    code &amp;lt;&amp;lt; links.join(separator)
    code &amp;lt;&amp;lt; &quot;&amp;lt;/ul&amp;gt;&quot; 
  end

  def separator
    # quitar comentario si quieres añadir un separador
    # %{ &amp;lt;span class=&quot;separator&quot;&amp;gt; | &amp;lt;/span&amp;gt; }
  end
&lt;/pre&gt; 

	&lt;p&gt;Y en la vista:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;div id=&quot;sidebar&quot;&amp;gt;
  &amp;lt;%= links_for_navigation %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt; 

	&lt;p&gt;Lo dicho, si alguien tiene una idea mejor, que no dude en compartirla.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:18</id>
    <published>2008-02-25T11:23:00Z</published>
    <updated>2008-04-16T07:01:43Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/paginaci-on-acts_as_taggable_on_steroids-will_paginate" rel="alternate" type="text/html"/>
    <title>Paginaci&#243;n acts_as_taggable_on_steroids + will_paginate</title>
<content type="html">
            &lt;p&gt;En un proyecto, estamos usando un par de plugins bastante conocidos, uno es &lt;a href=&quot;http://errtheblog.com/post/4791&quot;&gt;will_paginate&lt;/a&gt; y el otro &lt;a href=&quot;http://agilewebdevelopment.com/plugins/acts_as_taggable_on_steroids&quot;&gt;acts_as_taggable_on_steroids&lt;/a&gt;. Para ponernos en ejemplo, queremos obtener una lista de artículos paginados de 10 en 10, lo podemos hacer con:&lt;/p&gt;


&lt;pre&gt;
@articles = Article.paginate(:all, :per_page =&amp;gt; 10, :page =&amp;gt; params[:page])
&lt;/pre&gt;

	&lt;p&gt;Por otra parte, podemos marcar nuestros artículos con una o varias etiquetas, tags:&lt;/p&gt;


&lt;pre&gt;
  # modelo
  class Article &amp;lt; ActiveRecord::Base
    acts_as_taggable
    validates_presence_of :title, :body
  end

  # controlador
  def create
    @article = Article.new(params[:article])
    @article.tag_list = params[:tag_list]
    respond_to do |format|
      if @article.save
        flash[:notice] = 'Article was successfully created.'
        format.html { redirect_to article_url(@article) }
      else
        format.html { render :action =&amp;gt; &quot;new&quot; }
      end
    end
  end

  # formulario
  &amp;lt;p&amp;gt;
    &amp;lt;b&amp;gt;Title&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :title %&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;
    &amp;lt;b&amp;gt;Body&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_area :body %&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;
    &amp;lt;b&amp;gt;&amp;lt;%= _(&quot;Tags&quot;) %&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= text_field_tag :tag_list, @article.tags.collect{|t| t.name}.join(&quot; &quot;)  %&amp;gt;
  &amp;lt;/p&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Y en la vista mostrar una nube de etiquetas o tags:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;div id=&quot;sidebar&quot;&amp;gt;
  &amp;lt;h2&amp;gt;Tags&amp;lt;/h2&amp;gt;
  &amp;lt;% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %&amp;gt;
  &amp;lt;%= link_to tag.name, { :action =&amp;gt; :tag, :id =&amp;gt; tag.name }, :class =&amp;gt; css_class %&amp;gt;
   &amp;lt;% end %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Y lo que pretendemos es que cuando se pulse en una de las etiquetas, se muestren sólo los artículos perteneciente a ellas. Aquí es donde combinamos los dos plugins:&lt;/p&gt;


&lt;pre&gt;
# controlador
  def tag
    @articles = Article.paginate_by_id(Article.find_tagged_with(params[:id]), :page =&amp;gt; params[:page])
    respond_to do |format|
      format.html { render :action =&amp;gt; :index }
      format.xml  { render :xml =&amp;gt; @articles.to_xml }
    end
  end
&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:17</id>
    <published>2008-02-25T11:22:00Z</published>
    <updated>2008-04-16T07:01:36Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/calcular-fechas-pasadas-futuras-con-rails" rel="alternate" type="text/html"/>
    <title>Calcular fechas pasadas/futuras con Rails</title>
<content type="html">
            &lt;p&gt;A raiz de ciertos posts que he leido en el foro de &lt;a href=&quot;http://www.ruby-forum.com/forum/22&quot;&gt;Rails-es&lt;/a&gt; sobre como calcular fechas pasadas o futuras, aquí dejo un pequeño ejemplo.&lt;/p&gt;


&lt;pre&gt;
irb(main):001:0&amp;gt; require 'date'
=&amp;gt; true
irb(main):002:0&amp;gt; today = Date.today
=&amp;gt; #&amp;lt;Date: 4908771/2,0,2299161&amp;gt;
irb(main):003:0&amp;gt; today.to_s
=&amp;gt; &quot;2007-10-12&quot; 
irb(main):004:0&amp;gt; tomorrow = today+1
=&amp;gt; #&amp;lt;Date: 4908773/2,0,2299161&amp;gt;
irb(main):005:0&amp;gt; tomorrow.to_s     
=&amp;gt; &quot;2007-10-13&quot; 
irb(main):006:0&amp;gt; yesterday = today-1
=&amp;gt; #&amp;lt;Date: 4908769/2,0,2299161&amp;gt;
irb(main):007:0&amp;gt; yesterday.to_s
=&amp;gt; &quot;2007-10-11&quot; 
irb(main):008:0&amp;gt; nextmonth = today&amp;gt;&amp;gt;1
=&amp;gt; #&amp;lt;Date: 4908833/2,0,2299161&amp;gt;
irb(main):009:0&amp;gt; nextmonth.to_s      
=&amp;gt; &quot;2007-11-12&quot; 
irb(main):010:0&amp;gt; lastmonth = today&amp;lt;&amp;lt;1
=&amp;gt; #&amp;lt;Date: 4908711/2,0,2299161&amp;gt;
irb(main):011:0&amp;gt; lastmonth.to_s      
=&amp;gt; &quot;2007-09-12&quot; 
irb(main):012:0&amp;gt; lastmonth.strftime('%B %Y')
=&amp;gt; &quot;September 2007&quot; 
irb(main):013:0&amp;gt; lastmonth.strftime('%A %B %Y')
=&amp;gt; &quot;Wednesday September 2007&quot; 
irb(main):014:0&amp;gt; lastmonth.strftime('%a %b %y')
=&amp;gt; &quot;Wed Sep 07&quot; 
&lt;/pre&gt;

	&lt;p&gt;Como se puede comprobar:&lt;/p&gt;


	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt; +(n) &lt;/td&gt;
			&lt;td&gt; Suma n días a la fecha &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; -(n) &lt;/td&gt;
			&lt;td&gt; Resta n días a la fecha &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; &amp;gt;&amp;gt;(n) &lt;/td&gt;
			&lt;td&gt; Suma n meses a la fecha &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; &amp;lt;&amp;lt;(n) &lt;/td&gt;
			&lt;td&gt; Resta n meses a la fecha &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:16</id>
    <published>2008-02-25T11:22:00Z</published>
    <updated>2008-04-16T07:01:31Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/openticket-auto_complete_for" rel="alternate" type="text/html"/>
    <title>Openticket, auto_complete_for</title>
<content type="html">
            &lt;p&gt;Modificamos el formulario privado de añadir tickets para poder elegir un cliente, pero en vez de desplegar un select con todos ellos, veremos como utilizar auto_complete_for y como personalizar las vistas generadas.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://rapidshare.com/files/52081585/openticket_cap_12.mov&quot;&gt;Screencast 12&lt;/a&gt; [&lt;a href=&quot;http://www.vicentgozalbes.com/files/openticket/openticket_cap_12.tgz&quot;&gt;source&lt;/a&gt;]&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:15</id>
    <published>2008-02-25T11:21:00Z</published>
    <updated>2008-04-16T07:01:25Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/openticket-internacionalizaci-on-y-sindicaci-on-rss" rel="alternate" type="text/html"/>
    <title>Openticket, internacionalizaci&#243;n y sindicaci&#243;n RSS</title>
<content type="html">
            &lt;p&gt;Aquí os dejo los enlaces al screencast 11, donde:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Modificamos el formulario público para que el usuario pueda elegir el idioma en el que quiere verlo.&lt;/li&gt;
		&lt;li&gt;Modificamos el modelo Settings para subir nuestro logo o imagen corporativa. Utilizamos para ello el plugin &lt;a href=&quot;http://www.kanthak.net/opensource/file_column&quot;&gt;file_column&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Y por último, exportamos los tickets a &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; para poder leerlos desde nuestro lector de noticias preferido.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://rapidshare.com/files/51171411/openticket_cap_11.mov&quot;&gt;Screencast 11&lt;/a&gt; [&lt;a href=&quot;http://www.vicentgozalbes.com/files/openticket/openticket_cap_11.tgz&quot;&gt;source&lt;/a&gt;]&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:13</id>
    <published>2008-02-25T11:20:00Z</published>
    <updated>2008-04-16T07:01:13Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/openticket-env-io-de-emails" rel="alternate" type="text/html"/>
    <title>Openticket, env&#237;o de emails</title>
<content type="html">
            &lt;p&gt;Novena entrega de la saga. En este screencast permitimos a los usuarios subscribirse a un ticket para enviarle un email cuando este sufra un cambio.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://rapidshare.com/files/49578477/openticket_cap_9.mov&quot;&gt;Screencast 9&lt;/a&gt; [&lt;a href=&quot;http://www.vicentgozalbes.com/files/openticket/openticket_cap_9.tgz&quot;&gt;source&lt;/a&gt;], envío de emails.&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:14</id>
    <published>2008-02-25T11:20:00Z</published>
    <updated>2008-04-16T07:01:19Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/openticket-formulario-p-ublico-para-env-io-de-tickets" rel="alternate" type="text/html"/>
    <title>Openticket, formulario p&#250;blico para env&#237;o de tickets</title>
<content type="html">
            &lt;p&gt;Parece mentira, pero ya llevamos 10 screencast para realizar nuestra pequeña aplicación. Esta vez, hemos hecho un formulario público para que nuestros clientes nos envíen sus tickets. Además, personalizaremos el formulario para mostrar los errores de una forma distinta a la habitual.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://rapidshare.com/files/50575087/openticket_cap_10.mov&quot;&gt;Screencast 10&lt;/a&gt; [&lt;a href=&quot;http://www.vicentgozalbes.com/files/openticket/openticket_cap_10.tgz&quot;&gt;source&lt;/a&gt;], envío de emails.&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.vicentgozalbes.com/">
    <author>
      <name>vigosan</name>
    </author>
    <id>tag:www.vicentgozalbes.com,2008-02-25:11</id>
    <published>2008-02-25T11:19:00Z</published>
    <updated>2008-04-16T07:01:02Z</updated>
    <category term="Rails"/>
    <link href="http://www.vicentgozalbes.com/2008/2/25/openticket-impresi-on-de-tickets" rel="alternate" type="text/html"/>
    <title>Openticket, impresi&#243;n de tickets</title>
<content type="html">
            &lt;p&gt;Aquíos dejo el septimo screencast sobre Openticket. Modificamos la vista de los tickets para permitir al usuario poder imprimirlos.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://rapidshare.com/files/49712478/openticket_cap_7.mov&quot;&gt;Screencast 7&lt;/a&gt; [&lt;a href=&quot;http://www.vicentgozalbes.com/files/openticket/openticket_cap_7.tgz&quot;&gt;source&lt;/a&gt;], impresiÃ³n de tickets.&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
</feed>
