Ejemplos prácticos para integrar pases de fotos (slideshows jQuery) dinámicos

Nuevas funciones en WordPress 3.6 para trabajar con galerías y pases de fotos como Supersized o Backstretch

Aparte de las novedades más populares, como el nuevo diseño por defecto “Twenty Thirteen”, las mejoras en la gestión de los menus, revisiones, incrustación automática de audio y vídeo, etc. WordPress 3.6 presenta algunas funciones nuevas muy útiles para ayudarnos con la gestión de galerías, pases de fotos y elementos multimedia adjuntos en entradas y páginas, especialmente convenientes, por ejemplo, si utilizamos herramientas como Supersized o Backstretch para generar pases de fotos con jQuery a pantalla completa.

Estas nuevas funciones son:

get_post_gallery()

Recupera la primera galería de una entrada concreta, en caso de que haya sido creada previamente en la entrada original. También podemos utilizar “get_post_galleries”, que nos devolverá todas las galerías, en vez de únicamente la primera.

get_post_gallery_images()

Nos devuelve una lista de URLs (array) de todas las imágenes incluídas en la primera galería de una entrada específica. Si tenemos más de una galería en una entrada, podemos utilizar la función en plural, get_post_galleries_images(), que nos devolverá una lista (una matriz multidimensional) con las URLs de las imágenes incluídas en todas las galerías de una entrada.

has_shortcode

Comprueba si una entrada o página contiene un shortcode específico insertado en el contenido, por ejemplo [ gallery ]. Esto simplifica por ejemplo la tarea de cargar archivos Javascript de manera condicional cuando existe una galería.

get_attached_media()

Otra nueva función en WordPress 3.6. En este caso sirve para obtener los archivos multimedia adjuntos a una entrada, sean de tipo imagen, audio, vídeo…

Vamos a ver algunos ejemplos prácticos.

Recuperar e insertar galerías con get_post_gallery()

En su uso más simple, get_post_gallery() nos puede servir por ejemplo para recuperar una galería de fotos de otra entrada e insertarla donde queramos: en un lateral (sidebar), al final de otra entrada, en el pie de página o en cualquier otro lugar de las plantillas que forman parte de un theme de WordPress.

En otras palabras, esta función nos puede servir para incluir galerías en lugares poco frecuentes, siempre y cuando esta galería ya exista previamente en la entrada original (es decir, no nos funcionará si las imágenes solo estan adjuntas a esa entrada).

// Recuperamos la galería de fotos de la entrada con ID = 25
$special_gallery = get_post_gallery('25');
if ( $special_gallery ) 
	echo $special_gallery; 

Podemos pegar este código (editando lógicamente el identificador de la entrada y, si queremos, la variable también) en cualquier plantilla:

  • En single.php o content-single.php, para mostrar la galería antes o después del contenido de una entrada en particular
  • En sidebar.php, para mostrar la galería en algún bloque lateral
  • En footer.php, para mostrar una galería en el pie de página, por ejemplo para destacar trabajos o fotos recientes, o cualquier otra cosa
  • En functions.php, si queremos incorporarlo a alguna función para un uso más global

Además, podemos personalizar el resultado como queramos. Si necesitamos que el resultado final sea una lista (ul) de imágenes (li) con miniaturas (img):

// Recuperamos la galería de fotos de la entrada con ID = 25.
// Sustituir por $post o cualquier otro identificador, 
// según la funcionalidad deseada.
$special_gallery = get_post_gallery( '25', false );
$ids = explode( ",", $special_gallery['ids'] );
$html = '<ul class="mi-clase">';
foreach( $ids as $id ) {
	$link   = wp_get_attachment_url( $id );
	$image  = wp_get_attachment_image( $id, "thumbnail");
	$html .= '<li><a href="' . $link . '">' . $image . '</a></li>';
} 
$html .= '</ul>';
echo $html;

Lo que obtendremos será:

