src/source/howto-paragraph.rst
branchdoc-dc
changeset 75 5cf9c8a16aee
parent 73 a3a8642a31b2
child 76 ca63b1a69cbb
equal deleted inserted replaced
74:efe71f19939c 75:5cf9c8a16aee
     8 the front office website
     8 the front office website
     9 
     9 
    10 In this example we will create a contact paragraph to display at the user, who to contact
    10 In this example we will create a contact paragraph to display at the user, who to contact
    11 
    11 
    12 1) Define a paragraph Interface
    12 1) Define a paragraph Interface
    13 """""""""""""""""""""""""""""""
    13 -------------------------------
    14 
    14 
    15 At first we create a new paragraph interface.
    15 At first we create a new paragraph interface.
    16 
    16 
    17 .. code-block:: python
    17 .. code-block:: python
    18 
    18 
    19     CONTACT_PARAGRAPH_TYPE = 'Contact'
    19     CONTACT_PHONE_PARAGRAPH_TYPE = 'PhoneContact'
    20     CONTACT_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.contact.renderers'
    20     CONTACT_PHONE_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.contact.phone.renderers'
    21 
    21 
    22 
    22 
    23     class IContactParagraph(IBaseParagraph):
    23     class IContactPhoneParagraph(IBaseParagraph):
    24         """Contact paragraph interface"""
    24     """Contact with phone number paragraph interface"""
    25 
    25 
    26         name = TextLine(title=_("Contact identity"),
    26     name = TextLine(title=_("Contact identity"),
    27                         description=_("Name of the contact"),
    27                     description=_("Name of the contact"),
    28                         required=True)
    28                     required=True)
    29 
    29 
    30 
    30     photo = ImageField(title=_("Photo"),
    31         photo = ImageField(title=_("Photo"),
    31                        description=_("Use 'browse' button to select contact picture"),
    32                            description=_("Use 'browse' button to select contact picture"),
    32                        required=False)
    33                            required=False)
    33 
    34 
    34     phone = TextLine(title=_("Phone Number"),
    35         address = Text(title=_("Address"), required=False)
    35                      description=_("Name of the contact", required=False))
    36 
    36 
    37         contact_email = MailAddressField(title=_("Email address"),
    37     address = Text(title=_("Address"), required=False)
    38                                          description=_("Contact email address"),
    38 
    39                                          required=False)
    39     contact_email = MailAddressField(title=_("Email address"),
    40 
    40                                      description=_("Contact email address"),
    41         renderer = Choice(title=_("Contact template"),
    41                                      required=False)
    42                           description=_("Presentation template used for this contact"),
    42 
    43                           vocabulary=CONTACT_PARAGRAPH_RENDERERS,
    43     renderer = Choice(title=_("Contact template"),
    44                           default='default')
    44                       description=_("Presentation template used for this contact"),
       
    45                       vocabulary=CONTACT_PHONE_PARAGRAPH_RENDERERS,
       
    46                       default='default')
    45 
    47 
    46 
    48 
    47 
    49 
    48 
    50 
    49 2) Implement the interface
    51 2) Implement the interface
    50 """"""""""""""""""""""""""
    52 --------------------------
    51 
    53 
    52 An implementation of the interface
    54 An implementation of the interface
    53 
    55 
    54 .. code-block:: python
    56 .. code-block:: python
    55 
    57 
    56     @implementer(IContactParagraph)
    58     @implementer(IContactPhoneParagraph)
    57     @factory_config(provided=IContactPhoneParagraph)
    59     @factory_config(provided=IContactPhoneParagraph)
    58     class ContactParagraph(RenderedContentMixin, BaseParagraph):
    60     class ContactPhoneParagraph(BaseParagraph):
    59         """Contact paragraph"""
    61         """Contact paragraph"""
    60 
    62 
    61 
    63 
    62         icon_class = 'fa-id-card-o'
    64         icon_class = 'fa-phone'
    63         icon_hint = _("Contact card")
    65         icon_hint = _("Phone number card")
    64 
       
    65         name = FieldProperty(IContactParagraph['name'])
       
    66         _photo = FileProperty(IContactParagraph['photo'])
       
    67 
    66 
    68         address = FieldProperty(IContactParagraph['address'])
    67         address = FieldProperty(IContactParagraph['address'])
    69         contact_email = FieldProperty(IContactParagraph['contact_email'])
    68         contact_email = FieldProperty(IContactParagraph['contact_email'])
    70         renderer = FieldProperty(IContactParagraph['renderer'])
    69         renderer = FieldProperty(IContactParagraph['renderer'])
    71 
    70 
    79             if IImage.providedBy(self._photo):
    78             if IImage.providedBy(self._photo):
    80                 alsoProvides(self._photo, IResponsiveImage)
    79                 alsoProvides(self._photo, IResponsiveImage)
    81 
    80 
    82 
    81 
    83 3) renderer Vocabulary
    82 3) renderer Vocabulary
    84 """"""""""""""""""""""
    83 ----------------------
    85 
    84 
    86 The list of rendered available for a paragraph is build automatically and is based on adapters that provide this interface
    85 The list of rendered available for a paragraph is build automatically and is based on adapters that provide this interface
    87 
    86 
    88 .. code-block:: python
    87 .. code-block:: python
    89 
    88 
   103 =====================================
   102 =====================================
   104 
   103 
   105 To display and manage the new paragraph in the ZMI, you should create this associated forms
   104 To display and manage the new paragraph in the ZMI, you should create this associated forms
   106 
   105 
   107 1) paragraph factory
   106 1) paragraph factory
   108 """"""""""""""""""""
   107 --------------------
   109 
   108 
   110 To create a new element inside the zodb, we need a container to this element. PyAMS provide
   109 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
   110 `IParagraphContainerTarget`, it's the default container for all paragraphs. We could use this container interface
   112 as context to create a new paragraph.
   111 as context to create a new paragraph.
   113 
   112 
   139             return ContactParagraph()
   138             return ContactParagraph()
   140 
   139 
   141         def add(self, object):
   140         def add(self, object):
   142             IParagraphContainer(self.context).append(object)
   141             IParagraphContainer(self.context).append(object)
   143 
   142 
       
   143 
   144 - *JSON*
   144 - *JSON*
   145 
   145 
   146 .. code-block:: python
   146 .. code-block:: python
       
   147 
   147     @view_config(name='add-contact-paragraph.json', context=IParagraphContainerTarget, request_type=IPyAMSLayer,
   148     @view_config(name='add-contact-paragraph.json', context=IParagraphContainerTarget, request_type=IPyAMSLayer,
   148                  permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   149                  permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   149     class ContactParagraphAJAXAddForm(BaseParagraphAJAXAddForm, ContactParagraphAddForm):
   150     class ContactParagraphAJAXAddForm(BaseParagraphAJAXAddForm, ContactParagraphAddForm):
   150         """Contact paragraph add form, JSON renderer"""
   151         """Contact paragraph add form, JSON renderer"""
   151 
   152 
   152 
   153 
   153 2) Append the paragraph addform button in the menu
   154 2) Append the paragraph addform button in the menu
   154 """"""""""""""""""""""""""""""""""""""""""""""""""
   155 --------------------------------------------------
   155 
   156 
   156 We have created a new form and we want add a quick access button to create a new paragraph
   157 We have created a new form and we want add a quick access button to create a new paragraph
   157 
   158 
   158 .. code-block:: python
   159 .. code-block:: python
   159 
   160 
   165         label = _("Contact card...")
   166         label = _("Contact card...")
   166         label_css_class = 'fa fa-fw fa-id-card-o'
   167         label_css_class = 'fa fa-fw fa-id-card-o'
   167         url = 'add-contact-paragraph.html'
   168         url = 'add-contact-paragraph.html'
   168         paragraph_type = CONTACT_PARAGRAPH_TYPE
   169         paragraph_type = CONTACT_PARAGRAPH_TYPE
   169 
   170 
       
   171 
       
   172 3)Edit form
       
   173 -----------
       
   174 
       
   175 - *HTML*
       
   176 .. code-block:: python
       
   177 
       
   178     @pagelet_config(name='properties.html', context=IContactParagraph, layer=IPyAMSLayer,
       
   179                     permission=MANAGE_CONTENT_PERMISSION)
       
   180     class ContactParagraphPropertiesEditForm(BaseParagraphPropertiesEditForm):
       
   181         """Contact paragraph properties edit form"""
       
   182 
       
   183         prefix = 'contact_properties.'
       
   184 
       
   185         legend = _("Edit contact card properties")
       
   186         icon_css_class = 'fa fa-fw fa-id-card-o'
       
   187 
       
   188         fields = field.Fields(IContactParagraph).omit('__parent__', '__name__', 'visible')
       
   189         fields['renderer'].widgetFactory = RendererFieldWidget
       
   190 
       
   191         ajax_handler = 'properties.json'
       
   192         edit_permission = MANAGE_CONTENT_PERMISSION
       
   193 
       
   194         def updateWidgets(self, prefix=None):
       
   195             super(ContactParagraphPropertiesEditForm, self).updateWidgets(prefix)
       
   196             if 'address' in self.widgets:
       
   197                 self.widgets['address'].widget_css_class = 'textarea'
       
   198 
       
   199  - *JSON*
       
   200 
       
   201 .. code-block:: python
       
   202 
       
   203     @view_config(name='properties.json', context=IContactParagraph, request_type=IPyAMSLayer,
       
   204                  permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   205     class ContactParagraphPropertiesAJAXEditForm(BaseParagraphAJAXEditForm, ContactParagraphPropertiesEditForm):
       
   206         """Contact paragraph properties edit form, JSON renderer"""
       
   207 
       
   208 
       
   209     @adapter_config(context=(IContactParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
       
   210     @implementer(IInnerForm)
       
   211     class ContactParagraphInnerEditForm(ContactParagraphPropertiesEditForm):
       
   212         """Contact paragraph inner edit form"""
       
   213 
       
   214         legend = None
       
   215         ajax_handler = 'inner-properties.json'
       
   216 
       
   217         @property
       
   218         def buttons(self):
       
   219             if self.mode == INPUT_MODE:
       
   220                 return button.Buttons(IParagraphEditFormButtons)
       
   221             else:
       
   222                 return button.Buttons()
       
   223 
       
   224 
       
   225     @view_config(name='inner-properties.json', context=IContactParagraph, request_type=IPyAMSLayer,
       
   226                  permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   227     class ContactParagraphInnerAJAXEditForm(BaseParagraphAJAXEditForm, ContactParagraphInnerEditForm):
       
   228         """Contact paragraph inner edit form, JSON renderer"""
       
   229 
       
   230         def get_ajax_output(self, changes):
       
   231             output = super(ContactParagraphInnerAJAXEditForm, self).get_ajax_output(changes)
       
   232             updated = changes.get(IBaseParagraph, ())
       
   233             if 'title' in updated:
       
   234                 output.setdefault('events', []).append(get_json_paragraph_refresh_event(self.context, self.request))
       
   235             updated = changes.get(IContactParagraph, ())
       
   236             if ('photo' in updated) or ('renderer' in updated):
       
   237                 # we have to commit transaction to be able to handle blobs...
       
   238                 if 'photo' in updated:
       
   239                     ITransactionManager(self.context).get().commit()
       
   240                 output.setdefault('events', []).append(get_json_form_refresh_event(self.context, self.request,
       
   241                                                                                    ContactParagraphInnerEditForm))
       
   242             return output
       
   243 
       
   244 .. note::
       
   245 
       
   246     Select the new content block types in ZMI to make it available in tools
       
   247 
       
   248     .. image:: _static/select_paragraph.png