Modernizr, HTML5 y CSS3

Modernizr es una librería javascript que sirve para detectar el soporte de ciertas funcionalidades de HTML5 y CSS3 en los navegadores. No tiene sentido detectar si un navegador es capaz de servir páginas en HTML5. Lo que se hace es detectar si el navegador tiene implementadas ciertas funcionalidades de forma separada como: canvas, video, geolocalización, bordes redondeados, etc.

Actualmente van por la versión 1.6 de Modernizr y ocupa menos de 10Kb (la versión descomprimida son 33Kb). Su uso es muy simple. Vamos a poner un ejemplo sencillo para presentarlo.

Imaginemos que queremos detectar si el navegador del usuario que nos está visitando soporta la nueva etiqueta canvas (elemento de HTML5 que hace las veces de contenedor o «pizarra» y que permite la generación de gráficos dinámicamente). Si no la soporta, no queremos siquiera que se muestre (esto lo haremos con CSS, también apoyándonos en Modernizr), pero si la soporta, dibujaremos dentro del canvas un cuadrado de lado 100px de un color aleatorio.

Nuestro HTML será así. Se ha usado la sintaxis de HTML5, por eso tanto la etiqueta DOCTYPE como el meta charset son tan escuetas:

[sourcecode language=»html»]




Modernizr: HTML5 y CSS3








[/sourcecode]

Como podemos ver, se crea una etiqueta canvas de 320x240px y se le da un identificador muy original «myCanvas». Se incluyen dos ficheros javascript: el de modernizr y uno nuestro llamado canvas.js (cuyo contenido se muestra un poco más abajo).

Lo interesante aquí es tanto la parte del CSS incrustado donde se le dice que si no tiene soporte para canvas, directamente no muestre el elemento:
[sourcecode language=»html»]

[/sourcecode]