<ul class="mi-clase">
	<li><a href="http://ruta/foto/original/1.jpg"><img width="150" height="150" src="http://ruta/foto/miniatura/1.jpg" class="attachment-thumbnail" alt="Descripcion de la foto" /></a></li>
	<li><a href="http://ruta/foto/original/2.jpg"><img width="150" height="150" src="http://ruta/foto/miniatura/2.jpg" class="attachment-thumbnail" alt="Descripcion de la foto" /></a></li>
	<li><a href="http://ruta/foto/original/3.jpg"><img width="150" height="150" src="http://ruta/foto/miniatura/3.jpg" class="attachment-thumbnail" alt="Descripcion de la foto" /></a></li>
</ul>

Si necesitamos un resultado un poco menos habitual, como una lista de URLs para pasar a alguna herramienta de pases de fotos como Supersized, podemos cambiar el código de esta manera:

// Recuperamos la galería de fotos de la entrada con ID = 25.
// Sustituir por $post o cualquier otro identificador, según
// la funcionalidad deseada.
// Resultado adaptado para integrar Supersized con WordPress
$special_gallery = get_post_gallery( '25', false );
$ids = explode( ",", $special_gallery['ids'] );
$html = '';
foreach( $ids as $id ) {
	$link   = wp_get_attachment_url( $id );
	$html .= ",{ image: '$link' }";
}
// Eliminamos la última coma (la primera, en realidad)
$html = substr($html, 1); 
echo $html;

Lo que obtendremos en este caso será:

{ image: 'http://ruta/foto/1.jpg' },
{ image: 'http://ruta/foto/2.jpg' },
{ image: 'http://ruta/foto/3.jpg' },
{ image: 'http://ruta/foto/4.jpg' },
{ image: 'http://ruta/foto/5.jpg' }

Lo que hemos hecho es modificar el contenido que acompaña a cada ruta de imágen para ajustarlo a las necesidades de Supersized, es decir, una lista de URLs precedidas de “image:”, enmarcadas entre llaves “{ }” y separadas por comas. Para eliminar la última coma, especialmente problemática para navegadores obsoletos como Internet Explorer 8, utilizamos la función substr.

O si necesitamos una lista de URLs para pasar a Backstretch, otra herramienta popular para crear pases de fotos o slideshows a pantalla completa, tendremos que modificar el código de esta manera:

// Recuperamos la galería de fotos de la entrada con ID = 25.
// Resultado adaptado para integrar Backstretch con WordPress
$special_gallery = get_post_gallery( '25', false );
$ids = explode( ",", $special_gallery['ids'] );
$html = '';
foreach( $ids as $id ) {
	$link   = wp_get_attachment_url( $id );
	$html .= ",'$link'";
}
// Eliminamos la última coma (la primera, en realidad)
$html = substr($html, 1); 
echo $html;

El resultado ahora será justo lo que Backstretch espera, una lista de URLs de imágenes enmarcadas entre comillas simples, y separadas por comas. Para eliminar la coma del final, utilizamos la misma función “substr” de PHP que hemos usado más arriba.

'http://ruta/foto/1.jpg',
'http://ruta/foto/2.jpg',
'http://ruta/foto/3.jpg',
'http://ruta/foto/4.jpg',
'http://ruta/foto/5.jpg'

Cómo insertar galerías con “do_shortcode” y comprobar con “has_shortcode”

Aunque menos eficiente a nivel de rendimiento, otra manera sencilla de insertar galerías en cualquier sitio es utilizando la función do_shortcode, presente en WordPress desde la versión 2.5.

do_shortcode nos permite ejecutar cualquier shortcode en cualquier lugar de nuestras plantillas PHP, es decir, directamente en el código, fuera del editor de WordPress, por tanto, si pasamos el shortcode [ gallery ] (sin los espacios) junto con los parámetros que nos interesen (como número de columnas, identificador, IDs de imágenes, tamaño, etc.), tendremos galerías a medida en el sitio que queramos, algo muy útil para poder crear diseños más elaborados e interesantes.

