Contents
Los breadcrumbs (migas de pan) son una ayuda visual y de navegación muy útil en sitios WordPress: mejoran la experiencia de usuario, la accesibilidad y el SEO al mostrar la jerarquía de la página. Usar un plugin no siempre es necesario: con unas pocas líneas de PHP en tu tema puedes crear breadcrumbs simples, ligeros y personalizables, sin sobrecargar la instalación.
Requisitos y dónde colocar el código
Este tutorial asume conocimientos básicos de WordPress y PHP. El código que verás lo puedes añadir en el archivo functions.php de tu tema (o mejor aún, del tema hijo), o encapsularlo en un pequeño plugin si prefieres mantener el código separado del tema.
Objetivos de la función
- Soportar: página de inicio, entradas individuales, páginas anidadas (padres), categorías, etiquetas, taxonomías personalizadas, archivos de tipo de entrada personalizada, archivos por fecha, autor, búsqueda y 404.
- Manejo de paginación (page 2, etc.).
- Opciones configurables: separador, etiqueta de inicio, mostrar/ocultar la página actual y posibilidad de devolver el HTML o imprimirlo directamente.
- Salida semántica y ligera, fácil de estilizar vía CSS.
Inserta la siguiente función en functions.php. Ajusta las opciones por defecto según tus necesidades.
/ ,
home_label => Inicio,
show_on_home => true, // mostrar breadcrumb sólo en home?
show_current => true, // mostrar título de la página actual
echo => true, // imprimir directamente o devolver string
before => , // texto antes del título actual
after => , // texto después del título actual
)
opts = wp_parse_args( args, defaults )
// No hacer nada si estamos en la página de inicio y no queremos mostrar
if ( ( is_front_page() is_home() ) ! opts[show_on_home] ) {
return
}
breadcrumbs = array()
// Añadir enlace a inicio
home_url = home_url( / )
breadcrumbs[] = . esc_html( opts[home_label] ) .
if ( is_front_page() ! is_home() ) {
// Página estática como front page
if ( opts[show_current] ) {
breadcrumbs[] = opts[before] . get_the_title( get_option(page_on_front) ) . opts[after]
}
} elseif ( is_home() ! is_front_page() ) {
// Página principal del blog (listado de entradas)
blog_label = get_the_title( get_option(page_for_posts) ) ? get_the_title( get_option(page_for_posts) ) : Blog
breadcrumbs[] = opts[before] . esc_html( blog_label ) . opts[after]
} elseif ( is_single() ) {
post = get_post()
post_type = get_post_type( post )
if ( post_type != post ) {
// Post type personalizado: mostrar enlace al archivo del CPT si existe
pt_obj = get_post_type_object( post_type )
if ( pt_obj ) {
archive_link = get_post_type_archive_link( post_type )
if ( archive_link ) {
breadcrumbs[] = . esc_html( pt_obj->labels->name ) .
} else {
// Si no hay archivo, enlazar al singular label
breadcrumbs[] = esc_html( pt_obj->labels->singular_name )
}
}
} else {
// Post tipo post: mostrar categorías (primera)
categories = get_the_category( post->ID )
if ( ! empty( categories ) ) {
// Ordenar por jerarquía, usar la primero que devuelva WordPress
category = categories[0]
category_links = array()
anc = get_ancestors( category->term_id, category )
anc = array_reverse( anc )
foreach ( anc as cat_id ) {
cat = get_category( cat_id )
category_links[] = term_id ) ) . > . esc_html( cat->name ) .
}
category_links[] = term_id ) ) . > . esc_html( category->name ) .
breadcrumbs = array_merge( breadcrumbs, category_links )
}
}
// Añadir título de la entrada actual
if ( opts[show_current] ) {
breadcrumbs[] = opts[before] . get_the_title() . opts[after]
}
} elseif ( is_page() ) {
// Páginas: mostrar jerarquía de padres
global post
if ( post->post_parent ) {
anc = get_post_ancestors( post->ID )
anc = array_reverse( anc )
foreach ( anc as ancestor_id ) {
breadcrumbs[] = . esc_html( get_the_title( ancestor_id ) ) .
}
}
if ( opts[show_current] ) {
breadcrumbs[] = opts[before] . get_the_title() . opts[after]
}
} elseif ( is_category() ) {
cat = get_queried_object()
if ( cat->parent ) {
anc = get_ancestors( cat->term_id, category )
anc = array_reverse( anc )
foreach ( anc as cat_id ) {
c = get_category( cat_id )
breadcrumbs[] = term_id ) ) . > . esc_html( c->name ) .
}
}
breadcrumbs[] = opts[before] . single_cat_title( , false ) . opts[after]
} elseif ( is_tag() ) {
breadcrumbs[] = opts[before] . single_tag_title( , false ) . opts[after]
} elseif ( is_tax() ) {
// Taxonomía personalizada
term = get_queried_object()
taxonomy = get_taxonomy( term->taxonomy )
// Si la taxonomía tiene jerarquía
if ( term->parent ) {
anc = get_ancestors( term->term_id, term->taxonomy )
anc = array_reverse( anc )
foreach ( anc as term_id ) {
t = get_term( term_id, term->taxonomy )
breadcrumbs[] = . esc_html( t->name ) .
}
}
breadcrumbs[] = opts[before] . esc_html( term->name ) . opts[after]
} elseif ( is_author() ) {
author = get_queried_object()
breadcrumbs[] = opts[before] . esc_html( author->display_name ) . opts[after]
} elseif ( is_search() ) {
breadcrumbs[] = opts[before] . sprintf( Resultados de búsqueda: %s, get_search_query() ) . opts[after]
} elseif ( is_day() ) {
breadcrumbs[] = . get_the_time(Y) .
breadcrumbs[] = . get_the_time(F) .
breadcrumbs[] = opts[before] . get_the_time(d) . opts[after]
} elseif ( is_month() ) {
breadcrumbs[] = . get_the_time(Y) .
breadcrumbs[] = opts[before] . get_the_time(F) . opts[after]
} elseif ( is_year() ) {
breadcrumbs[] = opts[before] . get_the_time(Y) . opts[after]
} elseif ( is_post_type_archive() ) {
post_type = get_query_var( post_type )
if ( is_array( post_type ) ) {
post_type = reset( post_type )
}
pt_obj = get_post_type_object( post_type )
if ( pt_obj ) {
breadcrumbs[] = opts[before] . esc_html( pt_obj->labels->name ) . opts[after]
}
} elseif ( is_404() ) {
breadcrumbs[] = opts[before] . 404 . opts[after]
}
// Paginación: si hay paged
paged = get_query_var( paged )
if ( paged paged > 1 ) {
breadcrumbs[] = Página . intval( paged )
}
// Construir salida uniendo con separador
output = implode( opts[separator], breadcrumbs )
// Envolver en para salida (es sencillo y fácil de estilizar)
html =
if ( opts[echo] ) {
echo html
} else {
return html
}
}
?>
Cómo llamar a la función desde las plantillas
Coloca la llamada en el archivo de tu tema donde quieras que aparezcan las migas (por ejemplo header.php, single.php, page.php o dentro de un template-part):
Si prefieres devolver el HTML para manipularlo antes de imprimir:
false ) ) echo ?>
Ejemplos de configuración
- Usar separador > y ocultar la última parte:
> , show_current => false ) ) ?>
- Etiqueta de inicio personalizada y devolver HTML:
Mi Sitio, echo => false ) ) ?>
Estilos CSS recomendados
Este CSS básico te ayudará a que las migas se vean bien en la mayoría de los temas. Ajusta colores, tamaños y espaciado según tu diseño.
.breadcrumbs {
font-size: 13px
color: #666
margin: 12px 0
}
.breadcrumbs a {
color: #0073aa
text-decoration: none
}
.breadcrumbs a:hover {
text-decoration: underline
}
.breadcrumbs a:after {
/ nada aquí: el separador lo pone PHP si prefieres, elimina separador en PHP y lo añades con CSS /
}
Consideraciones y mejoras
- Accesibilidad: hemos usado aria-label en el párrafo si prefieres una estructura más semántica, usa un elemento nav con role y list items, pero si tu theme requiere solo etiquetas permitidas, mantén p y enlaces con texto claro.
- Schema.org: para SEO puedes añadir microdatos (itemtype/itemprop) a los enlaces o generar JSON-LD. Si necesitas microdatos, recuerda adaptar los atributos de las etiquetas HTML en la función.
- Rendimiento: esta implementación es muy ligera frente a plugins que añaden funciones extra. Es apta para la mayoría de sitios.
- Soporte para taxonomías complejas: la función incluye manejo básico de taxonomías jerárquicas si tu proyecto tiene taxonomías no jerárquicas o reglas especiales, añade los casos específicos.
- Internacionalización: para proyectos multilenguaje, envuelve etiquetas estáticas en funciones __() o _e() y asegúrate de traducir Inicio u otros textos.
Casos prácticos y notas sobre comportamiento
- Páginas anidadas: la función recorre ancestros con get_post_ancestors y los muestra en orden jerárquico.
- Entradas: intenta mostrar la categoría principal si deseas otra lógica (por ejemplo la categoría más profunda o la favorita), modifica la selección de categoría.
- Custom Post Types (CPT): si tu CPT tiene archivo habilitado, la función enlaza al archivo del CPT y muestra su label. Si no tiene archivo, muestra el label singular.
- Paginación: añade Página X si el query está paginado.
- 404: muestra simplemente 404 para que el usuario sepa dónde está.
Conclusión
Con unas decenas de líneas en functions.php tienes un breadcrumb funcional, ligero y personalizable, sin necesidad de instalar plugins. La función es una base sólida: puedes extenderla añadiendo microdatos, mejorando la lógica de selección de categoría para posts, o integrando con frameworks de temas.
|
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |
