What? I am modifying my theme to show comments of a post on a separate page.
How? Mostly based on this answer but with improved checks and code. So this is what my page-comments.php (kinda) looks like:
(The code is very easy to scan through, trust me!)
<?php get_header(); ?>
<?php
/*
* (Example URL: example.com/comments/?original_post=ID)
*
* Check if HTTP variable (original_post) exists in queried URL,
* AND that it is set to some value (ID), AND that the value (ID) is a number.
*/
if( array_key_exists( 'original_post', $_GET ) && isset( $_GET['original_post'] ) && ctype_digit( $_GET['original_post'] ) ) {
$query_original_post = new WP_Query( array(
'posts_per_page' => 1,
'p' => $_GET['original_post'],
'post_type' => 'any',
) );
if( $query_original_post->have_posts() ) {
while ( $query_original_post->have_posts() ) : $query_original_post->the_post();
// [...]
endwhile;
wp_reset_postdata();
} else {
/*
* Return 404 error if there are no posts
*/
global $wp_query;
$wp_query->set_404();
status_header( 404 );
nocache_headers();
get_template_part( '404', 'archive' );
//exit();
}
} else {
/*
* Return 404 error if the HTTP variable (original_post) doesn't
* exist in queried URL, OR it isn't set to any value (ID),
* OR the value (ID) isn't a number.
*/
global $wp_query;
$wp_query->set_404();
status_header( 404 );
nocache_headers();
get_template_part( '404', 'archive' );
//exit();
}
?>
<?php get_footer(); ?>
(The code I use to return a 404 error is based on these two solutions.)
As you can see I am doing two checks in the code (at least that’s what I intended to do):
-
Check if HTTP variable (original_post) exists in queried URL, AND that it is set to some value (ID), AND that the value (ID) is a number. OTHERWISE, return a 404 error with appropriate headers.
-
Check if the custom WordPress query (
$query_original_post
) has any results to loop over. OTHERWISE, return a 404 error with appropriate headers.
Problem:
-
Is that the right way to do it? (or at least, can it be any simpler?)
-
(If yes to #1) It appears to work, but returns 200 OK header when I go to an URL like:
example.com/comments/?original_post=NUMBER
, where NUMBER is any positive integer over 4 digits long (e.g. 14532).I don’t understand the relation. Why’d something like “example.com/comments/?original_post=14532` return 200 OK header when I am logged-into WordPress, and 404 error (which it should) when I am not?
Headers are sent long before you try to alter them. Headers are sent by actions associated with
get_header()
, so by the time your code executes, it is too late to alter the headers. You can demonstrate this with a simple experiment. Try each of the following:and
In a template file and watch the output with a tool like HttpFox or Wireshark (if you really want to have some fun 🙂 ).
To effectively change the headers you will need to run your logic before
get_header()
.I believe this will get the effect you want with fewer lines of code to boot:
And for the love of all that is holy please don’t use PHP opening and closing tags unless you actually need them.