// Mostramos una galería con las fotos de la entrada con ID = 10:
// Ojo, eliminar espacios interiores entre los corchetes
echo do_shortcode('[ gallery id="10" ]');
// Mostramos una galería a 4 columnas y tamaño mediano con las fotos especificadas:
// Ojo, eliminar espacios interiores entre los corchetes
echo do_shortcode('[ gallery columns="4" ids="15,14,13,12,11" size="medium" ]');

Después, si necesitamos saber si el contenido de una entrada tiene una galería insertada o no a través de un shortcode, podemos utilizar la función has_shortcode, introducida en WordPress 3.6.

Por ejemplo, pongamos que necesitamos dar una estructura o estilo diferente a las páginas con galerías y utilizar un condicional para diferenciar los dos tipos:

<?php 
if ( has_shortcode( $post->post_content, 'gallery' ) ) {
     // La entrada tiene al menos una galería.
     // Aquí iría la estructura o estilos para este caso.
} else {
     // La entrada no tiene galería.
     // Estructura o estilos para este caso.
}
?>

Otro ejemplo: pongamos que queremos añadir un script concreto solo para que se cargue en las entradas que contienen al menos una galería (para no cargar innecesariamente el resto de la web). En este caso, podríamos añadir este código en el archivo functions.php:

function mytheme_custom_scripts() {
     global $post;
     if ( has_shortcode( $post->post_content, 'gallery') ) {
          // Cargamos este script solo en las páginas y entradas con galerías
          wp_enqueue_script( 'my-script-for-galleries' );
     }
}
add_action( 'wp_enqueue_scripts', 'mytheme_custom_scripts');

Integración de Supersized y WordPress con ‘get_post_gallery_images’

Con la función get_post_gallery_images(), en vez de una galería tendremos una lista de URLs de las imágenes (es decir, la dirección única, la ruta de cada foto). Cualquiera que haya utilizado herramientas (plugins de jQuery, concretamente) como Supersized o Backstretch sabe que para integralas con WordPress lo que necesitamos es incluir de manera dinámica esa lista de direcciones.

Aunque existen plugins como WP Supersized o Envoke Supersized que facilitan la tarea de integrar ambas herramientas sin tener que editar nada, lo más probable es que estos plugins hagan mucho más de lo que en realidad necesitamos, y que seguramente sobrecarguen bastante más el sistema de lo necesario.

El ejemplo que hay en la propia página del Codex de WordPress sobre la función ‘get_post_gallery_images’ no tiene una utilidad muy práctica. Lo que hace es filtrar “the_content” para añadir una función que imprimirá la lista de URLs de todas las fotos al final de la entrada (ver imagen):

Ejemplo get_post_gallery_images

Ejemplo poco práctico de uso de la función get_post_gallery_images.

Pero este ejemplo sí que sirve para darnos una idea de las posibilidades de esta nueva función. Algo más práctico sería, por ejemplo, aprovechar esta nueva función para crear un pase de fotos o slideshow a pantalla completa. Si utilizamos Supersized, que es una de las herramientas más populares para esta tarea, podemos hacerlo de dos maneras: estática o dinámica.

Si lo montamos todo de manera estática, no tenemos ningún problema. Solo tenemos que incluir manualmente la lista de imágenes que queremos mostrar directamente en el código que activa este módulo:

<script>
	jQuery(function($){
		$.supersized({
			slideshow: 1,
			autoplay: 1,
			transition: 6,
			slides: [
				{ image: 'http://ruta/foto/1.jpg' },
				{ image: 'http://ruta/foto/2.jpg' },
				{ image: 'http://ruta/foto/3.jpg' }
			]
		});
	});
</script>

Pero si trabajamos con un gestor de contenido dinámico es para ofrecer al usuario la posibilidad de modificar cosas él mismo. En este caso, podemos utilizar esta nueva función para recuperar las URLs de las imágenes que queremos añadir a Supersized, ahorrándonos así los plugins.

Primero tendremos que añadir este fragmento de código en nuestro archivo de funciones ‘functions.php’:

