LSCache for WordPress API¶
Any WordPress plugin that populates front-end content that can be publicly cached should work with LSCache.
However, if the plugin needs to update some data, and the cache does not automatically purge the cached page, you may be required to write an integration script to remedy this or invoke LSCWP's third party plugin integration framework .
Potential for Customization¶
LSCache for WordPress provides hooks that allow you to customize many aspects of cache management, namely WordPress nonce
caching via ESI blocks as well as the other ones below.
Customized Smart Purging¶
LSCache works by tagging each cacheable page. In its most basic form, each page is tagged with its Post ID, then sent to the server to be cached. When someone makes a change to the page, that request will notify the server to purge the cached items associated with that page's post id.
A post will automatically be purged if the following events are triggered (unless changed from the defaults):
- edit_post
- save_post
- deleted_post
- trashed_post
- delete_attachment
These cases cover most situations in which a cache purge is necessary.
If your plugin has additional situations in which a cache purge is necessary, you have the ability to customize the notifications sent to the server. As the page is stored in the cache, you can assign your own tags to the page so that later, it may be purged as part of a custom group. Multiple tags can be set on a single page, and a single tag may be used on multiple pages. This many-to-many mapping provides a flexible system enabling you to group pages in a variety of ways.
Example
Page #1 is tagged with MTPP_F.1, MTPP_G.4, MTPP_S.wyoming
(because the page is in forum 1, group 4, and related to the state of Wyoming).
Page #2 is tagged with MTPP_F.1, MTPP_G.2, MTPP_S.iowa
.
If a change is made where all pages tagged MTPP_F.1
need to be purged, the tag system enables the server to easily purge both of those pages at once. If a request is sent to the server indicating that pages tagged MTPP_S.wyoming
need to be purged, then the tagging system knows to only purge Page #1.
Customized Do-Not-Cache Rules¶
Below is a list of what LSCWP considers non-cacheable.
LSCache considers a page to be non-cacheable if
- It is an Admin page
- It is a post request
is_trackback()
is trueis_search()
is true- No theme is used
- The URI is found in the Do Not Cache URIs list
- The post URL has a query string found in the Do Not Cache Query Strings list
- The post has a category found in the Do Not Cache Categories list
- The post has a tag found in the Do Not Cache Tags list
- The request has a cookie found in the Do Not Cache Cookies list
- The request has a user agent found in the Do Not Cache User Agents list
- The request is being made by a user whose role is checked in the Do Not Cache Roles List
If your plugin generates other private/transient data that cannot be cached for certain responses, you can instruct LSCWP to not cache that data.
Hooks¶
These are the hooks to be used in other plugins and most are from src/api.cls.php
under the init()
function. Please ignore the other non-public functions/hooks in that file. The benefit to using hooks instead of functions is so there is no need to detect if LSCWP is enabled and a function exists or not.
Init¶
Hook to plugin init¶
Action hook: litespeed_init
Parameter: the hook to be used
Usage:
do_action( 'litespeed_init', 'the_hook' );
Hook after admin page init¶
Action hook: litspeed_after_admin_init
Usage:
do_action( 'litspeed_after_admin_init' ) ;
Config¶
Get plugin config setting¶
Filter hook: litespeed_conf
.
Parameter: the setting tag/slug (all setting slugs are at src/base.cls.php
& default settings are in data/const.default.ini
)
Usage (this would get the private cache setting value):
$val = apply_filters( 'litespeed_conf', 'cache-priv' );
Append to plugin config setting¶
Action hook: litespeed_conf_append
Parameters: name of setting & value
Usage:
do_action( 'litespeed_conf_append', 'name', 'default' );
Append option save value filter¶
Action hook: litespeed_conf_multi_switch
Usage:
do_action( 'litespeed_conf_multi_switch' );
Change option dynamically¶
Note
This will only affect the AFTER usage of that option
Action hook: litespeed_conf_force
Parameters: key, variable
Usage:
do_action( 'litespeed_conf_force', 'key', 'variable' );
Apply updated settings¶
Action hook: litespeed_update_confs
Parameters: updated settings
Usage:
do_action( 'litespeed_update_confs', $update_confs );
Cache Control¶
Used to determine whether content should be cached and how to store it.
Set cache control hook¶
Specifies a hook for cache control. The hook will be triggered when the cache plugin is checking whether the current page is cacheable. This will not trigger on admin pages nor any page that has previously been marked as noncacheable.
Action hooks: litespeed_control_finalize
&& litespeed_api_control
Parameter: tags
Usage:
do_action( 'litespeed_control_finalize', 'tag' );
Set private cache¶
Action hook: litespeed_control_set_private
Usage:
do_action( 'litespeed_control_set_private' );
Set current page as non-cacheable¶
Action hook: litespeed_control_set_nocache
Parameter: reason
Usage:
do_action( 'litespeed_control_set_nocache', 'nocache due to logged in' );
Set current page as cacheable¶
Might need if hook wp
not called
Action hook: litespeed_control_set_cacheable
Parameter: reason
Usage:
do_action( 'litespeed_control_set_cacheable', 'cache for scripted page retrieval' );
Force current page as cacheable¶
Will ignore most kinds of non-cacheable conditions.
Action hook: litespeed_control_force_cacheable
Parameter: reason
Usage:
do_action( 'litespeed_control_force_cacheable', 'force caching for special page' );
Set cache to force public cache if cacheable¶
Will ignore most kinds of non-cacheable conditions.
Action hook: litespeed_control_force_public
Parameter: reason
Usage:
do_action( 'litespeed_control_force_public', 'special page preferred to be cached public' );
Check if current page is cacheable¶
Note: Read-Only. Directly appending to this filter won't work. Call actions above to set cacheable or not.
Filter hook: litespeed_control_cacheable
Usage (this would define the cacheable status on the current page that could be tested against later):
$cstatus = apply_filters( 'litespeed_control_cacheable', false );
Set custom TTL¶
Manually sets the TTL (Time to Live) for your cached object or ESI block.
Action hook: litespeed_control_set_ttl
Parameter: value
Usage:
do_action( 'litespeed_control_set_ttl', '1600' );
Get current page TTL¶
Filter hook: litespeed_control_ttl
Usage (this would get the TTL of the current page):
$pagettl = apply_filters( 'litespeed_control_ttl', 0 );
Tag¶
Used to classify content for cache storage
Final tagging¶
This hook is called at the end of every cacheable request, and provides an access point to your plugin, giving you the ability to add cache tags to the current request.
Action hook: litespeed_tag_finalize
Parameter: the hook
Usage:
do_action( 'litespeed_tag_finalize', 'the_hook' );
Add page tag¶
Adds a single cache tag (or group of cache tags) to the list of cache tags associated with the current page. These tags are appended the list of built-in tags generated by LSCWP and may be used to purge by a custom tag.
Action hook: litespeed_tag_add
Parameter: the tag to add
Usage:
do_action( 'litespeed_tag_add', 'the_new_tag' );
Add tag to post¶
Adds a custom cache tag to a post which could be used to trigger a purge if changed.
Action hook: litespeed_tag_add_post
Parameter: the custom tag to add
Usage (could use a string within a loop or after a conditional test):
do_action( 'litespeed_tag_add_post', $quantity );
Add tag to widget¶
Adds a custom cache tag to a widget which could be used to trigger a purge if changed.
Action hook: litespeed_tag_add_widget
Parameter: the custom tag to add
Usage (could use a string within a loop or after a conditional test):
do_action( 'litespeed_tag_add_widget', $quantity );
Add private cache tag¶
Adds private cache tags to the list of cache tags for the current page.
Action hook: litespeed_tag_add_private
Parameter: the tag to add
Usage:
do_action( 'litespeed_tag_add_private', 'the_tag_to_add' );
Add private ESI cache tag¶
Adds private ESI cache tags to the list of cache tags for the current page.
Action hook: litespeed_tag_add_private_esi
Parameter: the ESI tag to add
Usage:
do_action( 'litespeed_tag_add_private_esi', 'the_esi_tag_to_add' );
Purge¶
Final tagging¶
This hook is called at the end of every cacheable request, and gives you the ability to add purge tags to the current request.
Action hook: litespeed_purge_finalize
Parameter: the hook
Usage:
do_action( 'litespeed_purge_finalize', 'the_hook' );
Purge a cache tag¶
Action hook: litespeed_purge
Parameter: the cache tag to purge.
Usage:
do_action( 'litespeed_purge', 'the_tag_to_purge' );
Purge all existing caches¶
Action hook: litespeed_purge_all
Usage:
do_action( 'litespeed_purge_all' );
Purge a single post by ID¶
Action hook: litespeed_purge_post
Parameter: the post ID
Usage:
do_action( 'litespeed_purge_post', 'post_id' );
Purge posts by post type¶
Action hook: litespeed_purge_posttype
Parameter: the post type
Usage:
do_action( 'litespeed_purge_posttype', 'post_type' );
Purge posts by URL¶
Action hook: litespeed_purge_url
Parameter: URL to purge
Usage:
do_action( 'litespeed_purge_url', 'the_url' );
Tip
The URL parameter may be passed with or without a domain. So, both /path/to/page/
and https://www.example.com/path/to/page/
will work.
Purge posts by widget¶
Action hook: litespeed_purge_widget
Parameter: widget to purge
Usage:
do_action( 'litespeed_purge_widget', 'widget_to_purge' );
Purge posts by ESI¶
Action hook: litespeed_purge_widget
Parameter: ESI name to purge
Usage:
do_action( 'litespeed_purge_widget', 'esi_to_purge' );
Purge private cache by tag¶
Action hook: litespeed_purge_private
Parameter: tag to purge
Usage:
do_action( 'litespeed_purge_private', 'tag_to_purge' );
Purge private cache by ESI¶
Action hook: litespeed_purge_private_esi
Parameter: ESI name to purge
Usage:
do_action( 'litespeed_purge_private_esi', 'esi_to_purge' );
Purge all private cache¶
Action hook: litespeed_purge_private_all
Usage:
do_action( 'litespeed_purge_private_all' );
Hook action for post purges¶
Triggered when a post is purged
Action hook: litespeed_api_purge_post
Parameter: the hook
Usage:
do_action( 'litespeed_api_purge_post', 'esi_to_purge' );
Purge all object cache¶
Action hook: litespeed_purge_all_object
Usage:
do_action( 'litespeed_purge_all_object' );
Hook action for post Purge All¶
Triggered after a Purge All
Action hook: litespeed_purged_all
Usage:
do_action( 'litespeed_purged_all' );
Hook action for post Purge All Object¶
Triggered after a Purge All
Action hook: litespeed_purged_all_object
Usage:
do_action( 'litespeed_purged_all_object' );
ESI¶
Edge Side Includes (ESI) allows you to “punch holes” in a page in order to treat certain sections of the page differently. This is useful, for example, if you want to include a private shopping cart widget in a public page. For more on ESI and how it works, see our blog post on the subject.
Video
See a video demonstration of What is Edge Side Includes (ESI)? here.
The WordPress nonce
makes caching difficult with most plugins, however the LiteSpeed API has an elegant solution, and ESI is the key.
If your plugin uses a default nonce, then LiteSpeed Cache will automatically treat that nonce as an ESI block. This ensures the nonce is cached for only 12 hours, separate from the TTL of the page that it is on. You don't have to do anything special for this to work.
If your plugin uses a custom nonce, however, you will need to register the nonce action with our API before you use it.
Convert custom nonce to ESI¶
Action hook: litespeed_nonce
Parameter: custom nonce
Example
If you have the following line in your code
wp_create_nonce( 'example_nonce' );
do_action( 'litespeed_nonce', 'example_nonce' );
Once registered with our API, your custom nonce will be treated as an ESI block as long as your users have ESI enabled. (If ESI is not enabled, the API will call the native WordPress nonce
function.)
Get ESI enable status¶
Filter hook: litespeed_esi_status
Usage (this would get the status on if ESI is enabled):
$esi_status = apply_filters( 'litespeed_esi_status', false );
Generate ESI block URL¶
Filter hook: litespeed_esi_url
Parameters: $block_id, $wrapper, $params = array(), $control = 'private,no-vary', $silence = false, $preserved = false, $svar = false, $inline_val = false
(the first 2 are required parameters & the others are optional)
Action hook: litespeed_esi_load-$block
where $block
is the block name
Warning
Dynamic and uncached ESI blocks can slow a page down, if there are too many of them. Keep such ESI blocks to a minimum. If there will be many potential ESI blocks on a page, it might be more efficient to simply keep the page itself uncached, and not use ESI at all.
Usage example
First add the following code into the place where you want to insert the block:
apply_filters( 'litespeed_esi_url', 'my_esi_block', 'Custom ESI block' );
some_code_here
<div>
<?php
echo apply_filters( 'litespeed_esi_url', 'my_esi_block', 'Custom ESI block' );
?>
</div>
some_code_here
functions.php
: add_action( 'litespeed_esi_load-my_esi_block', 'my_esi_block_esi_load' );
function my_esi_block_esi_load()
{
do_action( 'litespeed_control_set_ttl', 300 );
#do_action( 'litespeed_control_set_nocache' );
echo "Hello world".rand (1,99999);
}
my_esi_block
is the block name, Custom ESI block
is a short comment, and 300
is the TTL for this block. You can swap the comments above to do_action( 'litespeed_control_set_nocache' );
if you want to set this block to no-cache
.
Example with parameters
If you'd like to pass a variable in as a parameter, you can modify this code:
$my_var = "test var";
$my_var2 = "test var 2";
add_action( 'litespeed_esi_load-my_esi_block', function() use ($my_var, $my_var2) {
do_action( 'litespeed_control_set_nocache' );
echo "Hello world".rand (1,99999);
echo '<br>my var:' . $my_var . $my_var2;
});
apply_filters( 'litespeed_esi_url', 'my_esi_block', 'Custom ESI block', array('123','abc') );
add_action( 'litespeed_esi_load-my_esi_block', 'my_esi_block_esi_load');
function my_esi_block_esi_load($params)
{
do_action( 'litespeed_control_set_nocache' );
echo "Hello world".rand (1,99999);
echo var_dump($params);
}
Random Number Example Plugin
In this example, we have a plugin called LiteSpeed Cache Plugin ESI, in which a PHP file called require_example.php
, generates a random number, and is excluded from caching. This is accomplished via multiple ESI API filters, including litespeed_esi_url
:
First, the PHP file that generates the random number, /wp-content/plugins/lscwp-esi/require_example.php
:
<?php
echo "Random number from required file: ".rand (1,99999);
echo '<br>';
echo 'variables received: <br>';
echo var_dump($params);
if ( is_user_logged_in() ) {
$current_user = wp_get_current_user();
$user_name = $current_user->user_login;
}
else {
$user_name = 'guest user';
}
echo '<br> hello, ' . $user_name;
Then, the plugin /wp-content/plugins/lscwp-esi/lscwp-esi.php
:
<?php
/*
Plugin Name: LiteSpeed Cache Plugin ESI
Description: LiteSpeed ESI test
*/
defined('WPINC') || exit;
if (!defined('LSCWP_V') || ! apply_filters( 'litespeed_esi_status', false ))
{
return;
}
add_action( 'litespeed_esi_load-my_esi_block', 'my_esi_block_esi_load' );
function my_esi_block_esi_load($params)
{
do_action( 'litespeed_control_set_nocache' );
require_once( WP_CONTENT_DIR . "/plugins/lscwp-esi/require_example.php");
}
add_action('wp_head', 'lscwp_esi_test');
add_action('wp_footer', 'lscwp_esi_test');
function lscwp_esi_test() {
$var1 = '123';
$var2 = 'abc';
echo '<div style="background: blue; color: white; text-align: center;">';
echo apply_filters( 'litespeed_esi_url', 'my_esi_block', 'Custom ESI block', array($var1,$var2) );
echo '</div>';
}
Hook widget default settings value¶
Filter hook litespeed_widget_default_options
.
Parameters: the hook & widget name
Usage:
See thirdparty/woocommerce.cls.php for in-depth example
Hook ESI parameters¶
Filter hook litespeed_esi_params
.
Parameter: $params, block_id
Usage:
add_filter( 'litespeed_esi_params', $params, 'block_id' );
Hook not ESI template¶
Action hooks: litespeed_tpl_normal
&& litespeed_is_not_esi_template
Usage:
See examples in both thirdparty/yith-wishlist.cls.php
& thirdparty/woocommerce.cls.php
Vary¶
The following Cache Vary API elements have been deprecated as of LSCWP v3.7:
Functions:
hook_vary_add()
vary_add()
filter_vary_cookies()
hook_vary()
Actions:
litespeed_vary_add
litespeed_vary_append
Filter:
-litespeed_api_vary
Going forward, use litespeed_vary_curr_cookies
and litespeed_vary_cookies
to build the cookie list.
Add to the Vary Cookies List¶
To add permanent cookies that apply to every page, use the filter hook: litespeed_vary_cookies
Parameter: Array of cookies
Usage:
$vary_cookies = apply_filters( 'litespeed_vary_cookies', $vary_cookies );
Example
To add a vary cookie for GDPR, assuming the name of the cookie is GDPR_cookie
, add the following code to functions.php
:
add_filter('litespeed_vary_curr_cookies', 'lscwp_add_custom_cookie'); add_filter('litespeed_vary_cookies', 'lscwp_add_custom_cookie');
function lscwp_add_custom_cookie($list){
$list[] = 'GDPR_cookie';
return $list;
}
To add cookies that apply only to the current page, use the filter hook: litespeed_vary_curr_cookies
Parameter: Array of cookies
Usage:
$vary_cookies = apply_filters( 'litespeed_vary_curr_cookies', $vary_cookies );
Alter default vary cookie value¶
Default vary cookie is an array before finalization, after that it will be combined to a string and stored as default vary cookie name.
Filter hook: litespeed_vary
Parameters: Cookie name and value
Usage:
add_filter( 'litespeed_vary', array( $val, 'var_cookie_name' ) );
Force finalize vary¶
Force a cache vary for the current page, even if the variation is caused by an AJAX call.
Action hook: litespeed_vary_ajax_force
Usage:
do_action( 'litespeed_vary_ajax_force' );
Set cache status to no vary¶
Do not create a cache vary for the current page.
Action hook: litespeed_vary_no
Usage:
do_action( 'litespeed_vary_no' );
Get mobile cache status¶
Filter hook: litespeed_is_mobile
Parameter: boolean
Usage (this would get the status on if is not mobile):
$is_mobile = apply_filters( 'litespeed_is_mobile', false );
Cloud¶
Verify Callback From QUIC.cloud CDN¶
Filter hook: litespeed_is_from_cloud
Parameter: boolean
This filter allows you to check the origin of a callback request, in order to reject REST access to unauthorized sources. The filter returns true
if the callback request originates from a recognized QUIC.cloud CDN node.
Usage:
$is_from_cloud = apply_filters( 'litespeed_is_from_cloud', false );
Optimize¶
Disable Page Optimization¶
Filter hook: litespeed_can_optm
Usage:
add_filter( 'litespeed_can_optm', '__return_false' );
Set a Custom CCSS Path¶
Filter hook: litespeed_ccss_url
Usage:
$val = apply_filters('litespeed_ccss_url', $request_url)
Set a Custom UCSS Path¶
Filter hook: litespeed_ucss_url
Usage:
$val = apply_filters('litespeed_ucss_url', $request_url)
Generate Single UCSS for Page Type¶
Filter hook: litespeed_ucss_per_pagetype
UCSS is generated per URL. You can use this filter to generate a single shared UCSS file for any posts where the type is page
. UCSS will still be generated by URL for all other post types.
Usage:
add_filter( 'litespeed_ucss_per_pagetype', function(){return get_post_type() == 'page';} );
Examples
Let's say you have a site with a blog and a WooCommerce shop. You want UCSS to be generated per URL for all blog posts and pages, but your products can share a single UCSS file.
You would add the following to your functions.php
file:
add_filter( 'litespeed_ucss_per_pagetype', function(){return get_post_type() == 'product';} );
The function in this example returns True
if the current post type is product
and False
in any other situation. Another way of looking at litespeed_ucss_per_pagetype
is that it generates UCSS by URL when passed a value of false, and generates UCSS by post type when passed a value of true. If you wanted UCSS to always be generated by post type, you wouldn't need to even check the current post type. You could just always pass it a true value, like so:
add_filter( 'litespeed_ucss_per_pagetype', '__return_true' );
Bypass UCSS for Page Type¶
Use the following to bypass generating UCSS for any posts where the type is page
. UCSS will continue to be generated for all other post types.
add_action( 'litespeed_optm', function(){get_post_type() == 'page' && do_action( 'litespeed_conf_force', 'optm-ucss', false );});
Exclude a URI from Optimization¶
Filter hook: litespeed_optm_uri_exc
Use the following to append a new URI to an existing list of excluded URIs:
add_filter('litespeed_optm_uri_exc', function($list){
$list[]='aa';
return $list;
});
Exclude JavaScript from Optimization¶
There are three JavaScript exclude settings, and a filter that corresponds to each one:
- JS Excludes:
litespeed_optimize_js_excludes
- JS Deferred/Delayed Excludes:
litespeed_optm_js_defer_exc
- Guest Mode JS Excludes:
litespeed_optm_gm_js_exc
Example
The following example shows you how to exclude the same three JS files from each type of optimization:
lscwp_custom_excludes($excludes) {
$my_custom_excludes = array(
'javascript_1.js',
'javascript_2.js',
'javascript_3.js',
);
return array_merge($excludes, $my_custom_excludes);
}
add_filter('litespeed_optimize_js_excludes', 'lscwp_custom_excludes');
add_filter('litespeed_optm_js_defer_exc', 'lscwp_custom_excludes');
add_filter('litespeed_optm_gm_js_exc', 'lscwp_custom_excludes');
Place Optimizations before /head
¶
Filter hook: litespeed_optm_html_after_head
When you use this filter, the optimized code for UCSS, CCSS, Combined CSS and/or Combined JS are placed just before the closing </head>
tag.
Usage:
add_filter('litespeed_optm_html_after_head','__return_true');
GUI¶
Start a to-be-removed html wrapper¶
Filter hook: litespeed_clean_wrapper_begin
Usage:
echo apply_filters( 'litespeed_clean_wrapper_begin', '' );
End a to-be-removed html wrapper¶
Filter hook: litespeed_clean_wrapper_end
Usage:
echo apply_filters( 'litespeed_clean_wrapper_end', '' );
Hooks for dropdown menu¶
Action hook: litespeed_frontend_shortcut
& litespeed_backend_shortcut
Usage:
do_action( 'litespeed_frontend_shortcut' );
Misc¶
Enables standard debug logging¶
Logs standard level of debugging information to wp-content/debug.log
.
Action hook: litespeed_debug
Parameter: reason
Usage:
do_action( 'litespeed_debug', 'Reason to start basic debugging' );
Enables advanced debug logging¶
Logs advanced level of debugging information to wp-content/debug.log
.
Action hook: litespeed_debug2
Parameter: reason
Usage:
do_action( 'litespeed_debug2', 'Reason to start thorough debugging' );
Disables all debug logging¶
Action hook: litespeed_disable_all
Parameter: reason
Usage:
do_action( 'litespeed_disable_all', 'Reason to stop debugging' );
Modify output buffer before¶
litespeed_buffer_before
acts on content before LSCache has manipulated it. So, before applying CDN rules, before applying CSS/JS optimizations, etc.
Action hook: litespeed_buffer_before
Usage:
function remove_pingback_link( $content ) {
return str_replace( '<link rel="pingback" href="https://example.com/xmlrpc.php">', '', $content );
}
add_filter( 'litespeed_buffer_before', 'remove_pingback_link', 0);
Modify output buffer after¶
litespeed_buffer_after
acts on content after LSCache has manipulated it. So, after applying CDN rules, after applying CSS/JS optimizations, etc. Remember though, due to the way page caching works, LiteSpeed hooks cannot be executed on cached content, so when we talk about the buffer content, it is always prior to caching.
Action hook: litespeed_buffer_after
Usage:
function remove_broken_style( $content ) {
return str_replace( '.content{opacity:0}', '', $content );
}
add_filter( 'litespeed_buffer_after', 'remove_broken_style', 0);
Bypasses adding missing media sizes¶
Use litespeed_media_add_missing_sizes
to bypass LiteSpeed Cache's Add Missing Sizes media option, if your application doesn't require media sizes, such as for Guest Optimization.
Filter: litespeed_media_add_missing_sizes
Debugging/Developer Tips¶
Many full usage examples are available in source under thirdparty/
in case of typos or incomplete examples. GitHub has most of it indexed although is better to search local file contents.
Besides the basic compatibility tests and troubleshooting steps, one can open a support ticket or even join our #wpcache-dev channel on Slack if further assistance is needed and/or you want to share your progress in cross-compatibility & improving functionality.