Archivo de 'Uncategorized'

Decoradores en Zend Form

De cuando en cuando, tengo que lidiar con formularios Zend_Form en Zend Framework. Son maravillosos, ya que simplifican enormemente el trabajo, y bien usados pueden aumentar notablemente la calidad de los formularios. Si no estás ya convencido, deja que te cuente alguna de sus ventajas:

  • Separación del formulario de las vistas. Ahora los formularios serán un objeto sobre el que puedes realizar numerosas operaciones. La clase encargada es Zend_Form.
  • Cada elemento del formulario es también un objeto, que hereda de Zend_Form_Element. Es decir, si añades un campo de texto, éste será también un objeto que, entre otras propiedades contiene su nombre, valor, etiqueta, descripción, errores, filtros, validadores, etc. Están todos los elementos de un formulario HTML disponibles en la biblioteca de Zend_Framework
  • Filtros, gracias a Zend_Filter. Podemos hacer que un elemento filtre de forma limpia y elegante su valor, como por ejemplo conversión a mayúsculas. Zend Framework trae un gran número de filtros.
  • Validaciones, gracias a Zend_Validate. Del mismo modo que podemos filtrar, también podemos añadir validaciones. Por ejemplo, que un valor numérico se encuentre en un determinado rango, que cumpla una determinada expresión regular, o que no exceda un determinado número de caracteres.
  • Comprobar el formulario. ¿Queremos saber si el formulario que ha completado el usuario es correcto? Simplemente invocamos el método isValid() del formulario, y sabremos si ha sido correcto.
  • Definir el formulario en un archivo .ini o .xml.

Pero volviendo al hilo, cada vez que tengo que retomar Zend_Form, hay un punto en el que me atasco: los decoradores. Su funcionamiento se basa en el patrón decorador.

Decorator Pattern

¿Qué hace exactamente? Añadir en tiempo de ejecución una nueva funcionalidad (decorar) a un objeto. Se usa mucho en entornos gráficos. Por ejemplo, para añadir nuevas opciones a una ventana o a un elemento gráfico. Nótese que en lugar de eso, podrían crearse subclases que heredaran unas de otras, pero esto conllevaría un problema: el número de clases total seguiría un crecimiento exponencial del tipo 2^funcionalidades. Precisamente ese problema es el que soluciona ese patrón.

Por ejemplo. Supongamos una clase base ‘Cafe’. Para la clase Cafe creamos 4 decoradores: ConAzucar, ConLeche, ConChocolate, ConEspuma. Si quisiéramos resolver todas las combinaciones posible, creando una clase para cada una de ellas, tendríamos 2^4 clases, es decir, 16. Con decoradores, añadimos estas funcionalidades al vuelo.

¿Y en qué afecta esto a Zend_Form? Como hemos dicho, tanto el formulario como los campos de éste, son objetos. Al renderizarse en HTML, muy seguramente, queramos modificar el modo en que se muestran por defecto. Y ahí es donde entra en juego el patrón decorador: Añadimos nuevas funcionalidades dinámicamente, para que por ejemplo un campo de texto esté envuelto en un div, que a su vez pertenece a una celda td.

Nota: La mayoría de la información de este artículo, y ejemplos, los he sacado del artículo Decorators with Zend Forms de la Zend Developer Zone.

La mayoría de elementos de un formulario (por ejemplo un campo de texto, un textarea o un combo) tiene una serie de decoradores “de serie” (el orden importa):

  1. ViewHelper – Es el encargado de renderizar el propio elemento
  2. Errors – En caso de que haya errores (por ejemplo, el valor introducido supera el tamaño máximo), lo mostraría este decorador.
  3. HtmlTag – Envoltura, por defecto con la etiqueta <dd> para el ViewHelper y Errors.
  4. Label – Etiqueta, envuelta en la etiqueta <dt> por defecto.

Se invocan (y anidan de dentro a fuera) en orden, de modo que la anterior pila generaría algo similar a lo siguiente:

$label->render($htmlTag->render($errors->render($viewHelper->render(''))));

Visto paso a paso, esto es lo que ocurriría:

Punto de partida

Partimos de una cadena de texto vacía

''

Se renderiza ViewHelper

A continuación se genera el código HTML de la etiqueta. En este ejemplo, al elemento se le había definido como tipo texto con nombre e id igual a “foo”

<input name="foo" id="foo" type="text" value="" />

Se renderiza Errors

Posteriormente se añade el código que muestra los errores. Por defecto se pospone (prepend) al contenido que ya hubiera.

<input name="foo" id="foo" type="text" value="" />
<div><ul>
    <li>...</li>
</ul></div>

Se renderiza HtmlTag

En este paso, añade una etiqueta dd (por omisión), que, por defecto, envuelve al contenido que ya hubiera.

