Como exibir links de paginação para WP_User_Query?

10

Acho que estou quase lá com isso, mas não consigo exibir os links de paginação para um diretório de autores que estou criando.

Meu código está abaixo, mas não sei como fazer com que os links naveguem entre as páginas dos autores para funcionar. Alguém pode me ajudar? Tenho a sensação de que isso pode ser útil, mas não sei como implementá-lo:

paginate_links ()

obrigado

Osu

    <?php 
/* ****************************************************************** */
                        /* !LIST AUTHORS */
/* ****************************************************************** */ 

// THANKS TO:
// http://www.mattvarone.com/wordpress/list-users-with-wp_user_query/

// pagination
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // Needed for pagination
$paged -= 1;
$limit = 2;
$offset = $paged * $limit;

// prepare arguments
$args  = array(
    // search only for Authors role
    'role'      => 'Subscriber',
    // order results by display_name
    'orderby'   => 'display_name',
    // return all fields
    'fields'    => 'all_with_meta',
    'number'    => $limit,
    'offset'    => $offset      
);
// Create the WP_User_Query object
$wp_user_query = new WP_User_Query($args);
// Get the results
$authors = $wp_user_query->get_results();
// Check for results
if (!empty($authors))
{
    echo '<div class="author-entry">';
    // loop trough each author
    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>First name</strong> : <?php echo $author_info->first_name; ?></span><br />
        <span class="ln"><strong>Last name</strong> : <?php echo $author_info->last_name; ?></span><br />
        <span class="em"><strong>Email address</strong> : <a href="mailto:<?php echo $author_info->user_email; ?>"><?php echo $author_info->user_email; ?></a></span><br />
        <span class="we"><strong>Website</strong> : <a href="<?php echo $author_info->user_url; ?>"><?php echo $author_info->user_url; ?></a></span><br />

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

    <?php 
    }
    echo '</div>';
} else {
    echo 'No authors found';
}
?>

<?php /* WHAT DO I PUT HERE TO CREATE THE PAGINATION LINKS? */ ?>
Osu
fonte
se você está olhando para o Ajax, em seguida, visitar aqui wordpress.stackexchange.com/questions/113379/...
Sabir Abdul Gafoor Shaikh

Respostas:

17

Isso deve levá-lo muito perto. Não testei, mas é quase idêntico a uma configuração que usei algumas vezes.

/*
 * We start by doing a query to retrieve all users
 * We need a total user count so that we can calculate how many pages there are
 */

$count_args  = array(
    'role'      => 'Subscriber',
    'fields'    => 'all_with_meta',
    'number'    => 999999      
);
$user_count_query = new WP_User_Query($count_args);
$user_count = $user_count_query->get_results();

// count the number of users found in the query
$total_users = $user_count ? count($user_count) : 1;

// grab the current page number and set to 1 if no page number is set
$page = isset($_GET['p']) ? $_GET['p'] : 1;

// how many users to show per page
$users_per_page = 5;

// calculate the total number of pages.
$total_pages = 1;
$offset = $users_per_page * ($page - 1);
$total_pages = ceil($total_users / $users_per_page);


// main user query
$args  = array(
    // search only for Authors role
    'role'      => 'Subscriber',
    // order results by display_name
    'orderby'   => 'display_name',
    // return all fields
    'fields'    => 'all_with_meta',
    'number'    => $users_per_page,
    'offset'    => $offset // skip the number of users that we have per page  
);

// Create the WP_User_Query object
$wp_user_query = new WP_User_Query($args);

// Get the results
$authors = $wp_user_query->get_results();

// check to see if we have users
if (!empty($authors))
{
    echo '<div class="author-entry">';
    // loop trough each author
    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>First name</strong> : <?php echo $author_info->first_name; ?></span><br />
        <span class="ln"><strong>Last name</strong> : <?php echo $author_info->last_name; ?></span><br />
        <span class="em"><strong>Email address</strong> : <a href="mailto:<?php echo $author_info->user_email; ?>"><?php echo $author_info->user_email; ?></a></span><br />
        <span class="we"><strong>Website</strong> : <a href="<?php echo $author_info->user_url; ?>"><?php echo $author_info->user_url; ?></a></span><br />

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

    <?php 
    }
    echo '</div>';
} else {
    echo 'No authors found';
}

