Cómo mostrar enlaces de paginación para WP_User_Query

4 jul 2012, 16:42:37
Vistas: 18.8K
Votos: 11

Creo que estoy cerca de conseguirlo, pero no logro que se muestren los enlaces de paginación para un directorio de autores que estoy creando.

Mi código está abajo, pero no sé cómo hacer que funcionen los enlaces para navegar entre las páginas de autores. ¿Alguien puede ayudarme? Tengo la sensación de que esto podría ser útil, pero no sé cómo implementarlo:

paginate_links()

Gracias

Osu

    <?php 
/* ****************************************************************** */
                        /* !LISTAR AUTORES */
/* ****************************************************************** */ 

// AGRADECIMIENTOS A:
// http://www.mattvarone.com/wordpress/list-users-with-wp_user_query/

// paginación
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // Necesario para la paginación
$paged -= 1;
$limit = 2;
$offset = $paged * $limit;

// preparar argumentos
$args  = array(
    // buscar solo por rol de Autor
    'role'      => 'Subscriber',
    // ordenar resultados por display_name
    'orderby'   => 'display_name',
    // devolver todos los campos
    'fields'    => 'all_with_meta',
    'number'    => $limit,
    'offset'    => $offset      
);
// Crear el objeto WP_User_Query
$wp_user_query = new WP_User_Query($args);
// Obtener los resultados
$authors = $wp_user_query->get_results();
// Comprobar si hay resultados
if (!empty($authors))
{
    echo '<div class="author-entry">';
    // recorrer cada autor
    foreach ($authors as $author)
    {
        $author_info = get_userdata($author->ID); ?>

        <span style="float:left;padding:0 5px 0 0;"><?php echo get_avatar( $author->ID, 50 ); /* http://codex.wordpress.org/Function_Reference/get_avatar */ ?></span>
        <span class="fn"><strong>Nombre</strong> : <?php echo $author_info->first_name; ?></span><br />
        <span class="ln"><strong>Apellido</strong> : <?php echo $author_info->last_name; ?></span><br />
        <span class="em"><strong>Correo electrónico</strong> : <a href="mailto:<?php echo $author_info->user_email; ?>"><?php echo $author_info->user_email; ?></a></span><br />
        <span class="we"><strong>Sitio web</strong> : <a href="<?php echo $author_info->user_url; ?>"><?php echo $author_info->user_url; ?></a></span><br />

        <span class="de"><strong>Biografía</strong> :<br /><?php echo $author_info->description ; ?></span>
        <div class="clear">&nbsp;</div>

    <?php 
    }
    echo '</div>';
} else {
    echo 'No se encontraron autores';
}
?>

<?php /* ¿QUÉ PONGO AQUÍ PARA CREAR LOS ENLACES DE PAGINACIÓN? */ ?>
1
Comentarios

si estás buscando información sobre Ajax, visita aquí http://wordpress.stackexchange.com/questions/113379/how-to-display-pagination-links-for-wp-user-query-in-ajax

Sabir Abdul Gafoor Shaikh Sabir Abdul Gafoor Shaikh
8 sept 2013 11:27:03
Todas las respuestas a la pregunta 3
9
18

Esto debería acercarte mucho a lo que necesitas. No lo he probado, pero es casi idéntico a una configuración que he usado varias veces.

/*
 * Comenzamos haciendo una consulta para recuperar todos los usuarios
 * Necesitamos un conteo total de usuarios para poder calcular cuántas páginas hay
 */

$count_args  = array(
    'role'      => 'Subscriber', // Rol: Suscriptor
    'fields'    => 'all_with_meta', // Todos los campos con metadatos
    'number'    => 999999       // Número arbitrariamente grande para obtener todos
);
$user_count_query = new WP_User_Query($count_args);
$user_count = $user_count_query->get_results();

// Contamos el número de usuarios encontrados en la consulta
$total_users = $user_count ? count($user_count) : 1;

// Obtenemos el número de página actual y lo establecemos en 1 si no está definido
$page = isset($_GET['p']) ? $_GET['p'] : 1;

// Cuántos usuarios mostrar por página
$users_per_page = 5;

// Calculamos el número total de páginas
$total_pages = 1;
$offset = $users_per_page * ($page - 1);
$total_pages = ceil($total_users / $users_per_page);


// Consulta principal de usuarios
$args  = array(
    // Buscar solo el rol de Suscriptor
    'role'      => 'Subscriber',
    // Ordenar resultados por nombre para mostrar
    'orderby'   => 'display_name',
    // Devolver todos los campos
    'fields'    => 'all_with_meta',
    'number'    => $users_per_page,
    'offset'    => $offset // Saltar el número de usuarios que tenemos por página  
);

