Skip to content

Commit

Permalink
Add ability to customise the CSS and JS in ZMI via Properties.
Browse files Browse the repository at this point in the history
Requested by customer who uses TTW approach.
  • Loading branch information
Michael Howitz authored and dwt committed Jun 12, 2018
1 parent 240eff0 commit f800075
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
20 changes: 20 additions & 0 deletions docs/ZMI.rst
Expand Up @@ -76,3 +76,23 @@ Example taken from `cmf.zmiicons`_:
.. _`cmf.zmiicons` : https://github.com/zopefoundation/cmf.zmiicons
Use custom resources via ZMI
++++++++++++++++++++++++++++

To add custom CSS or JavaScript resources via ZMI you have to add a property:

* ``zmi_additional_css_paths`` for additional CSS
* ``zmi_additional_css_paths`` for additional JavaScript

The properties can have one of the following types:

* ``string``
* ``ustring``
* ``lines``
* ``ulines``

The value of the properties have to be paths or URLs to CSS resp. JavaScript
which will be included in the HTML of the ZMI. (Paths have to be resolvable by
the browser aka not simple file system paths.)
14 changes: 12 additions & 2 deletions src/App/Management.py
Expand Up @@ -26,6 +26,7 @@
from zExceptions import Redirect
from zope.interface import implementer
import itertools
import six
import zope.event

try:
Expand Down Expand Up @@ -163,9 +164,11 @@ class Navigation(Base):
def manage_page_header(self, *args, **kw):
"""manage_page_header."""
kw['css_urls'] = itertools.chain(
*zope.component.subscribers((self,), ICSSPaths))
itertools.chain(*zope.component.subscribers((self,), ICSSPaths)),
self._get_zmi_additionals('zmi_additional_css_paths'))
kw['js_urls'] = itertools.chain(
*zope.component.subscribers((self,), IJSPaths))
itertools.chain(*zope.component.subscribers((self,), IJSPaths)),
self._get_zmi_additionals('zmi_additional_js_paths'))
return self._manage_page_header(*args, **kw)

security.declarePublic('manage_zmi_logout')
Expand All @@ -188,6 +191,13 @@ def manage_zmi_logout(self, REQUEST, RESPONSE):
</html>""")
return

def _get_zmi_additionals(self, attrib):
# Get additional assets for styling ZMI defined on properties in ZMI.
additionals = getattr(self, attrib, ()) or ()
if isinstance(additionals, six.string_types):
additionals = (additionals, )
return additionals

# Navigation doesn't have an inherited __class_init__ so doesn't get
# initialized automatically.

Expand Down
36 changes: 34 additions & 2 deletions src/App/tests/testManagement.py
@@ -1,11 +1,43 @@
import unittest
import Testing.ZopeTestCase


class TestNavigation(unittest.TestCase):
class TestNavigation(Testing.ZopeTestCase.ZopeTestCase):

def test_interfaces(self):
from App.interfaces import INavigation
from App.Management import Navigation
from zope.interface.verify import verifyClass

verifyClass(INavigation, Navigation)

def test_Management__Navigation__manage_page_header__1(self):
"""It respects `zmi_additional_css_paths` string property."""
self.folder.manage_addProperty(
'zmi_additional_css_paths', '/foo/bar.css', 'string')
self.assertIn('href="/foo/bar.css"', self.folder.manage_page_header())

def test_Management__Navigation__manage_page_header__2(self):
"""It respects `zmi_additional_css_paths` ustring property."""
self.folder.manage_addProperty(
'zmi_additional_css_paths', '/foo/bar.css', 'ustring')
self.assertIn('href="/foo/bar.css"', self.folder.manage_page_header())

def test_Management__Navigation__manage_page_header__3(self):
"""It respects `zmi_additional_css_paths` lines property."""
self.folder.manage_addProperty(
'zmi_additional_css_paths', ['/foo/bar.css', '/baz.css'], 'lines')
self.assertIn('href="/foo/bar.css"', self.folder.manage_page_header())
self.assertIn('href="/baz.css"', self.folder.manage_page_header())

def test_Management__Navigation__manage_page_header__4(self):
"""It respects `zmi_additional_css_paths` ulines property."""
self.folder.manage_addProperty(
'zmi_additional_css_paths', ['/foo/bar.css', '/baz.css'], 'lines')
self.assertIn('href="/foo/bar.css"', self.folder.manage_page_header())
self.assertIn('href="/baz.css"', self.folder.manage_page_header())

def test_Management__Navigation__manage_page_header__5(self):
"""It ignores an empty `zmi_additional_css_paths` property."""
self.folder.manage_addProperty(
'zmi_additional_css_paths', '', 'string')
self.assertNotIn('href=""', self.folder.manage_page_header())

0 comments on commit f800075

Please sign in to comment.