Mostrar entradas de la misma categoría usando enlaces siguiente/anterior
Estoy usando este código, pero cuando hago clic en el enlace de siguiente/anterior entrada, me redirige a la siguiente entrada/entrada anterior de una categoría diferente.
previous_post_link( '%link', 'Entrada anterior en categoría', $in_same_term = true );
next_post_link( '%link', 'Siguiente entrada en categoría', $in_same_term = true );
Estoy tratando de solucionar mi problema usando este artículo.
Aquí está el código que estoy usando para entradas y categorías, y no estoy usando tipos de contenido personalizados ni categorías:
$post_id = $post->ID;
$cat = get_the_category();
$current_cat_id = $cat[0]->cat_ID;
$args = array(
'category' => $current_cat_id,
'orderby' => 'post_date',
'order' => 'DESC'
);
$posts = get_posts( $args );
foreach( $posts as $post ) {
echo $post->post_content;
}
previous_post_link( '%link', 'Entrada anterior en categoría', $in_same_term = true );
next_post_link( '%link', 'Siguiente entrada en categoría', $in_same_term = true );
Básicamente está obteniendo todas las entradas basadas en la categoría, y ahora quiero que el enlace de siguiente entrada/entrada anterior funcione solo para esta categoría en particular.

Aquí está el código para obtener enlaces de anterior y siguiente basados en categorías en las publicaciones:
<?php
$post_id = $post->ID; // ID de la publicación actual
$cat = get_the_category();
$current_cat_id = $cat[0]->cat_ID; // ID de la categoría actual
$args = array(
'category' => $current_cat_id,
'orderby' => 'post_date',
'order' => 'DESC'
);
$posts = get_posts( $args );
// Obtener IDs de las publicaciones recuperadas con get_posts
$ids = array();
foreach ( $posts as $thepost ) {
$ids[] = $thepost->ID;
}
// Obtener y mostrar enlaces de anterior y siguiente en la misma categoría
$thisindex = array_search( $post_id, $ids );
$previd = isset( $ids[ $thisindex - 1 ] ) ? $ids[ $thisindex - 1 ] : false;
$nextid = isset( $ids[ $thisindex + 1 ] ) ? $ids[ $thisindex + 1 ] : false;
if (false !== $previd ) {
?><a rel="prev" href="<?php echo get_permalink($previd) ?>">Anterior</a><?php
}
if (false !== $nextid ) {
?><a rel="next" href="<?php echo get_permalink($nextid) ?>">Siguiente</a><?php
}

+1 Esto es exactamente lo que estaba buscando. Mi requisito era ordenar por el campo Orden en el cuadro Editar Atributos de Página. Así que cambié los $args a $args = array('category'=>$current_cat_id,'orderby'=>'menu_order','order'=> 'ASC');
y eso resolvió mi problema. ¡Muchísimas gracias por compartir la solución!

Las funciones previous_post_link
y next_post_link
tienen cinco parámetros:
$format
: Cadena de formato para el enlace, se usa para controlar lo que aparece antes y después del enlace
$link
: Texto del enlace a mostrar
$in_same_term
: Indica si el siguiente/anterior post debe estar en el mismo término de taxonomía que el post actual
$excluded_terms
: Términos de los cuales excluir posts
$taxonomy
: La taxonomía a usar cuando $in_same_term
es verdadero
Como puedes ver, el parámetro $in_same_term
hace exactamente lo que necesitas. Sin embargo, no lo estás usando correctamente en tu código de ejemplo. En realidad estás pasando el resultado de asignar true
a una variable $in_same_term
. Esto no funcionará: pasar un argumento es tan simple como pasar un valor:
previous_post_link( '%link', 'Post anterior en la categoría', true );
next_post_link( '%link', 'Post siguiente en la categoría', true );
Edición: (editado después de que el OP actualizó su pregunta)
El problema es que previous_post_link
y next_post_link
usan el objeto post global, que estás sobrescribiendo. Para evitar esto, usa otro nombre de variable en tu bucle $posts
, como $singlepost
:
foreach ( $posts as $singlepost ) {
echo $singlepost->post_content
}
De esta manera, se preserva el objeto global $post
. Alternativamente, podrías guardar el objeto post global en una variable temporal y resetear $post
nuevamente después, pero eso solo es realmente necesario si estás llamando a setup_postdata
(lo cual no estás haciendo).

Necesitarás proporcionarnos un poco más de información :-). ¿Estás utilizando un tipo de entrada personalizado o una taxonomía personalizada, o simplemente "Entradas" y "Categorías"? ¿Hay algún lugar donde podamos ver qué está saliendo mal exactamente?

