{"id":8348,"date":"2017-10-18T06:00:22","date_gmt":"2017-10-18T10:00:22","guid":{"rendered":"https:\/\/blog.litespeedtech.com\/?p=8348"},"modified":"2017-10-18T06:00:22","modified_gmt":"2017-10-18T10:00:22","slug":"wpw-lscache-and-your-plugin-perfect-together","status":"publish","type":"post","link":"https:\/\/lswp.store\/index.php\/2017\/10\/18\/wpw-lscache-and-your-plugin-perfect-together\/","title":{"rendered":"WpW: LSCache and your plugin &#8211; perfect together"},"content":{"rendered":"<p><img fetchpriority=\"high\" decoding=\"async\" title=\"\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/10\/null-7.jpeg\" alt=\"\" width=\"640\" height=\"320\" \/><\/p>\n<p>Welcome to another installment of <a href=\"http:\/\/blog.litespeedtech.com\/tag\/wordpress-wednesday\">WordPress Wednesday<\/a>!<\/p>\n<p><b><i>Disclaimer<\/i><\/b><i><span style=\"font-weight: 400;\">: The information contained in this post is accurate for LSCWP v1.4<\/span><\/i><i><span style=\"font-weight: 400;\">. If you are using a newer version of the plugin, some details may have changed. Please<\/span><\/i><a href=\"https:\/\/www.litespeedtech.com\/support\/wiki\/doku.php\/litespeed_wiki:cache:lscwp\"> <i><span style=\"font-weight: 400;\">refer to our wiki<\/span><\/i><\/a><i><span style=\"font-weight: 400;\"> for the latest!<\/span><\/i><\/p>\n<p>In most of our previous posts we\u2019ve talked to site owners and hosting providers. Today, we\u2019d like to address our fellow plugin developers. <strong>Let\u2019s talk about how to ensure your plugin is compatible with LiteSpeed Cache for WordPress.<\/strong> And for those of you who are developers and would like to help make <em>someone else<\/em>\u2019s plugin work well with LSCache, you\u2019ll want to check out \u201c<a href=\"\/#heading=h.b3f14nod1ofi\">What if it\u2019s not your plugin?<\/a>\u201d below.<\/p>\n<p>To know if your plugin is compatible with LSCache, it helps to understand a bit about caching in general, as well as LiteSpeed Cache in particular. For that, we recommend you have a look at <a href=\"https:\/\/lswp.store\/tag\/caching-101\/\">our Caching 101 series<\/a>.<\/p>\n<h2>Are we compatible?<\/h2>\n<p>If your plugin doesn\u2019t generate site content, or do anything out of the ordinary with existing front-end content, then chances are it is 100% compatible with LiteSpeed Cache for WordPress already. The vast majority of plugins will fall into this \u201calready compatible\u201d category. If, however, you have a plugin that makes changes to front-end-displayed content, and it does so in a non-traditional way, you\u2019ll want to read on.<\/p>\n<p>LSCWP purges pages from the cache when certain events are triggered. If your plugin generates content that triggers those same events, then we\u2019re already compatible in that area.<\/p>\n<p>LSCWP follows a set of rules to determine whether a page is cacheable. If your plugin generates content that also abides by those same rules, then we\u2019re already compatible in that area as well.<\/p>\n<p>Even if your plugin generates cacheable content that <em>doesn\u2019t<\/em> trigger the standard events, or it generates non-cacheable content that <em>doesn\u2019t<\/em> abide by the same rules that we do, we can still get along. You may just need to invoke <a href=\"https:\/\/www.litespeedtech.com\/support\/wiki\/doku.php\/litespeed_wiki:cache:lscwp:api\">our API<\/a> first.<\/p>\n<p>First, let\u2019s look at purging rules and exclude rules to understand what is possible, and then we can look at the API functions that allow you to realize those possibilities.<\/p>\n<h2>Purge rules<\/h2>\n<p><img decoding=\"async\" title=\"\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/10\/null-8.jpeg\" alt=\"\" width=\"672\" height=\"448\" \/><\/p>\n<p>LSCache will automatically purge a page from the cache if any of the following events are triggered:<\/p>\n<ul>\n<li>edit_post<\/li>\n<li>save_post<\/li>\n<li>deleted_post<\/li>\n<li>trashed_post<\/li>\n<li>delete_attachment<\/li>\n<\/ul>\n<p>LSCache\u2019s \u201csmart purge\u201d feature works by assigning tags to each cacheable page, and then using those tags to intelligently group together a collection of pages to be purged later.<\/p>\n<p>In its most basic form, each page is tagged with its Post ID, and then sent to the server to be cached. When one of the above events is triggered for the page, that request will notify the server to purge all of the cache\u2019s items that are also tagged with that page\u2019s Post ID. Depending on the purge rules that have been defined by the site owner, this could include related category pages, tag pages, and monthly archives, among other things.<\/p>\n<p>If your plugin makes modifications that trigger those same events, then you should be good. If, however, you have an application that changes what appears on a page without triggering any of those events, then you will need to inform LiteSpeed Cache that a purge is necessary.<\/p>\n<p>Our API gives you 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 useful ways.<\/p>\n<h3>Example:<\/h3>\n<ul>\n<li>Page #1 is tagged with <code>MTPP_F.1, MTPP_G.4, MTPP_S.wyoming<\/code> (because the page is in forum 1, group 4, and related to the state of Wyoming).<\/li>\n<li>Page #2 is tagged with <code>MTPP_F.1, MTPP_G.2, MTPP_S.iowa<\/code> (because the page is in forum 1, group 2, and related to the state of Iowa).<\/li>\n<\/ul>\n<p>If a change is made where all pages tagged <code>MTPP_F.1<\/code> need to be purged, the tag system enables the server to easily purge both Page #1 and Page #2. If a request is sent to the server indicating that pages tagged <code>MTPP_S.wyoming<\/code> need to be purged, then the tagging system knows to only purge Page #1.<\/p>\n<p>For this functionality, you\u2019ll want to pay special attention to the API functions <code>tag_add<\/code> and <code>purge<\/code>.<\/p>\n<p><strong>TIP<\/strong>: When defining tags, it is a good idea to give them a prefix that is unique to your application, that way you avoid stepping on anyone else\u2019s tags. In this example, we\u2019ve used <code>MTPP_<\/code> for \u201cmy third-party plugin.\u201d<\/p>\n<h2>Exclude rules<\/h2>\n<p><img decoding=\"async\" title=\"\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/10\/null-9.jpeg\" alt=\"\" width=\"672\" height=\"448\" \/><\/p>\n<p>As of v1.4, LSCache considers a page to be non-cacheable if<\/p>\n<ul>\n<li>It is an Admin page<\/li>\n<li>It is a post request<\/li>\n<li><code>is_trackback()<\/code> is true<\/li>\n<li><code>is_search()<\/code> is true<\/li>\n<li>No theme is used<\/li>\n<li>The URI is found in the <strong>Do Not Cache URIs<\/strong> List<\/li>\n<li>The post URL has a query string found in the <strong>Do Not Cache Query Strings<\/strong> List<\/li>\n<li>The post has a category found in the <strong>Do Not Cache Categories<\/strong> List<\/li>\n<li>The post has a tag found in the <strong>Do Not Cache Tags<\/strong> List<\/li>\n<li>The request has a cookie found in the <strong>Do Not Cache Cookies<\/strong> List<\/li>\n<li>The request has a user agent found in the <strong>Do Not Cache User Agents<\/strong> List<\/li>\n<\/ul>\n<p>If your plugin generates content that is non-cacheable but doesn\u2019t fall into one of the above categories, you will need to inform LiteSpeed Cache that the content cannot be cached. Our API gives you the ability to do so via the <code>hook_control<\/code> and <code>set_nocache<\/code> API hook and function.<\/p>\n<h2>API<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" title=\"\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/10\/null-10.jpeg\" alt=\"\" width=\"672\" height=\"448\" \/><\/p>\n<p>LiteSpeed Cache for WordPress\u2019 API provides functions and hooks that allow you to customize the aspects of cache management that we discussed above. Listed below are eight useful API functions and hooks. There is more to our API, though, and you can get all of the latest details and available functions <a href=\"https:\/\/www.litespeedtech.com\/support\/wiki\/doku.php\/litespeed_wiki:cache:lscwp:api\">on our wiki<\/a>.<\/p>\n<p>These functions are defined in <code>plugins\/litespeed-cache\/includes\/litespeed-cache-api.class.php<\/code> and may be used in any hook point prior to the <code>shutdown<\/code> hook point.<\/p>\n<h3>Customized Purging<\/h3>\n<p>Use these functions to implement your own purge rules, as in our forum\/group\/state example above.<\/p>\n<ul>\n<li><code>LiteSpeed_Cache_API::tag_add($tag)<\/code><br \/>\nWhen a page is created or edited, use this function to add 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.<\/li>\n<li><code>LiteSpeed_Cache_API::purge($tag)<\/code><br \/>\nWhen you need to purge a page and its related pages, use this function to add a single purge tag (or group of purge tags) to the list of tags to be purged with the request.<\/li>\n<\/ul>\n<h3>Customized Exclusions<\/h3>\n<p>If you plugin generates content that should not be cached, use these functions to implement your own exclude rules.<\/p>\n<ul>\n<li><code>LiteSpeed_Cache_API::set_nocache()<\/code><br \/>\nUse this function to mark the current page as non-cacheable.<\/li>\n<li><code>LiteSpeed_Cache_API::hook_control($hook)<\/code><br \/>\nSpecify a hook for cache control with this filter. The hook will be triggered when the cache plugin is checking whether the current page is cacheable. This filter will <em>not<\/em> trigger on admin pages nor any page that has previously been marked as non-cacheable.<\/li>\n<\/ul>\n<h3>Customized Admin Handling<\/h3>\n<p>If your plugin makes adjustments to content through WordPress Admin (for example, you change a product description and then need to purge that product) these are the functions to use.<\/p>\n<ul>\n<li><code>LiteSpeed_Cache_API::purge_post($id)<\/code><br \/>\nPurge a single post by id with this function.<\/li>\n<li><code>LiteSpeed_Cache_API::hook_purge($hook)<\/code><br \/>\nThis hook is called at the end of every cacheable request, and gives you the ability to add purge tags to the current request.<\/li>\n<\/ul>\n<h3>ESI Blocks<\/h3>\n<p>If you\u2019d like to use <a href=\"https:\/\/lswp.store\/2017\/09\/06\/wpw-esi-and-litespeed-cache\/\">ESI blocks<\/a> in your plugin, you\u2019ll want to employ the following functions:<\/p>\n<ul>\n<li><code>LiteSpeed_Cache_API::esi_url($block_id, $wrapper, $params = array(), $control = 'private,no-vary')<\/code><br \/>\nCreates a new ESI block. Use this if you wish to punch a hole for differently-cached content (i.e. a privately-cached individualized greeting on a publicly-cached page).<\/li>\n<li><code>LiteSpeed_Cache_API::hook_tpl_esi($block, $hook)<\/code><br \/>\nUse this hook to display an ESI block.<\/li>\n<\/ul>\n<p>For some detailed ESI examples, <a href=\"https:\/\/www.litespeedtech.com\/support\/wiki\/doku.php\/litespeed_wiki:cache:lscwp:esi_sample\">visit our wiki<\/a>.<\/p>\n<h2 id=\"heading=h.b3f14nod1ofi\">What if it\u2019s not your plugin?<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" title=\"\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2017\/10\/null-11.jpeg\" alt=\"\" width=\"672\" height=\"448\" \/><\/p>\n<p>Not every plugin author is interested in modifying their plugin for LSCache compatibility, and that\u2019s ok. You don\u2019t have to be the author of the plugin to make sure it is compatible with LiteSpeed Cache. In fact, we\u2019ve been adding support for well-known plugins ourselves since the beginning.<\/p>\n<p>If you are currently using an incompatible plugin, and you have some PHP skills, you can contribute to our project. Take a look at our plugin source code, and you\u2019ll see a <code>thirdparty<\/code> directory where you\u2019ll find our current integrations. Use these examples to help you write up some code that will make your own favorite plugin compatible with LSCache.<\/p>\n<p>And then <a href=\"https:\/\/wordpress.org\/support\/plugin\/litespeed-cache\">get in touch<\/a>! We\u2019d love to integrate your working solution into our plugin so that everyone may benefit.<\/p>\n<h2>Conclusion<\/h2>\n<p>The majority of plugins get along just fine with LSCache, and those that <em>don\u2019t <\/em>generally just need a line or two of code to make them compatible. If the advice we\u2019ve shared today doesn\u2019t help you with your particular application, or you\u2019d like to discuss any of these ideas in more depth, feel free to get in touch with us! Visit the <a href=\"https:\/\/wordpress.org\/support\/plugin\/litespeed-cache\">WordPress support forum for LSCache<\/a>, or go through <a href=\"https:\/\/store.litespeedtech.com\/store\/clientarea.php\">our ticket system<\/a>. We\u2019d be happy to help.<\/p>\n<p>&#8212;<br \/>\nHave some of your own ideas for future <a href=\"http:\/\/blog.litespeedtech.com\/tag\/wordpress-wednesday\">WordPress Wednesday<\/a> topics? Leave us a comment!<\/p>\n<p>Don\u2019t forget to meet us back here next week for the next installment. In the meantime, here are a few other things you can do:<\/p>\n<ul>\n<li>Subscribe to the <a href=\"http:\/\/blog.litespeedtech.com\/tag\/wordpress-wednesday\/feed\/\">WordPress Wednesday RSS feed<\/a><\/li>\n<li>Download <a href=\"https:\/\/wordpress.org\/plugins\/litespeed-cache\/\">LiteSpeed Cache for WordPress plugin<\/a><\/li>\n<li>Learn more about the plugin <a href=\"https:\/\/www.litespeedtech.com\/products\/cache-plugins\/wordpress-acceleration\">on our website<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Is your plugin compatible with LSCWP? Find out! And if it&#8217;s not, use our API to make it so.<\/p>\n","protected":false},"author":1,"featured_media":8350,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[28],"tags":[38,316,317],"class_list":["post-8348","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cache","tag-api","tag-wordpress","tag-wordpress-wednesday"],"jetpack_featured_media_url":"https:\/\/lswp.store\/wp-content\/uploads\/2017\/10\/null-7.jpeg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/8348","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/comments?post=8348"}],"version-history":[{"count":0,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/8348\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media\/8350"}],"wp:attachment":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media?parent=8348"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/categories?post=8348"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/tags?post=8348"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}