WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In a new project we are using wp-super-cache (the client's preferred plugin) to create the static html files for custom content types. But we are trying to figure out if everything is being cached properly.

This is a 2 part question.

1) The theme we have created utilizes page templates to output json that is ingested via ajax calls. ie. if you hit the page: theurl.com/sample - you will get pure json. While there is a non-javascript version of every page and post, Ajax drives the front end of this theme. We have removed the header and footer in these files so that it is pure json, and we are trying to figure out how to determine if the json is being cached. In theory the data would be cached because it is technically a page served up by wordpress. But, how can we figure out if it is being cached?

2) We are using the json api plugin to serve up certain post data as well. http://wordpress.org/extend/plugins/json-api/ For this example, let's say we are utilizing the plugin's default method of output and hitting this page: my url.com/category/news?json=1 - Does anyone know how we can verify if this output is being cached? If it isn't being cached, what method would make this happen?

There doesn't seem to be much information about this online, so in the spirit of creating compelling and optimized wordpress sites, help a brother out

share|improve this question

It did appear that the json wasn't being cached by wp-super-cache, but we decided to take a different approach. By using the transient api, we were able to do a faux-cache on all json, and drastically reduce the taxing of the database. Then on the ajax side of things, we are caching the html that is created from this semi-cached json. Things are super speedy! Here is a scaled down version of the code and concept.

    $transient_key = 'my-transient-key'; 
    $data = get_transient( $transient_key ); 

    if ( $data == '' ) { 
      $args = array(

    'post_type' => 'brand', 
    'posts_per_page' => 50

  );

  $postsArray = array();  
  // The Query
 query_posts( $args );

  // The Loop
  while ( have_posts() ) : the_post();

    $brand_id = get_the_ID();
    $slug = basename(get_permalink());
    $title = get_the_title();
    $description = get_the_content();

                $posts = array(

                   'brand_id' => $brand_id,
                   'machine_name' => $slug,
                              'postTitle' => $title,
                   'description' => $description,

                   );

    array_push($postsArray,$posts);


  endwhile;

   $data = json_encode($postsArray);


 set_transient( $transient_key, $data, 60 * 60 * 24 ); // one day
 }  // now all the brand information is cached as one table call.

echo $data;
share|improve this answer
    
nice, thumbs up!!! – Dipesh Kc Nov 21 '12 at 11:53

WP Super Cache examines your WordPress site's pages for some HTML tags before it caches them.

Your pages most probably don't have </html> tag (common issue), in that case, try adding something like //</html> -- that's a workaround, and WP Super Cache should then generate cached versions of your pages.

Why does WP Super Cache do it like that? See, there's no obvious way to check if a page is only half-loaded, than to check if all the basic HTML tags exist and are closed properly.

In Donncha's (WP Super Cache's developer) own words, "It's to stop half generated pages being cached."

share|improve this answer
    
I wish they had the option to cache json specifically, or other data types. So many options and yet not the one we needed for this project. But, this is a cool workaround. I'll give it a try. – Starfs May 9 '12 at 4:34

SECURITY NOTE: This (and the other solutions) shouldn't be used unless you have a way to override the Content-Type: text/html header that WP Super Cache sends with the appropriate application/json value. Sending JSON as text/html will cause the browser to render it as HTML, which could potentially be an XSS vector.

It looks like that needs to be done at the server layer, since WPSC doesn't provide the necessary hooks.


This is how I did it. It's similar to Liang's approach, but doesn't require modifying the plugin directly, and has a more precise regex pattern.

If you're using v2 of the REST API, you should use REST_REQUEST instead of JSON_REQUEST.

It'd be good to subscribe to 22 and #79 in case something changes in WP Super Cache.

/**
 * Tell WP Super Cache to cache API endpoints
 *
 * @param string $eof_pattern
 *
 * @return string
 */
function wcorg_json_cache_requests( $eof_pattern ) {
    global $wp_super_cache_comments;

    if ( defined( 'JSON_REQUEST' ) && JSON_REQUEST ) {
        // Accept a JSON-formatted string as an end-of-file marker, so that the page will be cached
        $json_object_pattern     = '^[{].*[}]$';
        $json_collection_pattern = '^[\[].*[\]]$';

        $eof_pattern = str_replace(
            '<\?xml',
            sprintf( '<\?xml|%s|%s', $json_object_pattern, $json_collection_pattern ),
            $eof_pattern
        );

        // Don't append HTML comments to the JSON output, because that would invalidate it
        $wp_super_cache_comments = false;
    }

    return $eof_pattern;
}
add_filter( 'wp_cache_eof_tags', 'wcorg_json_cache_requests' );
share|improve this answer

I met this problem too. I had wrote some my code to be API. When response type was XML, cache worked. But when response type was json, it did not work.

It take my some hours to fix this bug.

This is work for me.

enter image description here

Just update your code like my changes.

It works for me now.

share|improve this answer
3  
Please post real code and not an image of the code. – Pieter Goosen Sep 7 '15 at 4:26
    
You should use the wp_cache_eof_tags filter instead of modifying the plugin directly. – Ian Dunn Dec 30 '15 at 19:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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