Come creare uno shortcode per visualizzare un custom post all'interno di una pagina o articolo normale?
Vorrei creare uno shortcode che estragga informazioni da un custom post e le visualizzi all'interno di una Pagina o di un Post normale.
Caso d'uso specifico: Ho un custom post type "Film" per un sito web di un festival cinematografico. I film vengono visualizzati con il loro single-film.php, ma occasionalmente i proprietari del sito vogliono scrivere un post o una pagina che menzioni un film particolare e vorrebbero poter estrarre parti delle informazioni già inserite (ad esempio, nome del film, informazioni sulla prenotazione, ecc). Questo andrebbe in un "box" alla fine del post, e vorrei renderglielo facile fornendo una sorta di shortcode.
Come potrei procedere? Ci sono risorse/tutorial consigliati per indirizzarmi sulla strada giusta? Quali trabocchetti dovrei tenere presente (ad esempio, loop multipli in un post)?
// Esempio di soluzione
function film_info_shortcode($atts) {
// Estrai gli attributi
$atts = shortcode_atts(array(
'id' => 0,
), $atts);
// Verifica se l'ID è valido
if (!$atts['id']) {
return 'Specificare un ID film valido';
}
// Ottieni il post
$film = get_post($atts['id']);
// Verifica se il post esiste ed è di tipo 'film'
if (!$film || $film->post_type !== 'film') {
return 'Film non trovato';
}
// Ottieni i meta dati del film
$prenotazione = get_post_meta($film->ID, 'prenotazione', true);
$data = get_post_meta($film->ID, 'data_proiezione', true);
// Costruisci l'output
$output = '<div class="film-box">';
$output .= '<h3>' . esc_html($film->post_title) . '</h3>';
$output .= '<p>' . esc_html($film->post_excerpt) . '</p>';
$output .= '<p>Prenotazione: ' . esc_html($prenotazione) . '</p>';
$output .= '<p>Data: ' . esc_html($data) . '</p>';
$output .= '</div>';
return $output;
}
add_shortcode('film_info', 'film_info_shortcode');
// Uso: [film_info id="123"]

Ci sono ottimi tutorial sugli shortcode in tutta la rete e alcuni buoni esempi qui
ma solo per farti iniziare:
add_shortcode('film_q', 'film_shortcode_query');
function film_shortcode_query($atts, $content){
extract(shortcode_atts(array( // alcuni valori predefiniti
'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>Nome Film: <a href="'.get_permalink().'" title="' . get_the_title() . '">'.get_the_title() .'</a></h4>
<p class="Film_desc">'.get_the_content().'</p>';
// aggiungi qui altro...
$out .='</div>';
/* questi argomenti saranno disponibili all'interno di $content
get_permalink()
get_the_content()
get_the_category_list(', ')
get_the_title()
e campi personalizzati
get_post_meta($post->ID, 'field_name', true);
*/
endwhile;
else
return; // nessun post trovato
wp_reset_query();
return html_entity_decode($out);
}
e per usarlo inserisci in qualsiasi articolo/pagina:
[film_q p=FILM_POST_ID]
basta cambiare FILM_POST_ID con l'ID effettivo del post Film.
Spero sia utile

Ciao... Lo shortcode non estrae correttamente post_type=film, per qualche motivo? Se faccio un var_dump di $posts
, quei valori predefiniti forniti nell'estract non vengono utilizzati affatto? Dovrei restituire qualcosa di diverso da $atts
da usare nel new WP_Query()
?

Immagino che il var_dump di $post non sia nella funzione dello shortcode, se ho ragione allora stai chiamando var_dump nel loop del tuo tema ed è per questo che non vedi gli argomenti che cercavi.

Ah, ho aggiunto questo dopo l'estract: $film_query = 'posts_per_page='.$posts_per_page.'&post_type='.$post_type.'&p='.$id;
e ho usato $film_query
invece di $atts
nella query. Grazie :)

E se il mio film $content
contiene shortcode? Come faccio a farli analizzare correttamente? Dovrei creare un filtro per il contenuto restituito?

Ho costruito $film_query
da usare in $posts = new WP_Query($film_query);
perché $atts
mi forniva solo p=FILM_POST_ID
e non il resto dei valori predefiniti...

Prova a iniziare con questo tutorial.
Nella funzione di callback, esegui una custom_query (o usa get_post) per il post ed estrai solo i valori rilevanti per te. (Ad esempio: titolo, estratto...)
esempio di shortcode
[film id=10]
Usa l'id nella tua funzione per recuperare il contenuto del film.