// grab the current query parameters
$query_string = $_SERVER['QUERY_STRING'];

// The $base variable stores the complete URL to our page, including the current page arg

// if in the admin, your base should be the admin URL + your page
$base = admin_url('your-page-path') . '?' . remove_query_arg('p', $query_string) . '%_%';

// if on the front end, your base is the current page
//$base = get_permalink( get_the_ID() ) . '?' . remove_query_arg('p', $query_string) . '%_%';

echo paginate_links( array(
    'base' => $base, // the base URL, including query arg
    'format' => '&p=%#%', // this defines the query parameter that will be used, in this case "p"
    'prev_text' => __('&laquo; Previous'), // text for previous page
    'next_text' => __('Next &raquo;'), // text for next page
    'total' => $total_pages, // the total number of pages we have
    'current' => $page, // the current page
    'end_size' => 1,
    'mid_size' => 5,
));
Pippin
fonte
2
+1 teria desfrutado se o código poderia ser parceladas e explicou :)
kaiser
5
Há, acrescentou algumas melhores comentários e corrigiu um bug ou dois :)
Pippin
Obrigado por este @Pippin, vou experimentá-lo quando chegar ao estúdio. Uma pergunta: o que coloco na parte 'your-page-path' do admin_url? Essa é a raiz do meu site?
Osu
A página está mostrando seus usuários no administrador ou no front-end?
Pippin
11
Abordagem interessante. Percebi que você está executando duas consultas aqui: a primeira para obter todos os usuários e a segunda para obter apenas os usuários na página apropriada. Não teria melhor desempenho se você usasse apenas 1 consulta e usasse array_slice para dividir os resultados em páginas? Parece que, como você está realizando duas consultas diferentes nos mesmos dados, é possível economizar um pouco de desempenho ao soltar uma.
codescribblr
11

Você realmente não deve usar a resposta de Pippin. A consulta é muito ineficiente. $user_count_queryno exemplo, você pode retornar até 999.999 usuários do banco de dados para o script, com todos os campos do usuário. Isso certamente atingirá a memória e / ou limites de tempo para o PHP se / quando seu site crescer o suficiente.

Mas essa pode ter sido a única solução em 2012.

Aqui está uma maneira melhor de fazer isso. Neste exemplo, eu tenho apenas a página seguinte e a anterior, mas se você precisar de paginação numerada, as variáveis ​​estarão lá para construí-la. O WordPress não possui uma função de paginação compatível com WP_User_Query (que eu saiba).

<?php

// Pagination vars
$current_page = get_query_var('paged') ? (int) get_query_var('paged') : 1;
$users_per_page = 2; // RAISE THIS AFTER TESTING ;)

$args = array(
    'number' => $users_per_page, // How many per page
    'paged' => $current_page // What page to get, starting from 1.
);

$users = new WP_User_Query( $args );

$total_users = $users->get_total(); // How many users we have in total (beyond the current page)
$num_pages = ceil($total_users / $users_per_page); // How many pages of users we will need

?>
    <h3>Page <?php echo $current_page; ?> of <?php echo $num_pages; ?></h3>
    <p>Displaying <?php echo $users_per_page; ?> of <?php echo $total_users; ?> users</p>

    <table>
        <thead>
            <tr>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Email</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
        // Previous page
        if ( $current_page > 1 ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page-1)) .'">Previous Page</a>';
        }

        // Next page
        if ( $current_page < $num_pages ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page+1)) .'">Next Page</a>';
        }
        ?>
    </p>

Exemplo mostrando a página 2:

tabela de usuários, começando na página 2


Atualização 8/8/2018: Como adicionar números de página em vez de Avançar / Anterior

