ETags¶
ETags are used in to check whether pages need to be
re-calculated or can be served from cache. An ETag is simply
a string. Under
plone.app.caching
, it is a string of tokens separated by pipe characters.
The tokens hold values such as a user id, the current skin
name, or a counter indicating how many objects have been
added to the site. The idea is that the browser sends a
request with the ETag included in an
If-None-Match
header. Plone can then quickly calculate the current ETag
for the requested resource. If the ETag is the same, Plone
can reply with
304
NOT
MODIFIED
response, telling the browser to use its cached copy.
Otherwise, Plone renders the page and returns it as normal.
Many caching operations use ETags. The tokens to include are
typically listed in an
etags
tuple in the operation's options.
The ETag names tokens supported by default are:
-
- userid
The current user's id
-
- roles
-
A list of the current user's roles in the given context
-
- language
-
The language(s) accepted by the browser, in the
ACCEPT_LANGUAGE
header
-
- userLanguage
-
The current user's preferred language
-
- lastModified
-
A timestamp indicating the last-modified date of the given context
-
- catalogCounter
-
A counter that is incremented each time the catalog is updated, i.e. each time content in the site is changed.
-
- locked
-
Whether or not the given context is locked for editing.
-
- skin
-
The name of the current skin (theme)
-
- resourceRegistries
-
A timestamp indicating the most recent last-modified date for all three Resource Registries. This is useful for avoiding requests for expired resources from cached pages.
It is possible to provide additional tokens by registering
an
IETagValue
adapter. This should be a named adapter on the published
object (typically a view, file resource or Zope page
template object) and request, with a unique name. The name
is used to look up the component. Thus, you can also
override one of the tokens above for a particular type of
context or request (e.g. via a browser layer), by
registering a more specific adapter with the same name.
As an example, here is the
language
adapter:
from zope.interface import implements
from zope.interface import Interface
from zope.component import adapts
from plone.app.caching.interfaces import IETagValue
class Language(object):
"""The ``language`` etag component, returning the value of the
HTTP_ACCEPT_LANGUAGE request key.
"""
implements(IETagValue)
adapts(Interface, Interface)
def __init__(self, published, request):
self.published = published
self.request = request
def __call__(self):
return self.request.get('HTTP_ACCEPT_LANGUAGE', '')
This is registered in ZCML like so:
<adapter factory=".etags.Language" name="language" />