Extendiendo FormBuilder para añadir nuevos helpers personalizados

A la hora de hacer nuevos formularios en rails siempre había echado de menos algún helper que te ayudara a incluir los típicos mensajes de error junto al campo al que se refieren para contextualizar cada uno de los mensajes, en lugar de que aparezcan todos listados en la cabecera del formulario.

La idea fundamental de lo que pretendía conseguir es la siguiente: ejemplo de errores en campos de formulario

Todo esto usando para ello un helper de FormBuilder para que el objeto concreto quede implícito y que el código resultante (en haml) nos quede como el siguiente:

= form_for @user do |form|
   .field
      = form.label :name
      = form.error :p, :name
      = form.text:field :name

El primer parámetro indica el tag html que queremos usar como contenedor del error, y el segundo en atributo del modelo que debemos comprobar. Además, al tag contenedor le añadiremos la clase "error" de css para luego poder darle algunos estilos.

Tras dar algunas vueltas googleando me dí cuenta de que crear un nuevo helper no era tarea demasiado complicada, así que le eché un ojo a FormHelper y observé que está dividido en tres partes principales:

  1. El modulo FormHelper, que encapsula a todos los helpers de formularios.
  2. La clase FormBuilder, que es el resultado de usar el helper form_for y que contiene una instancia del objeto al que se refiere el formulario. Tiene métodos internos con el mismo nombre que los helpers que hacen uso de estos.
  3. La clase InstanceTag, que  es la encargada de generar el código para cada uno de los tags html. Es llamada desde los helpers.

Finalmente, adaptando un poco el código de otros helpers en el mismo fichero, el resultado fue:

module ActionView
  module Helpers
    module FormHelper
      def error(object_name, tag_name, method, options = {})
        InstanceTag.new(object_name, method, self, options.delete(:object)).to_error_tag(tag_name)
      end
    end

    class InstanceTag
      def to_error_tag(tag_name)
        unless @object.errors[@method_name].blank?
          content_tag tag_name, @object.errors[@method_name].first, :class => :error
        end
      end
    end

    class FormBuilder
      def error(tag_name, method, options = {})
        @template.error(@object_name, tag_name, method, objectify_options(options))
      end
    end
  end
end

Que también se puede ver en su gist correspondiente.

 

Actualización 22 de Marzo de 2011:

Otra forma de personalizar los mensajes de error de los formularios en rails, que acabo de ver en la guía de rails y que ya no recordaba, es usando ActionView::Base.field_error_proc. Simplemente se necesita asignarle un nuevo Proc que reciba el tag html y una instancia del modelo y listo. Podemos devolver lo que deseemos.

blog
Comments

HTML5 & CSS3

En estos momentos en los que los fabricantes de navegadores compiten para ver cuál es el más "moderno" y que cada vez parece que tenemos más cerca la publicación del nuevo estándar de html los desarrolladores web debemos ponernos al día y comenzar a implementar los nuevos estándares en nuestras webs. Para ello es importante tener a mano algunas buenas guías, presentaciones y algún libro que nos ayuden a mejorar nuestras webs mientras siguen funcionando en los navegadores más antiguos (lease IE6).

HTML5 and CSS3 de Brian P. Hogan hace un recorrido por el nuevo estándar dando para cada caso ejemplos de uso y soluciones alternativas (normalmente basadas en jQuery) que nos permitan usarlas en navegadores que actualmente no tienen suporte para ellas.

Haciendo un repaso rápido de los temas que se tocan en el libro y que forman parte de HTML5:

Nuevos elementos estructurales: Para hacer nuestros documentos más semánticos se han incorporado muchas etiquetas nuevas y se han eliminado muchas otras que aún seguían haciendo referencia a presentación. Algunas de estas nuevas etiquetas son header, footer, nav, section, article.

Web forms: Una de mis partes preferidas son los nuevos campos para formularios que nos van a ahorrar gran cantidad de javascript y nos va a permitir crear formularios muy complejos de una manera muy sencilla. Algunos de los nuevos elementos son: email, search, slider(type=range), date, color, number. Además se han añadido attributos muy interesantes como placeholder, autofocus y contenteditable.

CSS3: Para permitirnos mejorar visualmente nuestras webs sin necesidad de añadir clases o ids a cada elemento se han añadido montones de selectores y pseudo-selectores, entre ellos destacaría :nth-child(n) que nos permite crear tablas cebreadas sin necesidad de añadir las típicas clases odd y even.

Canvas: Nos permite crear imágenes complejas o gráficos programaticamente con javascript y sin necesidad de liberías externas como Flash.

Audio y video: Una de las características más conocidas es la inclusión de las etiquetas para audio y video que nos darán soporte nativo en el navegador, después, por supuesto, de que se resuelva la batalla sobre formatos que hay abierta entre los distintos navegadores.

Eye Candy (border-radius, shadows, gradients y transformations): Por supuesto, también se hablan de las nuevas propiedades de CSS que nos va a permitir crear bordes redondeados, sombras, gradientes y mucho más sin necesidad de añadir imágenes como fondos.

Por otro lado, se encuentran algunas API's javascript que aunque no pertenecen directamente al estándar, está asociadas al él y que habrá que tener en cuenta en el futuro. Las más destacadas son:

Local Storage: Que nos permite guardar cosas como la configuración de la aplicación sin necesidad de usar para ello cookies.

Session Storage: Que permite guardar datos en el navegador que se borran automáticamente al cerrar la sesión.

Web SQL databases: Bases de datos relacionales asociadas a un dominio y persistente entre sesiones.

Offline applications: Permite definir archivos que deben ser cacheados para que la aplicación pueda ejecutarse sin necesidad de conexión a internet.

History: Permite manejar el historial del navegador.

