Mi primera plantilla WordPress. ¡Chispas!

(Si no habéis pillado la cita del título de la entrada, dad gracias. Si la habéis pillado, disimulad.)

Captura de la página web laiablasco.com
Simple. Que suele ser un elogio.

Pues sí, después de años de hacer «chapucillas WordPress» (pequeños apaños a las plantillas que ha lucido este blog a lo largo de estos últimos ocho años, y a algún otro sitio por el camino), tras unas cuantas (bastantes, de hecho, que uno es lento) horas de trabajo ha salido del horno laiablasco.com, portafolio para la diseñadora del mismo nombre… El diseño no es mío, pero la implementación sí :-). Afortunadamente para un WordPressero sin mucha experiencia como yo, la propietaria del sitio opina que un portafolio debería esconderse y dejar sitio a su contenido, o sea que la cosa ha resultado relativamente sencilla de montar. Aún así, dejo un par de anotaciones que me han resultado importantes…

Maquetado, con Boks

Ya había hablado de Boks hace un tiempo. Y desde entonces no he encontrado ninguna herramienta que supere su combinación de simplicidad y facilidad de uso, ubicuidad (multiplataforma gracias a correr sobre Adobe Air) y precio (gratis, difícil de batir)…

Captura de pantalla de Boks con un esbozo del diseño de laiablasco.com
(Las imágenes 'placeholder', por cortesía de dummyimage.com)

Tres cosas más a destacar:

  • Me incliné por una parrilla de 24 columnas de 40 píxels de ancho, sin ‘gutters’ (los canales de separación entre columnas). Un error: los ‘gutters’ son muy importantes y ahorran bastante trabajo. No me volverá a pasar. Espero.
  • Cada vez que te casas con una parrilla predefinida te casas también con su familia, que suele componerse de clases poco o nada semánticas que suponen, a la larga, un riesgo de código espagueti poco mantenible. Queda en la lista de cosas por hacer una limpieza de clases, por tanto. Para cuando toque, un recurso: Blueprint’s compress.rb.
  • De momento, ni código ‘responsive’ ni leches. 960 píxels y tira millas. Diré en mi defensa que los navegadores móviles, en general, sacan algo bastante digno del maquetado tal y como está. Pero queda también en la lista de deberes, al menos, un diseño linealizado a una sola columna de la ‘home’ al bajar de, pongamos, 720 píxels de ancho. Si el CSS es más semántico cuando me ponga (ver punto anterior) no deberia ser complicado.

Alguna cosilla de código

La parrilla tres por tres imágenes implica algún pequeño cambio al bucle de WordPress para poner las clases necesarias a cada primer y tercer ítem. Bastante trivial, de hecho (aunque muy probablemente exista una solución más inteligente). Basta mantener una variable orden_post (o similar) y fijarse en si es 1 o 3 módulo 3 (¿veis como las congruencias servían para algo?):

  <?php 

  $orden_post=0;
  while ( have_posts() ) : the_post(); ?>
  
   <?php $orden_post++; ?>
   <div class="span-8 item 
		<?php if ($orden_post%3==1) echo 'clear '; 
		      if ($orden_post%3==0) echo 'last '; ?>
	">

	...

   </div>

   <?php endwhile; ?>
Captura de pantalla correspondiente a un solo ítem del portafolio
La última errata siemre se esconde en un título...

Otro punto frecuente al personalizar WordPress es la necesidad de sacar una imagen de cada entrada como destacada a la portada. En este caso (comparad la captura anterior con la que primera de este nanoartículo) podemos querer que en portada aparezca un recorte de la imagen principal, y no un mero escalado. El truco, curiosamente, es no hacer nada, dado que WordPress ya viene preparado por defecto para esta eventualidad (de haberlo sabido antes, la de horas que me habría ahorrado). Sólo hace falta indicar en el functions.php que, por ejemplo, queremos

   set_post_thumbnail_size( 310, 230, true );
   add_image_size( 'imagen_entrada', 960, 9999);

y después usar adecuadamente las herramientas de edición de imagen de WordPress para indicarle que en el ‘thumbnail’ queremos un recorte diferente:

