Migas de pan (breadcrumbs) con tipos de contenido personalizados sin plugin
He usado la siguiente función para las migas de pan en todos los sitios hasta ahora, pero el sitio de hoy tiene 3 tipos de contenido personalizados y el cliente desea que las migas de pan funcionen, por ejemplo, en lugar de "inicio / vinos / naire blanco" solo obtenemos "inicio / / naire blanco".
function the_breadcrumb() {
echo '<ol class="breadcrumb" itemprop="breadcrumb">';
if (!is_home()) {
echo '<li><a href="';
echo get_option('home');
echo '">';
echo 'Home';
echo '</a></li>';
if (is_category() || is_single() || is_post_type()) {
echo '<li>';
the_category(' </li><li> ');
echo get_post_type(' </li><li> ');
if (is_single()) {
echo '</li><li>';
the_title();
echo '</li>';
}
} elseif (is_page()) {
if($post->post_parent){
$anc = get_post_ancestors( $post->ID );
foreach ( $anc as $ancestor ) {
$output = $output . '<li><a href="'.get_permalink($ancestor).'" title="'.get_the_title($ancestor).'">'.get_the_title($ancestor).'</a></li> ';
}
echo $output;
echo '<strong title="'.$title.'"> '.$title.'</strong>';
} else {
echo '<li><a class="active" href="';
echo the_permalink();
echo '">';
echo the_title();
echo '</a></li>';
}
}
}
elseif (is_tag()) {single_tag_title();}
elseif (is_day()) {echo"<li>Archivo para "; the_time('F jS, Y'); echo'</li>';}
elseif (is_month()) {echo"<li>Archivo para "; the_time('F, Y'); echo'</li>';}
elseif (is_year()) {echo"<li>Archivo para "; the_time('Y'); echo'</li>';}
elseif (is_author()) {echo"<li>Archivo de Autor"; echo'</li>';}
elseif (isset($_GET['paged']) && !empty($_GET['paged'])) {echo "<li>Archivos del Blog"; echo'</li>';}
elseif (is_search()) {echo"<li>Resultados de búsqueda"; echo'</li>';}
echo '</ol>';
}
Como pueden ver en el código, he intentado agregar || is_post_type()
después de is_category() || is_single()
con un echo get_post_type()
pero esto no hizo nada.
Agradecería algo de orientación por favor.
Gracias

