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

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

fixed bug with default pages.

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