src/source/howto-renderer.rst
changeset 99 b2be9a32f3fc
child 104 942151432421
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/source/howto-renderer.rst	Thu Dec 06 08:24:10 2018 +0100
@@ -0,0 +1,135 @@
+.. _rendererhowto:
+
+
+How to create a Renderer?
+=========================
+
+
+**Renderer** are the layout of the utility data content. A renderer combine un context, a skin and
+a template to produce the front office html
+
+ To create new renderer you can override an already exist renderer or create a new one from scratch. Steps below
+ we will create a renderer for a `IContact` paragraph
+
+
+1. Override a Renderer
+----------------------
+
+The simplest is to create a new class that inherits from the existing **Renderer**  and modify this template.
+After that all you have to define a new adapter name and a new label.
+
+
+.. code-block:: python
+    :linenos:
+
+    # New custom contact paragraph renderer
+
+    @adapter_config(name='custom', context=(IContactParagraph, IPyAMSLayer), provides=ISharedContentRenderer)
+    @template_config(template='templates/contact-custom.pt', layer=IPyAMSLayer)
+    class ContactParagraphCustomRenderer(ContactParagraphDefaultRenderer):
+        """Context paragraph custom renderer"""
+
+        label = _("Custom contact renderer")
+        #settings_interface = IContactParagraphDefaultRendererSettings
+
+
+In this example, we have defined an adapter named 'custom' with :py:class:`IContactParagraph`,
+:py:class:`IPyAMSLayer` as context and provides :py:class:`ISharedContentRenderer` interface.
+
+Using ``@template_config()`` decorator, the renderer will be displayed in html container according to the template
+`templates/contact-custom.pt`
+
+The new renderer inherit of :py:class:`ContactParagraphDefaultRenderer`, have a new **label** (line 8)
+and this associated **settings_interface** is not modify(line 9)
+
+.. tip::
+
+    You can override the template of a renderer easily with the function :py:func:`pyams_template.template.override_template`
+    It's takes the context and the new template path as params.
+
+
+
+2. Create a new Renderer from scratch
+-------------------------------------
+
+We can define a new settings for the renderer, to do that we start by creating an interface:
+
+
+a) Create setting interface for the renderer
+""""""""""""""""""""""""""""""""""""""""""""
+
+.. code-block:: python
+
+    class IPhotoRendererSettings(Interface):
+        """Custom renderer settings interface"""
+
+
+        display_photo = Bool(title=_("Show photo?"),
+                             description=_("Display contact photo"),
+                             required=True,
+                             default=True)
+
+        can_display_photo = Attribute("Check if photo can be displayed")
+
+
+We have created an interface with two attributes *display_photo* and *can_display_photo*
+Then we create an implemantation of the interface
+
+.. code-block:: python
+
+    @implementer(IPhotoRendererSettings)
+    class PhotoRendererSettings(Persistent, Location):
+        """Custom renderer settings"""
+
+        display_photo = FieldProperty(IPhotoRendererSettings['display_photo'])
+
+        @property
+        def can_display_photo(self):
+            contact = IContactParagraph(self.__parent__)
+            if not contact.photo:
+                return False
+            return self.display_photo
+
+
+
+b) Create an adapter for the render setting interface
+"""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+With :py:func:`@adapter_config()` we declare a new adapter that applies to a context and provide the interface of
+ renderer settings
+
+.. code-block:: python
+
+    PHOTO_RENDERER_SETTINGS_KEY = 'pyams_content.contact.renderer:photo'
+
+    @adapter_config(context=IContactParagraph, provides=IPhotoRendererSettings)
+    def custom_renderer_settings_factory(context):
+        """Contact paragraph default renderer settings factory"""
+        return get_annotation_adapter(context, PHOTO_RENDERER_SETTINGS_KEY,
+                                      CustomRendererSettings)
+
+
+In this example the settings interface adapter is defined with `IContactParagraph` as context
+and provide `IPhotoRendererSettings`.
+
+
+
+c) Create an adapter for the render interface
+"""""""""""""""""""""""""""""""""""""""""""""
+
+.. code-block:: python
+
+    @adapter_config(context=(IContactParagraph, IPyAMSLayer), provides=ISharedContentRenderer)
+    @template_config(template='templates/contact-custom.pt', layer=IPyAMSLayer)
+    class PhotoRenderer(BaseContentRenderer):
+        """Context paragraph custom renderer"""
+
+        label = _("Custom contact renderer")
+        settings_interface = IPhotoRendererSettings
+
+
+Add settings interface to the renderer `settings_interface = IPhotoRendererSettings`
+
+.. tip::
+    When a setting_interface is associated to a renderer, you can access to `settings` attributes through the template
+