Note that this is largely copy+pasted from the Magento-Varnish extension since that is where most of the ESI code came from.
A caching policy defines whether a block should be stored in the cache, how it
is cached, and for how long. You can define a cache policy on a block (
or a reference (
<reference></reference>). Only blocks that inherit from
the Mage_Core_Block_Template class may have caching policies. You can create
cache policies for different blocks on the same page, and for the same block
on different pages (via handles).
A cache policy will generally look something like this:
<reference name="header"> <action method="setEsiOptions"> <params> <access>private</access> </params> </action> </reference>
Out of the box, the extension includes cache polices for the most common per-client blocks in a default Magento installation.
You can define a cache policy in any layout file, but I would recommend putting
any that are specific to your site/store in
app/design/frontend/base/default/layout/local.xml so that
your changes are not overwritten on an extension upgrade.
If you had some session based information showing on the page (the number of
items in your cart for example), this information is cached and every other
client accessing the same URL will see the exact page you saw, telling them
they have x items in their cart, even if they don't have any!
You will notice however, that the cart information is not cached! How is that
possible? Well, that's because the extension by default defines a specific
caching policy for the cart block stating that the "cart information" should be
cached, but, on a per-client basis.
You can find this policy in the frontend
turpentine_esi.xml layout file.
Ok, so how do you define a caching policy?
Let's use this predefined policy as an example.
Open the frontend
turpentine_esi.xml layout file. Near the top you can read:
<reference name="cart_sidebar"> <action method="setEsiOptions"> <params> <access>private</access> </params> </action> </reference>
<action method="setEsiOptions"> instructs Magento that we want a
specific ESI caching policy on the
cart_sidebar block. The
block is defined in the base layout file
checkout.xml. To use AJAX, you
<method>ajax</method>, but note that currently
AJAX requests are not cached and should really only be used for blocks that
change very frequently (like on every page load).
The caching policy for this block is defined in the
<params></params> node contains all the parameters defining our caching
In this case, we only have one parameter called
parameters indicates to Magento which type of caching we want on the block. In
this case, the type of caching is
private means that we want
Varnish to cache a different version of the
<block></block> for each
Given the example below:
<reference name="my_block" type="mycompany/myblock"> <action method="setEsiOptions"> <params> <method>ajax | esi</method> <access>private | public | customer_group</access> <scope>page | global</scope> <ttl>12345</ttl> <registry_keys> <current_product/> <current_category/> <my_custom_registry_key1/> <my_custom_registry_keyN/> </registry_keys> <dummy_blocks> <root/> <head/> <another_block_name/> </dummy_blocks> <flush_events> <sales_quote_save_after/> </flush_events> <only_cache_if>empty | no_text</only_cache_if> </params> </action> </reference>
<method />: Can take one and only one of the following values
esi : Load the block using Varnish's ESI capabilities. The inclusion is not visible to the client ajax : Load the block using an AJAX request. The block will only be loaded after the rest of the page is loaded and the loading is visible to the client
<access />: Can take one and only one of the following values
private : one version per client is stored in cache (the session cookie identifies which client gets which cached version of the block) public : one version of a block is stored for the entire website (only one cached version of the block exist and it is served to every client) customer_group : one version per customer group is stored in cache (special customer group cookie is used)
<scope />: Can take one and only one of the following values
page : one version of the block is cached per page (identified by the URL) global : one version of the block is stored for the entire site
<ttl />: Is a time in seconds for the block to be cached
3600 (1 hour) 259200 (3 days) 604800 (1 week)
The default ttl if not specified is a little complex: If access is private, then if method is ajax the default ttl is 0 (not cached) otherwise the default cookie expiration time is used. If access is global then the default page TTL is used (regardless of method).
<registry_keys />: Some blocks depend on values in Magento's registry
Mage::register()) when they are rendered. This
parameter lets you specify which keys to preserve so they can be set again upon
the ESI request. Note that if the value of the registry key you specify
Mage_Core_Model_Abstract instead of serializing the entire
model (which would make the ESI URL too long), only the model name and ID are
saved, then the object is loaded during the ESI request. Each key also has two
additional, optional parameters to help
encode it in the ESI data:
<idMethod/>. The model should
be the name of the model to use in case Turpentine can't automatically figure
it out, in the same format that
Mage::getModel() uses. The idMethod should
probably almost never be needed, but is used to tell Turpentine what object method
to use to get the objects ID from the database. Note that in most cases neither
of these will need to be specified.
<registry_keys> <key1/> <key2> <model>core/something</model> </key2> <key3> <model>thirdparty/something_else</model> <idMethod>getDatabaseId</idMethod> </key3> </registry_keys>
<dummy_blocks />: Dummy blocks is similar to
registry_keys in that it lets
you specify blocks that this block depends on to render. For example, in the
customer_account_index handle the customer_account_dashboard block tries to
set the page title by changing the head block. Since by default the head block
wouldn't exist during the ESI block rendering, you would get a Magento exception.
By using the
dummy_blocks setting a basic Mage_Core_Block_Template block will
be created for the head block which lets the customer_account_dashboard
block render without errors.
<dummy_blocks> <head/> <root/> </dummy_blocks>
<flush_events />: A list of events that should cause the block to be flushed
in the cache. Note that this currently only works for private access blocks,
public access blocks will only be flushed by regular cache flushing methods.
<flush_events> <event_name_one/> <event_name_two/> </flush_events>
<only_cache_if>: Can take one and only one of the following values:
empty : Direct Varnish to only cache a message block if it is empty no_text : Direct Varnish to only cache a message block if it has no text.