// Creamos el objeto WP_User_Query
$wp_user_query = new WP_User_Query($args);

// Obtenemos los resultados
$authors = $wp_user_query->get_results();

// Verificamos si tenemos usuarios
if (!empty($authors))
{
    echo '<div class="author-entry">';
    // Recorremos cada autor
    foreach ($authors as $author)
    {
        $author_info = get_userdata($author->ID); ?>

        <span style="float:left;padding:0 5px 0 0;"><?php echo get_avatar( $author->ID, 50 ); /* http://codex.wordpress.org/Function_Reference/get_avatar */ ?></span>
        <span class="fn"><strong>Nombre</strong> : <?php echo $author_info->first_name; ?></span><br />
        <span class="ln"><strong>Apellido</strong> : <?php echo $author_info->last_name; ?></span><br />
        <span class="em"><strong>Correo electrónico</strong> : <a href="mailto:<?php echo $author_info->user_email; ?>"><?php echo $author_info->user_email; ?></a></span><br />
        <span class="we"><strong>Sitio web</strong> : <a href="<?php echo $author_info->user_url; ?>"><?php echo $author_info->user_url; ?></a></span><br />

        <span class="de"><strong>Biografía</strong> :<br /><?php echo $author_info->description ; ?></span>
        <div class="clear">&nbsp;</div>

    <?php 
    }
    echo '</div>';
} else {
    echo 'No se encontraron autores';
}

// Obtenemos los parámetros actuales de la consulta
$query_string = $_SERVER['QUERY_STRING'];

// La variable $base almacena la URL completa a nuestra página, incluyendo el argumento de página actual

// Si estamos en el admin, la base debe ser la URL de admin + tu página
$base = admin_url('your-page-path') . '?' . remove_query_arg('p', $query_string) . '%_%';

// Si está en el frontend, tu base es la página actual
//$base = get_permalink( get_the_ID() ) . '?' . remove_query_arg('p', $query_string) . '%_%';

echo paginate_links( array(
    'base' => $base, // La URL base, incluyendo argumentos de consulta
    'format' => '&p=%#%', // Define el parámetro de consulta que se usará, en este caso "p"
    'prev_text' => __('&laquo; Anterior'), // Texto para página anterior
    'next_text' => __('Siguiente &raquo;'), // Texto para página siguiente
    'total' => $total_pages, // El número total de páginas que tenemos
    'current' => $page, // La página actual
    'end_size' => 1,
    'mid_size' => 5,
));
4 jul 2012 18:03:14
Comentarios

+1 Me hubiera gustado que el código estuviera dividido y explicado :)

kaiser kaiser
4 jul 2012 23:28:04

Listo, agregué mejores comentarios y corregí un par de errores :)

Pippin Pippin
4 jul 2012 23:53:22

Gracias por esto @Pippin, lo probaré cuando llegue al estudio. Una pregunta: ¿qué pongo en la parte 'your-page-path' del admin_url? ¿Es la raíz de mi sitio?

Osu Osu
5 jul 2012 19:02:10

¿La página que muestra a tus usuarios está en el administrador o en la parte pública del sitio?

Pippin Pippin
5 jul 2012 23:10:23

Hola @Pippin, es en la parte pública, pero me interesaba saber para qué servía esa parte del código :)

Osu Osu
6 jul 2012 12:41:58

Esa parte del código es necesaria para generar los enlaces de paginación. La función paginate_links() necesita saber a qué URL añadir los argumentos de consulta. Simplemente te di un ejemplo para el administrador y otro para la parte pública, pero puedes ignorar la versión del administrador.

Pippin Pippin
6 jul 2012 16:57:43

Me encanta este código. Una plantilla completamente funcional ;) muchas gracias. Para aquellos que copien y peguen (y quizás lo editen) - la variable $limit necesita cambiarse por $users_per_page. Supongo que se perdió cuando se agregaron las explicaciones.

Sagive Sagive
11 sept 2014 15:38:49

Enfoque interesante. Noté que estás ejecutando 2 consultas aquí: la primera para obtener todos los usuarios y la segunda para obtener solo los usuarios de la página correspondiente. ¿No tendría mejor rendimiento si usaras solo 1 consulta y luego usaras array_slice para dividir los resultados en páginas? Parece que, dado que estás realizando 2 consultas diferentes sobre los mismos datos, podrías ahorrar algo de rendimiento eliminando una.

codescribblr codescribblr
22 jun 2015 05:35:06

La consulta utilizada para obtener el conteo total de usuarios puede reemplazarse con $total_users = $wp_user_query->get_total();

