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

Last change on this file since 2700 was 2700, checked in by fenix, 14 years ago

removed home tab from potential parents of current item, this was done because home tab would be parent for all content tabs.

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