source: products/quintagroup.dropdownmenu/trunk/quintagroup/dropdownmenu/browser/viewlets.py @ 1319

Last change on this file since 1319 was 1319, checked in by piv, 15 years ago

override plone.registry forInterface proxy to look for properties from portal_properties tool

  • Property svn:eol-style set to native
File size: 7.1 KB
Line 
1# -*- coding: utf-8 -*-
2from Acquisition import aq_inner
3
4from zope.component import getMultiAdapter, getUtility
5
6from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
7from Products.CMFCore.utils import getToolByName
8from Products.CMFCore.interfaces import IAction, IActionCategory
9from Products.CMFCore.ActionInformation import ActionInfo
10
11from plone.memoize.instance import memoize
12from plone.app.layout.viewlets import common
13from plone.app.layout.navigation.navtree import buildFolderTree
14from plone.app.layout.navigation.interfaces import INavtreeStrategy
15from plone.app.layout.navigation.interfaces import INavigationQueryBuilder
16
17from quintagroup.dropdownmenu.interfaces import IDropDownMenuSettings
18from quintagroup.dropdownmenu.browser.menu import DropDownMenuQueryBuilder
19from quintagroup.dropdownmenu.util import getDropDownMenuSettings
20
21
22class GlobalSectionsViewlet(common.GlobalSectionsViewlet):
23    index = ViewPageTemplateFile('templates/sections.pt')
24    recurse = ViewPageTemplateFile('templates/sections_recurse.pt')
25
26    def update(self):
27        # we may need some previously defined variables
28        #super(GlobalSectionsViewlet, self).update()
29
30        # prepare to gather portal tabs
31        tabs = []
32        context = aq_inner(self.context)
33        self.conf = conf = self._settings()
34        self.tool = getToolByName(context, 'portal_actions')
35
36        # fetch actions-based tabs?
37        if conf.show_actions_tabs:
38            tabs.extend(self._actions_tabs())
39
40        # fetch content structure-based tabs?
41        if conf.show_content_tabs:
42            # put content-based actions before content structure-based ones?
43            if conf.content_before_actions_tabs:
44                tabs = self._content_tabs() + tabs
45            else:
46                tabs.extend(self._content_tabs())
47
48        # assign collected tabs eventually
49        self.portal_tabs = tabs
50
51    def _actions_tabs(self):
52        """Return tree of tabs based on portal_actions tool configuration"""
53        conf = self.conf
54        tool = self.tool
55        context = aq_inner(self.context)
56
57        # check if we have required root actions category inside tool
58        if conf.actions_category not in tool.objectIds():
59            return []
60
61        #category_ids = category.objectIds()
62        #selectedTabs = self.context.restrictedTraverse('selectedTabs')
63        ## try to find out selected subtab
64        #if tab['id'] == self.selected_portal_tab:
65            #selection = selectedTabs(None, None, tab['subtabs'])
66            #self.selected_sub_tab = selection['portal']
67        return self._subactions(tool._getOb(conf.actions_category), context)
68
69    def _subactions(self, category, object, level=0):
70        tabs = []
71        for info in self._actionInfos(category, object):
72            # prepare data for action
73            # TODO: implement current element functionality, maybe should be
74            #       done on a template level because of separate content and
75            #       actions tabs are rendered separately
76            currentItem = False
77            currentParent = False
78            icon = info['icon'] and '<img src="%s" />' % info['icon'] or ''
79
80            # look up children for a given action
81            children = []
82            bottomLevel = self.conf.actions_tabs_level
83            if bottomLevel < 1 or level < bottomLevel:
84                # try to find out appropriate subcategory
85                subcat_id = info['id']
86                if self.conf.nested_category_sufix is not None:
87                    subcat_id += self.conf.nested_category_sufix
88                if self.conf.nested_category_prefix is not None:
89                    subcat_id = self.conf.nested_category_prefix + subcat_id
90                if subcat_id != info['id'] and \
91                   subcat_id in category.objectIds():
92                    subcat = category._getOb(subcat_id)
93                    if IActionCategory.providedBy(subcat):
94                        children = self._subactions(subcat, object, level+1)
95
96            # make up final tab dictionary
97            tab = {'Title': info['title'],
98                   'Description': info['description'],
99                   'getURL': info['url'],
100                   'show_children': len(children) > 0,
101                   'children': children,
102                   'currentItem': currentItem,
103                   'currentParent': currentParent,
104                   'item_icon': {'html_tag': icon},
105                   'normalized_review_state': 'visible'}
106            tabs.append(tab)
107        return tabs
108
109    def _actionInfos(self, category, object, check_visibility=1,
110                     check_permissions=1, check_condition=1, max=-1):
111        """Return action infos for a given category"""
112        context = aq_inner(self.context)
113        ec = self.tool._getExprContext(object)
114        actions = [ActionInfo(action, ec) for action in category.objectValues()
115                    if IAction.providedBy(action)]
116
117        action_infos = []
118        for ai in actions:
119            if check_visibility and not ai['visible']:
120                continue
121            if check_permissions and not ai['allowed']:
122                continue
123            if check_condition and not ai['available']:
124                continue
125            action_infos.append(ai)
126            if max + 1 and len(action_infos) >= max:
127                break
128        return action_infos
129
130    def _content_tabs(self):
131        """Return tree of tabs based on content structure"""
132        context = aq_inner(self.context)
133
134        queryBuilder = DropDownMenuQueryBuilder(context)
135        strategy = getMultiAdapter((context, None), INavtreeStrategy)
136        # XXX This works around a bug in plone.app.portlets which was
137        # fixed in http://dev.plone.org/svn/plone/changeset/18836
138        # When a release with that fix is made this workaround can be
139        # removed and the plone.app.portlets requirement in setup.py
140        # be updated.
141        if strategy.rootPath is not None and strategy.rootPath.endswith("/"):
142            strategy.rootPath = strategy.rootPath[:-1]
143
144        return buildFolderTree(context, obj=context, query=queryBuilder(),
145                               strategy=strategy).get('children', [])
146
147    @memoize
148    def _settings(self):
149        """Fetch dropdown menu settings registry"""
150        return getDropDownMenuSettings(self.context)
151
152    def createMenu(self):
153        return self.recurse(children=self.portal_tabs, level=1)
154
155    def _old_update(self):
156        context_state = getMultiAdapter((self.context, self.request),
157                                        name=u'plone_context_state')
158        actions = context_state.actions()
159        portal_tabs_view = getMultiAdapter((self.context, self.request),
160                                           name='portal_tabs_view')
161        self.portal_tabs = portal_tabs_view.topLevelTabs(actions=actions)
162
163        selectedTabs = self.context.restrictedTraverse('selectedTabs')
164        self.selected_tabs = selectedTabs('index_html',
165                                          self.context,
166                                          self.portal_tabs)
167        self.selected_portal_tab = self.selected_tabs['portal']
Note: See TracBrowser for help on using the repository browser.