diff -r 1de74ac0628f -r 31b3d00edb8a src/source/developer_guide/howto-portlet.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/source/developer_guide/howto-portlet.rst Tue Dec 11 16:29:56 2018 +0100
@@ -0,0 +1,180 @@
+.. _portlethowto:
+
+
+How to create a 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
+
+