How to cache json with wp-super cache

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.

Read More

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

Related posts

Leave a Reply

4 comments

  1. 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;
    
  2. 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.”

  3. 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' );
    
  4. 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.