How and where are Portlet Assignments stored?¶
Description
When you choose a portlet to be displayed somewhere, for example, using the interface that appears when you hit the Manage Portlets button, what you're doing is storing a persistent instance of the Portlet Assignment class into your site, together with all its associated configuration data.
Portlet Assignments are stored in what's called an Assignment Mapping. This is an ordered container with a dict-like interface. The keys are unique string names, and the values are instances of the assignment class.
Assignment mappings can be stored in two different kinds of locations depending on their type: site-wide or contextual.
Site-wide¶
Site-wide assigned portlets are shown in the whole site,
unless blocked. They're stored in Portlet Managers.
Portlet Managers define a column or other area that can be
filled with portlets, and are analogous to the viewlet
manager for viewlets. They are named persistent local
utilites providing the
IPortletManager
interface.
You can look up a portlet manager like this:
manager = getUtility(IPortletManager, name=u"plone.leftcolumn")
By default, there are two standard portlet managers,
plone.leftcolumn
and
plone.rightcolumn
, as well as four portlet managers for the four columns
on the dashboard, from
plone.dashboard1
to
plone.dashboard4
. You can create your own in
portlets.xml
like this:
<portletmanager
name="my.package.myportletmanager"
type="my.package.interfaces.IMyPortletManagerType"
/>
The "type" is a marker interface that can be
used to install particular portlets only for particular
types of portlet managers, as explained above. Example:
plone.app.portlets.interfaces.IDashboard
.
Portlets in global categories (site-wide) are stored
directly inside the
IPortletManager
utility, under a particular category - e.g.
"group" - a category-specific key - e.g. the
group id - and finally a unique portlet id. Putting this
together, we could access a particular portlet assignment
like this:
from plone.portlets.constants import GROUP_CATEGORY
manager = getUtility(IPortletManager, name=u"plone.leftcolumn")
recent_assignment = manager[GROUP_CATEGORY][u"Administrators"][u"recent"]
Here we look up the left column portlet manager and get the portlet assignment named recent assigned to the Administrators group.
Each of the lookups here has a dict interface, so you can
iterate, call
keys()
and so on. You can store assignments under any string as
category, but the default portlet retriever is only aware
of the three site-wide assignment categories defined as
constants in plone.portlet.constants,
USER_CATEGORY
,
GROUP_CATEGORY
and
CONTENT_TYPE_CATEGORY
, which should be enough for most use-cases. More on
portlet retrievers later.
Contextual¶
Location-specific portlet assignments are stored on
annotations on objects providing the
ILocalPortletAssignable
marker interface.
To get hold of the assignment in this case, we multi-adapt
the content object and the manager instance to the
IPortletAssignment
interface, like so:
manager = getUtility(IPortletManager, name=u"plone.leftcolumn")
assignment_mapping = getMultiAdapter((context, manager), IPortletAssignmentMapping)
news_portlet = assignment_mapping[u"news"]
There are two functions in plone.app.portlets.utils to
make it easier to find the appropriate mapping for a
portlet, or to get a portlet assignment directly:
assignment_mapping_from_key()
and
assignment_from_key()
.
We can use GenericSetup to assign portlets to particular portlet managers upon the installation of a product. Read the Theme Reference Manual for info about how to do that. Read the Generic Setup tutorial for further info about what's GenericSetup and how it works.