El problema con la mayoría de las funciones de migas de pan es que dependen del objeto $post
en todas las páginas. No solo es que el global $post
sea totalmente poco confiable (ver mi publicación aquí), sino que incluso podría no contener los datos que necesitamos, incluso si el global $post
no está comprometido.
El global $post
en páginas de archivo (que incluyen categoría, etiqueta, fecha, término de taxonomía, autor y archivos de tipos de contenido personalizados) contiene el primer post en el bucle antes del bucle. No siempre es cierto que el primer post sea del archivo seleccionado (la página de archivo en la que estás), lo que significa que la información que buscas podría ser incorrecta, aunque el global $post
no esté comprometido. Las condiciones donde el primer post podría no ser del archivo seleccionado incluyen posts inyectados mediante stickies personalizados y el filtro the_posts
.
Recientemente he reescrito una de mis funciones de migas de pan más antiguas que utiliza el objeto $GLOBALS['wp_the_query']
y el objeto consultado guardado en el global $GLOBALS['wp_the_query']
. De esta manera, tenemos unas migas de pan 99.999% confiables que no dependen del global $post
o de datos comprometidos.
Aquí está la función: (Requiere PHP 5.4+. También, siéntete libre de modificarla según sea necesario)
function get_hansel_and_gretel_breadcrumbs()
{
// Establecer variables para uso posterior
$here_text = __( '¡Actualmente estás aquí!' );
$home_link = home_url('/');
$home_text = __( 'Inicio' );
$link_before = '<span typeof="v:Breadcrumb">';
$link_after = '</span>';
$link_attr = ' rel="v:url" property="v:title"';
$link = $link_before . '<a' . $link_attr . ' href="%1$s">%2$s</a>' . $link_after;
$delimiter = ' » '; // Delimitador entre migas
$before = '<span class="current">'; // Etiqueta antes de la miga actual
$after = '</span>'; // Etiqueta después de la miga actual
$page_addon = ''; // Añade el número de página si la consulta está paginada
$breadcrumb_trail = '';
$category_links = '';
/**
* Establecer nuestra propia variable $wp_the_query. No usar la versión global debido a
* problemas de confiabilidad
*/
$wp_the_query = $GLOBALS['wp_the_query'];
$queried_object = $wp_the_query->get_queried_object();
// Manejar solicitudes de posts únicos que incluyen páginas individuales, posts y adjuntos
if ( is_singular() )
{
/**
* Establecer nuestra propia variable $post. No usar la versión global debido a
* problemas de confiabilidad. Estableceremos la variable $post_object en $GLOBALS['wp_the_query']
*/
$post_object = sanitize_post( $queried_object );
// Establecer variables
$title = apply_filters( 'the_title', $post_object->post_title );
$parent = $post_object->post_parent;
$post_type = $post_object->post_type;
$post_id = $post_object->ID;
$post_link = $before . $title . $after;
$parent_string = '';
$post_type_link = '';
if ( 'post' === $post_type )
{
// Obtener las categorías del post
$categories = get_the_category( $post_id );
if ( $categories ) {
// Tomemos la primera categoría
$category = $categories[0];
$category_links = get_category_parents( $category, true, $delimiter );
$category_links = str_replace( '<a', $link_before . '<a' . $link_attr, $category_links );
$category_links = str_replace( '</a>', '</a>' . $link_after, $category_links );
}
}
if ( !in_array( $post_type, ['post', 'page', 'attachment'] )
{
$post_type_object = get_post_type_object( $post_type );
$archive_link = esc_url( get_post_type_archive_link( $post_type ) );
$post_type_link = sprintf( $link, $archive_link, $post_type_object->labels->singular_name );
}
// Obtener padres del post si $parent !== 0
if ( 0 !== $parent )
{
$parent_links = [];
while ( $parent ) {
$post_parent = get_post( $parent );
$parent_links[] = sprintf( $link, esc_url( get_permalink( $post_parent->ID ) ), get_the_title( $post_parent->ID ) );
$parent = $post_parent->post_parent;
}
$parent_links = array_reverse( $parent_links );
$parent_string = implode( $delimiter, $parent_links );
}
// Construir el rastro de migas de pan
if ( $parent_string ) {
$breadcrumb_trail = $parent_string . $delimiter . $post_link;
} else {
$breadcrumb_trail = $post_link;
}
if ( $post_type_link )
$breadcrumb_trail = $post_type_link . $delimiter . $breadcrumb_trail;
if ( $category_links )
$breadcrumb_trail = $category_links . $breadcrumb_trail;
}
// Manejar archivos que incluyen archivos de categoría, etiqueta, taxonomía, fecha, tipos de contenido personalizados y archivos de autor
if( is_archive() )
{
if ( is_category()
|| is_tag()
|| is_tax()
) {
// Establecer variables para esta sección
$term_object = get_term( $queried_object );
$taxonomy = $term_object->taxonomy;
$term_id = $term_object->term_id;
$term_name = $term_object->name;
$term_parent = $term_object->parent;
$taxonomy_object = get_taxonomy( $taxonomy );
$current_term_link = $before . $taxonomy_object->labels->singular_name . ': ' . $term_name . $after;
$parent_term_string = '';
if ( 0 !== $term_parent )
{
// Obtener todos los ancestros del término actual
$parent_term_links = [];
while ( $term_parent ) {
$term = get_term( $term_parent, $taxonomy );
$parent_term_links[] = sprintf( $link, esc_url( get_term_link( $term ) ), $term->name );
$term_parent = $term->parent;
}
$parent_term_links = array_reverse( $parent_term_links );
$parent_term_string = implode( $delimiter, $parent_term_links );
}
if ( $parent_term_string ) {
$breadcrumb_trail = $parent_term_string . $delimiter . $current_term_link;
} else {
$breadcrumb_trail = $current_term_link;
}
} elseif ( is_author() ) {
$breadcrumb_trail = __( 'Archivo del autor para ') . $before . $queried_object->data->display_name . $after;
} elseif ( is_date() ) {
// Establecer variables por defecto
$year = $wp_the_query->query_vars['year'];
$monthnum = $wp_the_query->query_vars['monthnum'];
$day = $wp_the_query->query_vars['day'];
// Obtener el nombre del mes si $monthnum tiene un valor
if ( $monthnum ) {
$date_time = DateTime::createFromFormat( '!m', $monthnum );
$month_name = $date_time->format( 'F' );
}
if ( is_year() ) {
$breadcrumb_trail = $before . $year . $after;
} elseif( is_month() ) {
$year_link = sprintf( $link, esc_url( get_year_link( $year ) ), $year );
$breadcrumb_trail = $year_link . $delimiter . $before . $month_name . $after;
} elseif( is_day() ) {
$year_link = sprintf( $link, esc_url( get_year_link( $year ) ), $year );
$month_link = sprintf( $link, esc_url( get_month_link( $year, $monthnum ) ), $month_name );
$breadcrumb_trail = $year_link . $delimiter . $month_link . $delimiter . $before . $day . $after;
}
} elseif ( is_post_type_archive() ) {
$post_type = $wp_the_query->query_vars['post_type'];
$post_type_object = get_post_type_object( $post_type );
$breadcrumb_trail = $before . $post_type_object->labels->singular_name . $after;
}
}
// Manejar la página de búsqueda
if ( is_search() ) {
$breadcrumb_trail = __( 'Consulta de búsqueda para: ' ) . $before . get_search_query() . $after;
}
// Manejar errores 404
if ( is_404() ) {
$breadcrumb_trail = $before . __( 'Error 404' ) . $after;
}
// Manejar páginas paginadas
if ( is_paged() ) {
$current_page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );
$page_addon = $before . sprintf( __( ' ( Página %s )' ), number_format_i18n( $current_page ) ) . $after;
}
$breadcrumb_output_link = '';
$breadcrumb_output_link .= '<div class="breadcrumb">';
if ( is_home()
|| is_front_page()
) {
// No mostrar migas de pan en la página uno de inicio y portada
if ( is_paged() ) {
$breadcrumb_output_link .= $here_text . $delimiter;
$breadcrumb_output_link .= '<a href="' . $home_link . '">' . $home_text . '</a>';
$breadcrumb_output_link .= $page_addon;
}
} else {
$breadcrumb_output_link .= $here_text . $delimiter;
$breadcrumb_output_link .= '<a href="' . $home_link . '" rel="v:url" property="v:title">' . $home_text . '</a>';
$breadcrumb_output_link .= $delimiter;
$breadcrumb_output_link .= $breadcrumb_trail;
$breadcrumb_output_link .= $page_addon;
}
$breadcrumb_output_link .= '</div><!-- .breadcrumbs -->';
return $breadcrumb_output_link;
}
Puedes llamarla simplemente así
echo get_hansel_and_gretel_breadcrumbs();
donde sea necesario
Esta función de migas de pan también maneja tipos de contenido personalizados

Tu código funciona genial, pero Google pronto dejará de dar soporte al marcado data-vocabulary (https://webmasters.googleblog.com/2020/01/data-vocabulary.html) y el código generará errores en Search Console. Lo modifiqué para hacerlo compatible con schema.org (https://schema.org/BreadcrumbList). Ya casi termino, pero no puedo implementar el valor para itemprop="position". Soy nuevo en la comunidad de StackExchange y aún no sé cómo pegar código, así que usé gist para mostrar mi código: https://gist.github.com/Marinski/4cefcbb7ded15582c4adfa0dc1c53946 . ¿Tienes alguna sugerencia sobre cómo hacer esto? Gracias.

¡Excelente! Funciona el código de la respuesta aceptada (de Pieter Goosen).
Nota: Solo agregué una pequeña tarea más. Hice una validación de verificación de esa función antes de llamarla, de esta manera:
<?php
if(function_exists('get_hansel_and_gretel_breadcrumbs')):
echo get_hansel_and_gretel_breadcrumbs();
endif;
?>
Adicionalmente, guardé esa función en un archivo llamado breadcrumbs.php
en la carpeta raíz del proyecto y lo incluí en el archivo functions.php usando include_once('breadcrumbs.php');
para tener mejor organización.

function get_hansel_and_gretel_breadcrumbs()
{
// Definir variables para uso posterior
$here_text = __( '¡Estás actualmente aquí!' );
$home_link = home_url('/');
$home_text = __( 'Inicio' );
$link_before = '<span typeof="v:Breadcrumb">';
$link_after = '</span>';
$link_attr = ' rel="v:url" property="v:title"';
$link = $link_before . '<a' . $link_attr . ' href="%1$s">%2$s</a>' . $link_after;
$delimiter = ' » '; // Separador entre migas
$before = '<span class="current">'; // Etiqueta antes de la miga actual
$after = '</span>'; // Etiqueta después de la miga actual
$page_addon = ''; // Añade el número de página si la consulta está paginada
$breadcrumb_trail = '';
$category_links = '';
/**
* Establecer nuestra propia variable $wp_the_query. No usar la versión global debido a
* problemas de confiabilidad
*/
$wp_the_query = $GLOBALS['wp_the_query'];
$queried_object = $wp_the_query->get_queried_object();
// Manejar solicitudes de publicaciones individuales que incluyen páginas, entradas y adjuntos
if ( is_singular() )
{
/**
* Establecer nuestra propia variable $post. No usar la versión global debido a
* problemas de confiabilidad. Estableceremos $post_object como $GLOBALS['wp_the_query']
*/
$post_object = sanitize_post( $queried_object );
// Establecer variables
$title = apply_filters( 'the_title', $post_object->post_title );
$parent = $post_object->post_parent;
$post_type = $post_object->post_type;
$post_id = $post_object->ID;
$post_link = $before . $title . $after;
$parent_string = '';
$post_type_link = '';
if ( 'post' === $post_type )
{
// Obtener las categorías de la publicación
$categories = get_the_category( $post_id );
if ( $categories ) {
// Tomemos la primera categoría
$category = $categories[0];
$category_links = get_category_parents( $category, true, $delimiter );
$category_links = str_replace( '<a', $link_before . '<a' . $link_attr, $category_links );
$category_links = str_replace( '</a>', '</a>' . $link_after, $category_links );
}
}
if ( !in_array( $post_type, ['post', 'page', 'attachment'] ) )
{
$post_type_object = get_post_type_object( $post_type );
$archive_link = esc_url( get_post_type_archive_link( $post_type ) );
$post_type_link = sprintf( $link, $archive_link, $post_type_object->labels->singular_name );
}
// Obtener padres de publicación si $parent !== 0
if ( 0 !== $parent )
{
$parent_links = [];
while ( $parent ) {
$post_parent = get_post( $parent );
$parent_links[] = sprintf( $link, esc_url( get_permalink( $post_parent->ID ) ), get_the_title( $post_parent->ID ) );
$parent = $post_parent->post_parent;
}
$parent_links = array_reverse( $parent_links );
$parent_string = implode( $delimiter, $parent_links );
}
// Construyamos el rastro de migas
if ( $parent_string ) {
$breadcrumb_trail = $parent_string . $delimiter . $post_link;
} else {
$breadcrumb_trail = $post_link;
}
if ( $post_type_link )
$breadcrumb_trail = $post_type_link . $delimiter . $breadcrumb_trail;
if ( $category_links )
$breadcrumb_trail = $category_links . $delimiter . $breadcrumb_trail;
}
// Manejar archivos que incluyen categorías, etiquetas, taxonomías, fechas, archivos de tipos de contenido personalizados y archivos de autores
if( is_archive() )
{
if ( is_category()
|| is_tag()
|| is_tax()
) {
// Establecer variables para esta sección
$term_object = get_term( $queried_object );
$taxonomy = $term_object->taxonomy;
$term_id = $term_object->term_id;
$term_name = $term_object->name;
$term_parent = $term_object->parent;
$taxonomy_object = get_taxonomy( $taxonomy );
$current_term_link = $before . $taxonomy_object->labels->singular_name . ': ' . $term_name . $after;
$parent_term_string = '';
if ( 0 !== $term_parent )
{
// Obtener todos los ancestros del término actual
$parent_term_links = [];
while ( $term_parent ) {
$term = get_term( $term_parent, $taxonomy );
$parent_term_links[] = sprintf( $link, esc_url( get_term_link( $term ) ), $term->name );
$term_parent = $term->parent;
}
$parent_term_links = array_reverse( $parent_term_links );
$parent_term_string = implode( $delimiter, $parent_term_links );
}
if ( $parent_term_string ) {
$breadcrumb_trail = $parent_term_string . $delimiter . $current_term_link;
} else {
$breadcrumb_trail = $current_term_link;
}
} elseif ( is_author() ) {
$breadcrumb_trail = __( 'Archivo del autor para ') . $before . $queried_object->data->display_name . $after;
} elseif ( is_date() ) {
// Establecer variables por defecto
$year = $wp_the_query->query_vars['year'];
$monthnum = $wp_the_query->query_vars['monthnum'];
$day = $wp_the_query->query_vars['day'];
// Obtener el nombre del mes si $monthnum tiene valor
if ( $monthnum ) {
$date_time = DateTime::createFromFormat( '!m', $monthnum );
$month_name = $date_time->format( 'F' );
}
if ( is_year() ) {
$breadcrumb_trail = $before . $year . $after;
} elseif( is_month() ) {
$year_link = sprintf( $link, esc_url( get_year_link( $year ) ), $year );
$breadcrumb_trail = $year_link . $delimiter . $before . $month_name . $after;
} elseif( is_day() ) {
$year_link = sprintf( $link, esc_url( get_year_link( $year ) ), $year );
$month_link = sprintf( $link, esc_url( get_month_link( $year, $monthnum ) ), $month_name );
$breadcrumb_trail = $year_link . $delimiter . $month_link . $delimiter . $before . $day . $after;
}
} elseif ( is_post_type_archive() ) {
$post_type = $wp_the_query->query_vars['post_type'];
$post_type_object = get_post_type_object( $post_type );
$breadcrumb_trail = $before . $post_type_object->labels->singular_name . $after;
}
}
// Manejar la página de búsqueda
if ( is_search() ) {
$breadcrumb_trail = __( 'Consulta de búsqueda para: ' ) . $before . get_search_query() . $after;
}
// Manejar errores 404
if ( is_404() ) {
$breadcrumb_trail = $before . __( 'Error 404' ) . $after;
}
// Manejar páginas paginadas
if ( is_paged() ) {
$current_page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );
$page_addon = $before . sprintf( __( ' ( Página %s )' ), number_format_i18n( $current_page ) ) . $after;
}
$breadcrumb_output_link = '';
$breadcrumb_output_link .= '<div class="breadcrumb">';
if ( is_home()
|| is_front_page()
) {
// No mostrar migas en la página uno de inicio y portada
if ( is_paged() ) {
$breadcrumb_output_link .= $here_text . $delimiter;
$breadcrumb_output_link .= '<a href="' . $home_link . '">' . $home_text . '</a>';
$breadcrumb_output_link .= $page_addon;
}
} else {
$breadcrumb_output_link .= $here_text . $delimiter;
$breadcrumb_output_link .= '<a href="' . $home_link . '" rel="v:url" property="v:title">' . $home_text . '</a>';
$breadcrumb_output_link .= $delimiter;
$breadcrumb_output_link .= $breadcrumb_trail;
$breadcrumb_output_link .= $page_addon;
}
$breadcrumb_output_link .= '</div><!-- .breadcrumbs -->';
return $breadcrumb_output_link;
}
