Skip to content

Instantly share code, notes, and snippets.

@Kevin-LeMasters-PixelParade
Last active February 20, 2026 11:56
Show Gist options
  • Select an option

  • Save Kevin-LeMasters-PixelParade/24786f2c2cfae0abfed762b717ff41e0 to your computer and use it in GitHub Desktop.

Select an option

Save Kevin-LeMasters-PixelParade/24786f2c2cfae0abfed762b717ff41e0 to your computer and use it in GitHub Desktop.
Master Breeze Cache Strategy (Auto-Detect + Custom Map)

Master Breeze Cache Strategy (Auto-Detect + Custom Map)

The Problem

If you use Cloudways, the Breeze caching plugin, and Cloudflare Enterprise Edge Cache, you've likely run into this frustrating issue: When you update a Post or Custom Post Type (CPT), the parent listing pages, custom taxonomy archives, and Page Builder pages (like a Knowledge Base containing a post grid) do not update. By default, Breeze aggressively clears the cache for the single post ID you just edited, but it fails to recognize the complex relationships of modern WordPress sites built with custom post types or page builders.

The Solution

This snippet bridges the gap between Breeze and your site's architecture. It acts as a "Traffic Controller" for the Cloudflare/Varnish cache, doing two main things:

  1. Auto-Detection: It programmatically hooks into WordPress to find the CPT Archive and any assigned Custom Taxonomy pages (e.g., Event Categories) and adds them to the purge queue.
  2. Relationship Mapping: It includes a simple $custom_page_map array where you can explicitly tell Breeze, "When an 'Event' is updated, also clear the '/knowledge-base/' page."

The Magic Behind It (Recent Breeze Hooks)

This snippet is made possible by two specific filters recently introduced in the Breeze plugin changelog:

  • breeze_cf_purge_type_on_post_update: By default, Breeze queues Cloudflare purges asynchronously via a WP-Cron job. This causes a confusing delay where the cache looks unbroken, but it's actually just waiting. This snippet forces the return value to 'synchronous', executing the purge immediately upon hitting "Update."
  • breeze_purge_post_cache_urls: This filter allows developers to inject an array of custom URLs into the Breeze purge queue.
    • Critical Nuance: As per the Breeze core code, Cloudflare strictly requires a trailing slash for these URLs. This snippet utilizes trailingslashit() on every generated URL to ensure the API call succeeds.

Prerequisites & Troubleshooting if using the Cloudways Cloudflare Enterprise integration (via native cloudways add-on)

For this snippet to successfully clear the Cloudflare Edge Cache, your Cloudways application must have its Cloudflare credentials loaded. This should be set when "smart purge" is turned on in the cloudflare settings tab.

Check your wp-config.php file. If the following constants are missing, Breeze will silently abort the Cloudflare purge: The solution is to re-configure "smart purge" on the cloudflare settings tab.

define( 'CDN_SITE_ID', '...' );
define( 'CDN_SITE_TOKEN', '...' );
<?php
/**
* Snippet Name: Master Breeze Cache Strategy (Auto-Detect + Custom Map)
* Description: Holistically manages cache purging for CPTs, Archives, Taxonomies, and Page Builder Pages. Also forces Cloudflare Edge purge on "Clear All".
*/
// ====================================================================
// 1. FORCE SYNCHRONOUS PURGE (Fixes the "Cron" Delay)
// ====================================================================
// Overrides the default 'cron' behavior so updates are instant.
add_filter('breeze_cf_purge_type_on_post_update', function() {
return 'synchronous';
});
// ====================================================================
// 2. THE MASTER PURGE STRATEGY (Relationship Map + Auto-Detect)
// ====================================================================
// Hooks into Breeze's URL array before sending to Varnish/Cloudflare.
add_filter('breeze_purge_post_cache_urls', 'wpcb_master_breeze_strategy', 10, 2);
function wpcb_master_breeze_strategy($urls, $post_id) {
if (!is_array($urls)) $urls = [];
$post = get_post($post_id);
if (!$post) return $urls;
// --- CONFIGURATION: THE RELATIONSHIP MAP ---
// Define which Custom Pages/Hubs should clear when a specific Post Type is updated.
// Format: 'post_type_slug' => ['/page-slug/', '/another-page/']
// Note: Use '/' for the Homepage.
$custom_page_map = [
'event' => [
'/', // Homepage
'/knowledge-base/', // Builder page with Event loop
'/community-hub/',
],
'project' => [
'/',
'/portfolio-overview/',
],
'post' => [
'/',
'/news-aggregator/',
],
];
// A. Process the Custom Map
if (array_key_exists($post->post_type, $custom_page_map)) {
foreach ($custom_page_map[$post->post_type] as $page_path) {
// MUST use trailingslashit() to meet Cloudflare/Breeze strict matching rules
$urls[] = trailingslashit(home_url($page_path));
}
}
// B. Auto-Detect Standard Archives (The "Parents")
$archive_link = get_post_type_archive_link($post->post_type);
if ($archive_link) {
$urls[] = trailingslashit($archive_link);
}
// C. Auto-Detect Taxonomies (The "Siblings")
// Finds every category/tag/custom-term assigned to this post and clears their archives.
$taxonomies = get_object_taxonomies($post);
foreach ($taxonomies as $tax_slug) {
$terms = get_the_terms($post_id, $tax_slug);
if (!empty($terms) && !is_wp_error($terms)) {
foreach ($terms as $term) {
$term_link = get_term_link($term);
if (!is_wp_error($term_link)) {
$urls[] = trailingslashit($term_link);
}
}
}
}
// D. The Blog Feed (If standard post)
if ($post->post_type === 'post') {
$page_for_posts_id = get_option('page_for_posts');
if ($page_for_posts_id) {
$urls[] = trailingslashit(get_permalink($page_for_posts_id));
}
}
return array_unique($urls);
}
// ====================================================================
// 3. FORCE CLOUDFLARE PURGE ON "CLEAR ALL CACHE" BUTTON
// ====================================================================
// Guarantees Cloudflare Edge clears even if Breeze UI settings fail to trigger it natively,
// assuming CDN_SITE_ID and CDN_SITE_TOKEN are present in wp-config.php.
add_action('breeze_clear_all_cache', 'wpcb_force_cloudflare_flush');
function wpcb_force_cloudflare_flush() {
if (class_exists('Breeze_CloudFlare_Helper')) {
Breeze_CloudFlare_Helper::reset_all_cache();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment