diff -r 9fdc2d81e685 -r de025ff8ba30 src/source/appextend.rst --- a/src/source/appextend.rst Wed May 16 15:10:38 2018 +0200 +++ b/src/source/appextend.rst Fri May 18 11:33:19 2018 +0200 @@ -1,167 +1,11 @@ .. _appextend: -How to create a new Portlet ? ------------------------------ - -**Portlets** are pluggable user interface software components that are managed and displayed in a web portal, -for example an enterprise portal or a web CMS. A portlet can aggregate (integrate) and personalize content from -different sources within a web page. A portlet responds to requests from a web client and generates dynamic content -(*reference:* `Wiki portlet`_). - -.. _`wiki portlet`: https://en.wikipedia.org/wiki/Portlet - - -**PyAMS Portal** provides the portal engine but only a very small set of predefined portlets that can be used to compose -and organize the structure of a web page; additional portlets are provided by other packages, like -:ref:`pyams_content`. - - -1. Define portlet settings -'''''''''''''''''''''''''' - -Portlet settings interface are defined in ``interfaces.py``, you can use :py:class:`pyams_portal.interfaces.IPortletSettings` -or extend the interface by adding additional properties for example: - -.. code-block:: python - - from zope.schema import Text - - NEW_PORTLET_NAME = 'new.portlet' - - class INewPortletSettings(IPortletSettings): - - comment = Text(title=_("Comment"), - required=True) - - -A :py:class:`pyams_portal.portlet.PortletSettings` persistent subclass then implements what IPortletSettings describes: - -.. code-block:: python - - @implementer(INewPortletSettings) - class NewPortletSettings(PortletSettings): - """Portlet settings""" - - comment = FieldProperty(INewPortletSettings['comment']) - - -2. Create Portlet -''''''''''''''''' - -The Portlet component is a utility, which implements the :py:class:`pyams_portal.interfaces.IPortlet` interface and is -registered by the :py:func:`pyams_portal.portlet.portlet_config` decorator; - -.. code-block:: python - - @portlet_config(permission=VIEW_PERMISSION) - class ImagePortlet(Portlet): - """Image portlet""" - - name = NEW_PORTLET_NAME - label = _("New portlet") - - toolbar_image = None - toolbar_css_class = 'fa fa-fw fa-2x fa-picture-o' - - settings_class = NewPortletSettings - - -Where: - - **permission**: permission required to display this portlet content - - **name**: internal name given to this portlet. This name must be unique between all portlets, so using your own - namespace into this name is generally a good option! - - **label**: user label given to this portlet - - **toolbar_image**: URL of an image used to display portlet button into ZMI toolbar, if any - - **toolbar_css_class**: CSS class used to display portlet button into ZMI toolbar, if any - - **settings_class**: class used to store portlet settings. - -3. Create portlet settings edit form -'''''''''''''''''''''''''''''''''''' - -Portlet settings have to be updated through management interface via a :py:class:`pyams_portal.zmi.portlet.PortletSettingsEditor` -subform: - -.. code-block:: python - - @pagelet_config(name='properties.html', context=INewPortletSettings, layer=IPyAMSLayer, - permission=VIEW_SYSTEM_PERMISSION) - class NewPortletSettingsEditor(PortletSettingsEditor): - """New portlet settings editor""" - - settings = INewPortletSettings - - - @adapter_config(name='properties.json', context=(INewPortletSettings, IPyAMSLayer), provides=IPagelet) - class NewPortletSettingsAJAXEditor(AJAXEditForm, NewPortletSettingsEditor): - """New portlet settings editor, JSON renderer""" - - -4. Previewing portlet content -''''''''''''''''''''''''''''' - -A *previewer* is used into ZMI to display portlet content into portal template definition page: - -.. code-block:: python - - @adapter_config(context=(Interface, IPyAMSLayer, Interface, INewPortletSettings), provides=IPortletPreviewer) - @template_config(template='my-portlet-preview.pt', layer=IPyAMSLayer) - class NewPortletPreviewer(PortletPreviewer): - """New portlet previewer""" - - -The previewer template is a Chameleon template: - -.. code-block:: genshi +Extending PyAMS +=============== - - -
Comment
-
- -
- - - - -
-
-
- -Here we check if portlet is visible or not to display a small icon when hidden; otherwise we display entered comment. - - -5. Rendering portlet content -'''''''''''''''''''''''''''' - -A *renderer* is used to display portlet content into rendered page content: - -.. code-block:: python +.. toctree:: + :maxdepth: 1 - @adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, INewPortletSettings), provides=IPortletRenderer) - @template_config(template='my-portlet-render.pt', layer=IPyAMSLayer) - class NewPortletRenderer(PortletRenderer): - """New portlet renderer""" - - label = _("Default comment renderer") - - -Each renderer template is also a Chameleon template: - -.. code-block:: genshi - -
Comment
- - -This is the configuration of a *default* renderer defined for this portlet; you can provide several renderers for a -given portlet by given distinct names to the adapters: - -.. code-block:: python - - @adapter_config(name='another-renderer', - context=(IPortalContext, IPyAMSLayer, Interface, INewPortletSettings), provides=IPortletRenderer) - @template_config(template='my-portlet-render-2.pt', layer=IPyAMSLayer) - class AnotherNewPortletRenderer(PortletRenderer): - """Another new portlet renderer""" - - label = _("Another comment renderer") + howto-adapter + howto-portlet