La «magia» hace que si no hay soporte para canvas, no se muestre el elemento canvas. Es decir, se aplica el estilo no-canvas. Si existe, no ponemos ningún estilo en particular (podríamos haber escrito .canvas #myCanvas).

Y nuestro javascript canvas.js será como sigue:

[sourcecode language=»javascript»]
function paintCanvas() {
if (Modernizr.canvas) {
// Tu navegador soporta Canvas
var myCanvas = document.getElementById(«myCanvas»);
var context = myCanvas.getContext(«2d»);
context.fillStyle = «rgb(» + Math.round(255 * Math.random()) + «,» + Math.round(255 * Math.random()) + «,» + Math.round(255 * Math.random()) + «)»;
context.fillRect(100, 50, 100, 100);
} else {
alert(‘Tu navegador no soporta Canvas… Aún.’);
}
}
[/sourcecode]

La parte importante de detección es Modernizr.canvas. Modernizr crea un objeto global que tiene un conjunto de atributos de tipo Boolean, correspondientes a las diferentes funcionalidades detectadas. Su valor será «true» si se ha detectado que el navegador soporta aquello por lo que estamos preguntando, es este caso, canvas.

Al cargarse la página, se llamará a la función paintCanvas, cuya misión es dibujar dicho cuadrado dentro del canvas «myCanvas», si se puede. Si no se puede, nos mostrará un mensaje de alerta. Bastante sencillo ¿verdad?

Descargar ejemplo de Canvas

Recursos para Temas de WordPress

Desde que tenemos el blog nekotek.com, llevo pensando en cambiar el diseño drásticamente. No coger un tema de WordPress y modificarlo, si no crear uno desde cero adaptado a nuestras necesidades. Buscando, y leyendo he ido encontrando tutoriales y recursos que me parecen útiles para crear un tema de WordPress (¿o sería mejor dejarlo como WordPress theme?).

Un tema minimalista se puede crear únicamente con 2 ficheros:

  • index.php
  • style.css

WordPress, siguiendo su jerarquía de plantillas, si no encuentra una en particular termina buscando index.php. La hoja de estilos también es obligatoria y debe tener un comentario al inicio con una estructura básica de la definición del tema.

Antes de comenzar a diseñar nuestro tema, recomiendo ver este post «The anatomy of a WordPress theme«, que nos muestra gráficamente y de una manera sencilla cuál es la estructura básica de un tema. Para continuar, recomiendo la lectura de «Theme Development«, de la documentación de WordPress, en la cual hay mucha otra información interesante. Casi toda está en inglés, no hay mucha información de calidad en español.

Y ya por último, si nos hemos quedado con ganas, existen algunos libros dedicados a este tema, cuya versión en kindle es más cara que la de papel (WTF!):

¡Ya no hay excusa para no hacer nuestro propio tema para WordPress! Bueno, sí, la falta de tiempo o no tener ni idea de HTML, CSS y PHP. Pero puede ser una buena puerta a aprenderlos.

Generics (II) – Clases genéricas

En la anterior entrada hablamos de qué eran las Generics y por qué eran útiles. En ésta veremos cómo se definen clases genéricas para su posterior uso.

Clases genéricas

Para ver cómo definir las clases, vamos a partir de un ejemplo sencillo. Supongamos que en nuestra aplicación tenemos la necesidad de trabajar con pares. En algunos puntos necesitaremos usar pares de manzanas y en otros puntos pares de piedras.

Dado que el cometido de estos pares de elementos dentro de nuestra aplicación va a ser similar, hemos decidido implementar una clase que represente un par de cosas, en lugar de dos clases, la del par de manzanas y la del par de tornillos. Además queremos que sea una clase genérica por las ventajas que nos aportan.

Por tanto, una posible implementación de la clase podría ser la siguiente:

public class Pair<T> {
  private T first;
  private T second;
 
  public T getFirst() {
    return first;
  }
 
  public T getSecond() {
    return second;
  }
 
  public void setFirst(T first) {
    this.first = first;
  }
 
  public void setSecond(T second) {
    this.second = second;
  }
}

NOTA: Como convenio se suele utilizar una letra mayúscula para indicar una clase genérica, siendo T y E las más usadas.

Hemos definido una clase de un tipo genérico. Se puede leer como esto es una clase que representa un par de objetos de la clase T, y dejamos al criterio del usuario de la clase de qué tipo quiere o no usarla.

Definir una clase genérica no tiene más misterio. Se puede hacer todo lo enrevesado que queramos, pero en esencia toda definición se reduce a esto. El punto clave es la T. Le estamos indicando al compilador que a la hora de usar la clase Pair, la clase que pongamos en lugar de la T situada entre los símbolos < y > se sustituirá por todas las T que aparezcan en el resto de la clase.

A continuación una serie de ejemplos con comportamientos que funcionan y comportamientos que dan error:

// ...
Pair<Integer> intPair = new Pair<Integer>();
intPair.setFirst(7); // OK
intPair.setSecond("5"); // ERROR
//...
Pair objPair = new Pair();
objPair.setFirst(7); // OK
objPair.setSecond("5"); // OK
//...

No parece que tengan mucho misterio, ¿no?. Únicamente puntualizar que, si no especificamos las clases, el objeto creado usará Object como clase para el tipo genérico, y no será necesario especificarlo.

Múltiples clases

Si por ejemplo, quisiésemos que el par de elementos fuesen de dos tipos, independietes el uno del otro, podríamos redefinir la clase Pair como:

public class Pair<T, E> {
  private T first;
  private E second;
 
  public T getFirst() {
    return first;
  }
 
  public E getSecond() {
    return second;
  }
 
  public void setFirst(T first) {
    this.first = first;
  }
 
  public void setSecond(E second) {
    this.second = second;
  }
}

Aquí estamos definiendo dos tipos, (T y E). De esta forma, la clase que pongamos en lugar de T se sustituirá en todos los T, y lo mismo con la clase que pongamos en lugar de E. Ejemplo:

// ...
Pair<Integer, String> intPair = new Pair<Integer, String>();
intPair.setFirst(7); // OK
intPair.setSecond("5"); // OK
//...
Pair objPair = new Pair();
objPair.setFirst(7); // OK
objPair.setSecond("5"); // OK
//...

Para finalizar

Poco más hay que contar sobre cómo declarar una clase para que se pueda usar de forma genérica. Así que para finalizar, voy a hacer una pregunta capciosa. Dada la siguiente jerarquía:

Jerarquía de clases

¿cuál de los siguientes ejemplos daría error?

// EJEMPLO 1
Collection<Apple> apples = new ArrayList<Apple>();
Collection<Stones> stones = apples;
// ...
// EJEMPLO 2
Collection<Apple> apples = new ArrayList<Apple>(); 
Collection<Thing> things = apples;
// ...

En efecto, el primer ejemplo da un error, ya que una colección de piedras no es lo mismo que una de manzanas (afortunadamente para los que comemos fruta).

Lo malo es que el segundo ejemplo también es incorrecto. Para Java, una colección de manzanas no es equivalente a una colección de cosas. La respuesta y la solución las veremos en el siguiente post dedicado a las clases comodín (las «Wildcards»). ¡Sed felices!.