¿Cómo crear un shortcode para mostrar una entrada personalizada dentro de una página o entrada regular?
Me gustaría crear un shortcode que extraiga información de una entrada personalizada y la muestre dentro de una Página o Entrada regular.
Caso de uso específico: Tengo un tipo de entrada personalizada "Film" para un sitio web de festival de cine. Las películas se muestran con su propio single-film.php, pero ocasionalmente los propietarios del sitio quieren escribir una entrada o página que mencione una película en particular, y les gustaría poder extraer fragmentos de la información que ya ha sido ingresada (por ejemplo, nombre de la película, información de reservas, etc). Esto iría en una "caja" al final de la entrada, y me gustaría facilitarles el trabajo proporcionándoles algún tipo de shortcode.
¿Cómo podría hacer esto? ¿Hay recursos/tutoriales recomendados que me pongan en el camino correcto? ¿Qué dificultades debería tener en cuenta (por ejemplo, múltiples loops en una entrada)?
Aquí hay un ejemplo de cómo podrías implementar esto:
// Registrar el shortcode
add_shortcode('mostrar_pelicula', 'mostrar_info_pelicula');
function mostrar_info_pelicula($atts) {
// Obtener el ID de la película del shortcode
$atts = shortcode_atts(array(
'id' => 0
), $atts);
// Iniciar el buffer de salida
ob_start();
// Obtener la película
$pelicula = get_post($atts['id']);
if ($pelicula && $pelicula->post_type == 'film') {
// Obtener meta datos personalizados
$fecha = get_post_meta($pelicula->ID, 'fecha_proyeccion', true);
$reservas = get_post_meta($pelicula->ID, 'info_reservas', true);
// Mostrar la información
?>
<div class="info-pelicula">
<h3><?php echo esc_html($pelicula->post_title); ?></h3>
<p><?php echo esc_html($pelicula->post_excerpt); ?></p>
<p>Fecha: <?php echo esc_html($fecha); ?></p>
<p>Reservas: <?php echo esc_html($reservas); ?></p>
</div>
<?php
}
// Retornar el contenido del buffer
return ob_get_clean();
}
Uso del shortcode:
[mostrar_pelicula id="123"]

Hay excelentes tutoriales sobre shortcodes por toda la web y algunos buenos ejemplos aquí
pero solo para empezar:
add_shortcode('film_q', 'film_shortcode_query');
function film_shortcode_query($atts, $content){
extract(shortcode_atts(array( // algunos valores por defecto
'posts_per_page' => '1',
'post_type' => 'film',
'caller_get_posts' => 1)
, $atts));
global $post;
$posts = new WP_Query($atts);
$output = '';
if ($posts->have_posts())
while ($posts->have_posts()):
$posts->the_post();
$out = '<div class="film_box">
<h4>Nombre de la película: <a href="'.get_permalink().'" title="' . get_the_title() . '">'.get_the_title() .'</a></h4>
<p class="Film_desc">'.get_the_content().'</p>';
// añade aquí más...
$out .='</div>';
/* estos argumentos estarán disponibles desde dentro de $content
get_permalink()
get_the_content()
get_the_category_list(', ')
get_the_title()
y campos personalizados
get_post_meta($post->ID, 'field_name', true);
*/
endwhile;
else
return; // no se encontraron posts
wp_reset_query();
return html_entity_decode($out);
}
y para usarlo ingresa en cualquier post/página:
[film_q p=ID_DEL_POST_DE_LA_PELÍCULA]
solo cambia ID_DEL_POST_DE_LA_PELÍCULA por el ID real del post de la película.
Espero que esto ayude

Hola... El shortcode no está extrayendo post_type=film correctamente, ¿por alguna razón? Si hago un var_dump de $posts
, esos valores predeterminados proporcionados en el extract no se están utilizando en absoluto. ¿Debería devolver algo diferente a $atts
para usar en el new WP_Query()
?

Supongo que el var_dump de $post no está en la función del shortcode, si estoy en lo correcto entonces estás llamando a var_dump en el loop de tu tema y por eso no ves los argumentos que buscabas.

Ah, agregué esto después del extract: $film_query = 'posts_per_page='.$posts_per_page.'&post_type='.$post_type.'&p='.$id;
y usé $film_query
en lugar de $atts
en la consulta. Gracias :)

¿Qué pasa si mi contenido de película $content
contiene shortcodes? ¿Cómo hago para que se analice correctamente? ¿Debería crear un filtro para el contenido devuelto?

Construí $film_query
para usar en $posts = new WP_Query($film_query);
porque $atts
solo me daba p=FILM_POST_ID
y no el resto de los valores predeterminados...

Intenta comenzar con este tutorial.
En la función de callback, realiza una custom_query (o usa get_post) para el post y extrae solo los valores que sean relevantes para ti. (Por ejemplo: título, extracto...)
Ejemplo de shortcode
[film id=10]
Utiliza el id en tu función para recuperar el contenido de la película.
