Archivo de 'desarrollo'

Botones súper increíbles con CSS3 y RGBA

CSS3 ya está aquí, y ha llegado para quedarse. Gracias a él, podemos crear increíbles efectos en navegadores modernos (Teniendo en cuenta un enfoque de graceful degradation). En éste artículo voy a mostrar cómo, desde ZURB, han creado unos botones CSS que realmente son súper increíbles. Accede a la página del artículo para ver demostraciones en vivo.

Botón en ancla »

Botón en ancla 2 »

La magia está en el CSS:

.button{
   background:#222 url(/wp-content/uploads/2009/12/alert-overlay.png) repeat-x 0 0;
   display:inline-block;
   padding:5px 15px 6px;
   color:#fff !important;
   font-size:13px;
   font-weight:bold;
   line-height:1;
   text-decoration:none;
   -moz-border-radius:5px;
   -webkit-border-radius:5px;
   -moz-box-shadow:0 1px 3px rgba(0,0,0,0.25);
   -webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25);
   text-shadow:0 -1px 1px rgba(0,0,0,0.25);
   border-bottom:1px solid rgba(0,0,0,0.25);
   position:relative;
   cursor:pointer;
   overflow:visible;
   width:auto
}

button::-moz-focus-inner{
   border:0;
   padding:0
}

.button:hover{
   background-color: #111111;
   color: white
}

.button:active{
   top:1px
}

Una sombra a la caja, otra al texto, un borde redondeado, y de fondo una imagen png que realiza el degradado (Se puede realizar también con CSS en Webkit). Una pasada hacer todo esto sólo con CSS, ¿no?

¡Pero espera! ¡Ahí no queda la cosa! ¿Qué ocurriría si cambiásemos el color de fondo sobre el que está el botón? La sombra se vería “rara”, al igual que el color del borde.

super-awesome-buttons-fixed

Y lo mismo ocurriría con la sombra del texto si cambiásemos el color de relleno del propio botón. ¿Cómo se soluciona? Ahora es cuando llega al rescate la A de RGBA :) Por ejemplo, en la sombra de la caja, lo hemos definido como:

rgba(0,0,0,0.25)

Es decir, color negro al 25% de transparencia. De ese modo, la sombra siempre “lucirá” del mismo modo usemos el color que usemos.

Espero que os haya gustado tanto como a mí.

Vía Smashin Magazine,

El test de Joel adaptado al desarrollo web

Leyendo blogs, me encuentro con este artículo que trata sobre una revisión del sencillo test de Joel Spolsky sobre la calidad del software. Esta nueva revisión, de la mano de Brandon Savage, propone 12 pasos adaptados al desarrollo web hoy día. Los pasos se responden con un sí o un no. Estos son los posibles resultados:

  • 12 síes. Perfecto.
  • 11 síes. Aceptable.
  • 10 o menos síes. Tienes un serio problema.

Ahora veamos las preguntas:

  1. ¿Usas algún sistema de control de versiones?
  2. ¿Puedes generar fichero para distribuir tu software en sólo un paso?
  3. ¿Usas integración continua?
  4. ¿Guardas un registro de bugs?
  5. ¿Corriges los bugs tras escribir nuevo código?
  6. ¿Cumples los hitos a tiempo?
  7. ¿Documentas las especificaciones?
  8. ¿Disfrutan tus programadores de un entorno de trabajo tranquilo?
  9. ¿Usas las mejores herramientas, y gastas dinero en aquéllas que son necesarias y caras?
  10. ¿Escribes test unitarios?
  11. ¿Tus nuevos candidatos demuestran sus conocimientos de programación con alguna prueba tangible durante la entrevista?
  12. ¿Tienes testers?

En mayor o menor medida, todas me parecen propuestas muy acertadas. No deja de ser una curiosidad más, pero posiblemente este “juego” sea una métrica de calidad de software equiparable a otros sistmas varios órdenes de magnitud más complejos.

Por cierto, yo obtengo un 6 sobre 11 (La pregunta número 11 no se aplica en mi caso).

Mejora progresiva