Captura de pantalla de la herramienta de edición de imágenes de WordPress
Fijaos en dos cosas: primero, podemos especificar numéricamente el tamaño del recorte (aunque WordPress ya se encarga de forzar las dimensiones que hayamos establecido); segundo, y más importante, podemos especificar que el recorte sea sólo para la miniatura.

Otro detalle que quizás merece atención es el hacer que tanto el nombre de categoría del h2 como los enlaces de cada ítem vayan en el color de la categoría (diseñadores… (-: ). tanto una cosa como la otra están hechas con parches bastante poco bonitos que buscan sustitutos más elegantes (si sabéis de alguno, para eso están los comentarios ;-) ). Para el título, por ejemplo,

<h2>
<?php if (is_single()) {
 echo ('&gt; ');
 foreach((get_the_category()) as $category) {
  echo '<span class="' . $category->slug . 
       '"><a href="http://www.laiablasco.com/portfolio/cat/' . 
       $category->slug . '">' . $category->cat_name . 
       '</a></span> ';
 }
 }; if (is_category()) {
  echo '<span class="generic">&gt;</span> '; single_cat_title();
 }
?>
</h2>

(y definimos, además, en el CSS, clases ‘alineadas’ con los ‘slugs’ de cada categoría, como .category-graphicdesign h2, por ejemplo).

Finalmente, apuntar que los metadatos de cada ítem (técnica, medidas, enlaces y demás) están hechos usando los campos personalizados de WordPress, una solución, que, me da a mí, a la larga será mejor reemplazar con taxonomías o alguna otra solución…

En fin, espero que a alguien le resulte de utilidad en algún momento el tostón. De momento, a mí me ha servido para organizar ideas :-).

Si tienes una web, vigila la seguridad

Estamos de noche electoral y hay que buscar, aunque sea debajo de las piedras, la estadística que diga que hemos ganado algo, o que al menos no nos la hemos pegado tanto como parecía. La nuestra:

Serie numérica de tráfico semanal, desde principios de año: 5278, 5338, 4751, 3376, 3763, 2864, 2636, 2886, 2813, 2927, 2877, 2932, 3137, 3018, 2781, 2585, 2878, 43717, 4406, 4402
Parece que volvemos a sacar la cabeza, después del batacazo de la cuesta de enero. Tráfico (por semanas) de este blog desde el inicio del año. Fuente: eXTReMe Tracking

El año había comenzado muy bien en esta casa y, pasadas las dos primeras semanas del año, parecía incluso que podríamos dejar el tráfico a la altura del pasado septiembre (la gráfica por meses no la voy a enseñar, que me hace daño) y olvidar el último trimestre de 2010. Y entonces, a media tercera semana, Google nos defenestró (a falta de una palabra más violenta): de más de 700 visitas diarias caímos a 400: una caída de alrededor del 45% que servidor atribuyó al refresco de índice que hizo Google por aquellas fechas. Craso error. Y además innecesario y demostrativo de descuido… Porque si tienes una web lo que deberías hacer, como mínimo, es pasar por www.google.com/webmasters/tools/, registrarte y seguir los pasos indicados para acceder a los datos que el buscador tiene sobre tu web y te ofrece (que no son todos, desde luego). Y eso lo había hecho. Hace meses, si no años. Pero lo único que se me ocurrió fue pasar por www.google.com/webmasters/tools/malware y confirmar que, según Google, mi web estaba libre de ‘malware’. Y creérmelo, maldecir mi suerte y seguir. Y es que Google, como he podido comprobar, no te alerta cuando cree que te estás comportando como un ‘link spammer’: sólo lo hace si cree que estás poniendo en peligro la salud informática de tus visitantes. Cosa que yo no hacía. Pero a fe mía que me tenían en la lista negra. Y con toda la razón. Porque lo que debería hecho justo después de comprobar que Google opinaba que estaba libre de ‘malware’ era (y no fue) pasarme por www.google.com/webmasters/tools/keywords. Si lo hubiese hecho habría comprobado (como hice semanas más tarde) que las ‘keywords’ de obm eran una ensalada de términos spammer, con hasta el último producto farmacéutico ‘de moda’ :-(.

Una vez entendido el problema, la solución es [relativamente] fácil: buscar dónde te han colocado el spam (en mi caso, era bastante burdo y fácil de localizar, una vez sabido que había algo que buscar), borrar y, más importante, averiguar cómo te lo están colocando. En el caso de obm, gracias a la inestimable colaboración de Carlos, la cosa fue rápida y localizamos (localizó, vaya) un img.php de aspecto inocente pero que (i) no tenía ningún motivo para estar donde estaba y (ii) contenía una plataforma de lanzamiento de armas de spam masivo en toda regla (el archivo es como para verlo, de verdad: un miniCMS en un solo archivo). En caso de no encontrar el agujero, el procedimiento habría sido un poco más engorroso pero no mucho más complicado: borrar todos los archivos de WordPress, plugins y temas incluidos, y vuelta a subir desde copias seguras. Y asegurarse que estás actualizado a las últimas versiones tanto de WP como de los plug-ins que tengas instalados, que es la única forma de minimizar los riesgos con ese adorable ‘gruyére’ que es WordPress…

Y a partir de ahí, santa paciencia. Porque Google (comprensiblemente, aunque me pese) no te va a quitar de la lista negra así como así, después de que tú te hayas pasado una buena temporada dando por saco… Y te vas a pasar unas cuantas semanas de tu vida observando con preocupación cómo no desaparecen las palabras clave spammers de la lista, buscando agujeros que, con un poco de suerte, ya no existen, mandando a hacer puñetas a Google, recordando después que la culpa es primero del impresentable que te colocó el paquete, mucho después tuya, después del agujero de turno de WP y/o el plug-in que sea y finalmente de Google… y vuelta a empezar :-S.

En fin. La cosa ‘sólo’ me ha costado cerca de 30.000 visitas. Como mínimo, espero haber aprendido que

  1. Hay que tener el CMS y sus plug-ins actualizados (o, si no estás preparado y/o dispuesto a asumir la responsabilidad, tirar de plataforma de publicación ajena) y
  2. Hay que ser consciente de la necesidad de monitorizar qué pasa y analizar por qué pasa.

Toquemos madera…

XSS en algunos temas de WordPress

Hace un par de días un compañero de trabajo me avisaba de que la web de Mosaic, en la que hago «más o menos» de responsable técnico tenía un problema de XSS (inyección de código) en el formulario de búsqueda.

Alarmado, rápidamente actualicé la versión de WordPress a la 2.9.1, pero no conseguí solucionar el problema. La prueba era fácil, poniendo este sencillo script en el formulario de búsqueda

<script>alert("hola");</script>

Se abría un cuadro de diálogo de alerta.

Hoy, con tranquilidad, me he dedicado a investigar. El error se produce sólo en algunos blogs de WordPress, no en todos. Por tanto no es un problema del gestor de contenidos.

Después de algunas pruebas y algunos cambios, el error ha aparecido. Es un problema de algunos temas de WordPress y es muy fácil de arreglar. En el formulario de búsqueda de los temas que tienen la vulnerabilidad podemos ver algo parecido a esto:

<label for="s"><input type="text" name="s" id="s" size="50" maxlength="200" value="<?php echo get_search_query(); ?>" /></label>

El problema es el echo del código php. Eliminándolo se elimina el problema. Fácil :)

Actualización: Tal como apuntan Javier y Oscar en los comentarios, el problema no es tanto del echo (que permite mostrar la cadena buscada) como el hecho que no se filtre adecuadamente get_search_query().

Por tanto, tal y como propone Javier, en vez de eliminar el echo la solución más elegante es <?php echo htmlentities(get_search_query()); ?>

Mis problemas con WordPress

Lo apunto aquí por si puede ser de alguna utilidad para alguien.

En los últimos tiempos he visto hackeados mis dos blogs creados con WordPress (Badalona bitàcola y Desnivell) cada uno de una manera diferente.

