Ok, I think I found something that actually works, and I’m posting it just in case someone need it.
The solution is simply to avoid using Pagenavi just for this page, using paginate_links()
instead and forcing it to behave more or less like Pagenavi to maintain coherence all over the site.
Let me explain.
My custom query is now something like this:
$query = "
SELECT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta
WHERE
$wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->posts.post_status="publish"
AND $wpdb->posts.post_type="post"
AND $wpdb->posts.post_date <= NOW()
AND (
$wpdb->posts.post_author = $curauth->ID
OR (
$wpdb->postmeta.meta_key = 'co_author'
AND $wpdb->postmeta.meta_value = $curauth->ID
)
)
GROUP BY $wpdb->posts.ID
ORDER BY $wpdb->posts.post_date DESC
";
Then I create some useful variables for pagination:
global $wpdb;
global $post;
$total_query = "SELECT COUNT(*) FROM ($query) AS combined_table";
// Total count of rows
$total = $wpdb->get_var($total_query);
// Number of rows per page, as set in WordPress settings
$items_per_page = get_option('posts_per_page');
// Current page; defaults to 1 if not requested
$page = isset($_GET['page']) ? abs((int) $_GET['page']) : 1;
// Offset for query LIMIT
$offset = ($page*$items_per_page) - $items_per_page;
// Well... the next one is pretty much self-explained...
$last_page = ceil($total/$items_per_page);
Then I perform the query and build the loop:
$posts = $wpdb->get_results($query." LIMIT $offset, $items_per_page");
foreach ($posts as $post) :
setup_postdata($post);
// The Loop
endforeach;
Finally, the pagination (note that I’m using an hybrid of paginate_links()
/ wp_pagenavi()
classes to style it):
// Echo "Page # of #"
echo '<span class="pages">Page '.$page.' of '.$last_page.'</span>';
// If this isn't the first page...
if ($page != 1)
echo '<a class="page-numbers" href="'.$base_url.'">< FIRST</a>';
// I don't really know how to explain this one because I found it somewhere I can't find again, but it works!
echo paginate_links(
'base' => add_query_arg('page', '%#%'),
'prev_text' => '<',
'next_text' => '>',
'total' => $last_page
'current' => $page
);
// If this isn't the last page...
if ($page != $last_page)
echo '<a class="page-numbers" href="'.$base_url.'?page=".$last_page."">LAST ></a>';
As you may have noticed, there is a $base_url
variable: that’s the only caveat I have.
First of all, this is $base_url
:
$current_url = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$current_url = explode('?', $current_url);
$base_url="http://".$current_url[0];
The caveat is that I couldn’t get paginate_links()
to echo rewritten urls, neither how to generate them for first page and last page links.
So now urls in this archive are something like http://www.example.com/author/username/?page=2
instead of http://www.example.com/author/username/page/2/
That’s it. I hope someone will find this useful!