Built-in Rules
MilliCache includes default rules that handle common caching scenarios. All built-in rules have negative or zero priority, so your custom rules (->order({10+})) run after them and can override their decisions.
Bootstrap Phase Rules#Copied!
Execute before WordPress loads via advanced-cache.php.
Core Bypass Rules (Order -10)#Copied!
These run first and bypass caching for non-cacheable scenarios:
| Rule ID | Condition | Result |
|---|---|---|
millicache:const:wp-cache |
WP_CACHE !== true |
Bypass |
millicache:request:check-method |
Method not GET/HEAD | Bypass |
millicache:request:cli |
Running in WP-CLI | Bypass |
millicache:request:xmlrpc |
XMLRPC_REQUEST is true |
Bypass |
millicache:request:file |
URL ends with file extension | Bypass |
millicache:request:rest |
URL contains wp-json |
Bypass |
millicache:config:ttl-not-set |
TTL is 0 or negative | Bypass |
Configuration-Based Rules (Order 0)#Copied!
Apply settings from your configuration:
| Rule ID | Condition | Result |
|---|---|---|
millicache:config:nocache-cookies |
Excluded cookie present | Bypass |
millicache:config:nocache-paths |
URL matches excluded path | Bypass |
Default excluded cookies:
wp-*pass*— WordPress password-protected contentcomment_author_*— Comment author cookies
WordPress Phase Rules#Copied!
Execute after WordPress loads on the template_redirect hook.
Context-Based Rules (Hook Priority 20)#Copied!
| Rule ID | Condition | Result |
|---|---|---|
millicache:wp:logged-in |
User is logged in | Bypass |
millicache:wp:response:code |
HTTP status ≠ 200 | Bypass |
millicache:wp:const:donotcachepage |
DONOTCACHEPAGE defined |
Bypass |
millicache:wp:const:doing-cron |
DOING_CRON defined |
Bypass |
millicache:wp:const:doing-ajax |
DOING_AJAX defined |
Bypass |
Rule Priority System#Copied!
Rules execute in priority order (lower numbers first):
| Priority | Who Uses It | Purpose |
|---|---|---|
| -10 | Core bypass rules | Fundamental checks (methods, CLI, etc.) |
| 0 | Configuration rules | Apply user settings |
| 10+ | Your custom rules | Override or extend defaults |
All Rules Run#Copied!
MilliRules evaluates all rules in order — there's no short-circuit behavior. Later rules can override earlier rules' decisions.
1// Built-in rule (order -10) sets do_cache(false) for POST requests
2// Your rule (order 10) runs AFTER and can override it
3Rules::create( 'mysite:cache-post-search', 'php' )
4 ->order( 10 )
5 ->when()
6 ->request_method( 'POST' )
7 ->request_url( '/search/*' )
8 ->then()
9 ->do_cache( true ) // Overrides the earlier bypass
10 ->register();
This means:
- All your rules always run after built-in rules
- Your rules can override built-in decisions (the last
do_cache()wins) - To completely replace a built-in rule, use the same rule ID (see below)
Available Actions#Copied!
Bootstrap Phase Actions#Copied!
Available in php rules (before WordPress):
| Action | Description | Example |
|---|---|---|
do_cache( $bool, $reason ) |
Enable/disable caching | ->do_cache( false, 'Preview' ) |
set_ttl( $seconds ) |
Override TTL | ->set_ttl( 3600 ) |
set_grace( $seconds ) |
Override grace period | ->set_grace( 86400 ) |
WordPress Phase Actions#Copied!
Available in wp rules (after WordPress loads):
| Action | Description | Example |
|---|---|---|
do_cache( $bool, $reason ) |
Enable/disable caching | ->do_cache( false, 'Admin' ) |
set_ttl( $seconds ) |
Override TTL | ->set_ttl( 300 ) |
set_grace( $seconds ) |
Override grace period | ->set_grace( 3600 ) |
add_flag( $flag ) |
Add cache flag | ->add_flag( 'custom:flag' ) |
remove_flag( $flag ) |
Remove cache flag | ->remove_flag( 'home' ) |
clear_cache( $targets ) |
Clear cache entries | ->clear_cache( ['post:*'] ) |
clear_site_cache() |
Clear entire site | ->clear_site_cache() |
Available Conditions#Copied!
Core Conditions#Copied!
Available in both php (bootstrap) and wp (WordPress) phases:
| Condition | Description | Example |
|---|---|---|
constant( $name, $value ) |
Check constant value | ->constant( 'WP_DEBUG', true ) |
custom( $id, $callback ) |
Custom callback | ->custom( 'my-check', fn() => ... ) |
request_method( $methods ) |
HTTP method | ->request_method( 'POST' ) |
request_url( $pattern ) |
URL pattern match | ->request_url( '/shop/*' ) |
cookie( $name, $value ) |
Cookie check | ->cookie( 'currency', 'EUR' ) |
WordPress is_* Conditions#Copied!
All is_* methods are available in wp phase rules (require WordPress context):
| Condition | Description |
|---|---|
is_singular( $post_types ) |
Single post/page/CPT |
is_front_page() |
Front page |
is_home() |
Blog homepage |
is_post_type_archive( $types ) |
Post type archive |
is_category( $category ) |
Category archive |
is_tag( $tag ) |
Tag archive |
is_tax( $taxonomy, $term ) |
Taxonomy archive |
is_author( $author ) |
Author archive |
is_date() |
Date archive |
is_feed( $feeds ) |
Feed page |
is_user_logged_in() |
User logged in |
WordPress has_* Conditions#Copied!
All has_* methods are available in wp phase rules (require WordPress context):
| Condition | Description |
|---|---|
has_term( $term, $taxonomy ) |
Post has specific term |
has_block( $block_name ) |
Post contains block |
has_tag( $tag ) |
Post has tag |
has_category( $category ) |
Post has category |
has_post_thumbnail() |
Post has featured image |
has_excerpt() |
Post has excerpt |
has_post_format( $format ) |
Post has format |
has_nav_menu( $location ) |
Menu location has menu |
has_custom_logo() |
Site has custom logo |
Debugging Rules#Copied!
Enable Debug Mode#Copied!
1define( 'MC_CACHE_DEBUG', true );
Check Response Headers#Copied!
The X-MilliCache-Status header shows the caching result:
| Value | Meaning |
|---|---|
hit |
Served from cache |
miss |
Not cached, will be stored |
bypass |
A rule prevented caching |
grace |
Serving stale while regenerating |
List Registered Rules#Copied!
1use MilliCacheDepsMilliRulesRules;
2
3// Log all rules
4foreach ( Rules::all() as $rule ) {
5 error_log( sprintf(
6 'Rule: %s (order: %d, phase: %s)',
7 $rule['id'],
8 $rule['order'],
9 $rule['phase']
10 ) );
11}
Override / Unregister Built-in Rules#Copied!
To change the behavior of a built-in rule, you can unregister them or create your own with the same ID:
1add_action('template_redirect', function() {
2 // Unregister a built-in rule to completely remove its behavior
3 Rules::unregister( 'millicache:wp:const:doing-ajax' );
4});
5
6// Override the logged-in user bypass to allow caching for subscribers
7Rules::create( 'millicache:wp:logged-in' ) // Same ID as built-in
8 ->on( 'template_redirect', 20 ) // Same hook & priority as built-in
9 ->order( 10 ) // Higher order to run after built-in
10 ->when()
11 ->is_user_logged_in()
12 ->custom( 'is-editor-or-higher', function() {
13 return current_user_can( 'edit_posts' );
14 })
15 ->then()
16 ->do_cache( false, 'Editor role or above' )
17 ->register();
Now subscribers can see cached pages, but editors and admins still bypass.
Next Steps#Copied!
- Examples — Practical rule examples
- MilliRules Conditions — Full conditions reference
- MilliRules Actions — Full actions reference