/ Updated 20 June 2023 / 3 min read

Forcing W3 Total Cache to Clear Parent Term Listing Pages on Post Save

In the page caching settings of W3 Total Cache there is an option to flush the ‘Post Terms Pages’ when saving or updating a post. This clears the listing pages for any terms that the post has been added to, but it doesn’t clear the listing pages of any parent terms that aren’t checked, even though the post can still show on those pages.

The following code uses WordPress filters to detect a change in a post and then invalidate the cache of any parent term listing pages whether they have been checked or not.

<?php
/**
 * Clear Total Cache term listing pages for a post
 * @param $post_id
 * @param $post
 *
 * @return void
 */
function rw_clear_total_cache_terms_pages( $post_id, $post ) {
	if ( function_exists( 'w3tc_flush_url' ) ) {
		$taxonomies = get_object_taxonomies( $post->post_type );
		foreach ( $taxonomies as $taxonomy ) {
			$terms = get_the_terms( $post_id, $taxonomy );
			if ( $terms ) {
				foreach ( $terms as $term ) {
					$urls = rw_get_post_term_urls( $term, $taxonomy );
					if ( ! empty( $urls ) ) {
						foreach ( $urls as $url ) {
							w3tc_flush_url( $url );
						}
					}
				}
			}
		}
	}
}

/**
 * Recursively get the URLs of all terms up to the parent
 * @param $term
 * @param $taxonomy
 * @param $urls
 *
 * @return array|mixed
 */
function rw_get_post_term_urls( $term, $taxonomy, $urls = array() ) {
	if ( $term ) {
		$urls[] = get_term_link( $term, $taxonomy );
		if ( $term->parent ) {
			$urls = array_merge( $urls, rw_get_post_term_urls( $term->parent, $taxonomy ), $urls );
		} else {
			return $urls;
		}
	}

	return $urls;
}

add_action( 'save_post', 'rw_clear_total_cache_terms_pages', 10, 2 );
add_action( 'delete_post', 'rw_clear_total_cache_terms_pages', 10, 2 );
add_action( 'publish_post', 'rw_clear_total_cache_terms_pages', 10, 2 );
add_action( 'draft_post', 'rw_clear_total_cache_terms_pages', 10, 2 );

W3 has a function called w3tc_flush_url, which allows us to invalidate the cache of any page by passing it the URL.

The actions for when a new post is saved, an existing page is updated, set to draft or deleted trigger the function rw_clear_total_cache_terms_pages.

That function first checks that the w3tc_flush_url function is available to use. Then it checks which taxonomies are assigned to the current post type. That could be categories, tags or anything else.

Looping through each available taxonomy, it checks the selected terms for each and then passes them to the rw_get_post_term_urls function.

That function stores the URL of that term listing page in an array and checks to see if that term has a parent. If it does, the parent term and the URL array are passed back to the same function until there are no more parents and the array of URLs is returned to the original function.

If the array isn’t empty, the w3tc_flush_url function is called on each URL to invalidate the cache.

As W3 serves stale cache to users whilst the new one is being built, the page will show the new content after a visitor has requested the page to trigger the update.