How To List All Posts Of An Archive, A Category Or A Search Result
June 26th, 2010 by Michael • WordPress Plugins • 7 Comments
Archive pages are usually paged according to your settings in options/reading. Sometimes you may want to offer a page with all posts for an archive (time, category, search result).
You need:
- a separate address for the unpaged archive,
- a filter for the internal WordPress query and
- a link to your ‘all posts’ page.
We put everything into a class to avoid name collisions and to keep the global namespace clean.
We name the file class.View_All_Posts.php.
Let’s start with the class, the parameter and a checker, this is easy:
class View_All_Posts
{
/**
* GET parameter to trigger a complete, not paged archive.
* @var string
*/
protected $all_param = 'all';
/**
* Are we there already?
*
* @return bool
*/
public function is_all_posts()
{
return isset ( $_GET[$this->all_param] );
}
}
For the address I use a very simple approach: a GET parameter named all. You may change the name here; just stay with ASCII chars from a—z. все_сообщения will get you in trouble!
Next we need a constructor that manages our work:
public function __construct()
{
/* Register the query argument. */
add_filter('query_vars', array ( $this, 'add_query_arg') );
/* Hook into the query. */
add_action('pre_get_posts', array ( $this, 'view_all_posts') );
}
The constructor references two internal functions – add_query_arg() and view_all_posts(), which we build next:
/**
* Registers the query arg in WordPress.
* Otherwise it will be unset.
*
* @param array $vars Already registered query args.
* @return array
*/
public function add_query_arg( array $vars )
{
return array_merge( $vars, array ( $this->query_arg ) );
}
/**
* Alters the query to remove the paging.
* @return void
*/
public function view_all_posts()
{
if ( ! $this->is_all_posts() )
{
return;
}
$GLOBALS['wp_query']->query_vars['nopaging'] = TRUE;
return;
}
The first function just registers our GET parameter in WordPress. The second alters the query to the database and removes the paging.
We are almost done. A template tag for the link would be nice, wouldn’t it?
/**
* Creates the markup for the link.
*
* Usage in archive.php, category.php or search.php:
* $GLOBALS['view_all_posts']->get_allposts_link();
*
* @param string $text Linktext
* @param bool $print echo or return
* @return string|void
*/
public function get_allposts_link(
$text = 'View all posts'
, $before = '<p class="allpostslink">'
, $after = '</p>;'
, $print = TRUE
)
{
if ( $this->is_all_posts()
or $GLOBALS['wp_query']->found_posts <= get_option('posts_per_page')
)
{ // No link needed.
return;
}
if ( isset ( $_SERVER['QUERY_STRING'] )
&& ! empty ( $_SERVER['QUERY_STRING'] )
)
{
/* We have already visible GET parameters: /?hello=world. */
$new_url = $_SERVER['REQUEST_URI'] . '&';
}
else
{
/* Note the difference: REQUEST_URL doesn't include
* the query string while REQUEST_URI does. */
$new_url = $_SERVER['REQUEST_URL'] . '?';
}
$link = "$before<a href='$new_url$this->all_param'>$text</a>$after";
if ( $print )
{
print $link;
return;
}
return $link;
}
Note: $GLOBALS['wp_query']->found_posts holds the sum of all posts for a given query, not just for the current page. Useful if you want to print out the total number on a paged archive.
If you want to avoid duplicate content, hide the full archives from search engines in your header:
/**
* Prevents indexing from search engines.
*
* Add this as an action to 'wp_head'.
*
* @return void
*/
public function meta_noindex()
{
if ( $this->is_all_posts() )
{
print '<meta name="robots" content="noindex">';
}
}
Our class is complete. Now we put an object of the class into the global namespace …
$GLOBALS['view_all_posts'] = new View_All_Posts;
… add an action to wp_head …
add_action(
'wp_head'
, array ( $GLOBALS['view_all_posts'], 'meta_noindex' )
);
… and include the file into the functions.php of our theme:
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR
. 'class.View_All_Posts.php';
In our archive templates (archive.php, category.php, search.php) we print the link:
$GLOBALS['view_all_posts']->get_allposts_link();
Done.
…
Oh, wait … maybe you want to see the full code? And a download link?
Here’s the link: Download class.View_All_Posts.php
The complete code:
/**
* Adds a view all posts page to any query.
* @author Thomas Scholz http://toscho.de
* @version 1.1
*/
class View_All_Posts
{
/**
* GET parameter to trigger a complete, not paged archive.
* @var string
*/
protected $all_param = 'all';
public function __construct()
{
/* Register the query argument. */
add_filter('query_vars', array ( $this, 'add_query_arg') );
/* Hook into the query. */
add_action('pre_get_posts', array ( $this, 'view_all_posts') );
}
/**
* Registers the query arg in WordPress.
* Otherwise it will be unset.
*
* @param array $vars Already registered query args.
* @return array
*/
public function add_query_arg( array $vars )
{
return array_merge( $vars, array ( $this->query_arg ) );
}
/**
* Alters the query to remove the paging.
* @return void
*/
public function view_all_posts()
{
if ( ! $this->is_all_posts() )
{
return;
}
$GLOBALS['wp_query']->query_vars['nopaging'] = TRUE;
return;
}
/**
* Are we there already?
*
* @return bool
*/
public function is_all_posts()
{
return isset ( $_GET[$this->all_param] );
}
/**
* Creates the markup for the link.
*
* Usage in archive.php, category.php or search.php:
* $GLOBALS['view_all_posts']->get_allposts_link();
*
* @param string $text Linktext
* @param bool $print echo or return
* @return string|void
*/
public function get_allposts_link(
$text = 'View all posts'
, $before = '<p class="allpostslink">'
, $after = '</p>'
, $print = TRUE
)
{
if ( $this->is_all_posts()
or $GLOBALS['wp_query']->found_posts <= get_option('posts_per_page')
)
{ // No link needed.
return;
}
if ( isset ( $_SERVER['QUERY_STRING'] )
&& ! empty ( $_SERVER['QUERY_STRING'] )
)
{
/* We have already visible GET parameters: /?hello=world. */
$new_url = $_SERVER['REQUEST_URI'] . '&';
}
else
{
/* Note the difference: REQUEST_URL doesn't include
* the query string while REQUEST_URI does. */
$new_url = $_SERVER['REQUEST_URL'] . '?';
}
$link = "$before<a href='$new_url$this->all_param'>$text</a>$after";
if ( $print )
{
print $link;
return;
}
return $link;
}
}
$GLOBALS['view_all_posts'] = new View_All_Posts;
Mission completed. Any suggestions?
Guest Post
This post is written by Thomas Scholz toscho.de, a good friend of us and a web designer from Halle, Germany.
Thank you very much from our part to Thomas.
Info
- Published in WordPress Plugins
- Tags: Plugin, WordPress
- Comment feed
- read: 25752 | today: 2
- leave a Comment


