src/source/howto-paragraph.rst
branchdoc-dc
changeset 73 a3a8642a31b2
parent 67 81281f49aeb4
child 75 5cf9c8a16aee
equal deleted inserted replaced
72:3f403b9c4220 73:a3a8642a31b2
     1 .. _paragraphhowto:
     1 .. _paragraphhowto:
     2 
     2 
     3 
     3 
     4 How to create a new paragraph type?
     4 How to create a new paragraph type?
     5 ===================================
     5 ===================================
       
     6 
       
     7 Paragraphs are components or blocs that contain elements/fields and provide one or many renderer methods to compose
       
     8 the front office website
       
     9 
       
    10 In this example we will create a contact paragraph to display at the user, who to contact
       
    11 
       
    12 1) Define a paragraph Interface
       
    13 """""""""""""""""""""""""""""""
       
    14 
       
    15 At first we create a new paragraph interface.
       
    16 
       
    17 .. code-block:: python
       
    18 
       
    19     CONTACT_PARAGRAPH_TYPE = 'Contact'
       
    20     CONTACT_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.contact.renderers'
       
    21 
       
    22 
       
    23     class IContactParagraph(IBaseParagraph):
       
    24         """Contact paragraph interface"""
       
    25 
       
    26         name = TextLine(title=_("Contact identity"),
       
    27                         description=_("Name of the contact"),
       
    28                         required=True)
       
    29 
       
    30 
       
    31         photo = ImageField(title=_("Photo"),
       
    32                            description=_("Use 'browse' button to select contact picture"),
       
    33                            required=False)
       
    34 
       
    35         address = Text(title=_("Address"), required=False)
       
    36 
       
    37         contact_email = MailAddressField(title=_("Email address"),
       
    38                                          description=_("Contact email address"),
       
    39                                          required=False)
       
    40 
       
    41         renderer = Choice(title=_("Contact template"),
       
    42                           description=_("Presentation template used for this contact"),
       
    43                           vocabulary=CONTACT_PARAGRAPH_RENDERERS,
       
    44                           default='default')
       
    45 
       
    46 
       
    47 
       
    48 
       
    49 2) Implement the interface
       
    50 """"""""""""""""""""""""""
       
    51 
       
    52 An implementation of the interface
       
    53 
       
    54 .. code-block:: python
       
    55 
       
    56     @implementer(IContactParagraph)
       
    57     @factory_config(provided=IContactPhoneParagraph)
       
    58     class ContactParagraph(RenderedContentMixin, BaseParagraph):
       
    59         """Contact paragraph"""
       
    60 
       
    61 
       
    62         icon_class = 'fa-id-card-o'
       
    63         icon_hint = _("Contact card")
       
    64 
       
    65         name = FieldProperty(IContactParagraph['name'])
       
    66         _photo = FileProperty(IContactParagraph['photo'])
       
    67 
       
    68         address = FieldProperty(IContactParagraph['address'])
       
    69         contact_email = FieldProperty(IContactParagraph['contact_email'])
       
    70         renderer = FieldProperty(IContactParagraph['renderer'])
       
    71 
       
    72         @property
       
    73         def photo(self):
       
    74             return self._photo
       
    75 
       
    76         @photo.setter
       
    77         def photo(self, value):
       
    78             self._photo = value
       
    79             if IImage.providedBy(self._photo):
       
    80                 alsoProvides(self._photo, IResponsiveImage)
       
    81 
       
    82 
       
    83 3) renderer Vocabulary
       
    84 """"""""""""""""""""""
       
    85 
       
    86 The list of rendered available for a paragraph is build automatically and is based on adapters that provide this interface
       
    87 
       
    88 .. code-block:: python
       
    89 
       
    90     @vocabulary_config(name=CONTACT_PARAGRAPH_RENDERERS)
       
    91     class ContactParagraphRendererVocabulary(RenderersVocabulary):
       
    92         """Contact paragraph renderers vocabulary"""
       
    93 
       
    94         content_interface = IContactParagraph
       
    95 
       
    96 
       
    97 .. seealso::
       
    98 
       
    99     :ref:`rendererhowto`
       
   100 
       
   101 
       
   102 How integrate a paragraph in the ZMI?
       
   103 =====================================
       
   104 
       
   105 To display and manage the new paragraph in the ZMI, you should create this associated forms
       
   106 
       
   107 1) paragraph factory
       
   108 """"""""""""""""""""
       
   109 
       
   110 To create a new element inside the zodb, we need a container to this element. PyAMS provide
       
   111 `IParagraphContainerTarget`, it's the default container for all paragraphs. We could use this container interface
       
   112 as context to create a new paragraph.
       
   113 
       
   114 We need to create two views
       
   115 
       
   116 - *HTML*
       
   117 
       
   118 .. code-block:: python
       
   119 
       
   120     @pagelet_config(name='add-contact-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
       
   121                     permission=MANAGE_CONTENT_PERMISSION)
       
   122     class ContactParagraphAddForm(AdminDialogAddForm):
       
   123         """Contact paragraph add form"""
       
   124 
       
   125         legend = _("Add new contact card")
       
   126         dialog_class = 'modal-large'
       
   127         icon_css_class = 'fa fa-fw fa-id-card-o'
       
   128 
       
   129         fields = field.Fields(IContactParagraph).omit('__parent__', '__name__', 'visible')
       
   130         ajax_handler = 'add-contact-paragraph.json'
       
   131         edit_permission = MANAGE_CONTENT_PERMISSION
       
   132 
       
   133         def updateWidgets(self, prefix=None):
       
   134             super(ContactParagraphAddForm, self).updateWidgets(prefix)
       
   135             if 'address' in self.widgets:
       
   136                 self.widgets['address'].widget_css_class = 'textarea'
       
   137 
       
   138         def create(self, data):
       
   139             return ContactParagraph()
       
   140 
       
   141         def add(self, object):
       
   142             IParagraphContainer(self.context).append(object)
       
   143 
       
   144 - *JSON*
       
   145 
       
   146 .. code-block:: python
       
   147     @view_config(name='add-contact-paragraph.json', context=IParagraphContainerTarget, request_type=IPyAMSLayer,
       
   148                  permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   149     class ContactParagraphAJAXAddForm(BaseParagraphAJAXAddForm, ContactParagraphAddForm):
       
   150         """Contact paragraph add form, JSON renderer"""
       
   151 
       
   152 
       
   153 2) Append the paragraph addform button in the menu
       
   154 """"""""""""""""""""""""""""""""""""""""""""""""""
       
   155 
       
   156 We have created a new form and we want add a quick access button to create a new paragraph
       
   157 
       
   158 .. code-block:: python
       
   159 
       
   160     @viewlet_config(name='add-contact-paragraph.menu', context=IParagraphContainerTarget, view=IParagraphContainerView,
       
   161                     layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=600)
       
   162     class ContactParagraphAddMenu(BaseParagraphAddMenu):
       
   163         """Contact paragraph add menu"""
       
   164 
       
   165         label = _("Contact card...")
       
   166         label_css_class = 'fa fa-fw fa-id-card-o'
       
   167         url = 'add-contact-paragraph.html'
       
   168         paragraph_type = CONTACT_PARAGRAPH_TYPE
       
   169