I am trying to enable 304 If Modified Since HTTP header in my WordPress site. After doing lot of Googling I find out a site where the author said to put the following line at the very end of wordpress wp-config.php file. Here is the line of code:

header("Last-Modified: " . the_modified_date());

Now the author said that this was it. I dont have to do anything else to achieve 304 If Modified Since HTTP header. But after doing this I tested by HTTP header using the site

http://httpstatus.io/

and here is the screenshot of my header:

enter image description here

Check the red marked section. The last modified header value is BLANK.

After that I thought this might be some issue with the_modified_date() function so I've also tried get_the_modified_date() function. But still no result.

At the very end, I've created a small shortcode function to test if these functions are working or not and echoed it inside the short code. When I used the shortcode I can clearly see that the functions are working fine but for some reason sending blank to the 304 If Modified Since HTTP header.

My site is here

Any suggestions on how to solve this?

up vote 3 down vote accepted

the_modified_date() is a template tag that must used inside the loop, that is why it is not wokring for you.

WordPress provide a action and filter hook to include or modify HTTP headers:

But it doesn't work for this purpose. For example, the next code is not working:

add_action( 'send_headers', 'cyb_add_last_modified_header' );
function cyb_add_last_modified_header() {
    //Check if we are in a single post of any type (archive pages has not modified date)
    if( is_singular() ) {
        $post_id = get_queried_object_id();
        if( $post_id ) {
            header("Last-Modified: " . get_the_modified_time("D, d M Y H:i:s", $post_id) );
        }
    }
}

Why?

The main wp query is not build at this moment, neither in wp_headers filter. So, is_singular() returns false, get_queried_object_id() returns NULL and there is no way to get the modified time of the current post.

A posible solution is to use template_redirect action hook, as suggested by Otto in this question (tested and working):

add_action('template_redirect', 'cyb_add_last_modified_header');
function cyb_add_last_modified_header($headers) {

    //Check if we are in a single post of any type (archive pages has not modified date)
    if( is_singular() ) {
        $post_id = get_queried_object_id();
        if( $post_id ) {
            header("Last-Modified: " . get_the_modified_time("D, d M Y H:i:s", $post_id) );
        }
    }

}
  • Thank you very much for the help. I think I better make it a plugin and then use it. Thanks a lot for your help. Also you are checking this for is_single() so will this works for pages and custom post types like portfolios? – iSaumya Dec 22 '14 at 9:42
  • Answer edited to include the correct DateTime format (thanks toscho). For @iSaumya, is_singular() checks for any type of post, including pages a custom post types. is_single() doesn't work for pages and attachments. – cybmeta Dec 22 '14 at 9:54
  • I'm really sorry for previous comments. That was happening due to the part left in wp-config file. But actually the above code is not working and not sending the Last Modified 304 to the header. Check: i.imgur.com/LlbxDbB.jpg There is nothing called last modified. I've checking the header of one of my blog post. – iSaumya Dec 22 '14 at 10:49
  • No, it is not working. I've testing and the main WP query seems not to be build as the send_headers event, so the is_singular() returns false and get_queried_object_id() returns NULL. I didn't expect that the query was not build as this point. I'm now investigating. – cybmeta Dec 22 '14 at 10:57
  • I've found the solution. See edited answer. – cybmeta Dec 22 '14 at 11:12

I tried the code from cybmeta but the date wasn't being set correctly. I am not entirely sure the reason, but after investigating I found the Add Headers plugin which is now deprecated but was a good source of useful code. In that plugin the author sets the Last-Modified header date in a different way and using that to modify the code worked for me. Here is what I ended up with:

add_action('template_redirect', 'cyb_add_last_modified_header');
function cyb_add_last_modified_header($headers) {
    //Check if we are in a single post of any type (archive pages has not modified date)
    if( is_singular() ) {
        $post_id = get_queried_object_id();
        if( $post_id ) {
            $post_mtime = get_the_modified_time("D, d M Y H:i:s", $post_id);
            $post_mtime_unix = strtotime( $post_mtime );
            $header_last_modified_value = str_replace( '+0000', 'GMT', gmdate('r', $post_mtime_unix) );
            header("Last-Modified: " . $header_last_modified_value );
        }
    }
}

My solution for Last-Modified and correct 304 Not Modified

Inside functions.php

add_action('template_redirect', 'last_mod_header');

function last_mod_header($headers) {
     if( is_singular() ) {
            $post_id = get_queried_object_id();
            $LastModified = gmdate("D, d M Y H:i:s \G\M\T", $post_id);
            $LastModified_unix = gmdate("D, d M Y H:i:s \G\M\T", $post_id);
            $IfModifiedSince = false;
            if( $post_id ) {
                if (isset($_ENV['HTTP_IF_MODIFIED_SINCE']))
                    $IfModifiedSince = strtotime(substr($_ENV['HTTP_IF_MODIFIED_SINCE'], 5));  
                if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
                    $IfModifiedSince = strtotime(substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 5));
                if ($IfModifiedSince && $IfModifiedSince >= $LastModified_unix) {
                    header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
                    exit;
                } 
     header("Last-Modified: " . get_the_modified_time("D, d M Y H:i:s", $post_id) );
                }
        }

    }
  • 4
    Could you explain the code a bit and let users know what it does please? – Howdy_McGee Jul 21 '16 at 21:51
  • 1
    This must be a plugin. The theme is for presentation only. You do not want to lose that functionality when you switch themes. – fuxia Jul 21 '16 at 22:37
  • I agree. You should really explain your code. But toscho I don't think he is asking anyone to put it in a theme. He just shared his code. So if someone thinks that he is not gonna change his theme ever he can use it in functions.php or can add it as a plugin. It's just a function. Anything can be done. But really Travis, you should really explain your code. – iSaumya Jul 22 '16 at 21:31

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.