From 814d98c1eabcba691bb242d535df41c21f48eae4 Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Thu, 22 Jan 2015 16:20:35 +0100 Subject: [PATCH] support for site_logo from registry - Added support for site logos stored in the portal registry via the site control panel for the logo viewlet with a fallback to the ``OFS.Image`` based ``logo.png`` file. Removed support of long-gone ``base_properties.props`` defined logo names. --- CHANGES.rst | 6 +++ plone/app/layout/viewlets/common.py | 40 +++++++++++++----- .../app/layout/viewlets/tests/test_common.py | 41 ++++++++++++++----- 3 files changed, 67 insertions(+), 20 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0c09b37d..ee37d4c4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,12 @@ Changelog 2.5.4 (unreleased) ------------------ +- Added support for site logos stored in the portal registry via the site + control panel for the logo viewlet with a fallback to the ``OFS.Image`` + based ``logo.png`` file. Removed support of long-gone + ``base_properties.props`` defined logo names. + [thet] + - Updated markup for dashboard. [davisagli] diff --git a/plone/app/layout/viewlets/common.py b/plone/app/layout/viewlets/common.py index 0aeec858..0f653050 100644 --- a/plone/app/layout/viewlets/common.py +++ b/plone/app/layout/viewlets/common.py @@ -24,6 +24,8 @@ from plone.app.layout.globals.interfaces import IViewView from plone.protect.utils import addTokenToUrl +from plone.formwidget.namedfile.converter import b64decode_file +from plone.namedfile.file import NamedImage class ViewletBase(BrowserView): @@ -191,18 +193,36 @@ class LogoViewlet(ViewletBase): 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.png' - - logoTitle = self.portal_state.portal_title() - self.logo_tag = portal.restrictedTraverse( - logoName).tag(title=logoTitle, alt=logoTitle) + # TODO: should this be changed to settings.site_title? self.navigation_root_title = self.portal_state.navigation_root_title() + registry = getUtility(IRegistry) + settings = registry.forInterface(ISiteSchema, prefix="plone") + logo_title = settings.site_title + + if getattr(settings, 'site_logo', False): + filename, data = b64decode_file(settings.site_logo) + data = NamedImage(data=data, filename=filename) + width, height = data.getImageSize() + img_src = '{}/@@site-logo/{}'.format( + self.navigation_root_url, filename) + self.logo_tag = u''.format( + img_src=img_src, + width=width, + height=height, + logo_title=logo_title + ) + else: + portal = self.portal_state.navigation_root() + # Support for OFS.Image/skin layer based logos + logo_name = 'logo.png' + self.logo_tag = portal.restrictedTraverse( + logo_name).tag(title=logo_title, alt=logo_title) + # TODO: deprecate the skin layer based logo above and use one + # defined as browser or plone resource. + class GlobalSectionsViewlet(ViewletBase): index = ViewPageTemplateFile('sections.pt') diff --git a/plone/app/layout/viewlets/tests/test_common.py b/plone/app/layout/viewlets/tests/test_common.py index cbe2650f..b7abe326 100644 --- a/plone/app/layout/viewlets/tests/test_common.py +++ b/plone/app/layout/viewlets/tests/test_common.py @@ -1,17 +1,24 @@ +# -*- coding: utf-8 -*- +from Products.CMFPlone.interfaces import INonStructuralFolder +from Products.CMFPlone.interfaces import ISiteSchema +from plone.app.layout.navigation.interfaces import INavigationRoot +from plone.app.layout.viewlets.common import ContentViewsViewlet +from plone.app.layout.viewlets.common import LogoViewlet +from plone.app.layout.viewlets.common import TitleViewlet +from plone.app.layout.viewlets.common import ViewletBase +from plone.app.layout.viewlets.tests.base import ViewletsTestCase +from plone.protect import authenticator as auth +from plone.registry.interfaces import IRegistry +from zope.component import getUtility from zope.interface import alsoProvides from zope.interface import directlyProvides from zope.interface import noLongerProvides -from Products.CMFPlone.interfaces import INonStructuralFolder -from plone.app.layout.viewlets.tests.base import ViewletsTestCase -from plone.app.layout.viewlets.common import ( - ViewletBase, LogoViewlet, TitleViewlet) - -from plone.app.layout.viewlets.common import ContentViewsViewlet -from plone.app.layout.navigation.interfaces import INavigationRoot - -from plone.protect import authenticator as auth +# Red pixel with filename pixel.png +SITE_LOGO_BASE64 = 'filenameb64:cGl4ZWwucG5n;datab64:iVBORw0KGgoAAAANSUhEUgAA'\ + 'AAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAAAA'\ + 'ElFTkSuQmCC' class TestViewletBase(ViewletsTestCase): @@ -119,7 +126,7 @@ def testTitleViewletInPortalfactory(self): self.assertEqual(viewlet.site_title, u'Add Page — Folder') - def testLogoViewlet(self): + def testLogoViewletDefault(self): """Logo links towards navigation root """ self._invalidateRequestMemoizations() @@ -131,3 +138,17 @@ def testLogoViewlet(self): self.assertEqual(viewlet.navigation_root_title, "Folder") # there is no theme yet in Plone 5, so we see the old png logo self.assertTrue("http://nohost/plone/logo.png" in viewlet.logo_tag) + + def testLogoViewletRegistry(self): + """If logo is defined in plone.app.registry, use that one. + """ + registry = getUtility(IRegistry) + settings = registry.forInterface(ISiteSchema, prefix='plone') + settings.site_logo = SITE_LOGO_BASE64 + + viewlet = LogoViewlet(self.folder.test, self.app.REQUEST, None) + viewlet.update() + self.assertTrue( + 'Plone site' + in viewlet.logo_tag)