Tutorial WordPress: Personalizar el bloque de navegación de post anterior/siguiente

·

·

Introducción

Este tutorial muestra, con todo lujo de detalles, cómo personalizar el bloque de navegación post anterior / siguiente en WordPress. Incluye varias rutas: modificar la plantilla PHP clásica, crear estilos o variaciones para el bloque de Gutenberg (core/post-navigation), usar filtros para reescribir el HTML generado por el bloque, añadir miniaturas, iconos SVG, atributos rel para SEO y buenas prácticas de accesibilidad y rendimiento.

Enfoques posibles (resumen)

Antes de empezar: recomendaciones

1) Implementación en plantilla PHP (ejemplo completo)

Ejemplo de función que muestra navegación con miniaturas, títulos, texto para lectores de pantalla, rel=prev/next y manejo condicional si no existe anterior o siguiente:

lt?php
function mi_post_nav_bonito() {
    // Solo en single posts
    if ( ! is_singular( post ) ) {
        return
    }

    prev = get_previous_post()
    next = get_next_post()

    // Si no hay ninguno, no hacemos nada
    if ( ! prev  ! next ) {
        return
    }

    echo ltnav class=mi-post-nav role=navigation aria-label=Navegación entre entradasgt

    if ( prev ) {
        prev_url   = esc_url( get_permalink( prev ) )
        prev_title = esc_html( get_the_title( prev ) )
        thumb      = get_the_post_thumbnail( prev->ID, array(120,120), array(loading =gt lazy, alt =gt prev_title) )
        // Rel prev y enlace semántico
        echo ltdiv class=nav-item nav-prevgt
        echo lta href=. prev_url . rel=prev aria-label=Entrada anterior: . esc_attr( prev_title ) .gt
        echo ltspan class=nav-thumbgt. thumb .lt/spangt
        echo ltspan class=nav-metagtltspan class=nav-labelgtAnteriorlt/spangtltspan class=nav-titlegt. prev_title .lt/spangtlt/spangt
        echo lt/agt
        echo lt/divgt
    }

    if ( next ) {
        next_url   = esc_url( get_permalink( next ) )
        next_title = esc_html( get_the_title( next ) )
        thumb      = get_the_post_thumbnail( next->ID, array(120,120), array(loading =gt lazy, alt =gt next_title) )
        echo ltdiv class=nav-item nav-nextgt
        echo lta href=. next_url . rel=next aria-label=Entrada siguiente: . esc_attr( next_title ) .gt
        echo ltspan class=nav-metagtltspan class=nav-labelgtSiguientelt/spangtltspan class=nav-titlegt. next_title .lt/spangtlt/spangt
        echo ltspan class=nav-thumbgt. thumb .lt/spangt
        echo lt/agt
        echo lt/divgt
    }

    echo lt/navgt
}
?gt

Uso: coloca la llamada mi_post_nav_bonito() donde quieras en single.php (por ejemplo, al final del contenido) o añádela a una plantilla parcial.

CSS sugerido para la plantilla (estilos base y responsive)

.mi-post-nav{
  display:flex
  justify-content:space-between
  gap:1rem
  align-items:center
  margin:2rem 0
}
.mi-post-nav .nav-item{
  flex:1 1 45%
  background:#fff
  border:1px solid #e1e1e1
  padding:0.75rem
  border-radius:8px
  display:flex
  align-items:center
  text-decoration:none
}
.mi-post-nav .nav-item a{
  display:flex
  align-items:center
  gap:0.75rem
  color:inherit
  text-decoration:none
}
.mi-post-nav .nav-thumb img{
  width:72px
  height:72px
  object-fit:cover
  border-radius:6px
  display:block
}
.mi-post-nav .nav-meta{ display:flex flex-direction:column }
.mi-post-nav .nav-label{ font-size:0.8rem color:#666 }
.mi-post-nav .nav-title{ font-weight:700 color:#222 }

/ Responsive: apila en móviles /
@media (max-width:700px){
  .mi-post-nav{ flex-direction:column }
  .mi-post-nav .nav-item{ width:100% }
}

/ Clase para ocultar visualmente pero dejar accesible para SR /
.visually-hidden{
  position:absolute!important
  height:1pxwidth:1px
  overflow:hidden
  clip:rect(1px,1px,1px,1px)
  white-space:nowrap
}

2) Personalizar el bloque de Gutenberg (core/post-navigation)

Si tu sitio usa el editor de bloques para componer la plantilla single, puedes registrar un nuevo estilo de bloque o interceptar la salida del bloque con filtros.

Registrar un estilo de bloque (functions.php)

Con register_block_style añades una opción en el editor que aplica una clase CSS específica al bloque.

lt?php
function registrar_estilos_post_navigation() {
    if ( function_exists( register_block_style ) ) {
        register_block_style( core/post-navigation, array(
            name  =gt mi-nav-cards,
            label =gt Navegación con tarjetas
        ) )
    }
}
add_action( init, registrar_estilos_post_navigation )
?gt

Luego en tu CSS (o enqueue para bloques) defines las reglas para .wp-block-post-navigation.is-style-mi-nav-cards

.wp-block-post-navigation.is-style-mi-nav-cards {
  / estilos similares a los mostrados anteriormente /
  display:flex
  gap:1rem
  align-items:center
}
.wp-block-post-navigation.is-style-mi-nav-cards .wp-block-post-navigation-link { / ... / }

Modificar la salida del bloque con render_block

Este patrón permite interceptar el HTML que genera el bloque y reescribirlo para incluir miniaturas, SVG o atributos extra.

lt?php
add_filter( render_block, mi_custom_render_post_navigation, 10, 2 )
function mi_custom_render_post_navigation( block_content, block ) {
    if ( isset( block[blockName] )  core/post-navigation === block[blockName] ) {
        // Modificamos sólo si estamos en single
        if ( is_singular( post ) ) {
            // Ejemplo simple: añadimos un contenedor con clase y un atributo aria adicional
            block_content = str_replace( class=wp-block-post-navigation, class=wp-block-post-navigation mi-post-nav-block role=navigation aria-label=Navegación entre entradas, block_content )
            // O más avanzado: parsear HTML y reemplazar el enlace por uno con miniatura (requiere DOMDocument o regex cuidadoso)
        }
    }
    return block_content
}
?gt

3) Añadir miniaturas al bloque (estrategia)

