Author: rmarianski
Date: 2007-11-24 01:21:14 -0500 (Sat, 24 Nov 2007)
New Revision: 11238
Modified:
opencore/branches/viewlet_menuitems/opencore/browser/topnav/topnav_menuitem.py
opencore/branches/viewlet_menuitems/opencore/listen/browser/topnav_menuitem.py
opencore/branches/viewlet_menuitems/opencore/tasktracker/browser/topnav_menuitem.py
opencore/branches/viewlet_menuitems/opencore/wordpress/browser/topnav_menuitem.py
Log:
create mixins to share more code among various viewlets
Modified:
opencore/branches/viewlet_menuitems/opencore/browser/topnav/topnav_menuitem.py
===================================================================
---
opencore/branches/viewlet_menuitems/opencore/browser/topnav/topnav_menuitem.py
2007-11-23 20:47:52 UTC (rev 11237)
+++
opencore/branches/viewlet_menuitems/opencore/browser/topnav/topnav_menuitem.py
2007-11-24 06:21:14 UTC (rev 11238)
@@ -1,4 +1,3 @@
-from zope.viewlet.viewlet import ViewletBase
from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
from Products.CMFCore.utils import getToolByName
from opencore.interfaces import IMemberFolder
@@ -6,17 +5,47 @@
from opencore.interfaces import IOpenPage
from opencore.interfaces.adding import IAddProject
from opencore.interfaces.adding import IAmAPeopleFolder
+from zope.interface import Interface
+from zope.viewlet.viewlet import ViewletBase
class BaseMenuItem(ViewletBase):
"""Base class for topnav menu items."""
+ # these 3 viewlet attributes are what the template renders
name = u''
url = '#'
css_class = None
def update(self):
- """subclasses can control setting state here"""
+ # check the context here to see if viewlet should be rendered
+ if not self.context_matches():
+ return self.no_render()
+ self.url = self.get_url()
+ if self.is_selected():
+ self.set_css_class()
+
+ def set_state(self):
+ """subclasses should set internal variables here for use later"""
+
+ def context_matches(self):
+ """subclasses should check here if they should be rendered"""
+
+ def get_url(self):
+ """subclasses should return the url attribute here
+ this represents the menu item's link"""
+
+ def is_selected(self):
+ """subclasses should check if the menu item should be rendered
+ selected"""
+
+ def set_css_class(self):
+ self.css_class = 'oc-topnav-selected'
+
+ def no_render(self):
+ # replace render method to return an empty string
+ self.render = lambda *args:''
+
def __cmp__(self, rhs):
#XXX this ideally would have happened
# with a custom sorting viewlet manager
@@ -31,154 +60,155 @@
render = ZopeTwoPageTemplateFile('topnav_menuitem.pt')
+# Here are some mixins for certain contexts that help reduce code
+
+class StartsWithMixin(object):
+ def is_selected(self):
+ return self.request.ACTUAL_URL.startswith(self.url)
+
+class ContextProvidedMixin(StartsWithMixin):
+ """Menu items must be in a particular context"""
+ should_be_provided = Interface
+ item_url = '#'
+
+ def set_state(self):
+ self.item = self._item_providing(self.should_be_provided)
+
+ def context_matches(self):
+ return self._item_providing(self.should_be_provided) is not None
+
+ def get_url(self):
+ item = self._item_providing(self.should_be_provided)
+ return '%s/%s' % (item.absolute_url(), self.item_url)
+
+class BaseProjectMenuItem(ContextProvidedMixin, BaseMenuItem):
+ should_be_provided = IProject
+
+class BaseMemberMenuItem(ContextProvidedMixin, BaseMenuItem):
+ should_be_provided = IMemberFolder
+
+class PortalContextMenuItem(BaseMenuItem):
+ folder_context = None
+
+ def context_matches(self):
+ # matching is handled by configuration here
+ return True
+
+ def get_url(self):
+ portal = getToolByName(self.context, 'portal_url').getPortalObject()
+ return getattr(portal, self.folder_context).absolute_url()
+
# Member menu items
-class MemberWikiMenuItem(BaseMenuItem):
+class MemberWikiMenuItem(BaseMemberMenuItem):
name = u'Wiki'
- def update(self):
- mem = self._item_providing(IMemberFolder)
- if mem is None:
- self.render = lambda *a:''
- return
- self.url = '%s/%s-home' % (mem.absolute_url(), mem.getId())
- if IOpenPage.providedBy(self.context):
- self.css_class = 'oc-topnav-selected'
+ def get_url(self):
+ mem = self._item_providing(self.should_be_provided)
+ return '%s/%s-home' % (mem.absolute_url(), mem.getId())
-class MemberMenuItem(BaseMenuItem):
- """Base class to allow easy creation of member menu items"""
- item_url = '#'
+ def is_selected(self):
+ return IOpenPage.providedBy(self.context)
- def update(self):
- mem = self._item_providing(IMemberFolder)
- if mem is None:
- self.render = lambda *a:''
- return
- self.url = '%s/%s' % (mem.absolute_url(), self.item_url)
- if self.request.ACTUAL_URL.startswith(self.url):
- self.css_class = 'oc-topnav-selected'
-
-class ProfileMenuItem(MemberMenuItem):
+class ProfileMenuItem(BaseMemberMenuItem):
name = u'Profile'
item_url = 'profile'
-class AccountMenuItem(MemberMenuItem):
+class AccountMenuItem(BaseMemberMenuItem):
name = u'Account'
item_url = 'account'
# Project menu items
-class ProjectWikiMenuItem(BaseMenuItem):
+class ProjectWikiMenuItem(BaseProjectMenuItem):
name = u'Wiki'
- def update(self):
- proj = self._item_providing(IProject)
- if proj is None:
- self.render = lambda *a:''
- return
- self.url = '%s/project-home' % proj.absolute_url()
- if IOpenPage.providedBy(self.context):
- self.css_class = 'oc-topnav-selected'
+ def get_url(self):
+ item = self._item_providing(self.should_be_provided)
+ return '%s/project-home' % item.absolute_url()
-class ProjectMenuItem(BaseMenuItem):
- """Base class to allow easy creation of project mneu items"""
- item_url = '#'
+ def is_selected(self):
+ return IOpenPage.providedBy(self.context)
- def update(self):
- proj = self._item_providing(IProject)
- if proj is None:
- self.render = lambda *a:''
- return
- self.url = '%s/%s' % (proj.absolute_url(), self.item_url)
- if self.request.ACTUAL_URL.startswith(self.url):
- self.css_class = 'oc-topnav-selected'
-
-class TeamMenuItem(ProjectMenuItem):
+class TeamMenuItem(BaseProjectMenuItem):
name = u'Team'
item_url = 'team'
-class ManageTeamMenuItem(ProjectMenuItem):
+class ManageTeamMenuItem(BaseProjectMenuItem):
name = u'Manage Team'
item_url = 'manage-team'
-class ContentsMenuItem(ProjectMenuItem):
+class ContentsMenuItem(BaseProjectMenuItem):
name = u'Contents'
item_url = 'contents'
-class PreferencesMenuItem(ProjectMenuItem):
+class PreferencesMenuItem(BaseProjectMenuItem):
name = u'Preferences'
item_url = 'preferences'
-class JoinMenuItem(BaseMenuItem):
+class JoinMenuItem(BaseProjectMenuItem):
name = u'Join Project'
+ item_url = 'request-membership'
- def update(self):
+ def context_matches(self):
+ if not super(JoinMenuItem, self).context_matches():
+ return False
proj = self._item_providing(IProject)
- if proj is None:
- self.render = lambda *a:''
- return
mstool = getToolByName(proj, 'portal_membership')
if not mstool.isAnonymousUser():
mem = mstool.getAuthenticatedMember()
team = proj.getTeams()[0]
filter_states = tuple(team.getActiveStates()) + ('pending',)
if mem.getId() in team.getMemberIdsByStates(filter_states):
- self.render = lambda *a:''
- return
- self.url = '%s/%s' % (proj.absolute_url(), 'request-membership')
+ return self.no_render()
+ return True
+
+ def is_selected(self):
+ return True
+
+ def set_css_class(self):
if self.request.ACTUAL_URL == self.url:
self.css_class = 'oc-topnav-selected'
else:
self.css_class = 'oc-topnav-join'
# Search menu items
-class PeopleMenuItem(BaseMenuItem):
+class PeopleMenuItem(PortalContextMenuItem):
name = u'People'
+ folder_context = 'people'
- def update(self):
- portal = getToolByName(self.context, 'portal_url').getPortalObject()
- self.url = portal.people.absolute_url()
- if IAmAPeopleFolder.providedBy(self.context):
- self.css_class = 'oc-topnav-selected'
+ def is_selected(self):
+ return IAmAPeopleFolder.providedBy(self.context)
-class ProjectsMenuItem(BaseMenuItem):
+class ProjectsMenuItem(PortalContextMenuItem):
name = u'Projects'
+ folder_context = 'projects'
- def update(self):
- portal = getToolByName(self.context, 'portal_url').getPortalObject()
- self.url = portal.projects.absolute_url()
- if (IAddProject.providedBy(self.context)
- and not self.request.ACTUAL_URL.endswith('/create')):
- self.css_class = 'oc-topnav-selected'
+ def is_selected(self):
+ return (IAddProject.providedBy(self.context)
+ and not self.request.ACTUAL_URL.endswith('/create'))
-class StartProjectMenuItem(BaseMenuItem):
+class StartProjectMenuItem(StartsWithMixin, BaseMenuItem):
name = u'Start A Project'
- def update(self):
+ def context_matches(self):
+ return True
+
+ def get_url(self):
portal = getToolByName(self.context, 'portal_url').getPortalObject()
- self.url = '%s/%s' % (portal.projects.absolute_url(), 'create')
- if self.request.ACTUAL_URL == self.url:
- self.css_class = 'oc-topnav-selected'
+ return '%s/%s' % (portal.projects.absolute_url(), 'create')
-
# Featurelets need to only provide
# name
# supp_must_provide - installed marker interface
-# flet_url - portion of url after project url
-class BaseFeatureletMenuItem(BaseMenuItem):
+# item_url - portion of url after project url
+class BaseFeatureletMenuItem(BaseProjectMenuItem):
"""Base class to allow easy creation of featurelet menu items"""
- supporter = IProject
- supp_must_provide = None
- flet_url = '#'
+ supp_must_provide = Interface
- def update(self):
- proj = self._item_providing(self.supporter)
- if proj is None:
- self.render = lambda *a:''
- return
+ def context_matches(self):
+ if not super(BaseFeatureletMenuItem, self).context_matches():
+ return False
+ proj = self._item_providing(IProject)
if not self.supp_must_provide.providedBy(proj):
- self.render = lambda *a:''
- return
-
- self.url = '%s/%s' % (proj.absolute_url(), self.flet_url)
- if self.request.ACTUAL_URL.startswith(self.url):
- self.css_class = 'oc-topnav-selected'
+ return self.no_render()
+ return True
Modified:
opencore/branches/viewlet_menuitems/opencore/listen/browser/topnav_menuitem.py
===================================================================
---
opencore/branches/viewlet_menuitems/opencore/listen/browser/topnav_menuitem.py
2007-11-23 20:47:52 UTC (rev 11237)
+++
opencore/branches/viewlet_menuitems/opencore/listen/browser/topnav_menuitem.py
2007-11-24 06:21:14 UTC (rev 11238)
@@ -4,4 +4,4 @@
class ListenMenuItem(BaseFeatureletMenuItem):
name = u'Mailing Lists'
supp_must_provide = IListenFeatureletInstalled
- flet_url = 'lists'
+ item_url = 'lists'
Modified:
opencore/branches/viewlet_menuitems/opencore/tasktracker/browser/topnav_menuitem.py
===================================================================
---
opencore/branches/viewlet_menuitems/opencore/tasktracker/browser/topnav_menuitem.py
2007-11-23 20:47:52 UTC (rev 11237)
+++
opencore/branches/viewlet_menuitems/opencore/tasktracker/browser/topnav_menuitem.py
2007-11-24 06:21:14 UTC (rev 11238)
@@ -4,4 +4,4 @@
class TasktrackerMenuItem(BaseFeatureletMenuItem):
name = u'Task tracker'
supp_must_provide = ITaskTrackerFeatureletInstalled
- flet_url = 'tasks'
+ item_url = 'tasks'
Modified:
opencore/branches/viewlet_menuitems/opencore/wordpress/browser/topnav_menuitem.py
===================================================================
---
opencore/branches/viewlet_menuitems/opencore/wordpress/browser/topnav_menuitem.py
2007-11-23 20:47:52 UTC (rev 11237)
+++
opencore/branches/viewlet_menuitems/opencore/wordpress/browser/topnav_menuitem.py
2007-11-24 06:21:14 UTC (rev 11238)
@@ -4,4 +4,4 @@
class WordpressMenuItem(BaseFeatureletMenuItem):
name = u'Blog'
supp_must_provide = IWordPressFeatureletInstalled
- flet_url = 'blog'
+ item_url = 'blog'
--
Archive:
http://www.openplans.org/projects/opencore/lists/openplans-svn/archive/2007/11/1195885288457
To unsubscribe send an email with subject unsubscribe to [EMAIL PROTECTED]
Please contact [EMAIL PROTECTED] for questions.