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

Last change on this file since 2267 was 2267, checked in by chervol, 14 years ago

added simple current item/parent implementation

  • Property svn:eol-style set to native
File size: 7.3 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                url = self.context.absolute_url()       
96                if url.startswith(info['url']):
97                    currentParent = True
98                if url == info['url']:
99                    currentItem = True
100            # make up final tab dictionary
101            tab = {'Title': info['title'],
102                   'Description': info['description'],
103                   'getURL': info['url'],
104                   'show_children': len(children) > 0,
105                   'children': children,
106                   'currentItem': currentItem,
107                   'currentParent': currentParent,
108                   'item_icon': {'html_tag': icon},
109                   'normalized_review_state': 'visible'}
110            tabs.append(tab)
111        return tabs
112
113    def _actionInfos(self, category, object, check_visibility=1,
114                     check_permissions=1, check_condition=1, max=-1):
115        """Return action infos for a given category"""
116        context = aq_inner(self.context)
117        ec = self.tool._getExprContext(object)
118        actions = [ActionInfo(action, ec) for action in category.objectValues()
119                    if IAction.providedBy(action)]
120
121        action_infos = []
122        for ai in actions:
123            if check_visibility and not ai['visible']:
124                continue
125            if check_permissions and not ai['allowed']:
126                continue
127            if check_condition and not ai['available']:
128                continue
129            action_infos.append(ai)
130            if max + 1 and len(action_infos) >= max:
131                break
132        return action_infos
133
134    def _content_tabs(self):
135        """Return tree of tabs based on content structure"""
136        context = aq_inner(self.context)
137
138        queryBuilder = DropDownMenuQueryBuilder(context)
139        strategy = getMultiAdapter((context, None), INavtreeStrategy)
140        # XXX This works around a bug in plone.app.portlets which was
141        # fixed in http://dev.plone.org/svn/plone/changeset/18836
142        # When a release with that fix is made this workaround can be
143        # removed and the plone.app.portlets requirement in setup.py
144        # be updated.
145        if strategy.rootPath is not None and strategy.rootPath.endswith("/"):
146            strategy.rootPath = strategy.rootPath[:-1]
147
148        return buildFolderTree(context, obj=context, query=queryBuilder(),
149                               strategy=strategy).get('children', [])
150
151    @memoize
152    def _settings(self):
153        """Fetch dropdown menu settings registry"""
154        return getDropDownMenuSettings(self.context)
155
156    def createMenu(self):
157        return self.recurse(children=self.portal_tabs, level=1)
158
159    def _old_update(self):
160        context_state = getMultiAdapter((self.context, self.request),
161                                        name=u'plone_context_state')
162        actions = context_state.actions()
163        portal_tabs_view = getMultiAdapter((self.context, self.request),
164                                           name='portal_tabs_view')
165        self.portal_tabs = portal_tabs_view.topLevelTabs(actions=actions)
166
167        selectedTabs = self.context.restrictedTraverse('selectedTabs')
168        self.selected_tabs = selectedTabs('index_html',
169                                          self.context,
170                                          self.portal_tabs)
171        self.selected_portal_tab = self.selected_tabs['portal']
Note: See TracBrowser for help on using the repository browser.