core/post-navigation no incluye por defecto miniaturas en todas las configuraciones. Para insertarlas desde PHP puedes usar render_block y, mediante DOMDocument o patrones, inyectar el HTML con get_the_post_thumbnail( id, thumbnail ). Otra alternativa es crear un bloque personalizado que renderice exactamente el HTML que deseas (más trabajo, pero control total).

Ejemplo simplificado: inyectar thumbnail mediante simple replace

lt?php
add_filter( render_block, mi_inyectar_thumb_post_nav, 10, 2 )
function mi_inyectar_thumb_post_nav( block_content, block ) {
    if ( isset( block[blockName] )  core/post-navigation === block[blockName]  is_singular( post ) ) {
        // Atención: esto es una aproximación en producción usar DOMDocument o un parser robusto
        // Reemplazar placeholder imaginario  y  si existieran,
        // o buscar los enlaces y añadir antes la miniatura.
        // Aquí mostramos lógica conceptual.
    }
    return block_content
}
?gt

Si necesitas insertar miniaturas de forma robusta, construir un bloque personalizado (o usar server-side render con register_block_type) es la opción más segura.

4) Accesibilidad y SEO

5) Icons y microinteracciones

Usar SVG inline dentro de los enlaces proporciona iconos nítidos y control de color con CSS. Ejemplo de inserción simple:

ltsvg width=20 height=20 viewBox=0 0 24 24 aria-hidden=true focusable=falsegt
  ltpath d=M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12zgtlt/pathgt
lt/svggt

Colócalo antes del título en anterior (flecha izquierda) y después del título en siguiente (flecha derecha). Controla el color con fill:currentColor para heredar el color del enlace.

6) Ejemplo completo y compacto (plantilla con todo integrado)

Ejemplo que combina miniatura, SVG, rel, lazy loading y clases semánticas. Inserta esto en functions.php o en plantilla parcial según prefieras.

lt?php
function mi_post_nav_completo() {
    if ( ! is_singular( post ) ) return
    prev = get_previous_post()
    next = get_next_post()
    if ( ! prev  ! next ) return

    echo ltnav class=mi-post-nav role=navigation aria-label=Navegación entre entradasgt

    if ( prev ) {
        url   = esc_url( get_permalink( prev ) )
        title = esc_attr( get_the_title( prev ) )
        thumb = get_the_post_thumbnail( prev->ID, thumbnail, array(loading =gt lazy, alt =gt title ) )
        echo ltdiv class=nav-item nav-prevgt
        echo lta href=. url . rel=prev aria-label=Entrada anterior: . title .gt
        echo ltspan class=nav-thumbgt. thumb .lt/spangt
        echo ltspan class=nav-contentgt
        echo ltsvg width=18 height=18 viewBox=0 0 24 24 aria-hidden=true focusable=falsegtltpath d=M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12zgtlt/pathgtlt/svggt
        echo ltspan class=nav-labelgtAnteriorlt/spangt
        echo ltspan class=nav-titlegt. esc_html( get_the_title( prev ) ) .lt/spangt
        echo lt/spangt
        echo lt/agt
        echo lt/divgt
    }

    if ( next ) {
        url   = esc_url( get_permalink( next ) )
        title = esc_attr( get_the_title( next ) )
        thumb = get_the_post_thumbnail( next->ID, thumbnail, array(loading =gt lazy, alt =gt title ) )
        echo ltdiv class=nav-item nav-nextgt
        echo lta href=. url . rel=next aria-label=Entrada siguiente: . title .gt
        echo ltspan class=nav-contentgt
        echo ltspan class=nav-labelgtSiguientelt/spangt
        echo ltspan class=nav-titlegt. esc_html( get_the_title( next ) ) .lt/spangt
        echo ltsvg width=18 height=18 viewBox=0 0 24 24 aria-hidden=true focusable=falsegtltpath d=M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6zgtlt/pathgtlt/svggt
        echo lt/spangt
        echo ltspan class=nav-thumbgt. thumb .lt/spangt
        echo lt/agt
        echo lt/divgt
    }

    echo lt/navgt
}
?gt

7) Buenas prácticas y consideraciones finales

  1. Usa un child theme o plugin para cambios que afecten a functions.php o estilos globales.
  2. Evita imágenes muy pesadas y sirve tamaños adecuados mediante las funciones de imagen de WP.
  3. Prueba en diferentes dispositivos y navegadores revisa enfoque de teclado y lector de pantalla.
  4. Si modificas bloques de Gutenberg, documenta la modificación para editores del sitio (qué estilos hay disponibles y cómo activarlos).
  5. Usa control de versiones (Git) para mantener un historial de cambios en plantillas y funciones.

Resumen práctico

Para mayor control: crea una función PHP que genere exactamente el HTML que quieras y úsala en la plantilla. Para integración con el editor de bloques: registra un estilo de bloque o intercepta la salida con render_block. Para personalizaciones profundas (miniaturas, microdiseño, lógica condicional): lo más robusto es un bloque personalizado o server-side render. En todos los casos, prioriza accesibilidad, SEO y rendimiento.



Leave a Reply

Your email address will not be published. Required fields are marked *