1naveengiri 1naveengiri
15 mar 2019 14:18:12
Mostrar los 4 comentarios restantes
6
12

Realmente no deberías usar la respuesta de Pippin. La consulta es muy ineficiente. $user_count_query en el ejemplo puede devolver hasta 999,999 usuarios de tu base de datos a tu script, con todos los campos de usuario. Esto seguramente alcanzará los límites de memoria y/o tiempo de PHP si/cuando tu sitio crezca lo suficiente.

Pero puede que esa haya sido la única solución en 2012.

Aquí hay una mejor manera de hacerlo. En este ejemplo solo tengo página siguiente y anterior pero si necesitas paginación numerada, las variables están ahí para construirla. WordPress no tiene una función de paginación compatible con WP_User_Query (que yo sepa).

<?php

// Variables de paginación
$current_page = get_query_var('paged') ? (int) get_query_var('paged') : 1;
$users_per_page = 2; // AUMENTA ESTO DESPUÉS DE PROBAR ;)

$args = array(
    'number' => $users_per_page, // Cuántos por página
    'paged' => $current_page // Qué página obtener, comenzando desde 1.
);

$users = new WP_User_Query( $args );

$total_users = $users->get_total(); // Cuántos usuarios tenemos en total (más allá de la página actual)
$num_pages = ceil($total_users / $users_per_page); // Cuántas páginas de usuarios necesitaremos

?>
    <h3>Página <?php echo $current_page; ?> de <?php echo $num_pages; ?></h3>
    <p>Mostrando <?php echo $users_per_page; ?> de <?php echo $total_users; ?> usuarios</p>

    <table>
        <thead>
            <tr>
                <th>Nombre</th>
                <th>Apellido</th>
                <th>Correo electrónico</th>
            </tr>
        </thead>

        <tbody>
            <?php
            if ( $users->get_results() ) foreach( $users->get_results() as $user )  {
                $firstname = $user->first_name;
                $lastname = $user->last_name;
                $email = $user->user_email;
                ?>
                <tr>
                    <td><?php echo esc_html($firstname); ?></td>
                    <td><?php echo esc_html($lastname); ?></td>
                    <td><?php echo esc_html($email); ?></td>
                </tr>
                <?php
            }
            ?>
        </tbody>
    </table>

    <p>
        <?php
        // Página anterior
        if ( $current_page > 1 ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page-1)) .'">Página Anterior</a>';
        }

        // Página siguiente
        if ( $current_page < $num_pages ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page+1)) .'">Página Siguiente</a>';
        }
        ?>
    </p>

Ejemplo mostrando página 2:

tabla de usuarios, comenzando en la página 2


Actualización 8/6/2018: Cómo añadir números de página en lugar de Siguiente/Anterior

