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

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

set category sufix as optional setting, fix actions tab level functionality

  • 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
16from plone.registry.interfaces import IRegistry
17
18from quintagroup.dropdownmenu.interfaces import IDropDownMenuSettings
19from quintagroup.dropdownmenu.browser.menu import DropDownMenuQueryBuilder
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        # TODO: make non-folderish work as proxy
133        context = aq_inner(self.context)
134
135        queryBuilder = DropDownMenuQueryBuilder(context)
136        strategy = getMultiAdapter((context, None), INavtreeStrategy)
137        # XXX This works around a bug in plone.app.portlets which was
138        # fixed in http://dev.plone.org/svn/plone/changeset/18836
139        # When a release with that fix is made this workaround can be
140        # removed and the plone.app.portlets requirement in setup.py
141        # be updated.
142        if strategy.rootPath is not None and strategy.rootPath.endswith("/"):
143            strategy.rootPath = strategy.rootPath[:-1]
144
145        return buildFolderTree(context, obj=context, query=queryBuilder(),
146                               strategy=strategy).get('children', [])
147
148    @memoize
149    def _settings(self):
150        """Fetch dropdown menu settings registry"""
151        registry = getUtility(IRegistry)
152        return registry.forInterface(IDropDownMenuSettings)
153
154    def createMenu(self):
155        return self.recurse(children=self.portal_tabs, level=1)
156
157    def _old_update(self):
158        context_state = getMultiAdapter((self.context, self.request),
159                                        name=u'plone_context_state')
160        actions = context_state.actions()
161        portal_tabs_view = getMultiAdapter((self.context, self.request),
162                                           name='portal_tabs_view')
163        self.portal_tabs = portal_tabs_view.topLevelTabs(actions=actions)
164
165        selectedTabs = self.context.restrictedTraverse('selectedTabs')
166        self.selected_tabs = selectedTabs('index_html',
167                                          self.context,
168                                          self.portal_tabs)
169        self.selected_portal_tab = self.selected_tabs['portal']
Note: See TracBrowser for help on using the repository browser.