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… :)

Puede mejorarNo está malMe gustaEs bueno¡Excelente! (Ninguna valoración todavía)
Cargando…

2 comentarios en “Añadir offset al loop principal de WordPress (con paginación)

  1. Xavi dice:

    Gracias por el articulo…pero hay un detalle, ojo con la paginación ya que si no tomamos medidas crearemos contenido duplicado.
    Saludos

    1. Darío BF dice:

      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.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

DARÍO BALBONTÍN FERNÁNDEZ es el Responsable del tratamiento de los datos personales del usuario y le informa que estos datos serán tratados de conformidad con lo dispuesto en el Reglamento (UE) 2016/679 de 27 de abril de 2016 (GDPR), por lo que se le facilita la siguiente información del tratamiento: Fin del tratamiento: mantener una relación comercial y el envío de comunicaciones sobre nuestros productos y servicios. Criterios de conservación de los datos: se conservarán mientras exista un interés mutuo para mantener el fin del tratamiento y cuando ya no sea necesario para tal fin, se suprimirán con medidas de seguridad adecuadas para garantizar la seudonimización de los datos o la destrucción total de los mismos.Comunicación de los datos: No se comunicarán los datos a terceros, salvo obligación legal. Derechos que asisten al usuario: Derecho a retirar el consentimiento en cualquier momento. Derecho de acceso, rectificación, portabilidad y supresión de sus datos y a la limitación u oposición al su tratamiento. Derecho a presentar una reclamación ante la Autoridad de control (agpd.es) si considera que el tratamiento no se ajusta a la normativa vigente. Datos de contacto para ejercer sus derechos: contacto@dariobf.com.