Añadir offset al loop principal de WordPress (con paginación)
Esta no será una entrada extensa, simplemente es un código que he utilizado y creo que viene bien guardar aquí para mi yo futuro.
Supongamos que tenemos un slider/carrusel (¡¡odio los sliders!!) con las últimas 10 entradas en la home. Lo lógico sería no repetir esas mismas entradas en el loop de entradas de la home, ¿verdad?
Para eso, WordPress nos facilita el offset. El problema del offset es que, si utilizamos algún tipo de paginación (bien sea el típico «Entradas siguientes» – «Entradas anteriores» o la paginación numerada), no funciona. No es que no funcione el offset, sino que no funciona la paginación.
El efecto es similar al problema con query_posts y la variable paged, que explico cómo solucionar aquí; la primera página está bien, pero el resto muestran lo mismo independientemente de qué página le solicitemos a la instalación de WordPress.
Fijaos si es un «fallo» reconocido, que hasta el propio Codex tiene un artículo para configurar offset con paginación.
Para repararlo, simplemente introducimos el siguiente código en nuestro functions.php:
// Fix for offset wp query home add_action('pre_get_posts', 'myprefix_query_offset', 1 ); function myprefix_query_offset(&$query) { //Before anything else, make sure this is the right query... if ( ! $query->is_home() ) { return; } //First, define your desired offset... $offset = get_option('posts_per_page'); //Next, determine how many posts per page you want (we'll use WordPress's settings) $ppp = get_option('posts_per_page'); //Next, detect and handle pagination... if ( $query->is_paged && $query->is_main_query() ) { //Manually determine page query offset (offset + current page (minus one) x posts per page) $page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp ); //Apply adjust page offset $query->set('offset', $page_offset ); } else { if($query->is_main_query()) //This is the first page. Just use the offset... $query->set('offset',$offset); } } |
Algunos apuntes:
- $offset es la variable que contiene el offset en si; si queremos que del loop original se quiten sólo las N primeras entradas, deberemos colocar N ahí. En el ejemplo de arriba yo utilizo el «posts_per_page» de la página de ajustes de lectura de WordPress. Pero porque el slider también utiliza este mismo número.
- En el if ( $query->is_paged && $query->is_main_query() ), si no añadimos $query->is_main_query(), es posible que WordPress aplique el offset a todas las queries de WordPress (incluidas las WP_Query personalizadas que tengamos en nuestro theme); puede resultar extraño y que no des con este error hasta metidas unas cuántas horas en el código.
- En el else, una vez más compruebo que es la consulta principal, sino no quiero que me aplique los cambios. Por eso tengo otro if dentro del else…
¿Te había pasado alguna vez? A mi si, pero nunca me acordé de compartirlo… :)
Gracias por el articulo…pero hay un detalle, ojo con la paginación ya que si no tomamos medidas crearemos contenido duplicado.
Saludos
Hola Xavi, gracias por la puntualización. Por suerte, este método ya tiene en cuenta esto; se supone que el offset elimina los n primeros elementos del loop, nada más. En la paginación también tiene en cuenta este factor.