function mytheme_supersized_gallery_urls() {

	global $post;

	// Si no estamos en una plantilla de tipo "is_singular",
	// es decir, is_single, is_page o is_attachment,
	// salimos sin hacer nada.
	if( ! is_singular() )
		return $content;

	// Si la entrada no incluye una galería, salimos sin hacer nada.
	if( ! has_shortcode( $post->post_content, 'gallery' ) )
		return $content;

	// Recuperamos las imágenes de la primera galería de la entrada.
   // Ojo, esta función es nueva en WordPress 3.6
	$gallery = get_post_gallery_images( $post );

	// Preparamos una variable para guardar el resultado.
	$fotos = '';
	
	// Para cada imagen de la galería...
	foreach( $gallery as $image ) {
		
		// Rellenamos nuestra variable con el contenido.
		// Adaptamos el formato para el plugin Supersized:
		$fotos .= ",{ image: '$image' }";
	}
	
	// Eliminamos la coma del final, especialmente problemática 
	// para navegadores obsoletos, como Internet Explorer 8
	$fotos = substr($fotos, 1); 
	
	// Imprimimos la lista de fotos con el formato deseado
	echo $fotos;

}

Después, en vez de incluir las direcciones de las imágenes a mano, directamente en el código de Supersized, incluimos la función que acabamos de crear para que haga su trabajo:

<script>
	jQuery(document).ready(function($) {
		$.supersized({
			slideshow: 1,
			autoplay: 1,
			transition: 6,
			slides: [
				<?php mytheme_supersized_gallery_urls(); ?>
			]
		});
	});
</script>

Nota: Supersized tiene muchas más opciones. En este ejemplo, aparte de la lista de fotos, solo utilizamos como muestra tres de las más frecuentes (slideshow, autoplay y transition), pero se pueden incluir todas las que necesitemos.

Integración de Backstretch + WordPress con ‘get_post_gallery_images’

Backstretch es un plugin de jQuery que sirve para añadir imágenes que se adaptan dinámicamente al tamaño del navegador, con la posibilidad de crear pases de fotos a pantalla completa o dentro de cualquier bloque HTML.

Para integrarlo con WordPress, el mismo código que hemos usado más arriba para Supersized nos sirve también para Backstretch, lo único que tenemos que cambiar será el formato de la lista de imágenes (en la linea 27), que en el caso de Backstretch es mucho más simple: solamente necesita una lista de URLs entrecomilladas y separadas por una coma:

$fotos .= ',"$image"';

Después, en vez de incluir a mano todas las imágenes que queremos utilizar en el pase de fotos, añadimos la función que se encargará de recuperarlas dinámicamente:

jQuery(document).ready(function($) {
	$.backstretch([
	      <?php mytheme_backstretch_gallery_urls(); ?>
	], {duration: 3000, fade: 750});
});

Cómo obtener los archivos adjuntos con “get_attached_media”

Get_attached_media es otra de las funciones nuevas presentadas en WordPress 3.6. Lo que hace es entregarnos una lista de archivos multimedia adjuntos a la entrada que queramos.

Para conseguir esto, hasta ahora teníamos que pasar una serie de argumentos por medio de get_children:

$args = array(
	'post_parent' => $post->ID,
	'post_type' => 'attachment',
	'post_mime_type' => 'image',
	'posts_per_page' => -1,
	'orderby' => 'menu_order',
	'order' => 'ASC',
);
$attachments = get_children( $args );

Pero “get_attached_media()” simplifica mucho más la tarea permitiéndonos hacer consultas muy concretas en una sola linea:

// Recuperamos todos los adjuntos de tipo "imagen"
$media = get_attached_media( 'image' );

// Obtenemos los adjuntos de tipo "audio" de la entrada con ID 102
$media = get_attached_media( 'audio', 102 );

// Recuperamos todos los videos adjuntos
$media = get_attached_media( 'video', $post->ID );

