WP desde cero (7): imágenes

En esta entrada aprenderemos a insertar imágenes en el loop según el tipo de conexión del usuario (normal o móvil).

Roy Lichtenstein

archivado en: WordPress / 5 diciembre, 2012 / taller:

Desde la versión 2.9, WordPress permite establecer una imagen destacada en las entradas.

[singlepic id=35 w=352 h=125 float=center]

Esta imagen se puede recuperar en el loop, lo que ha permitido otro tipo de diseños, menos parecidos a los blogs antiguos, similares a un magazine digital, como sucede en esta bitácora.

[singlepic id=34 w=490 h=326 float=center]

Entonces, lo primero que debemos hacer es habilitar las imágenes destacadas en nuestro tema. Para eso, crearemos un archivo llamado functions.php, donde a partir de ahora iremos añadiendo las utilidades que no vienen por defecto en el motor de WordPress. En ese archivo, incluimos el encabezado (con el nombre del tema que cada cual esté utilizando):

  • <?php
  • /*
  • * @package WordPress
  • * @subpackage mmfilesi-bones
  • * @since mmfilesi-bones 1.0
  • */
  • ?>

Y a continuación añadimos la siguiente sentencia, que dejaremos comentada para saber en un futuro cuál es su utilidad.

  • <?php
  • /*-----------------------------------------------
  • Funcionalidades añadidas
  • ----------------------------------------------- */
  • // añadir miniaturas
  • add_theme_support( 'post-thumbnails' );
  • ?>

A partir de ahora, cada vez que se añada una imagen destacada a un post, WordPress subirá la imagen y, además, generará de forma automática dos copias, una mediana y otra más pequeña, de la imagen.

[singlepic id=36 w=293 h=244 float=center]

Aunque se puede hacer por código en functions.php, el tamaño de estas dos copias los especifica el usuario en Ajustes > Multimedia.

[singlepic id=37 w=569 h=301 float=center]

Así, cuando se sube una imagen destacada, lo que hace WordPress es buscar el lado más largo, reducirlo al tamaño indicado en los Ajustes (300px o el que sea) y reducir el otro lado proporcionalmente.

Imágenes personalizadas

Si además de las que vienen por defecto en WordPress, es decir, los dos tamaños que especifica el usuario, queremos que se generen más copias con tamaños personalizados hay que añadir una función al archivo functions.php: add_image_size(). Su sintaxis es:

  • <?php add_image_size( $name, $width, $height, $crop ); ?>

En el primer parámetro se indica, entre comillas simples, el nombre de la nueva copia, el cual se utilizará más adelante para recuperarlo; en el segundo, el ancho, en el tercero, el alto; y en el último un valor booleano (true o false, 1 ó 0) para indicar si queremos que se recorte (cropped) en el caso de que las medidas no se puedan redimensionar. Por ejemplo, si ponemos que la imagen debe tener 150px de alto y 150px de ancho y subimos una de 600 x 300, como no es escalable, WordPress tiene que recortar por algún lado para ajustarla.

Un ejemplo, así añadimos una miniatura de 200 x 100 llamada mi_miniatura, la cual se recortará al estar definido el último parámetro como true.

  • if ( function_exists( 'add_image_size' ) ) {
  • add_image_size( 'mi_miniatura1', 200, 100, true );
  • }

Esta en cambio, que tiene un ancho máximo imposible (9999), nunca se recortará. Solo reducirá el ancho y luego el alto proporcionalmente.

  • if ( function_exists( 'add_image_size' ) ) {
  • add_image_size( 'mi_miniatura2', 300, 9999 );
  • }

Observad que en ambos casos, la función add_image_size se declara en una estructura condicional de otra función function_exist(), la cual evalúa si esa función existe o no. Esto se hace para que el tema sea compatible con versiones antiguas de WordPress, pero no es realmente necesario, pues raro es el WordPress que no esté actualizado. Bueno, de todas maneras, como este es un tema de carácter didáctico, vamos a hacerlo de la manera ortodoxa.

Las imágenes en el loop

Para recuperar las imágenes en el loop es tan sencillo como usar la función the_post_thumbnail(), que se suele llamar dentro de una estructura condicional con la función has_post_thumbnail(), la cual verifica si hay alguna imagen destacada.

  • <?php
  • if ( has_post_thumbnail() ) {
  • the_post_thumbnail();
  • }
  • ?>

Pero lo suyo, ya que podemos saber con facilidad si hay o no una imagen destacada, es que carguemos una imagen por defecto si no hay ninguna (la típica no picture).

  • <?php
  • if ( has_post_thumbnail() ) {
  • the_post_thumbnail();
  • } else { ?>
  • <img src="<?php echo get_template_directory_uri(); ?>/images/sin_imagenes.jpg" />
  • <?php }

Importante: fijaos en que para especificar la ruta de la imagen a mostrar por defecto he usado la misma función que servía para localizar los scripts: get_template_directory_uri().

Para recuperar una copia en concreto se especifica como argumento en la función:

  • the_post_thumbnail(); // Sin argumento: escoge la más pequeña
  • the_post_thumbnail('thumbnail'); // la copia pequeña (x defecto, el lado más grande 150px)
  • the_post_thumbnail('medium'); // la copia mediana (el lado más grande 300px)
  • the_post_thumbnail('large');  // la copia larga cuando se ha incluido al añadir la imagen (640px)
  • the_post_thumbnail('full'); // la copia original

Y especificando el nombre que veíamos antes para obtener una copia de tamaño personalizado:

  • <?php
  • if ( has_post_thumbnail() ) {
  • the_post_thumbnail('mi_miniatura1');
  • } else { ?>
  • <img src="<?php echo get_template_directory_uri(); ?>/images/sin_imagenes.jpg" />
  • <?php } ?>

Arrays asociativos

Ya vimos en la entrada anterior qué eran las matrices o arrays y cómo funcionaban las arrays asociativas vinculando pares de elementos (clave/valor) mediante el operador =>. Como WordPress trabaja mucho con bucles y arrays, vamos a profundizar un poco más en el tema.

En los arrays sencillos, cada elemento tiene un índice formado por su posición. Por ejemplo, este array de culturas mesoamericanas:

  • $culturas_mesoamericanas =  array ("olmecas", "mixtecas", "mayas", "aztecas");

equivale a:

  • $culturas_mesoamericanas =  array (
  • 0 => "olmecas",
  • 1 => "mixtecas",
  • 2 => "mayas",
  • 3 => "aztecas"
  • );

Para acceder a los elementos del array basta con referirse a su posición. Por ejemplo,

  • <?php echo $culturas_mesoamericas[2]; ?>

devolvería en pantalla: «mayas».

En los arrays asociativos, en vez de emplear una numeración autoincremental como clave, como índice, se usa otro dato. (Observad que cada par clave valor está separado por comas).

  • array (
  • clave => valor,
  • clave2 => valor2,
  • clave3 => valor3,
  • ... )

Por ejemplo, este sería un array asociativo donde las claves serían las culturas y el valor las ciudades correspondientes:

  • $culturas_mesoamericanas =  array (
  • "olmecas" => "tabasco",
  •  "mixtecas" => "actalán",
  • "mayas" => "palenque",
  • "aztecas" => "tenochtitlan"
  • );

Ahora si escribiéramos:

  • <?php echo $culturas_mesoamericanas['mayas'] ?>

Obtendríamos la cadena de texto «palenque». Volvamos ahora con el loop de WP.

Atributos

En la función the_post_thumbnail() se puede indicar como un segundo argumento opcional un array para modificar algunos atributos de la etiqueta imagen, como class, title, src y alt.

  • $default_attr = array(
  • 'src' => $src,
  • 'class' => "attachment-$size",
  • 'alt' => trim(strip_tags( $wp_postmeta->_wp_attachment_image_alt )),
  • 'title' => trim(strip_tags( $attachment->post_title ))
  • );

El único que realmente nos interesa ahora es class, ya que los demás van bien con los valores por defecto. Trataré de explicarme un poco mejor.

Cuando llamamos a la función the_post_thumbail() en el loop, el código que se genera dinámicamente es similar a este:

  • <img width="300" height="237" src="ruta de la imagen" class="attachment-medium wp-post-image" alt="nombre de la imagen" title="nombre de la imagen" />