<dd>
    <input name="foo" id="foo" type="text" value="" />
    <div><ul>
        <li>...</li>
    </ul></div>
</dd>

Se renderiza Label

Y en último lugar, se genera el código HTML de la etiqueta (por omisión viene envuelto en dd), y lo antepone a lo que ya hubiera (append).

<dt><label for="foo">Foo</label><dt>
<dd>
    <input name="foo" id="foo" type="text" value="" />
    <div><ul>
        <li>...</li>
    </ul></div>
</dd>

¿Cómo modificamos la forma en que se genera el código por defecto? Hay dos vías.

La primera nos permite añadir nuevos decoradores al comienzo de la pila, eliminar alguno de ellos, y/o modificar la ubicación en que se muestra alguno de los que ya hay. Por ejemplo, esto extraería el decorador ‘label’ de la pila de decoradores del elemento, y modificaría su ubicación (valores posibles appendo o prepend):

$label = $element->getDecorator('label');
$label->setOption('placement', 'append');

Del mismo modo, podríamos eliminar de la pila de decoradores el decorador ‘label’ así:

$element->removeDecorator(‘label’);

La segunda es más potente, y nos permite redefinir toda la pila

$element->setDecorators(array(
    'ViewHelper',
    'Description',
    'Errors',
    array(array('elementDiv' => 'HtmlTag'), array('tag' => 'div')),
    array(array('td' => 'HtmlTag'), array('tag' => 'td')),
    array('Label', array('tag' => 'td')),
));

Cada elemento dentro del array es un decorador, de modo que en este caso tenemos 6: ‘ViewHelper’, ‘Description’, ‘Errors’, ‘HtmlTag’, ‘HtmlTag’, ‘Label’.

A cada elemento le podemos añadir opciones, como por ejemplo el tag a utilizar. En ese caso, en lugar de utilizar sólo su nombre, lo haríamos así:

array('decorador', array('opción' => 'valor'))

Además, si usamos dos veces un mismo decorador, debemos necesariamente etiquetarle con un nombre que lo identifique de manera unívoca, ya que sino, el último decorador de ese tipo que se añada, sustituirá al anterior. Para poner una etiqueta, lo haríamos así:

array( array('etiqueta' => 'decorador'), array('opción' => 'valor'))

Explicación:

  1. Primero renderiza ViewHelper (V), que es un atajo del elemento (por ejemplo, el campo de entrada). De forma resumida, generaría el siguiente código: <V>.
  2. En segundo lugar, renderiza la descripción (D), que por defecto se ubica tras (prepend) lo que hubiera, de modo que quedaría: <V><D>.
  3. Ahora con los errores (E), los renderiza por defecto antes (append) de lo que hubiera: <E><V><D>.
  4. En el cuarto paso, creamos un decorador de tipo HtmlTag al que etiquetamos como ‘elementDiv’, y que le pasamos como opciones que use el tag ‘div’. Este decorador, por defecto, envuelve lo que hubiera: <div><E><V><D></div>.
  5. Quinto paso, al igual que en el anterior creamos un decorador de tipo HtmlTag, etiquetado como ‘td’, y que usará el tag ‘td’, quedando así: <td><div><E><V><D></div></td>.
  6. Sexto y último paso, renderizamos la etiqueta (L), cuya ubicación por defecto es antes de lo que hubiera (append), y a la que le pasamos una opción adicional para que esté contenida dentro de un tag de tipo ‘td’: <td><div><E><V><D></div></td><td><L></td>.

Ahora ya conocemos la dinámica de cómo decorar un elemento de un formulario. Hemos visto sólo unos pocos (ViewHelper, Description, Errors, HtmlTag y Label). Por cada tipo de campo (input text, button, file, etc.) hay un decorador, siendo ViewHelper sólo un atajo que deduce cuál de ellos usar. Estos algunos decoradores más (aquí la lista completa):

  • Callback – Si no nos queremos complicar, podemos definir una función callback que reciba como parámetro el elemento, para con una sentencia similar a ésta, devolver el nuevo contenido:
    return ’<span>’ . $element->getLabel() . ”</span>”;
  • Form – Es el decorador por defecto del propio formulario. No lo hemos dicho, pero no sólo los elementos del formulario tienen decoradores. También los tienen los formularios en sí.
  • FormElements – Este es el encargado de renderizar cada uno de los elementos dentro de un formulario, es decir, es el que envuelve a nuestros elementos.
  • Image – Para renderizar una etiqueta de tipo img en el formulario. Útil por ejemplo cuando queremos mostrar en un formulario de actualizar perfil de usuario su avatar activo.
  • ViewScript – ¿Que todo lo anterior resulta demasiado farragoso para un simple formulario? No hay problemas. ViewScript permite diseñarlo a la antigua usanza, con una plantilla. Todo esto sin tener que dejar de lado toda la potencia y facilidades que nos ofrece utilizar Zend_Form como sustituto de los formularios no gestionados.