Tu código no tiene sentido para mí, aparte de tener un error de sintaxis. Tal como está tu código, cuando haces clic en una publicación desde una página de entradas/blog, te lleva a la vista individual de la publicación como debería ser. Solo esa publicación se muestra en single.php.
El problema comienza cuando haces clic en los enlaces de publicación, no importa si es el enlace de publicación anterior o siguiente. Lo que se devuelve son todas las publicaciones de esa categoría particular cuando se carga la página siguiente/anterior. Así es como has codificado tu single.php, y por qué tus enlaces de publicación no funcionan como esperas.
Yo no usaría get_posts()
para configurar mi loop en la página single.php. Simplemente usaría el loop normal adecuado. Por favor revisa esta página en el codex sobre Desarrollo de Temas
Aquí hay un ejemplo de un single.php que funcionará como se espera:
<?php
get_header(); ?>
<div id="main-content" class="main-content">
<div id="primary" class="content-area">
<div id="content" class="site-content" role="main">
<?php
// Iniciar el Loop.
while ( have_posts() ) : the_post(); ?>
<?php
get_template_part( 'content', get_post_format() );
// Navegación entre publicaciones anterior/siguiente.
previous_post_link( '%link', 'Publicación anterior en categoría', true );
next_post_link( '%link', 'Publicación siguiente en categoría', true );
// Si los comentarios están abiertos o tenemos al menos un comentario, cargar la plantilla de comentarios.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
endwhile;
?>
</div><!-- #content -->
</div><!-- #primary -->
<?php get_sidebar( 'content' ); ?>
</div><!-- #main-content -->
<?php
get_footer();
Como se señala en la otra respuesta, ve y lee sobre cómo usar next_post_link
y previous_post_link

Gracias por tu respuesta, ¿puedes decirme dónde está el error de sintaxis en mi código?

Por favor, configura debug a true en wp-config. Esto debería ayudarte mucho

Deberías probar lo que dije, tu código no puede funcionar, con tu código tal como está, simplemente recargará la misma página una y otra vez con los enlaces de las publicaciones

Tenía el mismo problema ADEMÁS necesitaba todo eso para un tipo de post personalizado y taxonomía personalizada. user54318 me orientó en la dirección correcta, que no es capaz de manejar CPTs, así que compartiré mis resultados aquí también:
//obtener taxonomías personalizadas
$terms = wp_get_post_terms( get_the_ID(), 'product_cat' ); //el último argumento es la taxonomía personalizada. cambiar por la taxonomía deseada
//recorrer todos los términos y filtrar el que necesito
$stay_in = array();
foreach( $terms as $term ) :
/*este bucle busca una categoría que sea hija de la categoría con ID 37. cambiar según necesidades.
solo es importante construir un array de IDs de términos para incluirlos en el comportamiento anterior/siguiente, así que si ya conoces tus IDs, podrías usar algo como $stay_in = array( 43 ); y saltarte todo este bucle...*/
if ( $term->parent == 37 ) :
$stay_in[] = $term->term_id;
break; //salir del foreach si se encuentra
endif;
endforeach;
//obtener todos los IDs de posts que están en mi categoría definida
$args = array(
'post_type' => 'product', //tipo de post personalizado
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat', //taxonomía personalizada
'field' => 'term_id',
'terms' => $stay_in,
'operator' => 'IN', //cambiar según necesidades... IN, NOT IN, AND, EXISTS, NOT EXISTS
)
),
'orderby' => 'post_date',
'order' => 'ASC',
'fields' => 'ids', //solo devolver los IDs de los posts, no los objetos completos
);
$all_posts = new WP_Query( $args );
//buscar el post actual por su ID y buscar los IDs anterior/siguiente
$this_index = array_search( $post->ID, $all_posts->posts );
$prev_id = $all_posts->posts[ $this_index - 1 ];
$next_id = $all_posts->posts[ $this_index + 1 ];
//mostrar enlaces, si existen anterior/siguiente
if ( ! empty( $prev_id ) ) :
echo '<a rel="prev" href="' . get_permalink( $prev_id ) . '">' . __( 'anterior', 'your_theme_text_domain' ) . '</a>';
endif;
if ( ! empty( $next_id ) ) :
echo '<a rel="next" href="' . get_permalink( $next_id ) . '">' . __( 'siguiente', 'your_theme_text_domain' ) . '</a>';
endif;
wp_reset_postdata();