Se você deseja ter números de página em vez de links de página seguinte / anterior, eis como você pode configurá-lo. Observe que você precisará substituir os números pelos links das páginas; eles não serão clicáveis ​​neste exemplo (com base em https://stackoverflow.com/a/11274294/470480 , modificado para mostrar uma quantidade consistente de números do meio e não adicionar o "...", a menos que uma página seja realmente ignorada).

Você também pode ver meu arquivo gist, que contém uma função reutilizável para esse fim.

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

$edge_number_count = 2; // Change this, optional

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

// Minus one so that we don't split the start number unnecessarily, eg: "1 ... 2 3" should start as "1 2 3"
if ( ($start_number - 1) < 1 ) {
    $start_number = 1;
    $end_number = min($num_pages, $start_number + ($edge_number_count*2));
}

// Add one so that we don't split the end number unnecessarily, eg: "8 9 ... 10" should stay as "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} ";

Saída (da 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]
Radley Sustaire
fonte
Concordo. A resposta de Pippin requer 2 acertos no banco de dados, que devem ser evitados se possível.
The Sumo
11
Olá @ radley-sustaire, esta é uma ótima solução, mas eu queria saber se existe uma maneira de alterar a parte "exibindo 2 de 6 usuários" para o intervalo real de usuários por página. Então, algo como "exibindo 1-2 de 6" para a página 1, "3-4 de 6" para a página 2 e "5-6 de 6" para a página 3. No momento, apenas mostra "2 de 6" para todas as páginas.
damienoneill2001
11
@ damienoneill2001 Essa é uma boa ideia, você pode começar com algo como: $start_user_num = (($current_page-1) * $users_per_page) + 1;e $end_user_num = $start_user_num + count($users->get_results());.
Radley Sustaire
@RadleySustaire excelente, obrigado por isso. No início, eu recebi o seguinte erro: Call to a member function get_results() on a non-objectassim que eu alterado $end_user_numberpara $start_user_num + ($users_per_page-1);e que resolveu o problema. Obrigado novamente!
damienoneill2001
Acontece que falei logo sobre isso. Quando chego à página final que não contém uma lista completa de usuários, ela obviamente mostra o valor errado da $end_user_numbersolução. De volta à prancheta, ha!
damienoneill2001
1

O crédito total deve ir para @ radley-sustaire, para sua resposta, mas eu vi uma pequena falha com ela, então estou compartilhando minha versão da resposta aqui.

Com a minha versão, eu também estava filtrando os resultados por local, palavra-chave etc., portanto, algumas páginas tiveram menos resultados do que a variável '$ users_per_page'. Por exemplo, se meus usuários por página foram configurados para mostrar 10, mas os resultados do filtro retornaram apenas três, obtive 'Exibindo 10 de 3 usuários' na parte superior da página. Obviamente, isso não fazia sentido, então adicionei uma simples declaração "if" para verificar se a contagem de resultados era maior que a variável '$ users_per_page'.

Radley, se você editar sua resposta com a atualização, votarei com prazer nela como a resposta correta, pois acho que é melhor que a solução de Pippin.

Portanto, este é o código final para quem quiser.

<?php

// Pagination vars
$current_page = get_query_var('paged') ? (int) get_query_var('paged') : 1;
$users_per_page = 10;

$args = array(
    'number' => $users_per_page, // How many per page
    'paged' => $current_page // What page to get, starting from 1.
);

$users = new WP_User_Query( $args );

$total_users = $users->get_total(); // How many users we have in total (beyond the current page)
$num_pages = ceil($total_users / $users_per_page); // How many pages of users we will need

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

?>
    <h3>Page <?php echo $current_page; ?> of <?php echo $num_pages; ?></h3>
    <p>Displaying <?php echo $users_per_page; ?> of <?php echo $total_users; ?> users</p>

    <table>
        <thead>
            <tr>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Email</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
        // Previous page
        if ( $current_page > 1 ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page-1)) .'">Previous Page</a>';
        }

        // Next page
        if ( $current_page < $num_pages ) {
            echo '<a href="'. add_query_arg(array('paged' => $current_page+1)) .'">Next Page</a>';
        }
        ?>
    </p>
O Sumo
fonte