Hay mucho más que ver sobre los decoradores, como por ejemplo, aprender a definir nuestros propios decoradores, o saber cómo hacer uso de ViewScript. En cualquier caso, Matthew Weier O’Phinney lo tiene todo explicado de maravilla en el artículo del Zend Developer Zone que enlazaba al comienzo.

Gracias por leer este artículo :)

Requisitos en proyectos a licitación

Recientemente, en un proyecto que salió a licitación dependiente del Ministerio de Medio Ambiente, y Medio Rural y marino, vi unos cuantos requisitos que, en mi opinión, merece la pena compartir y revisar con detenimiento. Para entrar en contexto, el proyecto consiste en el diseño, desarrollo, implantación y mantenimiento de una página web. Es normal que quieran curarse en salud, todos lo hacemos en nuestros contratos. Pero esto…

Lo primero que me llama la atención, es un párrafo que dice lo siguiente:

La herramienta de gestión de contenidos proporcionará a la Fundación Biodiversidad la capacidad de modificar en su totalidad el diseño, imagen del portal Web y todos sus contenidos. Todo ello de una manera sencilla sin requerir conocimientos de programación ni HTML.

Lamentablemente no existe tecnología que permita realizar esto. Existen multitud de editores WYSIWYG, aplicaciones que permiten editar textos de forma enriquecida sin necesidad de lidiar con CSS o HTML. Pero no existe nada que permita modificar el aspecto de toda una web sin necesidad de tener conocimientos de HTML y/o CSS. Ni siquiera aplicaciones como WordPress, Joomla o Blogger, todas ellas conocidas por lo sencillas de manejar que son, permiten nada remotamente parecido. Permiten instalar plantillas, eso sí, desarrolladas por gente que sí tiene conocimientos técnicos.

Pero sigamos. En otro párrafo nos indican esto:

La propiedad intelectual de los trabajos realizados por el adjudicatario pertenecerá a la Fundación Biodiversidad.

Todos desarrollamos código reutilizable. Por ejemplo, si un día diseño una página web en la que hay un sistema de gestión de usuarios, procuraré que este código se pueda reutilizar para otros proyectos. Es bastante frecuente contar con un buen número de “bloques” de código que reutilizas para ensamblar nuevos proyectos. Esto permite abaratar costes sin perder en calidad.

Pero volvamos con la cita anterior. Si toda la propiedad intelectual (esto incluye el software) pasa a pertenecer a la Fundación Biodiversidad, ¿qué ocurre con nuestros anteriores clientes? ¿Sus aplicaciones serán en parte propiedad de esta fundación? O una pregunta todavía más interesante, ¿y si el software utilizado, bien desarrollado por nosotros, bien por terceros, está licenciado como software libre? Por favor, si me equivoco agradecería alguna explicación, pero hasta donde yo sé, la única solución viable consiste en desarrollar un software desde cero para este proyecto.

Pero hay más puntos interesantes a analizar:

Además la Fundación Biodiversidad se reserva el derecho a ampliar los contenidos sin que el presupuesto varíe.

Al definir un proyecto siempre se olvida algún contenido o requisito. Esto es normal. Si presupuesto una web que inicialmente cuenta con 30 documentos, pero finalmente se realizan 33, muy posiblemente el precio no variará con respecto al presupuesto inicial (salvo que se trate de apartados especialmente costosos en tiempo, y siempre indicándoselo con antelación al cliente).

Pero que te obliguen a firmar unas condiciones en las que te comprometes a añadir todos los contenidos extra que te proporcionen, únicamente fiándote de su buena fe, lo veo abusivo. ¿Quién te garantiza que finalmente no será el doble de lo estimado? Personalmente considero una cláusula así como un claro indicativo de la seriedad del cliente con el que vas a trabajar. Por suerte no he tenido ningún cliente así; la gente entiende que si se salen de los requisitos iniciales, es normal pagar por ello.

Diseño personalizado para mapas de Google

Con tanto revuelo que hay con la Google I/O 2010 (La apertura de Wave, Google TV, y la Chrome Web Store), poco se habla del resto de novedades. Una de ellas son los Styled Maps de la API de Google Maps.

Gracias a estas cositas, muchos diseñadores que hasta ahora se mostraban reticentes, se animarán a usar esta API para sus páginas.

Aquí tenemos un ejemplo de qué se puede hacer:


Consejos SEO de Bing