La ruta (src) no tendríamos por qué cambiarla nunca y con el title y el alt que genera por defecto va bien. Para el title coge el nombre de la imagen y para el alt el que se ha especificado al subir la imagen o, si no existe, su nombre, lo cual nos recuerda que los los nombres de las imágenes siempre deben ser identificativos y no cábalas del tipo "pic08263.gif" (una buena práctica que, además, repercute en el SEO).

[singlepic id=38 w=500 h=167 float=center]

Sin embargo, sí que nos interesa mucho poder indicar la clase, ya que necesitaremos usar una específica para las imágenes responsive. Por lo tanto, en nuestra función the_post_thumbail(), al menos, pondremos la clase en el segundo argumento:

  • <?php the_post_thumbnail('full', array('class' => 'imagenes_elasticas')); ?>

Lo cual nos dará un código similar a este (sí, se pueden indicar dos nombres de clase en un mismo elemento separados por espacios).

  • <img... class="imagenes_elasticas wp-post-image" ... >

Recuperar la imagen directamente

Como ocurre con las demás funciones del loop, también en este caso podemos recuperar directamente los datos. No voy a explicarlo en detalle, porque ya he sobrepasado las fronteras del toxo-post hace rato, pero lo dejo apuntado:

  • <?php if (has_post_thumbnail()) : ?>
  • <?php
  • $image_id = get_post_thumbnail_id();
  • $image_url = wp_get_attachment_image_src($image_id,'medium', true); ?>
  • <img src="<?php echo $image_url[0]; ?>" >
  • <?php else : ?>
  • <img src="ruta por defecto" />
  • <?php endif; ?>

Cargar tamaños dinámicamente

Para terminar, un poquito de responsive design. Como ya he comentado alguna vez, es una lástima enviar muchos datos a través de una conexión móvil. Por lo general, se tiene una tarifa plana muy limitada, en la que cada dato recibido consume un poco del cupo mensual, y los móviles se utilizan para navegar en sitios de mala conexión, como el metro o el autobús. Por lo tanto, es mejor si analizamos cuál es la conexión del usuario y, en función de eso, enviamos las imágenes grandes o las pequeñas.

No es muy conocida, pero desde la versión 3.4., WordPress tiene una función para reconocer la conexión del usuario:  wp_is_mobile(). No es tan potente como la clase Mobile-Detect de Serban Ghita y Victor Stanciu, pero funciona. La sintaxis es muy sencilla:

  • <?php wp_is_mobile(); ?>

Devuelve un valor booleano: true si la conexión viene un móvil y false en el caso contrario. Así, podemos cargar la imagen grande en el caso de que sea una conexión normal y una copia pequeña si es un móvil:

  • <?php if ( wp_is_mobile() ) {
  • <?php the_post_thumbnail('medium', array('class' => 'imagenes_elasticas')); ?>
  •  } else {
  • <?php the_post_thumbnail('full', array('class' => 'imagenes_elasticas')); ?>
  • ?>

Podríamos añadir un tamaño personalizado, pero no compensa. Me explico: la resolución de los móviles suele oscilar entre los 240 píxeles, cuando están en vertical, y los 320, cuando están apaisados. Como haremos las imágenes elásticas, nos vale la miniatura de 300, que se estirará apenas un poco cuando se vea grande, sin merma perceptible de la calidad, y que no supondrá mucho peso añadido superfluo en vertical.

Así, incluyendo entonces la imagen destacada, nuestro loop debería tener ya un aspecto similar a este:

  1. <div id="primary">
  2. <?php while (have_posts()) : the_post(); ?> <!-- principio del loop -->
  3. <article>
  4. <?php if ( wp_is_mobile() ) {
  5. if ( has_post_thumbnail() ) {
  6. the_post_thumbnail('medium', array('class' => 'imagenes_elasticas' ));
  7. } else { ?>
  8. <img src="<?php echo get_template_directory_uri(); ?>/images/sin_imagenes.jpg" class="imagenes_elasticas"/>
  9. <?php }
  10. } else {
  11. if ( has_post_thumbnail() ) {
  12. the_post_thumbnail('full', array('class' => 'imagenes_elasticas' ));
  13. } else { ?>
  14. <img src="<?php echo get_template_directory_uri(); ?>/images/sin_imagenes.jpg" class="imagenes_elasticas" />
  15. <?php }
  16. } ?>
  17. <header>
  18. <h3><a href="<?php the_permalink( ); ?>"> <?php the_title() ; ?> </a></h3>
  19. </header>
  20. <?php the_excerpt() ; ?>
  21. <aside>
  22. <p><?php _e('Clasificado en: ','mmfilesi-bones'); ?>
  23. <?php the_category(', '); ?></p>
  24. <p><?php the_tags(); ?></p>
  25. <?php _e('Escrito el: ','mmfilesi-bones'); ?>
  26. <?php the_time('j/m/Y'); ?></p>
  27. </aside>
  28. </article>
  29. <?php endwhile; ?> <!-- final del loop -->
  30. </div> <!-- #primary -->

Como el código empieza ya a adquirir cierta complejidad, a partir de ahora iré subiendo los archivos de cada entrada de esta serie a Git Hub a medida que los vayamos viendo.

ver archivos de esta entrada en Git Hub

Advertencia final

Por razones que no vienen al caso, cada vez que cargamos una imagen estamos haciendo una llamada a la base de datos (una query), por lo que si el servidor es poco potente, hay muchas imágenes y muchas conexiones de golpe, la página se puede ralentizar muchísimo. (Y cuando hablo de muchas conexiones quiero decir miles y miles... 30.000, 40.000 al mismo tiempo). Por lo tanto, si una web tiene muchísimo tráfico y vais a incluir las imágenes, aseguraos de que tenéis contratado un buen plan.

Bueno, pues por hoy ya está bien  :-), el próximo día empezamos con las CSS.

