|
1 .. _rendererhowto: |
|
2 |
|
3 |
|
4 How to create a new Renderer? |
|
5 ============================= |
|
6 |
|
7 **Renderer** are the layout of the utility data content |
|
8 |
|
9 |
|
10 1. Create a Renderer |
|
11 '''''''''''''''''''' |
|
12 |
|
13 The simplest is to create a new class that inherits from the existing **Renderer**, to modify this template and |
|
14 to define a new adapter name. You must also override the label to distinguish rendering modes in the ZMI. |
|
15 |
|
16 |
|
17 |
|
18 .. code-block:: python |
|
19 :linenos: |
|
20 |
|
21 # New custom contact paragraph renderer |
|
22 |
|
23 @adapter_config(name='custom', context=(IContactParagraph, IPyAMSLayer), provides=IContentRenderer) |
|
24 @template_config(template='templates/contact-custom.pt', layer=IPyAMSLayer) |
|
25 class ContactParagraphCustomRenderer(ContactParagraphDefaultRenderer): |
|
26 """Context paragraph custom renderer""" |
|
27 |
|
28 label = _("Custom contact renderer") |
|
29 settings_interface = IContactParagraphDefaultRendererSettings |
|
30 |
|
31 In this example the new renderer inherit of :py:class:`ContactParagraphDefaultRenderer`, we have defined a **label** (line 8) |
|
32 and associated an **settings_interface** (line 9) |
|
33 |
|
34 We have declared this adapter with 'custom' name, it takes :py:class:`IContactParagraph`, :py:class:`IPyAMSLayer` as context |
|
35 and provides :py:class:`IContentRenderer` interface. |
|
36 |
|
37 Using ``@template_config()`` decorator, the renderer can be displayed in html container according to the template |
|
38 |
|
39 |
|
40 2. Define a Renderer settings |
|
41 ''''''''''''''''''''''''''''' |
|
42 |
|
43 In the previous point, we did not change the settings interface of the renderer. |
|
44 However, we can define a new settings interface for the new renderer, for that we start by creating an interface |
|
45 |
|
46 a) Create interface |
|
47 """"""""""""""""""" |
|
48 |
|
49 |
|
50 .. code-block:: python |
|
51 |
|
52 |
|
53 class ICustomRendererSettings(Interface): |
|
54 """Custom renderer settings interface""" |
|
55 |
|
56 |
|
57 display_photo = Bool(title=_("Show photo?"), |
|
58 description=_("Display contact photo"), |
|
59 required=True, |
|
60 default=True) |
|
61 |
|
62 display_phone_number = Bool(title=_("Show phone number?"), |
|
63 description=_("Display the phone number of the contact?"), |
|
64 required=True, |
|
65 default=True) |
|
66 |
|
67 can_display_photo = Attribute("Check if photo can be displayed") |
|
68 |
|
69 |
|
70 |
|
71 b) Implement interface |
|
72 """""""""""""""""""""" |
|
73 |
|
74 .. code-block:: python |
|
75 |
|
76 |
|
77 @implementer(ICustomRendererSettings) |
|
78 class CustomRendererSettings(Persistent, Location): |
|
79 """Custom renderer settings""" |
|
80 |
|
81 display_photo = FieldProperty(ICustomRendererSettings['display_photo']) |
|
82 display_phone_number = FieldProperty(ICustomRendererSettings['display_phone_number']) |
|
83 |
|
84 @property |
|
85 def can_display_photo(self): |
|
86 contact = IContactParagraph(self.__parent__) |
|
87 if not contact.photo: |
|
88 return False |
|
89 return self.display_photo |
|
90 |
|
91 |
|
92 |
|
93 c) Create the adapter |
|
94 """"""""""""""""""""" |
|
95 |
|
96 .. code-block:: python |
|
97 |
|
98 CUSTOM_RENDERER_SETTINGS_KEY = 'pyams_content.contact.renderer:custom' |
|
99 |
|
100 @adapter_config(context=IContactParagraph, provides=ICustomRendererSettings) |
|
101 def custom_renderer_settings_factory(context): |
|
102 """Contact paragraph default renderer settings factory""" |
|
103 return get_annotation_adapter(context, CUSTOM_RENDERER_SETTINGS_KEY, |
|
104 CustomRendererSettings) |
|
105 |
|
106 |
|
107 d) Add settings interface renderer |
|
108 """""""""""""""""""""""""""""""""" |
|
109 |
|
110 .. code-block:: python |
|
111 settings_interface = ICustomRendererSettings |
|
112 |
|
113 By linking a setting_interface with renderer you can use directly in the template, setting attributs |
|
114 |