Vía Bing Community os traigo esta serie de consejos SEO que nos proponen. La mayoría me han resultado viejos conocidos, pero otros… Son sobre los enlaces, y el artículo se titula “making links work for you“. Aquí los tenéis:

  1. Canonizar la URL de inicio. ¿Con o sin www? ¿Con barra final o sin ella? Sólo puede quedar una ;)
  2. Escoger entre enlaces relativos y absolutos. Nos aconsejan usar siempre enlaces absolutos, sobre todo porque refuerzan nuestra URL.
  3. Utiliza una buena sintaxis en las URLs de los enlaces. Por ejemplo, debemos omitir el fichero por defecto de una carpeta (Típicamente index).
  4. Utiliza el atributo title en enlaces internos. En los enlaces que apuntan a tu propia página completa el atributo title con una descripción de la página de destino.
  5. Identifica la URL canónica de cada página. Ya sabéis, como en el punto 1, pero para todas las páginas.
  6. Minimiza el número de parámetros de URLs dinámicas. Suelen ser problemáticas para los bots que rastrean la página.
  7. Evita usar IDs de sesiones o cookies. Dificultarás el rastreo a los bots.
  8. Ten al menos un enlace interno a cada página. Lógico. Todos los documentos deben ser accesibles.
  9. Limita el número de enlaces de una página. Nos aconsejan que un documento no contenga más de 100 (Salvo que sea necesario).
  10. Evitar que el rastreador siga un enlace. Mediante rel=”nofollow”. Cuanto más tiempo dedique a las páginas no interesantes, menos dedicará a las que de verdad nos interesan.

Sobre los links, también hicieron unos artículos muy interesantes titulados “El bueno, el feo y el malo” (Parte 1 y Parte 2).

http://www.bing.com/community/blogs/webmaster/

Google lanza un teclado virtual

Vía programmable web me entero de que Google acaba de lanzar un teclado virtual especialmente útil para páginas con soporte multi-idioma. ¿Qué vamos a poder hacer con esto? Podremos incluír un teclado en otro idioma directamente en nuestra web sólo con unas pocas líneas de javascript.

Actualmente están disponibles:

  • Árabe (العربية)
  • Hindi (हिन्दी)
  • Polaco (Polski)
  • Ruso (Русский)
  • Tailandés (ไทย)

Estoy seguro que tanto mi hermana Olalla como mi cuñado Samer se alegrarán de tener esta herramienta, y seguro que la utilizarán :)

Read more

Season finale de Lost

En este post voy a compartir mis teorías del capítulo que cierra la quinta temporada de Lost, de modo que si no lo has visto, por favor, deja de leer! :)

Y aviso otra vez: HAY SPOILERS, de modo que cuidadito.

Lo primero es lo primero; Este capítulo doble es impresionante. Ya desde el primer minuto nos inunda con respuestas, y cuanto más avanza, más emocionado estás ante la vorágine de aclaraciones que da.

Sin duda lo que más impactado me ha dejado ha sido el hecho de que John Locke esté muerto. ¿Quién ha estado entonces toda la temporada hablando y actuando en su nombre? Pues ni más ni menos que el némesis de Jacob, como ya le han apodado en lostpedia. Sensacional el momento en que te encajan las piezas y descubres quién es este Locke y cómo ha encontrado “el agujero” para matar a Jacob.

Uno de los personajes que más me han intrigado siempre ha sido Richard Alpert. En este capítulo nos revela que su nombre real es Ricardo. Y yo tengo una teoría… Al comienzo del episodio vemos un navío, que a mi parecer es de la época de los grandes descubrimientos geográficos, que Jacob ha “llevado” a la isla. ¿Quién iba a bordo de dicho navío? Pues yo lo veo claro: Richard. Lo cual despierta en mi cierta esperanza patria; Ricardo es un español a bordo de un navío conquistador de finales del siglo XV.

Por otra parte hemos conocido finalmente la respuesta a “What lies in the shadow of the statue?“, cuya respuesta es en latín, el idioma de “los otros”. Luego entonces, ¿quiénes son Ilana y Bram? ¿A que grupo pertenecen? ¿Cuáles son sus intereses? ¿Y porqué Jacob dice “ya vienen” en su lecho de muerte?

Otro de los momentos estelares es el final, cuando vemos cómo Juliet logra detonar la bomba, aunque tampoco me resulta tan enigmático el momento: Queda una temporada y todos esos personajes (Jack, Kate, Sawyer, Hurley, Jin, Milles, etc) no pueden morir.

Otra de mis teorías es que “whatever happened, happened”, de modo que “el incidente” es el mismo que ocurrió en la iteración anterior (Porque esto es un bucle, ¿no? ;) ). No se puede cambiar el pasado, y la detonación de la bomba siempre ha formado parte de la historia de la estación del Cisne.

¿Qué os ha parecido a vosotros? ¿Qué teorías tenéis? No sé si aguantaré 8 meses de espera hasta que llegue la sexta temporada antes de que me haga el hara-kiri.