1 .. _tales: |
|
2 |
|
3 Custom TALES extensions |
|
4 ======================= |
|
5 |
|
6 PyAMS defines a custom expression for TALES called *extension*. |
|
7 |
|
8 When this expression is encountered, the renderer is looking for an |
|
9 :py:class:`ITALESExtension <pyams_utils.interfaces.tales.ITALESExtension>` |
|
10 multi-adapter for the current *context*, *request* and *view*, for the current |
|
11 *context* and *request*, or only for the current *context*, in this order. |
|
12 If an adapter is found, the renderer call it's :py:func:`render` method with |
|
13 the expression parameters as input parameters. |
|
14 |
|
15 For example, the *metas* extension is an *ITALESExtension* adapter defined into |
|
16 :py:mod:`pyams_skin.metas` module which can be used to include all required headers in |
|
17 a page template. Extension is used like this in the page layout template: |
|
18 |
|
19 .. code-block:: html |
|
20 |
|
21 <tal:var replace="structure extension:metas" /> |
|
22 |
|
23 This extension is defined like this: |
|
24 |
|
25 .. code-block:: python |
|
26 |
|
27 from pyams_skin.interfaces.metas import IHTMLContentMetas |
|
28 from pyams_utils.interfaces.tales import ITALESExtension |
|
29 from pyramid.interfaces import IRequest |
|
30 |
|
31 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter |
|
32 |
|
33 @adapter_config(name='metas', context=(Interface, IRequest, Interface), provides=ITALESExtension) |
|
34 class MetasTalesExtension(ContextRequestViewAdapter): |
|
35 '''extension:metas TALES extension''' |
|
36 |
|
37 def render(self, context=None): |
|
38 if context is None: |
|
39 context = self.context |
|
40 result = [] |
|
41 for name, adapter in sorted(self.request.registry.getAdapters((context, self.request, self.view), |
|
42 IHTMLContentMetas), |
|
43 key=lambda x: getattr(x[1], 'order', 9999)): |
|
44 result.extend([meta.render() for meta in adapter.get_metas()]) |
|
45 return '\n\t'.join(result) |
|
46 |
|
47 Some TALES extensions can require or accept arguments. For example, the *absolute_url* extension can accept |
|
48 a context and a view name: |
|
49 |
|
50 .. code-block:: html |
|
51 |
|
52 <tal:var define="logo config.logo"> |
|
53 <img tal:attributes="src extension:absolute_url(logo, '++thumb++200x36.png');" /> |
|
54 </tal:var> |
|
55 |
|
56 The extension is defined like this: |
|
57 |
|
58 .. code-block:: python |
|
59 |
|
60 from persistent.interfaces import IPersistent |
|
61 from pyams_utils.interfaces.tales import ITALESExtension |
|
62 |
|
63 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter |
|
64 from pyramid.url import resource_url |
|
65 from zope.interface import Interface |
|
66 |
|
67 @adapter_config(name='absolute_url', context=(IPersistent, Interface, Interface), provides=ITALESExtension) |
|
68 class AbsoluteUrlTalesExtension(ContextRequestViewAdapter): |
|
69 '''extension:absolute_url(context, view_name) TALES extension''' |
|
70 |
|
71 def render(self, context=None, view_name=None): |
|
72 if context is None: |
|
73 context = self.context |
|
74 return resource_url(context, self.request, view_name) |
|