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 = ''
, $after = '
;'
, $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$text$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 '';
}
}
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 = ''
, $after = '
'
, $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$text$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.
Comments
7 responses to “How To List All Posts Of An Archive, A Category Or A Search Result”
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 😉