src/source/howto-renderer.rst
changeset 90 06915aa059c5
parent 83 ee94d17857a4
child 92 7fc18ab1b5b4
equal deleted inserted replaced
67:81281f49aeb4 90:06915aa059c5
     1 .. _rendererhowto:
     1 .. _rendererhowto:
     2 
     2 
     3 
     3 
     4 How to create a new renderer?
     4 How to create a Renderer?
     5 =============================
     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=IContentRenderer)
       
    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:`IContentRenderer` interface.
       
    38 
       
    39 Using ``@template_config()`` decorator, the renderer will be displayed in html container according to the template
       
    40 
       
    41 The new renderer inherit of :py:class:`ContactParagraphDefaultRenderer`, have a new **label** (line 8)
       
    42 and is associated an **settings_interface** (line 9)
       
    43 
       
    44 .. tip::
       
    45 
       
    46     You can override the template of a renderer easily with the function :py:func:`pyams_template.template.override_template`
       
    47     It's takes the context and the new template path as params.
       
    48 
       
    49 
       
    50 2. Create a new Renderer from scratch
       
    51 -------------------------------------
       
    52 
       
    53 We can define a new settings interface for the renderer, to do that we start by creating an interface
       
    54 
       
    55 
       
    56 a) Create setting interface for the renderer
       
    57 """"""""""""""""""""""""""""""""""""""""""""
       
    58 
       
    59 .. code-block:: python
       
    60 
       
    61     class IPhotoRendererSettings(Interface):
       
    62         """Custom renderer settings interface"""
       
    63 
       
    64 
       
    65         display_photo = Bool(title=_("Show photo?"),
       
    66                              description=_("Display contact photo"),
       
    67                              required=True,
       
    68                              default=True)
       
    69 
       
    70         can_display_photo = Attribute("Check if photo can be displayed")
       
    71 
       
    72 
       
    73 We have created an interface with two attributes *display_photo* and *can_display_photo*
       
    74 Then we create an implemantation of the interface
       
    75 
       
    76 .. code-block:: python
       
    77 
       
    78     @implementer(IPhotoRendererSettings)
       
    79     class PhotoRendererSettings(Persistent, Location):
       
    80         """Custom renderer settings"""
       
    81 
       
    82         display_photo = FieldProperty(IPhotoRendererSettings['display_photo'])
       
    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 b) Create an adapter for the render setting interface
       
    94 """""""""""""""""""""""""""""""""""""""""""""""""""""
       
    95 
       
    96 With :py:func:`@adapter_config()` we declare a new adapter that applies to a context and provide the interface of
       
    97  renderer settings
       
    98 
       
    99 .. code-block:: python
       
   100 
       
   101     PHOTO_RENDERER_SETTINGS_KEY = 'pyams_content.contact.renderer:photo'
       
   102 
       
   103     @adapter_config(context=IContactParagraph, provides=IPhotoRendererSettings)
       
   104     def custom_renderer_settings_factory(context):
       
   105         """Contact paragraph default renderer settings factory"""
       
   106         return get_annotation_adapter(context, PHOTO_RENDERER_SETTINGS_KEY,
       
   107                                       CustomRendererSettings)
       
   108 
       
   109 
       
   110 In this example the settings interface adapter is defined with `IContactParagraph` as context
       
   111 and provide `IPhotoRendererSettings`.
       
   112 
       
   113 
       
   114 
       
   115 c) Create an adapter for the render interface
       
   116 """""""""""""""""""""""""""""""""""""""""""""
       
   117 
       
   118 .. code-block:: python
       
   119 
       
   120     @adapter_config(context=(IContactParagraph, IPyAMSLayer), provides=IContentRenderer)
       
   121     @template_config(template='templates/contact-custom.pt', layer=IPyAMSLayer)
       
   122     class PhotoRenderer(BaseContentRenderer):
       
   123         """Context paragraph custom renderer"""
       
   124 
       
   125         label = _("Custom contact renderer")
       
   126         settings_interface = IPhotoRendererSettings
       
   127 
       
   128 
       
   129 Add settings interface to the renderer `settings_interface = IPhotoRendererSettings`
       
   130 
       
   131 .. tip::
       
   132     When a setting_interface is associated to a renderer, you can access to `settings` attributes through the template
       
   133