def testINavigationRootWithRelativeRootSet(self): """test that navigation portlet uses relative root set by user even in INavigationRoot case. """ self.assertFalse(INavigationRoot.providedBy(self.portal.folder1)) # make folder1 as navigation root directlyProvides(self.portal.folder1, INavigationRoot) self.assertTrue(INavigationRoot.providedBy(self.portal.folder1)) # add two nested subfolders in folder1 self.portal.folder1.invokeFactory('Folder', 'folder1_1') self.portal.folder1.folder1_1.invokeFactory('Folder', 'folder1_1_1') # make a navigation portlet with navigation root set assignment = navigation.Assignment(bottomLevel=0, topLevel=0, root='/folder1/folder1_1') portlet = self.renderer(self.portal.folder1.folder1_1, assignment=assignment) # check there is a portlet self.assertTrue(portlet.available) # check that portlet root is actually the one specified root = portlet.getNavRoot() self.assertEqual(root.getId(), 'folder1_1') # check that portlet tree actually includes children tree = portlet.getNavTree() self.assertEqual(len(tree['children']), 1) self.assertEqual(tree['children'][0]['item'].getPath(), '/plone/folder1/folder1_1/folder1_1_1')
def bodyClass(self, template, view): """Returns the CSS class to be used on the body tag. """ body_class = LayoutPolicyOriginal.bodyClass(self, template, view) columns = [] if self.have_portlets('plone.leftcolumn', view): columns.append('-one') if self.have_portlets('plone.rightcolumn', view): columns.append('-two') column_class = columns and ' has-columns%s' % ''.join(columns) or ' has-no-columns' body_class += column_class context = aq_inner(self.context) context_state = getMultiAdapter( (self.context, self.request), name=u'plone_context_state') if context_state.is_default_page(): is_nav_root = INavigationRoot.providedBy(aq_base(aq_parent(context))) else: is_nav_root = INavigationRoot.providedBy(context) if is_nav_root: body_class += ' navigation-root' portal_state = getMultiAdapter( (context, self.request), name=u'plone_portal_state') if portal_state.anonymous(): body_class += ' is-anonymous' # add classes from the registry # we have global classes (redomino.css3theme.classes) # and user defined classes (cookies) registry = getUtility(IRegistry) classes = set(registry.get('redomino.css3theme.classes', [])) userclasses = str2set(self.request.cookies.get('redomino.css3theme.userclasses', None)) useraddableclasses = set(registry.get('redomino.css3theme.useraddableclasses', [])) userclasses = userclasses & useraddableclasses classes = classes | userclasses if classes: body_class += ' %s' % ' '.join(classes) # add contextual classes contextual_classes = context.css3theme_get_contextual_classes() if contextual_classes: body_class += " %s" % contextual_classes return body_class
def is_navigation_root_or_default_page(self): context = aq_inner(self.context) context_state = getMultiAdapter( (context, self.request), name=u'plone_context_state') if context_state.is_default_page(): return INavigationRoot.providedBy(aq_parent(context)) else: return INavigationRoot.providedBy(context)
def publishTraverse(self, request, name): obj = self.default.publishTraverse(request, name) context = self.context if IFrontendLayer.providedBy(request) and not INavigationRoot.providedBy(context): interface.alsoProvides(context, INavigationRoot) elif not IFrontendLayer.providedBy(request) and INavigationRoot.providedBy(context): interface.noLongerProvides(context, INavigationRoot) return obj
def _translations(self, missing): # Figure out the "closest" translation in the parent chain of the # context. We stop at both an INavigationRoot or an ISiteRoot to look # for translations. # Exceptions: 1) If the object does not implement ITranslatable (= not # LP-aware) or # 2) if the object is set to be neutral # then return this object and don't look for a translation. context = aq_inner(self.context) translations = {} chain = aq_chain(context) first_pass = True _checkPermission = getSecurityManager().checkPermission for item in chain: if ISiteRoot.providedBy(item) \ or not ITranslatable.providedBy(item) \ or not item.Language(): # We have a site root, which works as a fallback has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, first_pass, has_view_permission) break translatable = ITranslatable(item, None) if translatable is None: continue item_trans = item.getTranslations(review_state=False) for code, trans in item_trans.items(): code = str(code) if code not in translations: # make a link to a translation only if the user # has view permission has_view_permission = bool(_checkPermission('View', trans)) if (not INavigationRoot.providedBy(item) and not has_view_permission): continue # If we don't yet have a translation for this language # add it and mark it as found translations[code] = (trans, first_pass, has_view_permission) missing = missing - set((code, )) if len(missing) <= 0: # We have translations for all break if INavigationRoot.providedBy(item): # Don't break out of the navigation root jail has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, False, has_view_permission) break first_pass = False # return a dict of language code to tuple. the first tuple element is # the translated object, the second argument indicates wether the # translation is a direct translation of the context or something from # higher up the translation chain return translations
def _translations(self, missing): # Figure out the "closest" translation in the parent chain of the # context. We stop at both an INavigationRoot or an ISiteRoot to look # for translations. We do want to find something that is definitely # in the language the user asked for. context = aq_inner(self.context) translations = {} chain = aq_chain(context) first_pass = True _checkPermission = getSecurityManager().checkPermission for item in chain: if ISiteRoot.providedBy(item): # We have a site root, which works as a fallback has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, first_pass, has_view_permission) break elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue canonical = ITranslationManager(item, None) item_trans = canonical.get_translations() for code, trans in item_trans.items(): code = str(code) if code not in translations: # make a link to a translation only if the user # has view permission has_view_permission = bool(_checkPermission('View', trans)) if (not INavigationRoot.providedBy(item) and not has_view_permission): continue # If we don't yet have a translation for this language # add it and mark it as found translations[code] = (trans, first_pass, has_view_permission) missing = missing - set((code, )) if len(missing) <= 0: # We have translations for all break if INavigationRoot.providedBy(item): # Don't break out of the navigation root jail has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, False, has_view_permission) break first_pass = False # return a dict of language code to tuple. the first tuple element is # the translated object, the second argument indicates wether the # translation is a direct translation of the context or something from # higher up the translation chain return translations
def testINavigationRootAvailability(self): self.failIf(INavigationRoot.providedBy(self.portal.folder1)) self.portal.folder1.invokeFactory('Folder', 'folder1_1') directlyProvides(self.portal.folder1, INavigationRoot) self.failUnless(INavigationRoot.providedBy(self.portal.folder1)) view = self.renderer(self.portal.folder1, assignment=navigation.Assignment(bottomLevel=0, topLevel=1, root=None)) tree = view.getNavTree() root = view.getNavRoot() self.failIf(root is not None and len(tree['children']) > 0)
def testINavigationRootWithRelativeRootSet(self): self.failIf(INavigationRoot.providedBy(self.portal.folder1)) self.portal.folder1.invokeFactory('Folder', 'folder1_1') directlyProvides(self.portal.folder1, INavigationRoot) self.failUnless(INavigationRoot.providedBy(self.portal.folder1)) self.portal.folder1.folder1_1.invokeFactory('Folder', 'folder1_1_1') view = self.renderer(self.portal.folder1.folder1_1, assignment=navigation.Assignment(bottomLevel=0, topLevel=0, root='/folder1/folder1_1')) tree = view.getNavTree() self.failUnless(tree) root = view.getNavRoot() self.assertEqual(root.getId(), 'folder1_1') self.assertEqual(len(tree['children']), 1) self.assertEqual(tree['children'][0]['item'].getPath(), '/plone/folder1/folder1_1/folder1_1_1')
def setUpLanguage(self, code, name): """ Create the language folders on top of the site """ doneSomething = False folderId = "%s" % code if code != 'id' else 'id-id' folder = getattr(self.context, folderId, None) wftool = getToolByName(self.context, 'portal_workflow') if folder is None: self.context.invokeFactory(self.folder_type, folderId) folder = getattr(self.context, folderId) ILanguage(folder).set_language(code) folder.setTitle(name) state = wftool.getInfoFor(folder, 'review_state', None) # This assumes a direct 'publish' transition from the initial state if state != 'published': wftool.doActionFor(folder, 'publish') folder.reindexObject() doneSomething = True LOG.info("Added '%s' folder: %s" % (code, folderId)) self.folders[code] = folder if not INavigationRoot.providedBy(folder): alsoProvides(folder, INavigationRoot) doneSomething = True LOG.info("INavigationRoot setup on folder '%s'" % code) return doneSomething
def setupSharedFolder(self): """ Create the shared neutral language folder """ doneSomething = False folderId = "shared" folder = getattr(self.context, folderId, None) wftool = getToolByName(self.context, 'portal_workflow') if folder is None: self.context.invokeFactory(self.folder_type, folderId) folder = getattr(self.context, folderId) ILanguage(folder).set_language(LANGUAGE_INDEPENDENT) folder.setTitle("Language Shared") state = wftool.getInfoFor(folder, 'review_state', None) # This assumes a direct 'publish' transition from the initial state if state != 'published': wftool.doActionFor(folder, 'publish') folder.reindexObject() doneSomething = True LOG.info("Added LANGUAGE_INDEPENDENT folder: %s" % (folderId)) if not INavigationRoot.providedBy(folder): alsoProvides(folder, INavigationRoot) doneSomething = True LOG.info("INavigationRoot setup on shared folder ") return doneSomething
def get_datacontext(self, obj): if ISectionImage.providedBy(obj): return ISectionImage(obj) if not IOrganisationFolder.providedBy(obj) \ and not INavigationRoot.providedBy(obj): return self.get_datacontext(aq_parent(obj)) return None
def _items(self, **query): adapter = IAdapter(self.context) sort_limit = adapter.get_feed_number(self.interface) if sort_limit: query['sort_limit'] = sort_limit if isinstance(self, BaseNewsEventFeedViewlet): query['sort_limit'] += adapter.get_feed_number(ITopPageMainFeed) base = IBaseAdapter(self.context) res = [] for item in base.get_content_listing(**query): obj = item.getObject() if not isinstance(self, BaseNewsEventFeedViewlet) or ( ISiteRoot.providedBy(self.context) and not ITopPageFeed.providedBy(obj)) or ( not ISiteRoot.providedBy(self.context) and INavigationRoot.providedBy(self.context) and not IMicroSiteFeed.providedBy(obj)): parent = aq_parent(aq_inner(obj)) res.append({ 'title': item.Title(), 'url': item.getURL(), 'parent_title': parent.Title(), 'parent_url': parent.absolute_url(), 'date': self._date(item), 'image': self._image(item), 'description': self._description(item), }) if sort_limit: return res[:sort_limit] return res
def is_subsite(self): context = aq_inner(self.context) while not INavigationRoot.providedBy(context): context = aq_parent(context) if ISubSite.providedBy(context): return True return False
def available(self): context = self.context if INavigationRoot.providedBy(context.__parent__) and IATDocument.providedBy(context): # Product is not installed return True else: return False
def find_banner(self): registry = getUtility(IRegistry) settings = registry.forInterface(IBannerSettingsSchema) types = settings.types context = aq_inner(self.context) # first handle the obj itself if IBanner.providedBy(context): if context.banner_hide: return False banner = self.banner(context) if banner: return banner if context.banner_stop_inheriting: return False # if all the fields are empty and inheriting is not stopped if context.portal_type not in types: return False context = context.__parent__ # we walk up the path for item in context.aq_chain: if IBanner.providedBy(item): # we have a banner. check. if item.banner_stop_inheriting: return False banner = self.banner(item) if banner: return banner if INavigationRoot.providedBy(item): return False if item.portal_type not in types: return False return False
def setupSharedFolder(self): """ Create the shared neutral language folder """ doneSomething = False folderId = SHARED_NAME folder = getattr(self.context, folderId, None) wftool = getToolByName(self.context, 'portal_workflow') if folder is None: # bypass all settings that don't allow creating # content in the Plone root _createObjectByType(self.folder_type, self.context, folderId) #self.context.invokeFactory(self.folder_type, folderId) folder = getattr(self.context, folderId) ILanguage(folder).set_language(LANGUAGE_INDEPENDENT) folder.setTitle("Language Shared") state = wftool.getInfoFor(folder, 'review_state', None) # This assumes a direct 'publish' transition from the initial state available_transitions = [t['id'] for t in wftool.getTransitionsFor(folder)] if state != 'published' and 'publish' in available_transitions: wftool.doActionFor(folder, 'publish') folder.reindexObject() doneSomething = True LOG.info("Added LANGUAGE_INDEPENDENT folder: %s" % (folderId)) if not INavigationRoot.providedBy(folder): alsoProvides(folder, INavigationRoot) doneSomething = True LOG.info("INavigationRoot setup on shared folder ") return doneSomething
def can_translate(context, language): """ Check if required parent translations are in place so that we can translate this item :return: True if the item can be translated """ parent = aq_parent(context) if ISiteRoot.providedBy(parent): return True # Parent is a language base folder at plone site root if INavigationRoot.providedBy(parent): return True if ITranslatable.providedBy(parent): translatable = ITranslatable(parent) else: from logging import getLogger log = getLogger("silvuple.views.can_translate") log.info("Parent is not translatable: %s" % parent.absolute_url()) return False translation = translatable.getTranslation(language) return translation is not None
def index(self): sm = getSecurityManager() context = aq_inner(self.context) container = aq_parent(context) if isDefaultPage(container, context): context = container # avoid redirecting if we are visiting an url different from the url of the context viewname = self.context.getLayout() if self.request.URL != self.context.absolute_url() and self.request.URL != self.context.absolute_url() + '/' + viewname: return '' originalcontext = context while all([not INavigationRoot.providedBy(context), IRedirectToParent.providedBy(context), not sm.checkPermission(ModifyPortalContent, context)]): # contextid = context.id context = aq_parent(context) if context != originalcontext: viewurl = getMultiAdapter((context, self.request), name='plone_context_state').view_url() self.request.RESPONSE.redirect(viewurl + '#content=' + originalcontext.absolute_url()) return ''
def setUpLanguage(self, code, name): """ Create the language folders on top of the site """ doneSomething = False folderId = "%s" % code if code != 'id' else 'id-id' folder = getattr(self.context, folderId, None) wftool = getToolByName(self.context, 'portal_workflow') if folder is None: self.context.invokeFactory(self.folder_type, folderId) folder = getattr(self.context, folderId) ILanguage(folder).set_language(code) folder.setTitle(name) state = wftool.getInfoFor(folder, 'review_state', None) # This assumes a direct 'publish' transition from the initial state # We are going to check if its private and has publish action for the out of the box case # otherwise don't do anything available_transitions = [t['id'] for t in wftool.getTransitionsFor(folder)] if state != 'published' and 'publish' in available_transitions: wftool.doActionFor(folder, 'publish') folder.reindexObject() doneSomething = True LOG.info("Added '%s' folder: %s" % (code, folderId)) self.folders[code] = folder if not INavigationRoot.providedBy(folder): alsoProvides(folder, INavigationRoot) doneSomething = True LOG.info("INavigationRoot setup on folder '%s'" % code) return doneSomething
def on_homepage(self): """Verifiy if we are on the homepage""" context_helper = getMultiAdapter((self.context, self.request), name="plone_context_state") if INavigationRoot.providedBy(context_helper.canonical_object()): return True return False
def index(self): context = aq_inner(self.context) container = aq_parent(context) if isDefaultPage(container, context): context = container originalcontext = context # avoid redirecting if we are visiting an url different from the url of the context viewname = self.context.getLayout() if self.request.URL != self.context.absolute_url() and self.request.URL != self.context.absolute_url() + '/' + viewname: return '' while all([not INavigationRoot.providedBy(context), IRedirectToParent.providedBy(context)]): # contextid = context.id context = aq_parent(context) if context != originalcontext: viewurl = getMultiAdapter((context, self.request), name='plone_context_state').view_url() return u'<a class="redirect-to-parent" href="%s">%s</a>' % (viewurl + '#content=' + originalcontext.absolute_url(),context.Title()) else: return ''
def _findSource(self, fieldname, search_refs=True): """Find a parent item that contains valid information in [fieldname]""" item = self.context source = None while not (source or INavigationRoot.providedBy(item) or IPloneSiteRoot.providedBy(item)): if hasattr(item, 'markedAs') and item.markedAs.lower() == u"dossier": # check whether item has field filled in if item.Schema()[fieldname].get(item): source = item else: if search_refs: # find theme through ref catalog theme = item.reference_catalog(targetUID=item.UID(), relationship='itemsInTheme') # Reference to Dossier found in Theme if theme: # Assume a Dossier is always related to ONE theme source = theme[0].getObject().getSourceObject() if not source: item = item.aq_parent return source
def run(self, resource, adapter, session, *args, **kwds): """ JSON-LD export of latest news within our homepage """ context = self.context if not has_linked_data: return if not INavigationRoot.providedBy(context) and \ not ILinkedDataHomepage.providedBy(context.aq_parent): return fview = context.restrictedTraverse('@@frontpage_highlights') ItemList = session.get_class(surf.ns.SCHEMA['ItemList']) ListElement = session.get_class(surf.ns.SCHEMA['ListItem']) ilist = ItemList("#itemList2") portal_properties = getToolByName(context, 'portal_properties') fp = getattr(portal_properties, 'frontpage_properties') # use news as latest news while keeping it flexible in case we want # other products promoted as latest news latest_category = fp.getProperty('getLatestNewsCategory', 'news') products = fview.getLatest(latest_category) position = 0 for brain in products: url = brain.getURL() position += 1 list_item = ListElement("LatestNewsListItem" + str(position)) list_item.schema_position = position list_item.schema_url = url list_item.update() ilist.schema_itemListElement.append(list_item) ilist.update()
def _check_context(self): """ check if we should show slider in current context """ for obj in self.chain: if INavigationRoot.providedBy(obj): #Plone site return default view default = obj.getDefaultPage() if default: try: obj = obj[default] except KeyError: obj = obj extended = getattr(obj, 'getField', None) if extended: field = extended('show_slider') if field: show = field.getAccessor(obj)() if show == SLIDER_PARENT: #skip context go up continue elif show == SLIDER_NO: return False elif show == SLIDER_YES: return True elif show == SLIDER_MYSELF: return True return False
def update(self): super(LogoViewlet, self).update() portal = self.portal_state.portal() bprops = portal.restrictedTraverse('base_properties', None) if bprops is not None: logoName = bprops.logoName else: logoName = 'logo.jpg' context = aq_inner(self.context) while not INavigationRoot.providedBy(context): context = aq_parent(context) if ISubSite.providedBy(context): logoTitle = context.Title() if context.restrictedTraverse('@@images').scale('image', 'large'): self.logo_tag = context.restrictedTraverse('@@images').scale('image').tag() self.navigation_root_title = context.Title() else: logoTitle = self.portal_state.portal_title() self.logo_tag = portal.restrictedTraverse(logoName).tag(title=logoTitle, alt=logoTitle) self.navigation_root_title = context.Title() else: logoTitle = self.portal_state.portal_title() self.logo_tag = portal.restrictedTraverse(logoName).tag(title=logoTitle, alt=logoTitle) self.navigation_root_title = self.portal_state.navigation_root_title()
def insertOrg(self, **kwa): """ kwa should be a dict with keys matching orgs columns. returns new oid. """ assert(self.db_org_id == 0) assert(INavigationRoot.providedBy(self.context)) assignments = [] for key in kwa.keys(): assert(key.replace('_', '').isalnum()) val = kwa[key] if val is None: val = '' if type(val) == type(u''): val = encodeString(val) assignments.append("""%s=%s""" % (key, self._sql_quote(val))) query = """ INSERT INTO Orgs SET %s """ % (", ".join(assignments)) self.reader.query(query) query = """ select distinct last_insert_id() as liid from Orgs """ self.db_org_id = Results(self.reader.query(query))[0].liid return self.db_org_id
def heading_link_target(self): """ Get the href target where clicking the portlet header will take you. If this is a customized portlet with a custom root item set, we probably want to take the user to the custom root item instead of the sitemap of the navigation root. Plone does not have subsection sitemaps so there is no point of displaying /sitemap links for anything besides nav root. """ if not self.data.root: # No particular root item assigned -> should get link to the # navigation root sitemap of the current context acquisition chain portal_state = getMultiAdapter((self.context, self.request), name="plone_portal_state") return portal_state.navigation_root_url() + "/sitemap" nav_root = self.getNavRoot() # Root content item gone away or similar issue if not nav_root: return None if INavigationRoot.providedBy(nav_root) or ISiteRoot.providedBy(nav_root): # For top level folders go to the sitemap return nav_root.absolute_url() + "/sitemap" else: # Go to the item /view we have chosen as root item return nav_root.absolute_url()
def get_latex_heading(context, layout, toc=None): title = layout.get_converter().convert(context.pretty_title_or_id()) # level: depth of rendering level = -1 max_level = len(HEADING_COMMANDS) - 1 obj = context while obj and not IBook.providedBy(obj) and level != max_level: obj = aq_parent(aq_inner(obj)) level += 1 if INavigationRoot.providedBy(obj): # cancel, use section level = 1 break command = HEADING_COMMANDS[level] hide_from_toc_field = context.Schema().getField('hideFromTOC') hide_from_toc = hide_from_toc_field and hide_from_toc_field.get(context) # generate latex tocmark = '' if toc is None and hide_from_toc is True or toc is False: tocmark = '*' latex = '\\%s%s{%s}\n' % ( command, tocmark, title) return latex
def __call__(self): cfg = authomatic_cfg() if cfg is None: return "Authomatic is not configured" if not ( ISiteRoot.providedBy(self.context) or INavigationRoot.providedBy(self.context) ): # callback url is expected on either navigationroot or site root # so bevor going on redirect root = api.portal.get_navigation_root(self.context) self.request.response.redirect( "{0}/authomatic-handler/{1}".format( root.absolute_url(), getattr(self, 'provider', '') ) ) return "redirecting" if not hasattr(self, 'provider'): return self.template() if self.provider not in cfg: return "Provider not supported" if not self.is_anon: if self.provider in self._provider_names: raise ValueError( 'Provider {0} is already connected to current ' 'user.'.format(self.provider) ) # TODO: some sort of CSRF check might be needed, so that # not an account got connected by CSRF. Research needed. pass auth = Authomatic( cfg, secret=authomatic_settings().secret.encode('utf8') ) result = auth.login( ZopeRequestAdapter(self), self.provider ) if not result: logger.info('return from view') # let authomatic do its work return if result.error: return result.error.message display = cfg[self.provider].get('display', {}) provider_name = display.get('title', self.provider) if not self.is_anon: # now we delegate to PAS plugin to add the identity self._add_identity(result, provider_name) self.request.response.redirect( "{0}".format(self.context.absolute_url()) ) else: # now we delegate to PAS plugin in order to login self._remember_identity(result, provider_name) self.request.response.redirect( "{0}/login_success".format(self.context.absolute_url()) ) return "redirecting"
def test_past_events_url_and_navigation_root(self): # ensure support of INavigationRoot features dosen't break #9246 #9668 # remove default plone content(s) if "events" in self.portal: self.portal._delObject("events") # lets create mynewsite self.portal.invokeFactory("Folder", "mynewsite") directlyProvides(self.portal.mynewsite, INavigationRoot) self.failUnless(INavigationRoot.providedBy(self.portal.mynewsite)) lb = ICalendarLinkbase(self.portal.mynewsite) # mynewsite events: # -- events # ---- aggregator # ------ previous self.portal.mynewsite.invokeFactory("Folder", "events") self.portal.mynewsite.events.invokeFactory("Folder", "aggregator") self.portal.mynewsite.events.aggregator.invokeFactory("Folder", "previous") self.failUnless(lb.past_events_url().endswith("/mynewsite/events/aggregator/previous")) # mynewsite events: # -- events # ---- previous self.portal.mynewsite._delObject("events") self.portal.mynewsite.invokeFactory("Folder", "events") self.portal.mynewsite.events.invokeFactory("Folder", "previous") self.failUnless(lb.past_events_url().endswith("/mynewsite/events/previous")) # no mynewsite events self.portal.mynewsite._delObject("events") self.assertTrue("@@search?advanced_search=True&end.query" in lb.past_events_url())
def get_items_brains(self): context = aq_inner(self.context) if not INavigationRoot.providedBy(context): context = aq_parent(context) path = '/'.join(context.getPhysicalPath()) query = {'portal_type': 'Image', 'Subject': 'Slideshow', 'path': path, 'sort_on': 'effective', 'sort_order': 'reverse'} brains = self.portal_catalog(**query) return brains
def testPortletNotDisplayedOnINavigationRoot(self): """test that navigation portlet does not show on INavigationRoot folder """ self.assertFalse(INavigationRoot.providedBy(self.portal.folder1)) # make folder1 as navigation root directlyProvides(self.portal.folder1, INavigationRoot) self.assertTrue(INavigationRoot.providedBy(self.portal.folder1)) # add nested subfolder in folder1 self.portal.folder1.invokeFactory("Folder", "folder1_1") # make a navigation portlet view = self.renderer(self.portal.folder1, opts(bottomLevel=0, topLevel=1)) tree = view(expand=True) self.assertTrue(tree) # check there is no portlet self.assertFalse(tree["contextnavigation"]["items"])
def get_vocabulary(self): # Look up named vocabulary and check permission. context = self.context factory_name = self.request.get('name', None) field_name = self.request.get('field', None) if not factory_name: raise VocabLookupException('No factory provided.') authorized = None sm = getSecurityManager() if (factory_name not in PERMISSIONS or not INavigationRoot.providedBy(context)): # Check field specific permission if field_name: permission_checker = queryAdapter(context, IFieldPermissionChecker) if permission_checker is not None: authorized = permission_checker.validate( field_name, factory_name) elif sm.checkPermission( PERMISSIONS.get(factory_name, DEFAULT_PERMISSION), context): # If no checker, fall back to checking the global registry authorized = True if not authorized: raise VocabLookupException('Vocabulary lookup not allowed') # Short circuit if we are on the site root and permission is # in global registry elif not sm.checkPermission( PERMISSIONS.get(factory_name, DEFAULT_PERMISSION), context): raise VocabLookupException('Vocabulary lookup not allowed') factory = queryUtility(IVocabularyFactory, factory_name) if not factory: raise VocabLookupException('No factory with name "%s" exists.' % factory_name) # This part is for backwards-compatibility with the first # generation of vocabularies created for plone.app.widgets, # which take the (unparsed) query as a parameter of the vocab # factory rather than as a separate search method. if isinstance(factory, FunctionType): factory_spec = inspect.getargspec(factory) else: factory_spec = inspect.getargspec(factory.__call__) query = _parseJSON(self.request.get('query', '')) if query and 'query' in factory_spec.args: vocabulary = factory(context, query=query) else: # This is what is reached for non-legacy vocabularies. vocabulary = factory(context) return vocabulary
def __call__(self): context = aq_inner(self.context) self.request.response.setHeader('Content-Type', 'text/css;charset=utf-8') while not INavigationRoot.providedBy(context): context = aq_parent(context) if ISubSite.providedBy(context): css = context.specific_css return css else: return ''
def testPortletNotDisplayedOnINavigationRoot(self): """test that navigation portlet does not show on INavigationRoot folder """ self.assertFalse(INavigationRoot.providedBy(self.portal.folder1)) # make folder1 as navigation root directlyProvides(self.portal.folder1, INavigationRoot) self.assertTrue(INavigationRoot.providedBy(self.portal.folder1)) # add nested subfolder in folder1 self.portal.folder1.invokeFactory('Folder', 'folder1_1') # make a navigation portlet assignment = navigation.Assignment(bottomLevel=0, topLevel=1, root_uid=None) portlet = self.renderer(self.portal.folder1, assignment=assignment) # check there is no portlet self.assertFalse(portlet.available)
def getApplicationRoot(obj): """ Application Root """ portal_url = getToolByName(obj, 'portal_url') portal = portal_url.getPortalObject() while not INavigationRoot.providedBy(obj) and ( aq_base(obj) is not aq_base(portal)): obj = utils.parent(obj) return obj
def get_url_to_dashboard(): """URL to dashboard depends on i18n settings in the site """ site = api.portal.get() portal_state = getMultiAdapter((site, site.REQUEST), name=u'plone_portal_state') current_language = portal_state.language() lang_root_folder = getattr(site, current_language, None) if lang_root_folder and INavigationRoot.providedBy(lang_root_folder): return '{0}/@@optout-dashboard'.format(lang_root_folder.absolute_url()) return '{0}/@@optout-dashboard'.format(site.absolute_url())
def get_comments_context(context, request): context_uuid = IUUID(context, None) uid = request.get("uid", None) if IPloneSiteRoot.providedBy(context): if uid is None: raise ValueError() if INavigationRoot.providedBy(context): if uid is not None and uid != str(context_uuid): context = uuidToObject(uid) if not context: raise ValueError() return context
def get_url_to_path(rel_path): """URL to dashboard depends on i18n settings in the site """ site = api.portal.get() portal_state = getMultiAdapter((site, site.REQUEST), name=u"plone_portal_state") current_language = portal_state.language() if rel_path and not rel_path.startswith('/'): relpath = '/' + rel_path lang_root_folder = getattr(site, current_language, None) if lang_root_folder and INavigationRoot.providedBy(lang_root_folder): return '{0}{1}'.format(lang_root_folder.absolute_url(), rel_path) return '{0}{1}'.format(site.absolute_url(), rel_path)
def available(self): if INavigationRoot.providedBy(self.context): return False lt = getToolByName(self.context, 'portal_languages', None) if lt is None: return False supported = lt.listSupportedLanguages() if len(supported) < 2: return False return True
def is_front_page(self): """ Check if the viewlet is on a front page. Handle canonical paths correctly. based on docs: http://docs.plone.org/develop/plone/serving/traversing.html#checking-if-an-item-is-the-site-front-page """ # Get path with "Default content item" wrapping applied context_helper = getMultiAdapter((self.context, self.request), name="plone_context_state") canonical = context_helper.canonical_object() path = canonical.absolute_url_path() return INavigationRoot.providedBy(canonical)
def __call__(self): factories_menu = getUtility(IBrowserMenu, name='plone_contentmenu_factory', context=self.context).getMenuItems( self.context, self.request) factories_menu = [ m for m in factories_menu if m.get('title') != 'folder_add_settings' ] context = aq_inner(self.context) crumbs = [] while not INavigationRoot.providedBy(context): crumbs.append({ 'id': context.getId(), 'title': utils.pretty_title_or_id(context, context) }) context = utils.parent(context) catalog = getToolByName(self.context, 'portal_catalog') try: brains = catalog(UID=IUUID(self.context)) except TypeError: brains = [] item = None if len(brains) > 0: obj = brains[0] # context here should be site root base_path = '/'.join(context.getPhysicalPath()) item = {} for attr in self.attributes: key = attr if key == 'path': attr = 'getPath' val = getattr(obj, attr, None) if callable(val): if attr in _safe_callable_metadata: val = val() else: continue if key == 'path': val = val[len(base_path):] item[key] = val return json_dumps({ 'addButtons': factories_menu, 'defaultPage': self.context.getDefaultPage(), 'breadcrumbs': [c for c in reversed(crumbs)], 'object': item })
def uninstall(portal, reinstall=False): if not reinstall: if 'intranet' in portal: intranet = portal['intranet'] # do not leave broken marker interfaces behind if INavigationRoot.providedBy(intranet): noLongerProvides(intranet, INavigationRoot) if IMicroblogContext.providedBy(intranet): noLongerProvides(intranet, IMicroblogContext) profile = 'profile-%s:uninstall' % PROJECTNAME setup_tool = api.portal.get_tool(name='portal_setup') setup_tool.runAllImportStepsFromProfile(profile) return 'Ran all uninstall steps.'
def is_subsection(self, context, view): # if isDefaultPage(context): # if ISectionIntro.providedBy(context) or ISectionIntro.providedBy(view): return False while not INavigationRoot.providedBy(context): context = aq_parent(context) if ISectionIntro.providedBy(context): return True default_page = getDefaultPage(context, self.request) if default_page and ISectionIntro.providedBy( getattr(context, default_page)): return True return False
def jsonByType(self, rooted, document_base_url, searchtext): """ Returns the actual listing """ catalog_results = [] results = {} obj = self.obj portal_catalog = getToolByName(obj, 'portal_catalog') normalizer = getUtility(IIDNormalizer) if 'filter_portal_types' in self.request.keys(): self.filter_portal_types = self.request['filter_portal_types'] else: self.filter_portal_types = [i[0] for i in self._getCurrentValues()] if INavigationRoot.providedBy(obj) or (rooted == "True" and document_base_url[:-1] == obj.absolute_url()): results['parent_url'] = '' else: results['parent_url'] = aq_parent(obj).absolute_url() if rooted == "True": results['path'] = self.getBreadcrumbs(results['parent_url']) else: # get all items from siteroot to context (title and url) results['path'] = self.getBreadcrumbs() # get all portal types and get information from brains path = '/'.join(obj.getPhysicalPath()) catalog_query = {'sort_on': 'getObjPositionInParent'} catalog_query['portal_type'] = self.filter_portal_types catalog_query['path'] = {'query': path, 'depth': 1} if searchtext: catalog_query = {'SearchableText': '{0}*'.format(searchtext)} for brain in portal_catalog(**catalog_query): catalog_results.append({ 'id': brain.getId, 'uid': brain.UID or None, # Maybe Missing.Value 'url': brain.getURL(), 'portal_type': brain.portal_type, 'normalized_type': normalizer.normalize(brain.portal_type), 'classicon': 'contenttype-{0}'.format(normalizer.normalize(brain.portal_type)), 'r_state': 'state-{0}'.format(normalizer.normalize(brain.review_state or '')), 'title': brain.Title == "" and brain.id or brain.Title, 'icon': self.getIcon(brain).html_tag() or '', 'is_folderish': brain.is_folderish}) # add catalog_ressults results['items'] = catalog_results # return results in JSON format return json.dumps(results)
def tilePageDepth(self): context = aq_inner(self.context) iter = context.aq_parent depth = 0 while iter is not None: if INavigationRoot.providedBy(iter): break if ITilePage.providedBy(iter): depth = depth+1 if not hasattr(iter, "aq_parent"): raise RuntimeError("Parent traversing interrupted by object: " + str(iter)) iter = iter.aq_parent return depth
def parentColor(self): context = aq_inner(self.context) iter = context.aq_parent color = None while iter is not None: if ITilePage.providedBy(iter) and iter.color != None: color = iter.color break if INavigationRoot.providedBy(iter): break if not hasattr(iter, "aq_parent"): raise RuntimeError("Parent traversing interrupted by object: " + str(iter)) iter = iter.aq_parent return color
def my_projects(self): """ get projects current user can see """ if not INavigationRoot.providedBy(self.context): return [] pc = self.tools['portal_catalog'] query = { 'portal_type': 'Project', 'sort_on': 'modified', 'sort_order': 'descending', } brains = pc.searchResults(query) results = [] for brain in brains[:10]: results.append(self._brain_to_cacheable_value(brain)) return results
def _get_supplier(self, context): """If available, get supplier name and email address """ supplier = None while not INavigationRoot.providedBy(context): field = context.getField('supplier') if field is not None: supplier = field.get(context) if supplier: break context = aq_parent(aq_inner(context)) return supplier
def add_url(self): initial_path = self.initial_path if initial_path is None: initial_path = '' else: if initial_path.startswith('/'): initial_path = initial_path[1:] ctx = api.portal.get_navigation_root(self.context) if not INavigationRoot.providedBy(ctx): ctx = api.portal.get() base = ctx.absolute_url() initial_path = '/'.join([base, initial_path]) return u'{0}++add++{1}'.format( initial_path, self.content_type, )
def findBannerImageFor(self, folder): """Find the banner image to be displayed in a folder""" # First see if the banner is defined by the folder if IBannerImage.providedBy(folder): banner = IBannerImage(folder) if banner.banner_image: logger.info("banner_image defined by folder %s" % folder) self.banners = [banner] self.available = True return # Next check for (possibly multiple) banner(s) in the folder # and return them all path = folder.getPhysicalPath() path = "/".join(path) catalog = getToolByName(self.context, 'portal_catalog') brains = catalog(path={"query": path, "depth": 1}, object_provides=IBannerSlide.__identifier__, review_state="published", sort_on="getObjPositionInParent") if brains: self.banners = [] for brain in brains: obj = brain.getObject() if obj.banner_image: self.banners.append(obj) logger.info("Found the banners %s inside folder %s" % (self.banners, folder)) if self.banners: self.available = True return # Lastly check the parent (unless this is the navigation root) if not INavigationRoot.providedBy(folder): #parent = folder.aq_parent parent = folder.aq_parent logger.info("check parent - findBannerImageFor(parent) %s " % parent ) self.findBannerImageFor(parent) else: # Otherwise - we searched all the way to the nav root & found nothing logger.info("At root - found nothing") self.available = False
def __call__(self): cfg = authomatic_cfg() if cfg is None: return "Authomatic is not configured" if not (ISiteRoot.providedBy(self.context) or INavigationRoot.providedBy(self.context)): # callback url is expected on either navigationroot or site root # so bevor going on redirect root = api.portal.get_navigation_root(self.context) self.request.response.redirect("{0}/authomatic-handler/{1}".format( root.absolute_url(), getattr(self, 'provider', ''))) return "redirecting" if not hasattr(self, 'provider'): return self.template() if self.provider not in cfg: return "Provider not supported" if not self.is_anon: if self.provider in self._provider_names: raise ValueError( 'Provider {0} is already connected to current ' 'user.'.format(self.provider)) # TODO: some sort of CSRF check might be needed, so that # not an account got connected by CSRF. Research needed. pass auth = Authomatic(cfg, secret=authomatic_settings().secret.encode('utf8')) result = auth.login(ZopeRequestAdapter(self), self.provider) if not result: logger.info('return from view') # let authomatic do its work return if result.error: return result.error.message display = cfg[self.provider].get('display', {}) provider_name = display.get('title', self.provider) if not self.is_anon: # now we delegate to PAS plugin to add the identity self._add_identity(result, provider_name) self.request.response.redirect("{0}".format( self.context.absolute_url())) else: # now we delegate to PAS plugin in order to login self._remember_identity(result, provider_name) self.request.response.redirect("{0}/login_success".format( self.context.absolute_url())) return "redirecting"
def find_banner(self): # noqa: C901 types = api.portal.get_registry_record( 'collective.behavior.banner.browser.controlpanel.IBannerSettingsSchema.types' ) # noqa: E501 context = aq_inner(self.context) # first handle the obj itself if IBanner.providedBy(context): if context.banner_hide: return False banner = self.banner(context) config_keys = [key for key in banner.keys() if key != 'banner_obj'] if config_keys: return banner if context.banner_stop_inheriting: return False # if all the fields are empty and inheriting is not stopped if context.portal_type not in types: return False context = context.__parent__ # we walk up the path for item in context.aq_chain: if IBanner.providedBy(item): # we have a banner. check. if item.banner_stop_inheriting: return False banner = self.banner(item) config_keys = [ key for key in banner.keys() if key != 'banner_obj' ] if config_keys: return banner if INavigationRoot.providedBy(item): default_page = get_default_page(item) if default_page: default_page = item[default_page] if IBanner.providedBy(default_page): banner = self.banner(default_page) if banner: return banner return False if item.portal_type not in types: return False return False
def __call__(self): """ Explore the site's content and place it on the right RLF """ context = aq_inner(self.context) pl = getToolByName(context, "portal_languages") pu = getToolByName(context, "portal_url") portal = pu.getPortalObject() supported_langs = pl.getSupportedLanguages() output = [] for path, obj in findObjects(portal): try: lang_adptr = ILanguage(obj) except: info_str = "Found object %s with no language support." % (path) logger.info(info_str) output.append(info_str) continue obj_lang = lang_adptr.get_language() if obj_lang not in supported_langs: info_str = "Found object %s with unsupported language %s." % ( path, obj_lang) logger.info(info_str) output.append(info_str) else: target_folder = ITranslationLocator(obj)(obj_lang) parent = aq_parent(obj) if IPloneSiteRoot.providedBy(parent) \ and ITranslatable.providedBy(obj) \ and not INavigationRoot.providedBy(obj): target_folder = getattr(portal, obj_lang, None) if target_folder != parent: cb_copy_data = parent.manage_cutObjects(obj.getId()) list_ids = target_folder.manage_pasteObjects(cb_copy_data) new_id = list_ids[0]['new_id'] new_object = target_folder[new_id] info_str = "Moved object %s to lang folder %s" % ( parent.getPhysicalPath(), obj_lang) logger.info(info_str) output.append(new_object.id) return output
def siblings(self): context = aq_inner(self.context) parent = context.aq_parent if INavigationRoot.providedBy(parent): return [] catalog = api.portal.get_tool(name='portal_catalog') siblings = catalog( object_provides=[ITilePage.__identifier__], path={ 'query': '/'.join(parent.getPhysicalPath()), 'depth': 1 }, sort_on='getObjPositionInParent' ) return siblings
def getPortletContainerPath(self): context = aq_inner(self.context) container_url = context.absolute_url() # Portlet container will be in the context, # Except in the portal root, when we look for an alternative if INavigationRoot.providedBy(self.context): pc = getToolByName(context, 'portal_catalog') # Add the use case of mixin types of IHomepages. The main ones of a # non PAM-enabled site and the possible inner ones. result = pc.searchResults(object_provides=IHomePage.__identifier__, portal_type='Document', Language=pref_lang()) if result: # Return the object without forcing a getObject() container_url = result[0].getURL() return container_url
def getTranslations(self): context = self.context.aq_inner parent = context.__parent__ if isDefaultPage(parent, context): if not INavigationRoot.providedBy(parent): context = parent lang_items = ITranslationGraph(context).getNearestTranslations() translations = {} for lang_id, item, distance in lang_items: if item is None: continue parent = item.__parent__ if isDefaultPage(parent, item): item = parent translations[lang_id] = item return translations
def breadcrumbs(self): path = self.request.get('path') portal = self.navigation_root if path is None: context = portal else: context = portal.restrictedTraverse(unquote(path)) crumbs = [] context = aq_inner(context) while context is not None: if not IHideFromBreadcrumbs.providedBy(context): crumbs.append({ 'path': "/".join(context.getPhysicalPath()), 'url': context.absolute_url(), 'title': context.title_or_id() }) if INavigationRoot.providedBy(context): break context = utils.parent(context) crumbs.reverse() return crumbs
def trackers(self): """ get global generic trackers from `trackers` folder, if any. """ if not INavigationRoot.providedBy(self.context): return [] if not base_hasattr(self.context, self.trackers_folder_id): return [] trackers_folder = getattr(self.context, self.trackers_folder_id) pc = self.tools['portal_catalog'] query = { 'portal_type': 'PoiTracker', 'sort_on': 'modified', 'sort_order': 'descending', 'path': '/'.join(trackers_folder.getPhysicalPath()) } brains = pc.searchResults(query) results = [] for brain in brains[:10]: results.append(self._brain_to_cacheable_value(brain)) return results
def _relativePath(context, row): # Walk through the tree obj = context for x in [r for r in row.values.split('/') if r]: if x == "..": if INavigationRoot.providedBy(obj): break parent = aq_parent(obj) if parent: obj = parent else: if base_hasattr(obj, x): child = getattr(obj, x, None) if child and base_hasattr(child, "getPhysicalPath"): obj = child row = Row(index=row.index, operator=row.operator, values='/'.join(obj.getPhysicalPath())) return _path(context, row)