|| Tags: , ,

valoración de los lectores sobre WP desde cero (7): imágenes

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 4.8 sobre 5 (13 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

9 respuestas a “WP desde cero (7): imágenes

  1. Genial el aporte que hiciste.
    Entonces convengamos de que
    con esto me puedo asegurar de
    que el sitio vaya mas rapido y sea m
    mas liviano, cierto? Abrazos y saludos

  2. Hola Edgard, gracias.

    Sí, el truco es calibrar bien el tamaño de las imágenes y usar los tamaños -medium, full…- en the_post_thumbnail();

  3. José Quilón el dijo:

    Hola, estoy haciendo este curso de wordpress y en esta lección me surge un fallo, en la versión móvil no se ve la imagen, tiene el código algún error que no detecto o falta algo, no me gustaría continuar con esta duda, saludos y gracias, es un curso muy bueno.

  4. José Quilón el dijo:

    Hola de nuevo, he seguido investigando sobre el porque no se ven las imágenes si accedo desde mi móvil o tablet en mi red local pero intuyo que tiene que ser un problema de configuración del servidor local pues me ocurre con todos los temas ni muestra imágenes ni aplica los css, sera por lo de que muestre los errores que configuramos al principio, esto no me ocurre con otras páginas solo con WordPress, perdonen por la brasa, intentare hacer las pruebas con un servidor remoto, saludos y felicidades por el tutorial.

  5. marcos el dijo:

    Hola José, gracias por compartir el resultado de tus investigaciones.

    ¿Estás utilizando XAMPP?

  6. José Quilón el dijo:

    hola, verificado, en remoto va perfecto pero en local no funcionan ni las imágenes ni el css, y el servidor local que uso es Wamp server 2.2, supongo que sera un tema de configuración, saludos y gracias por compartir tus conocimientos.

  7. Antes que nada te agradezco por el genail aporte. Sin embargo tengo una consulta importantísima. Resulta que estoy haciendo sitio web en wordpress con la plantilla desde cero. En index.php coloqué (maqueté casi todo con Bootstrap) un slider de fotos. Acá va lo importante: las imágenes que va rotando y mostrando son 3 ó 4 pero de las PAGINAS. Y acá está problema cuando coloco el loop y las demás cosas; no se como hacerle entender al worpress que tome las thumbnails pero de las páginas y NO de los post (o entradas, es lo mismo). Cómo hago? Cuál es el código o la palabrita que tengo que cambiar? Acá te mando una copia de la parte importante.

    <img src="/img/bootstrap-mdo-sfmoma-01.jpg” alt=””>

    EDIFICAR
    Servicios Inmobiliarios y bodegas

    <img src="/img/bootstrap-mdo-sfmoma-01.jpg” alt=””>