Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

ESI_Cache_Policy

Alex Headley edited this page · 9 revisions

Note that this is largely copy+pasted from the Magento-Varnish extension since that is where most of the ESI code came from.

What is an ESI Cache Policy?

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 (<block></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.

Where do I define caching policies?

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.

How do I define a caching policy?

It's easy!

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>

The <action method="setEsiOptions"> instructs Magento that we want a specific ESI caching policy on the cart_sidebar block. The cart_sidebar block is defined in the base layout file checkout.xml. To use AJAX, you can use <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. The <params></params> node contains all the parameters defining our caching policy.

In this case, we only have one parameter called <access></access>. This parameters indicates to Magento which type of caching we want on the block. In this case, the type of caching is private. private means that we want Varnish to cache a different version of the <block></block> for each client.

What are the parameters for defining a cache policy?

Given the example below:

<reference name="my_block" type="mycompany/myblock">
    <action method="setEsiOptions">
        <params>
            <method>ajax | esi</method>
            <access>private | public</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>
        </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)

<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::registry() and 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 inherits from 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: <model/> and <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>
Something went wrong with that request. Please try again.