Make WordPress Core

Opened 14 years ago

Closed 12 years ago

Last modified 12 years ago

#18190 closed defect (bug) (invalid)

Don't redirect to 404 page on empty post archives

Reported by: gazpachu's profile 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
14 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
14 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
14 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
14 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
12 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
12 years ago

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