src/source/howto-renderer.rst
changeset 99 b2be9a32f3fc
child 104 942151432421
equal deleted inserted replaced
-1:000000000000 99:b2be9a32f3fc
       
     1 .. _rendererhowto:
       
     2 
       
     3 
       
     4 How to create a Renderer?
       
     5 =========================
       
     6 
       
     7 
       
     8 **Renderer** are the layout of the utility data content. A renderer combine un context, a skin and
       
     9 a template to produce the front office html
       
    10 
       
    11  To create new renderer you can override an already exist renderer or create a new one from scratch. Steps below
       
    12  we will create a renderer for a `IContact` paragraph
       
    13 
       
    14 
       
    15 1. Override a Renderer
       
    16 ----------------------
       
    17 
       
    18 The simplest is to create a new class that inherits from the existing **Renderer**  and modify this template.
       
    19 After that all you have to define a new adapter name and a new label.
       
    20 
       
    21 
       
    22 .. code-block:: python
       
    23     :linenos:
       
    24 
       
    25     # New custom contact paragraph renderer
       
    26 
       
    27     @adapter_config(name='custom', context=(IContactParagraph, IPyAMSLayer), provides=ISharedContentRenderer)
       
    28     @template_config(template='templates/contact-custom.pt', layer=IPyAMSLayer)
       
    29     class ContactParagraphCustomRenderer(ContactParagraphDefaultRenderer):
       
    30         """Context paragraph custom renderer"""
       
    31 
       
    32         label = _("Custom contact renderer")
       
    33         #settings_interface = IContactParagraphDefaultRendererSettings
       
    34 
       
    35 
       
    36 In this example, we have defined an adapter named 'custom' with :py:class:`IContactParagraph`,
       
    37 :py:class:`IPyAMSLayer` as context and provides :py:class:`ISharedContentRenderer` interface.
       
    38 
       
    39 Using ``@template_config()`` decorator, the renderer will be displayed in html container according to the template
       
    40 `templates/contact-custom.pt`
       
    41 
       
    42 The new renderer inherit of :py:class:`ContactParagraphDefaultRenderer`, have a new **label** (line 8)
       
    43 and this associated **settings_interface** is not modify(line 9)
       
    44 
       
    45 .. tip::
       
    46 
       
    47     You can override the template of a renderer easily with the function :py:func:`pyams_template.template.override_template`
       
    48     It's takes the context and the new template path as params.
       
    49 
       
    50 
       
    51 
       
    52 2. Create a new Renderer from scratch
       
    53 -------------------------------------
       
    54 
       
    55 We can define a new settings for the renderer, to do that we start by creating an interface:
       
    56 
       
    57 
       
    58 a) Create setting interface for the renderer
       
    59 """"""""""""""""""""""""""""""""""""""""""""
       
    60 
       
    61 .. code-block:: python
       
    62 
       
    63     class IPhotoRendererSettings(Interface):
       
    64         """Custom renderer settings interface"""
       
    65 
       
    66 
       
    67         display_photo = Bool(title=_("Show photo?"),
       
    68                              description=_("Display contact photo"),
       
    69                              required=True,
       
    70                              default=True)
       
    71 
       
    72         can_display_photo = Attribute("Check if photo can be displayed")
       
    73 
       
    74 
       
    75 We have created an interface with two attributes *display_photo* and *can_display_photo*
       
    76 Then we create an implemantation of the interface
       
    77 
       
    78 .. code-block:: python
       
    79 
       
    80     @implementer(IPhotoRendererSettings)
       
    81     class PhotoRendererSettings(Persistent, Location):
       
    82         """Custom renderer settings"""
       
    83 
       
    84         display_photo = FieldProperty(IPhotoRendererSettings['display_photo'])
       
    85 
       
    86         @property
       
    87         def can_display_photo(self):
       
    88             contact = IContactParagraph(self.__parent__)
       
    89             if not contact.photo:
       
    90                 return False
       
    91             return self.display_photo
       
    92 
       
    93 
       
    94 
       
    95 b) Create an adapter for the render setting interface
       
    96 """""""""""""""""""""""""""""""""""""""""""""""""""""
       
    97 
       
    98 With :py:func:`@adapter_config()` we declare a new adapter that applies to a context and provide the interface of
       
    99  renderer settings
       
   100 
       
   101 .. code-block:: python
       
   102 
       
   103     PHOTO_RENDERER_SETTINGS_KEY = 'pyams_content.contact.renderer:photo'
       
   104 
       
   105     @adapter_config(context=IContactParagraph, provides=IPhotoRendererSettings)
       
   106     def custom_renderer_settings_factory(context):
       
   107         """Contact paragraph default renderer settings factory"""
       
   108         return get_annotation_adapter(context, PHOTO_RENDERER_SETTINGS_KEY,
       
   109                                       CustomRendererSettings)
       
   110 
       
   111 
       
   112 In this example the settings interface adapter is defined with `IContactParagraph` as context
       
   113 and provide `IPhotoRendererSettings`.
       
   114 
       
   115 
       
   116 
       
   117 c) Create an adapter for the render interface
       
   118 """""""""""""""""""""""""""""""""""""""""""""
       
   119 
       
   120 .. code-block:: python
       
   121 
       
   122     @adapter_config(context=(IContactParagraph, IPyAMSLayer), provides=ISharedContentRenderer)
       
   123     @template_config(template='templates/contact-custom.pt', layer=IPyAMSLayer)
       
   124     class PhotoRenderer(BaseContentRenderer):
       
   125         """Context paragraph custom renderer"""
       
   126 
       
   127         label = _("Custom contact renderer")
       
   128         settings_interface = IPhotoRendererSettings
       
   129 
       
   130 
       
   131 Add settings interface to the renderer `settings_interface = IPhotoRendererSettings`
       
   132 
       
   133 .. tip::
       
   134     When a setting_interface is associated to a renderer, you can access to `settings` attributes through the template
       
   135