#11348 closed defect (bug) (wontfix)
Archive Page Should be 404.php When !have_posts()
Reported by: | miqrogroove | Owned by: | ryan |
---|---|---|---|
Milestone: | Priority: | high | |
Severity: | major | Version: | 2.8.4 |
Component: | Query | Keywords: | |
Focuses: | Cc: |
Description
When categories are empty, WordPress does not link to /category/iamempty/ anywhere I can think of. Yet if you hit an empty category URL directly, WordPress fails to forward to the 404 page.
Change History (27)
#2
@
15 years ago
- Resolution set to invalid
- Status changed from new to closed
It shouldn't be a 404. What's displayed on this page should be handled by the theme's category.php
file. Just because something doesn't have posts, doesn't mean it's an invalid URL.
WordPress will also link to a category without posts using:
wp_list_categories( array( 'hide_empty' => false ) );
I'm going to mark this one as invalid unless others think this needs more discussion.
#3
follow-up:
↓ 6
@
15 years ago
- Resolution invalid deleted
- Status changed from closed to reopened
I'm reopening this ticket because the default theme doesn't have a category.php file, despite greenshady's assertion that it fixes this bug.
#4
follow-up:
↓ 7
@
15 years ago
But in the case of an empty category, it has found something
What did it find, and how is it relevant? This is a direct quote from a fresh WordPress installation:
"Sorry, but there aren't any posts in the term1 category yet."
That is the ONLY content being displayed other than the headers and footers. That is a not found condition, and that is exactly what the 404 status is used for.
#6
in reply to:
↑ 3
@
15 years ago
Replying to miqrogroove:
I'm reopening this ticket because the default theme doesn't have a category.php file, despite greenshady's assertion that it fixes this bug.
Don't put words into my mouth. I'm not saying this is a bug at all.
And, the default theme does have an archive.php
template, which handles category archives when there is no category.php
template.
#7
in reply to:
↑ 4
@
15 years ago
Replying to miqrogroove:
"Sorry, but there aren't any posts in the term1 category yet."
That is the ONLY content being displayed other than the headers and footers. That is a not found condition, and that is exactly what the 404 status is used for.
The conditions appropriate for a 404 response are defined in the HTTP RFC: "The server has not found anything matching the Request-URI."
In contrast, when you query an empty category the server does find something: that category's page. In WordPress categories can be empty. Hence, they can exist and be found by the server, even when they do not contain posts. Therefore the current behavior is not a bug and this ticket is invalid.
#8
follow-up:
↓ 9
@
15 years ago
filosofo, by your logic the server always finds index.php and should never use 404 for any reason.
#9
in reply to:
↑ 8
@
15 years ago
Replying to miqrogroove:
filosofo, by your logic the server always finds index.php and should never use 404 for any reason.
No. The concept of "resource" is a logical one; it has to do with data and data's relationship across the web. Although
- a garbage request string such as
/index.php?whatever=irrelevant-string
and - a blog post request such as
/index.php?post_id=1
both involve the "index.php" file, they differ semantically. The first deserves a 404 response because its request doesn't map to a known resource; the second deserves something like a 200 because the request maps to a known resource (the blog post).
The actual implementation files routing the query, such as index.php, are not part of the semantics of the query.
With your example of /category/iamempty/
the query maps to a known, existing resource: namely, an empty category. The meaning of the query /category/iamempty/
is that it requests the category named "iamempty."
Because category "iamempty" exists, and the server has found it (the resource---the existing, empty category), returning a 404 in this case would go against the HTTP 404 definition.
#10
follow-up:
↓ 12
@
15 years ago
The meaning of the query /category/iamempty/ is that it requests the category named "iamempty."
Except that is not the meaning. The meaning can be customized. The default meaning is that it requests the posts in the category. When the category is empty, no links for the category exist, the category is hidden.
On a test server, I can make a directory with nothing in it. If I click on the index link it will respond 200 with no files listed. If I then hide the directory, the index link disappears, and the server responds 404 at the URL for the directory. Now by your explanation above, that means my server goes "against the HTTP 404 definition" because the empty category is an existing resource, even though it is empty and hidden.
I wonder, why did the authors of a web server not go out their way to ensure that an empty hidden resource respond with 200?
#11
@
15 years ago
Another server I just tested responds 403 for hidden resources. That surprised me, actually, but I still didn't get anything like 200 Sorry there aren't any posts here.
#12
in reply to:
↑ 10
@
15 years ago
Replying to miqrogroove:
The meaning of the query /category/iamempty/ is that it requests the category named "iamempty."
Except that is not the meaning. The meaning can be customized. The default meaning is that it requests the posts in the category.
How do you figure? What you're saying sounds a lot like the fallacy of composition. Besides, a typical category rewrite rule in WP looks like this:
'category/(.+?)/?$' => 'index.php?category_name=$matches[1]'
That seems to be saying that a query for /category/iamempty/
is a query for the category named "iamempty." Common sense says the same thing.
In wp-includes/classes.php, we see that a query starts out as an assumed 404 until it matches an object:
148 // If we match a rewrite rule, this will be cleared. 149 $error = '404';
Of course the query /category/iamempty/
matches the rule given above, so then the following comes into play when WP_Query shows that there are no posts in category "iamempty":
463 // Don't 404 for these queries if they matched an object. 464 if ( ( is_tag() || is_category() || is_author() ) && $wp_query->get_queried_object() ) { 465 if ( !is_404() ) 466 status_header( 200 ); 467 return; 468 }
Note how the category is considered the queried object (and for a non-existent queried object, $wp_query->get_queried_object()
returns null). And also, note the analogy to an author's page: would you consider an author's page non-existent just because she hadn't yet written any posts?
When the category is empty, no links for the category exist, the category is hidden.
greenshady already proved this false, above:
WordPress will also link to a category without posts using:
wp_list_categories( array( 'hide_empty' => false ) );
On a test server, I can make a directory with nothing in it. If I click on the index link it will respond 200 with no files listed. If I then hide the directory, the index link disappears, and the server responds 404 at the URL for the directory. Now by your explanation above, that means my server goes "against the HTTP 404 definition" because the empty category is an existing resource, even though it is empty and hidden.
Please refer again to the definition of a 404 response: "The server has not found anything matching the Request-URI." If you've hidden a file from the web server, then it can't find it, can it?
And I really don't understand why you think a hidden directory is analogous to an empty category. Thankfully in real life my empty glass isn't hidden; otherwise the waiter would never get me a refill!
I wonder, why did the authors of a web server not go out their way to ensure that an empty hidden resource respond with 200?
Don't conflate "hidden" and "empty," as they're obviously not the same (even to Apache). As you pointed out above:
On a test server, I can make a directory with nothing in it. If I click on the index link it will respond 200 with no files listed.
#13
@
15 years ago
How do you figure?
When there are posts, it shows the posts. Where there are no posts, it says there are no posts found. That's all it does by default. That's all it does. Why are you quoting all this code?
would you consider an author's page non-existent just because she hadn't yet written any posts?
Absolutely, yes. This is the entire content shown on a default author page:
"Sorry, but there aren't any posts by user1 yet."
I'd be grateful for the ability to 404 that page as well.
they're obviously not the same
I never said they were the same.
#14
@
15 years ago
There are plenty of times where I've wanted an "author" page to exist even if the user hasn't posted anything (like a profile page). Tags and categories can both have definitions (#9381), which may make sense to display even if no posts exist yet for that tag or category.
I think it should stay just as it is.
#15
@
15 years ago
To clarify, if someone wants to make something in all this easier to extend from a plugin or theme...I'm fine with that. I'd like the default behavior to "stay just as it is"
#16
@
15 years ago
filosofo is bang on. As the contributor of the patch in #5324, I'll weigh in.
1) You seem to only want to fight. That's not really a great way to get things done.
2) Server resources and web application resources are different
3) A 404 is a server response code
4) Apache/IIS can both find an empty category archive so it is not a 404
5) Apache/IIS cannot find a URL like /my-lovely-category-archive/iamempty/ without help from a plugin so it would be a 404.
6) Reiterating 4... WordPress can run a successful query against the database because it has all the resources necessary to do it with /category/iamempty/. It returns an empty dataset from MySQL but not an empty HTTP resource. It's not a 404.
7) Reiterating 5... WordPres cannot create a successful dataset from MySQL because the variables passed via HTTP are not legitimate. Therefore the HTTP request is bad resource URI generating a legitimate 404.
Why are we even debating this?
#17
follow-up:
↓ 19
@
15 years ago
+1, if a post doesn't exist, it should return 404 as the status code, not 200, which it currently does
#18
@
15 years ago
- Milestone changed from 2.9 to 3.0
- Priority changed from normal to high
- Severity changed from normal to major
Raising Severity and Priority for 3.0
#19
in reply to:
↑ 17
@
15 years ago
Replying to jdingman:
+1, if a post doesn't exist, it should return 404 as the status code, not 200, which it currently does
If I can get support for this issue on posts but not categories, I will take what I can get.
#20
@
15 years ago
If a request is for a specific post_id (e.g. ?p=123) and that post_id does not exist within wp_posts, then I'd agree, it should return a 404; that content is truly not found.
In the specific example cited on this ticket though, where we're talking about a Category, which does exist, but doesn't contain any posts, then I think 200 is an appropriate response code (the Category was indeed found after all).
#21
@
15 years ago
Status 200: Infinite namespace failures
http://wpdevel.wordpress.com/?p=9999999[[BR]]
http://wpdevel.wordpress.com/?m=9999999[[BR]]
http://wpdevel.wordpress.com/?page_id=9999999[[BR]]
http://wpdevel.wordpress.com/?monthnum=9999999[[BR]]
http://wpdevel.wordpress.com/?day=9999999[[BR]]
http://wpdevel.wordpress.com/?w=9999999[[BR]]
http://wpdevel.wordpress.com/?minute=9999999[[BR]]
http://wpdevel.wordpress.com/?second=9999999[[BR]]
http://wpdevel.wordpress.com/?hour=9999999
#22
@
15 years ago
well shoot... trying with spaces
Status 200: Infinite namespace failures
http://wpdevel.wordpress.com/?p=9999999
http://wpdevel.wordpress.com/?m=9999999
http://wpdevel.wordpress.com/?page_id=9999999
http://wpdevel.wordpress.com/?monthnum=9999999
http://wpdevel.wordpress.com/?day=9999999
http://wpdevel.wordpress.com/?w=9999999
http://wpdevel.wordpress.com/?minute=9999999
http://wpdevel.wordpress.com/?second=9999999
http://wpdevel.wordpress.com/?hour=9999999
#23
@
15 years ago
(!empty($_SERVER['QUERY_STRING']) && (false === strpos($_SERVER['REQUEST_URI'], '?')))
ow, my brain, after reading this... :(
#24
@
15 years ago
Discussion spilled over to #12250 for clarity.
This ticket will likely end up wontfix.
#25
@
15 years ago
I just wanted to echo beaulebens, if a category, tag, or author exists and just has no posts, it should give 200 not 404. If the category, tag, or author doesn't exist, that's a different story.
I don't think a 404 response is appropriate for an existing but empty category. According to the HTTP protocol, a 404 means "The server has not found anything matching the Request-URI." But in the case of an empty category, it has found something: that URI corresponds to the requested category.