En Badalona bitàcola el ataque consistió en redireccionar al bot de Google a una página basura con cientos de enlaces. El resultado fue que mi página cayó de los índices de Google de una manera espectacular. Lógico, cuando Google llegaba no encontraba mi página, sino otra diferente :( Me di cuenta porque usando la herramienta para webmasters de Google no conseguía verificar la página.

¿Cómo lo solucioné? El problema estaba en el fichero .htaccess Lo malo es que lo tuve que revisar varias veces para encontrar lo que los hackers habían añadido. Estaba después de un buen número de líneas en blanco, de manera que al abrir el fichero con un editor de texto normal no era fácil darse cuenta de que habían cosas añadidas…

En Desnivell el ataque fue a más mala leche. Al entrar en la página de administración del blog, intentaba descargar un troyano en mi ordenador. El antivirus detectó el problema. La primera cosa que intenté fue borrar todo WordPress y subir de nuevo la última versión. No funcionó… Evidentemente la nueva versión no machaca el fichero config.php y allí estaba el problema.

Afortunadamente, cuando me disponía a borrarlo todo y empezar de nuevo se me ocurrió que podría ser problema del config.php… Eso sí las líneas añadidas también estaban «escondidas», esta vez, poniéndolas hacia la derecha.

Así que, si tienes problemas con tu WordPress, mírate los ficheros .htaccess y config.php antes de borrar nada.

PS 20090313 NdE El plugin WP Security Scan puede ser una idea para reducir un punto el riesgo de ‘hackeo’…

PS 20090313 NdE Otro lugar en el que buscar ideas: 18 Useful Plugins & Hacks To Protect Your WordPress Blog.

WordPress, ‘titles’, ‘alts’ y ‘captions’…

La interfaz de WordPress avisa que usará el mismo texto para la 'leyenda' de la imagen
¿Debe usarse la 'leyenda' como 'texto alternativo'?

…o títulos, leyendas y textos alternativos, si somos más respetuosos con el idioma. Cuenta WordPress desde hace un tiempo con una interfaz ‘muy apañá’ para subir imágenes a nuestras entradas. Y aún así, cada vez que la uso la maldigo un poco… Y es que esa insistencia en usar un único campo para leyenda (o pie de foto) y texto alternativo de una imagen es bastante contraproducente.

  • Dice el W3C que el atributo title puede anotar diversos elementos (entre ellos, los a y los img). Los agentes de usuario visuales (también conocidos como navegadores) los pueden mostrar, por ejemplo, como «tool tips» si nos paramos con el ratón sobre el elemento en cuestión, mientras que los auditivos (los lectores de pantalla) podrían leer en voz alta el contenido del atributo al pasar por él. Aunque solo es una sugerencia.
  • También cuenta el W3C que el atributo alt debe especificarse para los elementos img y area (y es opcional en input y applet). El atributo da un texto alternativo a la imagen (o applet o…) a usar cuando el agente de usuario no puede mostrarla (como es el caso con los lectores de pantalla o los dispositivos que transforman texto en braille). Para hacernos una idea, si nos estuviesen «contando la página por teléfono» sería lo que querríamos que nos dijesen al llegar a la imagen.
  • Finalmente, según el DRAE, entre otras cosas la leyenda es el texto que acompaña a un plano, a un grabado, a un cuadro, etc. Vamos, el texto que ponen bajo la foto los diarios…

Uno entiende que WordPress exija un ‘título’ para las imágenes: de alguna forma hay que guardarlas en la base de datos. No entiende tanto que coloque ese título como elemento title de las imágenes por defecto y sin preguntar. Pero directamente no le cuadra nada que texto alternativo y leyenda sean una misma cosa: en la mayoría de casos nadie pondría como leyenda la descripción del contenido de la imagen. Cuando el blogger poco familiarizado con temas de accesibilidad (¿podemos suponer que la inmensa mayoría?) sube una imagen, piensa en el pie de imagen… y acaba castigando al que debe usar un lector de pantalla con un texto duplicado y que, de regalo, le deja en muchos casos sin la más remota idea de qué hay en la imagen. Para los que nos preocupamos algo más del tema (no tanto como deberíamos, pero lo tenemos en mente), la herramienta nos obliga luego a buscar en la entrada y poner las cosas como corresponde, haciéndonos perder un minuto innecesariamente. WordPress, además, presume de su atención a los estándares web o sea que, aprovechando que se acerca verisón nueva, ¿por qué no darle un repaso al tema?