Custom TALES extensionsΒΆ
PyAMS defines a custom expression for TALES called extension.
When this expression is encountered, the renderer is looking for an
ITALESExtension
multi-adapter for the current context, request and view, for the current
context and request, or only for the current context, in this order.
If an adapter is found, the renderer call it’s render()
method with
the expression parameters as input parameters.
For example, the metas extension is an ITALESExtension adapter defined into
pyams_skin.metas
module which can be used to include all required headers in
a page template. Extension is used like this in the page layout template:
<tal:var replace="structure extension:metas" />
This extension is defined like this:
from pyams_skin.interfaces.metas import IHTMLContentMetas
from pyams_utils.interfaces.tales import ITALESExtension
from pyramid.interfaces import IRequest
from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
@adapter_config(name='metas', context=(Interface, IRequest, Interface), provides=ITALESExtension)
class MetasTalesExtension(ContextRequestViewAdapter):
'''extension:metas TALES extension'''
def render(self, context=None):
if context is None:
context = self.context
result = []
for name, adapter in sorted(self.request.registry.getAdapters((context, self.request, self.view),
IHTMLContentMetas),
key=lambda x: getattr(x[1], 'order', 9999)):
result.extend([meta.render() for meta in adapter.get_metas()])
return '\n\t'.join(result)
Some TALES extensions can require or accept arguments. For example, the absolute_url extension can accept a context and a view name:
<tal:var define="logo config.logo">
<img tal:attributes="src extension:absolute_url(logo, '++thumb++200x36.png');" />
</tal:var>
The extension is defined like this:
from persistent.interfaces import IPersistent
from pyams_utils.interfaces.tales import ITALESExtension
from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
from pyramid.url import resource_url
from zope.interface import Interface
@adapter_config(name='absolute_url', context=(IPersistent, Interface, Interface), provides=ITALESExtension)
class AbsoluteUrlTalesExtension(ContextRequestViewAdapter):
'''extension:absolute_url(context, view_name) TALES extension'''
def render(self, context=None, view_name=None):
if context is None:
context = self.context
return resource_url(context, self.request, view_name)