Si quieres tener números de página en lugar de enlaces de página siguiente/anterior, aquí está cómo puedes configurarlo. Ten en cuenta que necesitarás reemplazar los números con enlaces de página, no serán clickeables en este ejemplo (basado en https://stackoverflow.com/a/11274294/470480, modificado para mostrar una cantidad consistente de números intermedios y no añadir "..." a menos que se salte una página).

También puedes ver mi archivo gist que contiene una función reusable para este propósito.

$current_page = 5; // Ejemplo
$num_pages = 10; // Ejemplo

$edge_number_count = 2; // Cambia esto, opcional

$start_number = $current_page - $edge_number_count;
$end_number = $current_page + $edge_number_count;

// Menos uno para no dividir el número inicial innecesariamente, ej: "1 ... 2 3" debería empezar como "1 2 3"
if ( ($start_number - 1) < 1 ) {
    $start_number = 1;
    $end_number = min($num_pages, $start_number + ($edge_number_count*2));
}

// Más uno para no dividir el número final innecesariamente, ej: "8 9 ... 10" debería permanecer como "8 9 10"
if ( ($end_number + 1) > $num_pages ) {
    $end_number = $num_pages;
    $start_number = max(1, $num_pages - ($edge_number_count*2));
}

if ($start_number > 1) echo " 1 ... ";

for($i=$start_number; $i<=$end_number; $i++) {
    if ( $i === $current_page ) echo " [{$i}] ";
    else echo " {$i} ";
}

if ($end_number < $num_pages) echo " ... {$num_pages} ";

Salida (de la página 1 a 10):

[1]  2  3  4  5  ... 10 
1  [2]  3  4  5  ... 10 
1  2  [3]  4  5  ... 10 
1  2  3  [4]  5  ... 10 

1 ...  3  4  [5]  6  7  ... 10 
1 ...  4  5  [6]  7  8  ... 10 

1 ...  6  [7]  8  9  10
1 ...  6  7  [8]  9  10
1 ...  6  7  8  [9]  10
1 ...  6  7  8  9  [10]
14 may 2017 05:10:44
Comentarios

Estoy de acuerdo. La respuesta de Pippin requiere 2 consultas a la base de datos, lo cual debería evitarse si es posible.

The Sumo The Sumo
18 ago 2017 18:16:27

Hola @radley-sustaire, esta es una gran solución, pero me preguntaba si hay alguna manera de cambiar la parte que dice "mostrando 2 de 6 usuarios" por el rango real de usuarios por página. Algo como "mostrando 1-2 de 6" para la página 1, "3-4 de 6" para la página 2 y "5-6 de 6" para la página 3. Actualmente, solo muestra "2 de 6" para todas las páginas.

damienoneill2001 damienoneill2001
13 feb 2018 12:50:27

@damienoneill2001 Esa es una buena idea, puedes comenzar con algo como: $start_user_num = (($current_page-1) * $users_per_page) + 1; y $end_user_num = $start_user_num + count($users->get_results());.

Radley Sustaire Radley Sustaire
14 feb 2018 01:04:27

@RadleySustaire excelente, gracias por eso. Al principio, recibí el siguiente error: Call to a member function get_results() on a non-object así que modifiqué $end_user_number a $start_user_num + ($users_per_page-1); y eso resolvió el problema. ¡Gracias de nuevo!

damienoneill2001 damienoneill2001
14 feb 2018 13:42:49

Resulta que hablé demasiado pronto sobre eso. Cuando llego a la página final que no contiene una lista completa de usuarios, obviamente muestra la cifra incorrecta para $end_user_number en mi solución. ¡De vuelta a la mesa de dibujo, ja!

damienoneill2001 damienoneill2001
14 feb 2018 15:41:20

paged no parece funcionar para mí, más bien offset

Tim Hallman Tim Hallman
6 mar 2019 22:23:58
Mostrar los 1 comentarios restantes
0

Todos los créditos deberían ir para @radley-sustaire por su respuesta, pero noté un pequeño error en ella, así que comparto mi versión de la respuesta aquí.

Con mi versión también estaba filtrando resultados por ubicación, palabra clave, etc., por lo que algunas páginas tenían menos resultados que la variable '$users_per_page'. Por ejemplo, si tenía configurado mostrar 10 usuarios por página, pero el filtro solo devolvía 3 usuarios, obtenía "Mostrando 10 de 3 usuarios" en la parte superior de la página. Obviamente esto no tenía sentido, así que agregué una simple declaración "if" para verificar si el conteo de resultados era mayor que la variable '$users_per_page'.

Radley, si editas tu respuesta con esta actualización, con gusto votaré por ella como la respuesta correcta, ya que creo que es mejor que la solución de Pippin.

Así que este es el código final para quien lo necesite.

<?php

// Variables de paginación
$current_page = get_query_var('paged') ? (int) get_query_var('paged') : 1;
$users_per_page = 10;

$args = array(
    'number' => $users_per_page, // Cuántos por página
    'paged' => $current_page // Qué página obtener, comenzando desde 1.
);

$users = new WP_User_Query( $args );

$total_users = $users->get_total(); // Cuántos usuarios tenemos en total (más allá de la página actual)
$num_pages = ceil($total_users / $users_per_page); // Cuántas páginas de usuarios necesitaremos

if ($total_users < $users_per_page) {$users_per_page = $total_users;}

?>
    <h3>Página <?php echo $current_page; ?> de <?php echo $num_pages; ?></h3>
    <p>Mostrando <?php echo $users_per_page; ?> de <?php echo $total_users; ?> usuarios</p>

    <table>
        <thead>
            <tr>
                <th>Nombre</th>
                <th>Apellido</th>
                <th>Correo electrónico</th>
            </tr>
        </thead>

        <tbody>
            <?php
            if ( $users->get_results() ) foreach( $users->get_results() as $user )  {
                $firstname = $user->first_name;
                $lastname = $user->last_name;
                $email = $user->user_email;
                ?>
                <tr>
                    <td><?php echo esc_html($firstname); ?></td>
                    <td><?php echo esc_html($lastname); ?></td>
                    <td><?php echo esc_html($email); ?></td>
                </tr>
                <?php
            }
            ?>
        </tbody>
    </table>

    <p>
        <?php
        // Página anterior
        if ( $current_page > 1 ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page-1)) .'">Página anterior</a>';
        }

        // Página siguiente
        if ( $current_page < $num_pages ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page+1)) .'">Página siguiente</a>';
        }
        ?>
    </p>
21 ago 2017 10:56:06