Setup a custom dashboard

by Ricardo Alves last modified Jul 24, 2009 07:38 PM
How to setup the default set of portlets for the user dashboard.

Plone 3 features a default dashboard for each user. The dashboard is composed by four columns which are portlet managers and behave like the left and right columns. The set of portlet assignments created by default are: news, events, recent items and review list. This document explains how to setup a different default set of portlets for the user dashboard. We'll assume you have a custom package called mypackage, with the following structure:

mypackage/
    __init__.py
    configure.zcml
    interfaces.py
    dashboard.py

When a new user is created, the portlets machinery looks up an adapter for the user object that implements the IDefaultDashboard interface. The component lookup will retrieve the adapter that matches the context for the more specific interface the user object implements, so you'll define a new marker interface, IMyPortalUser, which must be implemented by users of your portal. This way, when an adapter to the IDefaultDashboard interface is looked up, our own default dashboard adapter (defined below) will be retrieved instead of the out-of-the-box plone.app.portlets.dashboard.DefaultDashboard one.

Module package/interfaces.py should include:

from Products.PluggableAuthService.interfaces.authservice import IPropertiedUser

class IMyPortalUser(IPropertiedUser):
    """ Marker interface implemented by users in my portal. """

The following ZCML declaration, at file mypackage/configure.zcml, explicitly declares that the PropertiedUser class implements our marker interface.

<configure
  xmlns="http://namespaces.zope.org/zope"
  xmlns:five="http://namespaces.zope.org/five">

  <five:implements
    class="Products.PluggableAuthService.PropertiedUser.PropertiedUser"
    interface=".interfaces.IMyPortalUser"/>

</configure>

You can then define your own adapter for IMyPortalUser. It will be used for new users in your portal. For example, say you want the default dashboard to include portlets news, calendar, search and recent items, assigned to the four columns respectively. Add the adapter implementation at module mypackage/dashboard.py:

from zope.interface import implements
from zope.component import adapts
from interfaces import IMyPortalUser
from plone.app.portlets.interfaces import IDefaultDashboard
from plone.app.portlets.dashboard import DefaultDashboard
from plone.app.portlets import portlets

class MyPortalDefaultDashboard(DefaultDashboard):
    """ A new custom default dashboard for users. """
    implements(IDefaultDashboard)
    adapts(IMyPortalUser)

    def __call__(self):
        news = portlets.news.Assignment()
        recent = portlets.recent.Assignment()
        calendar = portlets.calendar.Assignment()
        search = portlets.search.Assignment()

        return {
            'plone.dashboard1' : (news,),
            'plone.dashboard2' : (calendar,),
            'plone.dashboard3' : (search,),
            'plone.dashboard4' : (recent,),
        }

Note that the __call__ method returns a dictionary with portlet manager names as keys and the correspondent list of portlet assignments as values.

Then you'll need to register the adapter factory at mypackage/configure.zcml:

<adapter factory=".dashboard.MyPortalDefaultDashboard"/>

Restart your Zope instance and now every time a dashboard is initialized for a new user it will provide this default set of portlets. Users already registered will not be affected by this change.

Further information

For more information about the dashboard behavior check the documentation of plone.portlets and plone.app.portlets.

For an introduction about how the portlet machinery works, check the Portlets Developer Manual.