De un tiempo a ahora, cada vez leo con más frecuencia el término progressive enhancement, o en catellano, mejora progresiva. ¿Qué es exactamente? Como desarrolladores web, debemos lidiar con numerosos navegadores, cada uno con una serie de prestaciones y recursos. Como veremos a continuación, normalmente hay 4 formas de abordar esta situación:

  1. Impedir el acceso a determinados navegadores. Creedme, existen páginas a las que no se puede acceder con según qué navegadores. No me refiero a que se muestren defectuosas, es que directamente te muestran un mensaje de error. Tratad de acceder a una página de El Plural cambiando el user-agent de vuestro navegador y sabréis a qué me refiero. Ésta es una pésima solución.
  2. Quedarnos en el mínimo común denominador. Esto es, diseñar la página de modo que sólo contenga recursos disponibles por todos los navegadores. No es una solución muy escalable, puesto que se está limitando a las funcionalidades mínimas (Funcionalidades que, por otro lado, normalmente se corresponden con las de nuestro querido IE6). Visto con un enfoque más visual, esto significa que la manada debe ir a la velocidad del más lento. Por ejemplo, querémos posicionar un <div> de forma ‘fixed’. IE6 no lo permite, de modo que, o no lo hacemos, o dedicamos esfuerzos en buscar retorcidos hacks para lograrlo en este navegador. Mmmm no me gusta. ¿Qué más hay?
  3. Graceful degradation. Durante mucho tiempo ésta ha sido la tendencia reinante, y seguramente seguirá siéndolo. Consiste en partir del máximo de prestaciones de forma que, a medida que se usen navegadores menos avanzados, la página se mantenga usable con pequeños defectos. Un ejemplo perfecto es el uso de imágenes PNG con semitransparencias: Mientras que los usuarios de Firefox o Safari las verán sin problemas, los de IE6 se encontrarán con imágenes corruptas. En estos casos es frecuente dividir la página en dos niveles: El nivel 1 corresponde a una buena experiencia para el usuario, el nivel 2 con una versión degradada de la página. Encontramos un ejemplo en el servicio de correo de Google Gmail, con su versión avanzada (Por defecto) y una versión básica.
  4. Mejora progresiva. Y al fin llegamos a la mejora progresiva. ¿En qué consiste? Es exactamente igual que graceful degradation pero al revés. En lugar de partir de una versión avanzada, se parte de la versión mínima, de forma que, a medida que un navegador ofrece mejores recursos, la página también se ve mejorada. En este caso, se parte de un mínimo razonable, por ejemplo, que sea compatible con HTML 4. Podría, por ejemplo, usarse transparencias en GIF, y sin embargo, en aquéllos navegadores que sí lo soporten, semitransparencias en PNG.

Lógicamente las dos mejores soluciones son las dos últimas. ¿Cuál es mejor? Realmente depende del caso. Pero como método general yo prefiero la mejora progresiva, pues a diferencia de graceful degradation parte de una experiencia de usuario razonablemente buena. Además, con esto siempre ganaremos en accesibilidad.

Si bien cada día existen más navegadores con sus respectivas versiones, también es cierto que disponemos cada vez más de recursos que nos permiten abstraernos de ellos, como los numerosos frameworks javascript como jquery o mootools, además de brillantes soluciones como Google Chrome Frame.

Más información:

FirePHP – Integra logs de PHP en Firefox

En todo desarrollo se hacen necesarias herramientas que permitan hacer un seguimiento del código. Hoy voy a mostrar cómo mostrar logs desde PHP directamente a una consola en Firefox. ¡Di adiós a los “echos” y a los “var_dump”!

En primer lugar, debemos tener instalada la extensión Firebug. Por si no lo conocéis, es uno de los plugins más instalados de Firefox y nos es útil para numerosas tareas:

  • Inspeccionar el árbol DOM y HTML.
  • Modificar CSS al vuelo.
  • Monitorizar actividades en la red (¿Qué hace que tarde tanto en cargar mi página?)
  • Depurar código JavaScript.
  • Consola JavaScript
  • Y mucho más (En serio).

Una vez instalado Firebug, toca instalar otra nueva extensión. Se trata de FirePHP. Para que funcione, es necesario tener en Firebug activadas las pestañas de Red y de Consola. De momento está siendo fácil, ¿verdad? Pues ya no nos queda nada :)

Ahora que tenemos el cliente listo, sólo nos queda activarlo en el servidor. Al ser un sistema muy popular, la mayoría de los frameworks traen integradas de serie las bibliotecas necesarias, pero también se pueden usar las bibliotecas nativas si nuestro proyecto no utiliza ningún framework.

En este mini howto voy a mostrar cómo hacerlo funcionar con Zend Framework (Ver casos de uso con la biblioteca genérica).

FirePHP en Zend Framework