Cross-documents messages: Nos da la posibilidad de enviar mensajes entre ventanas con contenido cargado desde diferentes dominios.

Websockets: Crean una conexión con estado entre un navegador y un servidor.

Geolocation: Permite obtener la latitud y la longitud de un navegador web.

Por otro lado, existen otro montón de tecnologías que aún no se encuentran suficientemente maduras para usar en ningún navegador y por las cuales todavía tendremos que esperar un tiempo. Entre ellas se encuentran las siguientes:

CSS3 Transitions: Animaciones sobre interacciones directamente en CSS.

WebWorkers: Ejecución de javascript en segundo plano.

3D canvas con WebGL: Creación de imágenes 3D sobre el objeto canvas.

IndexedDB: Bases de datos de tipo clave/valor en el navegador similares a las NoSQL.

Drag & Drop: Api para arrastrar y soltar elementos entre el sistema operativo y el navegador.

Client-side form validations: Validaciones de formularios en el navegador sin usar javascript.

En resumen, nos esperan unos años muy prometedores en lo que ha desarrollo web se refiere con montones de tecnologías nuevas que vienen a facilitarnos el trabajo y a abrirnos un montón de posibilidades nuevas. Creo que es importante que comencemos a usar esas tecnologías desde ya para que los usuarios más avanzados puedan comenzar a beneficiarse de ellas, sin dejar de lado a los usuarios de navegadores sin soporte, y para que cuando llegue el resto de usuarios todas esas tecnologías se encuentren maduras y todos podamos disfrutar de una web mejor.

blog
Comments

¿Qué hace a un buen programador?

Pensando sobre las cualidades que debe tener un buen programador, y para que se me quede bien grabado, según Andrew Hunt y David Thomas en su libro The pragmatic programer, todos los programadores deben compartir las siguientes cualidades.

adoptador precoz / adaptador veloz: Instinto para probar nuevas tecnologías y técnicas, y para adaptarlas rápidamente al resto de su conocimiento.

inquisitivo: Tendencia a preguntarse cómo funcionan las cosas, lo que puede afectar a sus decisiones futuras.

pensador crítico: Siempre se pregunta por qué las cosas se hacen cómo se hacen y rara vez se conforma con aceptarlas tal cual.

realista: Intenta entender la naturaleza de cada problema al que se enfrenta, lo que le permite afrontar los problemas sabiendo cómo de dificiles y cuánto tiempo pueden tomar.

hombre orquesta: Se interesa por un amplio espectro de tecnologías, y aunque su trabajo requiera ser un especialista, siempre será capaz de afrontar nuevos retos.

Todas estas características no serían nada sin la más importante.

Piensa en tu trabajo

Para completar la lista dejo la guía para programadores pragmáticos que se encuentra al final del libro Referencia rápida para desarrolladores pragmaticos.

blog
Comments

The RSpec Book 2

Con motivo de la reciente publicación de RSpec 2 y la correspondiente reedición de The RSpec Book de David Chelimsky, estos días he estado repansando un poco de Behaviour Driven Development o BDD.

The RSpec Book: Behaviour-Driven Development with RSpec, Cucumber, and Friends

El libro está dividido en 5 partes fundamentales.

En primer lugar un ejemplo práctico de uso de RSpec y Cucumber en el que se desarrolla un pequeño juego llamado Codebreaker, donde el usuario debe adivinar un número secreto, y que nos familiariza con el ciclo básico del BDD: red, green, refactor.

La segunda parte está dedicada exclusivamente al BDD, y se centra en explicar por qué los proyectos tradicionales fallan y qué aporta dicha metodología para evitar esos errores.

La tercera parte nos introduce en RSpec y da un repaso completo a la librería: cómo definer expects, el uso de mocks y stubs para aislar cada test y por último cómo extenderla a través de macros o custom matchers entre otros.

La cuarta parte se centra en Cucumber y en cómo escribir requisitos usando Gherkin, cómo definir escenarios y cómo implementar cada uno de los pasos. Sin embargo, he de confesar que este apartado me lo leí un poco más por encima ya que en Qoolife hemos reemplazado Cucumber por Steak para hacer los test de aceptación. La razón fundamental es que ya que el producto lo estamos desarrollando en casa, y que todos los que vamos a escribir / leer las historias de usuarios conocemos ruby, eliminamos la capa de definición de los requisitos en lenguaje natural y pasamos directamente a implementarlas usando RSpec y Capybara.

En la quinta y última parte se hace un repaso a la integración con rails, desde la definición de features, pasando por distintas opciones que existe para simular el navegador usando Webrat y Selenium y acabando en cada una de las capas del MVC: vista, controlador y finalmente los modelos.

En resumen, un libro muy recomendable para todos aquellos interesados en ponerse al día en lo que a Behaviour Driven Development se refiere, y para los que deseen utilizar RSpec y/o Cucumber como herramienta de testing en particular.

blog
Comments

Teambox publica su versión 3.0

Para quienes no lo conozcan, Teambox es un proyecto de software libre español liderado por Pablo Villalba basado en Ruby On Rails que trata de desbancar como gestor de proyectos a otras aplicaciones tan conocidas internacionalmente como Basecamp o Redmine. Ya ha recibido numerosos reconocimientos por la crítica especializada y para mi representa un ejemplo de como en España también tenemos profesionales del más alto nivel capaces de competir internacionalmente.

Ayer publicaron su versión 3.0 y entre las novedades más destacadas se encuentran la actualización de la plataforma a la versión 3.0 de Ruby On Rails, lo que les permitirá usar los desarrollos más novedosos de la vibrante comunidad rails; y la renovación de la navegación de la aplicación que toma más protagonismo situándose a la derecha de la pantalla.

Muchas felicidades al equipo de Teambox y gracias por esta gran aplicación.

blog
Comments