Esta es una pregunta bastante interesante ( que he votado, especialmente por su enfoque e investigación ). La gran bola curva aquí es la primera página de la consulta:
No puede configurar la consulta para que devuelva 0publicaciones en la primera página
Al mover el contenido de cada página una página hacia arriba, perderá la última página, ya que la consulta solo tendrá la misma cantidad de publicaciones, por lo que la $max_num_pagespropiedad seguirá siendo la misma.
Tendremos que "engañar" de alguna manera a la WP_Queryclase para que devuelva nuestras publicaciones correctamente con el desplazamiento de una página, y también obtenga el número correcto de páginas para no perder la última página de la consulta
Veamos la siguiente idea e intentemos poner todo en código. Sin embargo, antes de hacerlo, me gustaría plantear algunas notas aquí.
NOTAS IMPORTANTES:
No se ha probado todo, por lo que puede tener errores. Asegúrese de probar esto localmente con la depuración activada
El código requiere al menos PHP 5.3, cualquier versión por debajo de 5.3 causará un error fatal. Tenga en cuenta que si todavía usa alguna versión por debajo de PHP 5.5, ya debería haber actualizado hace mucho tiempo
Modifique y abuse del código como mejor le parezca para satisfacer sus necesidades exactas
LA IDEA DE LA BOMBILLA:
LO QUE NECESITAREMOS
Para que todo funcione, necesitaremos lo siguiente:
El número de página actual que se está viendo
La posts_per_pageopción establecida en la configuración de lectura
Personalizado offset
Modificar la $found_postspropiedad de la consulta para corregir la $max_num_pagespropiedad.
La paginación se WP_Queryreduce a unas pocas líneas de código muy simples
if ( empty($q['nopaging']) && !$this->is_singular ) {
$page = absint($q['paged']);
if ( !$page )
$page = 1;
// If 'offset' is provided, it takes precedence over 'paged'.
if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) {
$q['offset'] = absint( $q['offset'] );
$pgstrt = $q['offset'] . ', ';
} else {
$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
}
$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
}
Lo que sucede básicamente, una vez que se establece explícitamente un desplazamiento, pagedse ignora el parámetro. El primer parámetro de la LIMITcláusula SQL se vuelve a calcular a partir del desplazamiento y será el número de publicaciones que se omitirán en la consulta SQL generada.
Según su pregunta, aparentemente cuando se establece offseten 0, la consulta de desplazamiento falla, lo cual es extraño, ya que la siguiente comprobación debería devolver verdadero
if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) )
0es un número válido y debe devolver verdadero. Si esto no ocurre en su instalación, debe depurar el problema
Para volver al tema en cuestión, utilizaremos el mismo tipo de lógica para calcular y establecer nuestro desplazamiento para obtener la publicación 1 en la página 2 y desde allí paginar la consulta. Para la primera página, no modificaremos nada, por lo que las publicaciones que se supone que están en la página 1 seguirán estando en la página de forma normal, solo tendremos que "ocultarlas" más adelante para que no las visualicemos en la página 1
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$current_page = $q->get( 'paged' ); // Get the current page number
// We will only need to run this from page 2 onwards
if ( $current_page != 0 ) { // You can also use if ( is_paged() ) {
// Get the amount of posts per page
$posts_per_page = get_option( 'posts_per_page' );
// Recalculate our offset
$offset = ( ( $current_page - 1) * $posts_per_page ) - $posts_per_page; // This should work on page 2 where it returns 0
// Set our offset
$q->set( 'offset', $offset );
}
}
});
Debería ver las mismas publicaciones de la página 1 en la página 2. Como dije anteriormente, si esto no sucede, is_numeric( 0 )está devolviendo falso ( que no debería ) o tiene otra pre_get_postsacción que también está tratando de establecer un desplazamiento o usted están utilizando los posts_*filtros de cláusula ( más específicamente, el post_limitsfiltro ). Esto sería algo que necesitaría depurar usted mismo.
El siguiente problema es corregir la paginación, ya que, como dije anteriormente, tendrá una página corta. Para esto, tendremos que agregar el valor de get_option( 'posts_per_page' )a la cantidad de publicaciones encontradas en la consulta, ya que estamos compensando la consulta por esa cantidad. Al hacer esto, estamos agregando efectivamente 1a la $max_num_pagespropiedad.
add_action( 'found_posts', function ( $found_posts, $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$found_posts = $found_posts + get_option( 'posts_per_page');
}
}, 10, 2 );
Esto debería ordenar todo, excepto la primera página.
TODOS JUNTOS AHORA ( y especialmente para @ialocin - Yellow Submarine )
Todo esto debería entrar en functions.php
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$current_page = $q->get( 'paged' ); // Get the current page number
// We will only need to run this from page 2 onwards
if ( $current_page != 0 ) { // You can also use if ( is_paged() ) {
// Get the amount of posts per page
$posts_per_page = get_option( 'posts_per_page' );
// Recalculate our offset
$offset = ( ( $current_page - 1) * $posts_per_page ) - $posts_per_page; // This should work on page 2 where it returns 0
// Set our offset
$q->set( 'offset', $offset );
}
}
});
add_filter( 'found_posts', function ( $found_posts, $q )
{
if ( !is_admin() // Only target the front end, VERY VERY IMPORTANT
&& $q->is_main_query() // Only target the main query, VERY VERY IMPORTANT
&& $q->is_cateory( 'news' ) // Only target the news category
) {
$found_posts = $found_posts + get_option( 'posts_per_page');
}
return $found_posts;
}, 10, 2 );
OPCIONES DE PRIMERA PÁGINA
Aquí hay algunas opciones:
OPCIÓN 1
Lo más probable es que elija esta opción. Lo que querría hacer aquí es crear un category-news.php( si aún no lo ha hecho ). Esta será la plantilla que se utilizará cada vez que se vea la newscategoría. Esta plantilla será muy sencilla.
Ejemplo
<?php
get_header()
if ( !is_paged() ) { // This is the first page
get_template_part( 'news', 'special' );
} else { // This is not the first page
get_template_part( 'news', 'loop' );
}
get_sidebar();
get_footer();
Como puede ver, he incluido dos partes de plantilla, news-special.phpy news-loop.php. Ahora, los conceptos básicos de las dos plantillas personalizadas son:
news-special.php-> Esta parte de la plantilla será lo que quieras mostrar en la primera página. Agregue toda su información estática personalizada aquí. Tenga mucho cuidado de no llamar al bucle en esta plantilla ya que esto mostraría las publicaciones de la primera página.
news-loop.php-> Esta es la plantilla donde invocaremos el bucle. Esta sección se verá así:
global $wp_query;
while ( have_posts() ) {
the_post();
// Your template tags and markup
}
OPCION 2
Cree una plantilla separada con su contenido estático y simplemente use el category_templatefiltro para usar esta plantilla cuando veamos la primera página de la newscategoría. Además, asegúrese de no invocar el bucle predeterminado en esta plantilla. Además, asegúrese de que su convención de nomenclatura aquí no choque con los nombres de las plantillas dentro de la jerarquía de plantillas
Espero que esto sea útil. Siéntase libre de dejar comentarios con inquietudes
EDITAR
Gracias al OP, hay un error definitivo en la WP_Queryclase, verifique el boleto de tránsito # 34060 . El código que publiqué es de Wordpress v4.4, y el error se corrigió en esta versión.
Regresé al código fuente de v4.3, donde está el error, y puedo confirmar que 0se ignora cuando se establece como valor, offsetya que el código simplemente verifica si el offsetparámetro es empty. 0se toma como vacío en PHP. No estoy seguro de si este comportamiento (error) solo se encuentra en v4.3 solo o en todas las versiones anteriores (de acuerdo con el ticket, este error está en v4.3), pero hay un parche para este error que puede verificar fuera en el boleto de trac. Como dije, este error definitivamente se ha solucionado en v4.4
return $found_posts;después de la instrucción if en la acción found_posts. ¡Gracias!query.php, y sí,0será ignorado porque la marca aquí está vacía y0se toma como vacía. El código en mi respuesta es el código de actualización que se envía con v4.4, por lo que puedo confirmar que el error se corrigió en 4.4. Actualizaré mi respuesta en consecuencia. Sobre elfound_poststema, buena captura, en realidad es un filtro y debe devolverse. DisfrutaActualizar:
Prueba algo como
fuente