Hi Thomas!
looks realy good but ... it dosen't show anything on my test blogs...
i've try it on wp3.0 and on wp2.9.2
btw ...
wp3.0 does not show posts with post_status=future even when i try to show it with:
...
$ main_query = new WP_Query ($ query_string. 'Category_name = Concerts & post_status = publish, future & order = ASC');
...
@Milemann Where don’t you see anything? On the result page “/?all”?
Do you get useful errors, when you turn error reporting on your wp-config.php?
define('WP_DEBUG', true);
i've put the class file into the template folder,
into funtions.php -
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR
. 'class.View_All_Posts.php';
into archive.php -
"$GLOBALS['view_all_posts']->get_allposts_link();"
does it mean that in this case all postlinks should appear on each archiv site?
i try to invoke the site with
http://192.168.178.25/bbgwp/?m=201006&paged=all
even with
http://192.168.178.25/bbgwp/?m=201006
i dont see the any postlinks either any errors??
@Milemann The link will be displayed only if you have more posts in the archive than the normal page shows. This is checked by:
$GLOBALS['wp_query']->found_posts <= get_option('posts_per_page')
To force the link set the post per page option to a very low value.
ok!
i've got it.
I misunderstood the approach of your class ...
my other problem after update to 3.0
i have the query in the archive.php like:
$main_query = new WP_Query($query_string.'&post_status=publish,future&order=ASC');
to show planned events.
i have a lot of future posts, when i want to get month archives with future date:
http://192.168.178.25/bbgwp/?m=201009
wo3.0 redirected to 404
(in 2.9.2 it works pretty well)
do you have an idea how to fix it??
Hi,
I need help to make sidebar widget (header-images) customized. Like already at this website in right side column, each widget has its own header image. I want the same on my blog can you please help me with this? If required i can provide you my coding also.
I appreciate your kind help in this regard.
Sorry Obaid, but we can't offer such a service ;)