Lo primero es inicializar el sistema de logs en el fichero bootstrap:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

   ...

   protected function _initLogging()
   {
      $this->bootstrap('frontController');
      $logger = new Zend_Log();

      $writer = 'production' == $this->getEnvironment() ?
         new Zend_Log_Writer_Stream(APPLICATION_PATH .
            '/../data/logs/app.log') :
         new Zend_Log_Writer_Firebug();

      $logger->addWriter($writer);

      if ('production' == $this->getEnvironment()) {
         $filter = new Zend_Log_Filter_Priority( Zend_Log::CRIT);
         $logger->addFilter($filter);
      }

      $this->_logger = $logger;
      Zend_Registry::set('log', $logger);
   }
   ...
}

Veamos paso a paso lo que hemos hecho:

  1. Nos aseguramos de que el frontController está inicializado.
  2. Creamos una nueva instancia de la clase Zend_Log.
  3. Por seguridad, si estamos en un entorno de producción, el registro de logs se volcará en el fichero data/logs/app.log. En caso contrario, se mostrará mediante Firebug. Existen muchas más clases que heredan de Zend_Log_Writer_Abstract, como por ejemplo para mandar por correo electrónico, o almacenar en base de datos.
  4. De nuevo, si estamos en un entorno de producción filtramos las alertas a aquéllas que sean, por lo menos, críticas. Existen hasta 7 niveles de prioridad.
  5. Establecemos el atributo $this->_logger.
  6. Guardamos una referencia de $logger en el registro, de modo que éste esté accesible para toda la aplicación.

Bueno ahora está ya todo listo. Nuestro servidor sabe cómo adjuntar estos logs, y nuestro cliente sabe cómo interpretarlos. ¿Qué nos queda? Pues un hola mundo :) Por ejemplo, modifiquemos el método _initLogging() para añadir una nueva línea al final del mismo:

$this->_logger->info('Bootstrap ' . __METHOD__);

Ahora sí que sí. Ya está todo listo. Accedamos a la página, abramos Firebug con las pestañas de consola y de red activadas, y con FirePHP también activado y veamos la magia:

Captura del resultado en Firebug

Captura del resultado en Firebug

Una maravilla que nos permitirá hacer un seguimiento de qué ocurre en cada petición a nuestra página web.

¿Pero cómo funciona todo esto? Fácil: Toda esta información se adjunta en forma de cabeceras HTTP, de modo que nunca interferirán en el cuerpo de la petición. Puedes usarlo por tanto en llamadas AJAX, ficheros binarios como imágenes, etc.

¡Pero espera, que aún hay más!

Profiling de bases de datos

Zend Framework te permite hacer profiling de la base de datos. Por si no sabes qué es esto, es un análisis del comportamiento de una aplicación cuyo objetivo normalmente es optimizar la ejecución. En este caso, podremos conocer cuáles son todas las consultas a base de datos que se han ejecutado, y cuánto tiempo han llevado. ¿Y cómo lo hacemos? Crearemos un nuevo método en el fichero bootstrap:

protected function _initDbProfiler()
{
   if ('production' !== $this->getEnvironment()) {
      $this->bootstrap('db');
      $profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
      $profiler->setEnabled(true);
      $this->getPluginResource('db')
         ->getDbAdapter()
         ->setProfiler($profiler);
      }
 }

En este caso, si la instancia de la aplicación no está en producción, realizaremos lo siguiente:

  1. Iniciamos la base de datos.
  2. Creamos una instancia del profiler especializado de Firebug pasándole como parámetro su etiqueta.
  3. Activamos el objeto profiler.
  4. Y finalmente, activamos el profiling en la base de datos por defecto.

Ahora ya puedes inspeccionar las consultas que hace tu aplicación, minimizar las llamadas, y solucionar cuellos de botella :)

Expresiones Regulares

La primera vez que ves una de ellas sientes nauseas. A partir de ese momento cada vez que te enfrentas a ellas sientes mareos, hasta que poco a poco empiezas a entender su idioma. Llega un día en el que te sientes capaz de dialogar con ellas. La amistad se ha forjado.

Con las expresiones regulares ocurre como con los frameworks de desarrollo. La curva de aprendizaje suele ser lenta, pero siempre acaba mereciendo la pena. Son las encargadas de poner orden en los caos con los que muchas veces tienen que lidiar nuestros pobres procesos.

Gracias a ellas podemos confeccionar laboriosas expresiones como por ejemplo “Quiero saber cuales son todas las palabras que preceden a todos los números de 4 cifras que no terminan en 2″. Inventate una condición, seguro que se puede construir.

AVISO: No he sometido a prueba ninguno de los ejemplos que aquí pongo.

En PHP, como en la mayoría de lenguajes, es muy sencillo construirlas. En su forma más básica:

<?php
    $pattern = '/\d\d/';
    $subject = "El día 22 me voy de viaje";
    preg_match($pattern, $subject, $match);

    var_dump($match);
