.. _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`.
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'
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
NB: the argument **settings_class** could be set to add a portlet settings (see below).
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:
1) create portlet settings
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. 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. declare the settings portlet
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Add the settings portlet class inside the portlet
.. 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
3. portlet settings edit form
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Portlet settings have to be updated through management interface (ZMI) 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"""
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