// Obtenemos todos los archivos, independientemente de su tipo
$media = get_attached_media( '', $post->ID );

Por ejemplo, podríamos obtener todos los archivos adjuntos a la entrada con ID ‘101’ y después imprimir la lista de esta manera:

$media = get_attached_media( '', 101 );
if ( $media ) {
	foreach ( $media as $attachment ) {

		// HTML completo de la imagen, en el tamaño que seleccionemos
		echo wp_get_attachment_image( $attachment->ID, 'medium' );
		
		// URLs limpias del archivo original, sin código HTML adicional (para Supersized, Backstretch, etc.)
		// echo wp_get_attachment_url( $attachment->ID );

	}
}

Conclusión

Aunque todo esto ya se podía conseguir antes de la versión 3.6, montar páginas web con WordPress es como construir cosas con Tente o con Lego. Tienes piezas que sirven y soluciones propias a problemas frecuentes, pero de vez en cuando presentan una pieza para una función específica que no solo te facilita el trabajo sinó que te permite ir más lejos y montar proyectos más sofisticados, de manera más elegante y eficiente, utilizando funciones nativas del sistema sin tener que escribir códigos complicados ni recargarlos innecesariamente.

Comentarios

  1. Gabriel Flores Olea

    Buenas noches, me han servido las funciones aquí descritas, sin embargo tengo una duda, ¿existe alguna función o forma de obtener el título/nombre del adjunto? Mi caso en particular estoy recuperando archivos de audio, y necesito obtener los títulos para ponerlos como el texto del enlace, gracias.

  2. Daniel

    Hola Gabriel. Una manera de obtener datos relacionados con los archivos adjuntos sería asignar una variable que incluya todos los datos, y después recuperar los que nos interese dentro de un bucle “foreach”.

    Por ejemplo, aquí primero pedimos todas las imágenes de la entrada, y después recuperamos el título de cada imagen, el bloque HTML y el tamaño que necesitamos:

    // Obtenemos información de los adjuntos
    function prefix_slideshow() {
    	global $post;
    	$images = get_attached_media( 'image' );
    	$slides = '';
    	if ( $images ) {
    		foreach ($images as $image) {
    			$image_title = $image->post_title;
    			$image_html = wp_get_attachment_image($image->ID, 'medium');
    			$image_url = wp_get_attachment_url($image->ID, false);
    			$slides .= "<div class='slide'><a href='$image_url' title='$image_title'>$image_html</a></div>";
    		}
    		echo $slides;
    	}
    }
    

    También podemos acceder a la descripción y a la leyenda (caption) de los adjuntos, añadiendo estas variables:

    $image_caption = $image->post_excerpt;
    $image_description = $image->post_content;

  3. Antonio

    ¿Como puedo habilitar la opción del botón derecho, “Guardar imagen como…”, en las galerías nativas de WordPress?.

  4. Francisco

    Hola daniel mi duda es donde creo la galería para obtener la id, por que por ej en multimedia no se pueden crear carpetas de imágenes que me entreguen una id, saludos.

  5. Yoan Sierra Tejeda

    Hola saludos! como hago para solo mostrar una URL en la funcion de arriba?
    como resultado se imprime esto


    'http://ruta/foto/1.jpg',
    'http://ruta/foto/2.jpg',
    'http://ruta/foto/3.jpg',
    'http://ruta/foto/4.jpg',
    'http://ruta/foto/5.jpg'

    y yo solo quiero extraer:
    http://ruta/foto/1.jpg
    es decir extraerlo sin las comillas?

Y tú qué opinas?

Las URLs se convertirán en enlaces automáticamente. Tu dirección de email no se publicará ni se utilizará para enviar ningún tipo de información. Los mensajes que no aporten nada al tema que se trata en esta entrada se borrarán. Las imágenes que aparecen al lado de cada autor utilizan el servicio de Gravatar. Recuerda que puedes usar etiquetas HTML como <a href>, <code>, <em> o <strong> en los comentarios.

(necesario)

(opcional)