?>

Este artículo no pretende ser una guía de iniciación a las expresiones regulares (Hay libros enteros que tratan sobre ello). Si estás interesado, hay páginas muy útiles, aunque personalmente me entiendo mejor con la nueva guía que hay disponible en la documentación de PHP.

Quiero apuntarme, a modo de recordatorio, varias trucos muy útiles que he aprendido recientemente.

Asignar nombres a subpatrones

Cuando ejecutamos una expresión regular, podemos capturar todos los subpatrones que se han detectado para usarlos más adelante. Por ejemplo, si parseamos una fecha en formato ISO-8601 con esta expresión regular “/(\d\d\d\d)-(\d\d)-(\d\d)/”, obtendremos un array en el que en la posición 0 tenemos el año, en la 1 el mes y en la 2 el día. ¿Y si un día introducimos un nuevo subpatrón en medio de los anteriores? Bien, la solución pasa por asignar nombres:

"/(?P<nombre>\d{4})/"

Ahora tendremos ese valor en $array['nombre']. ¡Muy útil!

No capturar un subpatrón

¿Y si tenemos un subpatrón del que no nos interesa realmente su valor? La memoria es limitada, y para no llenarla innecesariamente utilizaremos esto:

"/(?:\d{4})/"

Repeticiones perezosas

A mendo queremos que un patrón se detenga tan pronto como se haya cumplido la condición que busca (Este no es el comportamiento por defecto… Las expresiones regulares son voraces). Por ejemplo, supongamos que queremos obtener el nombre “Julia” de este texto:

<p>Julia</p><p>Álvaro</p>

Esta expresión regular no nos serviría: “/<p>(.+)<\/p>/”, ya que capturaría esto: “Julia</p><p>Álvaro

La solución fácil es esta (Nota el símbolo de interrogación):

"/<p>(.+?)<\/p>/"

La difícil, o la que yo venía usando hasta ahora era esta, que capturaba todos los caracteres excepto el que delimitaba el fin de la cadena buscada:

"/<p>([^<]+)<\/p>/"

Back references

En lenguajes como XML, gramáticas independientes del contexto, necesitamos hacer referencias a elementos anteriores. Por ejemplo

<miEtiqueta>Un valor <b>cualquiera</b></miEtiqueta>

¿Cómo podemos parsear eso si no conocemos de antemano el nombre de la etiqueta?

"/<(.*?)>(.*?)<\/\1>/"

Por supuesto, también podemos usar el nombre del subpatrón si lo tuviera:

"/<(?P<tagname>.*?)>(.*?)<\/(?P=tagname)>/"

Aserciones

Una maravilla… Básicamente son condiciones que no mueven el cursor, es decir, no consumen ningún caracter. Hay de dos tipos:

  1. Búsqueda por delante. A su vez dividida en dos subtipos:
    1. Positiva. Debe cumplirse la condición: (?=patron)
    2. Negativa. No debe cumplirse la condición: (?!patron)
  2. Búsqueda por detrás. A su vez dividida en dos subtipos:
    1. Positiva. Debe cumplirse la condición: (?<=patron)
    2. Negativa. No debe cumplirse la condición: (?<!patron)

Por ejemplo, esta expresión regular:

"/(?<!foo)bar/"

Encuentra aquellas ocurrencias de “bar” que no están precedidas por “foo”. En este caso hemos usado búsqueda por detrás negativa.

Una gran pega es que las condiciones que hay dentro de las aserciones deben tener un tamaño de caracteres fijo. En el caso de PHP y de Java, se permite además tener una serie de palabras opcionales, cada una de tamaño fijo. La única excepción notable es .NET framework, que sí permite “lo que sea” (¿A que no te lo esperabas?).

En fin, que igual igual alguno de estos “trucos” le es útil a alguien. A mi se me aparecen situaciones donde usarlos todas las semanas. ¡Disfrutadlos!

Escribe mejor CSS con lesscss

Vía SitePoint descrubo una joya :) Se trata de una herramienta programada en Ruby que permite escribir código CSS de forma más efectiva: LESS. En palabras de sus creadores, LESS extiende CSS añadiendo variables, mezclas, operaciones y anidamiento de reglas.

Por ejemplo, podemos definir una variable que contiene un color en notación HTML, y desde ahí se definen estilos con ese color. De esta forma, si mañana lo cambiamos, sólo tendremos que actualizar esa variable.

El anidamiento mejora enormemente la legibilidad del código. Si a eso le sumamos las operaciones que podemos realizar, como por ejemplo multiplicaciones, el resultado es sensacional.

Prometo usarlo :)