WordPress.org

Make WordPress Core

Opened 9 years ago

Closed 7 years ago

Last modified 7 years ago

#18190 closed defect (bug) (invalid)

Don't redirect to 404 page on empty post archives

Reported by: gazpachu Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.2.1
Component: Query Keywords:
Focuses: Cc:

Description

"../archive/2010/09/29" redirects to a 404 Error because there are no posts that day.

If there are no posts, it shouldn't redirect to a 404 page. It should let the user perform the loop and show a message like this:

"Sorry, there are no posts for that date"

Change History (6)

#1 follow-up: @nacin
9 years ago

/archive/2010/09/29/ isn't a rewrite rule we support in core, so core won't actually consider it a post type archive...

#2 in reply to: ↑ 1 @gazpachu
9 years ago

Replying to nacin:

/archive/2010/09/29/ isn't a rewrite rule we support in core, so core won't actually consider it a post type archive...

Thanks for replaying :)

Well, let's forget about "archive/". The point is archives pages without posts shouldn't be redirected to a 404 page. I think we should offer a consistent archive navigation experience and explain to the user that this particular date doesn't have posts rather than send him to a 404 page.

What do you think, nacin?

#3 @gazpachu
9 years ago

After some time, I've found a way to fix this:

function dg_override_404() {
	global $wp_query, $post;

	if ( $wp_query->post_count == 0 )
	{ 
		$day = get_query_var( 'day' );
		$monthnum = get_query_var( 'monthnum' );
		$year = get_query_var( 'year' );
		
		if ( $day || $monthnum || $year )
		{
			status_header( 200 );
			
			$id=-28; // need an id
			$post = new stdClass();
			$post->ID= $id;
			$post->post_content='';
			$post->post_excerpt= '';
			$post->post_status='publish';
			$post->post_title= '';
			$post->post_type='post';
			$post->post_date = $year.'-'.$monthnum.'-'.$day.'00:00:00';
				
			$wp_query->queried_object=$post;
			$wp_query->post=$post;
			$wp_query->found_posts = 1;
			$wp_query->post_count = 1;
			$wp_query->is_404 = false;
			$wp_query->posts = array($post);
			$wp_query->is_archive = 1;
		}
	}
}

add_filter('template_redirect', 'dg_override_404');

#4 @gazpachu
9 years ago

A more complete approach:

function dg_override_404() {
	global $wp_query, $post;

	if ( $wp_query->post_count == 0 )
	{ 
		$day = get_query_var( 'day' );
		$monthnum = get_query_var( 'monthnum' );
		$year = get_query_var( 'year' );
		
		if( $year )
		{
			$wp_query->is_year = 1;
			$wp_query->is_month = 0;
			$wp_query->is_day = 0;
		}
			
		if( $monthnum )
		{
			$wp_query->is_month = 1;
			$wp_query->is_day = 0;
			$wp_query->is_year = 0;
		}
		
		if ( $day )
		{
			
			$wp_query->is_day = 1;
			$wp_query->is_year = 0;
			$wp_query->is_month = 0;
		}
		
		if( $monthnum && !$day )
			$day = 1;
			
		if( $year && !$monthnum )
		{
			$monthnum = 1;
			$day = 1;
		}
		
		if ( $day || $monthnum || $year )
		{
			status_header( 200 );
			
			$id=-28; // need an id
			$post = new stdClass();
			$post->ID= $id;
			$post->post_content='';
			$post->post_excerpt= '';
			$post->post_status='publish';
			$post->post_title= '';
			$post->post_type='post';
			$post->post_date = $year.'-'.$monthnum.'-'.$day.' 00:00:00';
				
			$wp_query->queried_object=$post;
			$wp_query->post=$post;
			$wp_query->found_posts = 1;
			$wp_query->post_count = 1;
			$wp_query->is_404 = false;
			$wp_query->posts = array($post);
			$wp_query->is_archive = 1;
			$wp_query->is_date = 1;
		}
	}
}

add_filter('template_redirect', 'dg_override_404');

#5 @c3mdigital
7 years ago

  • Keywords needs-patch removed
  • Resolution set to invalid
  • Status changed from new to closed

The check for posts should be done when the archive link is generated. WordPress will not generate date archives if no posts exist for that date.

#6 @SergeyBiryukov
7 years ago

  • Component changed from General to Query
  • Milestone Awaiting Review deleted
Note: See TracTickets for help on using tickets.