Skip to content

Commit

Permalink
Sketch possible solution without fanstatic.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Howitz committed Feb 9, 2018
1 parent 20ff9d4 commit 14c22ff
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 65 deletions.
2 changes: 1 addition & 1 deletion buildout.cfg
Expand Up @@ -22,7 +22,7 @@ parts =
sources-dir = develop
auto-checkout =
js.bootstrap
zmi.icons
zmi.styles
Persistence
AccessControl
Products.BTreeFolder2
Expand Down
67 changes: 44 additions & 23 deletions docs/ZMI.rst
Expand Up @@ -10,12 +10,12 @@ browser.
Bootstrap ZMI
-------------

Since Zope 4.0b4 the ZMI is styled using Twitter bootstrap. The previously used
Since Zope 4.0b4 the ZMI is styled using Twitter Bootstrap. The previously used
GIF icons were replaced by font glyphs which are stored in the package
`zmi.icons`_
`zmi.styles`_ together with the CSS and JavaScript needed by Twitter Bootstrap.

Inside that package is a table of the `available icons`_ including the names
which are required to use them.
which are required to use them in the ZMI.

Update packages
+++++++++++++++
Expand All @@ -26,32 +26,53 @@ the ZMI, the default icon will be shown.
To use one of the new icons add an attribute named `zmi_icon` to the class. The
value should be one of the names listed on `available icons`_.

.. _`zmi.icons` : https://github.com/zopefoundation/zmi.icons
.. _`available icons` : http://htmlpreview.github.io/?https://github.com/zopefoundation/zmi.icons/blob/master/zmi/icons/resources/demo.html
.. _`zmi.styles` : https://github.com/zopefoundation/zmi.styles
.. _`available icons` : http://htmlpreview.github.io/?https://github.com/zopefoundation/zmi.styles/blob/master/zmi/styles/resources/zopetello/demo.html
Use custom icons
++++++++++++++++
Use custom icons and resources
++++++++++++++++++++++++++++++

To use custom icons (which are not part of `zmi.icons`), you need to subscribe
to ``App.interfaces.IRenderZMIEvent`` to need your resources.
To use custom icons (which are not part of `zmi.styles`) or load custom CSS resp. JavaScript, you have to:

Example from `Products.CMFCore/Products/CMFCore/zmi.py`::
1. create a directory and fill it with your assets
2. register this directory as resource directory
3. register a subscription adapter for :class:`App.interfaces.ICSSPaths` resp.
:class:`App.interfaces.IJSPaths`. This adapter has to return an iterable of
paths resp. URLs which should be loaded when rendering the ZMI.

import App.interfaces
import cmf.icons
import zope.component
Example taken from `cmf.zmiicons`_:

* Register the resource directory via ZCML:

@zope.component.adapter(App.interfaces.IRenderZMIEvent)
def load_assets(event):
"""Load the CMS icons for the ZMI."""
cmf.icons.cmf_icons.need()
.. code-block:: XML
The subscriber is registered in
`Products.CMFCore/Products/CMFCore/event.zcml` like this::
<browser:resourceDirectory
name="cmf.zmiicons"
directory="resources" />
<subscriber
handler=".zmi.load_assets" />
* Create a subscription adapter returning the path to the CSS file:

You can can `need` arbitrary fanstatic resources in the event subscriber, not
only icon fonts, but also custom CSS and JavaScript.

.. code-block:: Python
import zope.component
import zope.interface
@zope.component.adapter(zope.interface.Interface)
def css_paths(context):
"""Return paths to CSS files needed for the Zope 4 ZMI."""
return (
'/++resource++cmf.zmiicons/css/cmftello.css',
)
* Register the subscriber via ZCML:

.. code-block:: XML
<subscriber
provides="App.interfaces.ICSSPaths"
factory=".css_paths" />
.. _`cmf.zmiicons` : https://github.com/zopefoundation/cmf.zmiicons
4 changes: 1 addition & 3 deletions setup.py
Expand Up @@ -68,16 +68,14 @@ def _read_file(filename):
'RestrictedPython',
'ZConfig >= 2.9.2',
'ZODB',
'fanstatic >= 1.0',
'ipaddress',
'js.bootstrap >= 4.0.dev0',
'setuptools',
'six',
'transaction',
'waitress',
'zExceptions >= 3.4',
'z3c.pt',
'zmi.icons',
'zmi.styles',
'zope.browser',
'zope.browsermenu',
'zope.browserpage >= 4.0',
Expand Down
2 changes: 1 addition & 1 deletion sources.cfg
Expand Up @@ -15,7 +15,7 @@ Persistence = git ${remotes:github}/Persistence pushurl=${remotes:github_push}/P
RestrictedPython = git ${remotes:github}/RestrictedPython pushurl=${remotes:github_push}/RestrictedPython
zExceptions = git ${remotes:github}/zExceptions pushurl=${remotes:github_push}/zExceptions
zope.globalrequest = git ${remotes:github}/zope.globalrequest pushurl=${remotes:github_push}/zope.globalrequest
zmi.icons = git ${remotes:github}/zmi.icons pushurl=${remotes:github_push}/zmi.icons
zmi.styles = git ${remotes:github}/zmi.styles pushurl=${remotes:github_push}/zmi.styles

# Required depencencies
js.bootstrap = git https://github.com/gocept/js.bootstrap4.git branch=bootstrap4
Expand Down
9 changes: 7 additions & 2 deletions src/App/Management.py
Expand Up @@ -18,12 +18,14 @@
from AccessControl.class_init import InitializeClass
from AccessControl.Permissions import view_management_screens
from App.interfaces import INavigation
from App.interfaces import RenderZMIEvent
from App.interfaces import ICSSPaths
from App.interfaces import IJSPaths
from App.special_dtml import DTMLFile
from ExtensionClass import Base
from six.moves.urllib.parse import quote, unquote
from zExceptions import Redirect
from zope.interface import implementer
import itertools
import zope.event

try:
Expand Down Expand Up @@ -160,7 +162,10 @@ class Navigation(Base):
security.declareProtected(view_management_screens, 'manage_page_header')
def manage_page_header(self, *args, **kw):
"""manage_page_header."""
zope.event.notify(RenderZMIEvent())
kw['css_urls'] = itertools.chain(
*zope.component.subscribers((self,), ICSSPaths))
kw['js_urls'] = itertools.chain(
*zope.component.subscribers((self,), IJSPaths))
return self._manage_page_header(*args, **kw)

security.declarePublic('manage_zmi_logout')
Expand Down
6 changes: 6 additions & 0 deletions src/App/dtml/manage_page_header.dtml
Expand Up @@ -7,6 +7,12 @@
<meta http-equiv="content-type" content="text/html;charset=&dtml-management_page_charset;" />
<dtml-call "RESPONSE and RESPONSE.setHeader('content-type','text/html;charset='+management_page_charset)">
<title><dtml-if title_or_id><dtml-var title_or_id><dtml-else>Zope</dtml-if></title>
<dtml-in css_urls>
<link rel="stylesheet" type="text/css" href="&dtml-sequence-item;" />
</dtml-in>
<dtml-in js_urls>
<script type="text/javascript" src="&dtml-sequence-item;"></script>
</dtml-in>
</head>
<body>
<div class="container-fluid">
10 changes: 4 additions & 6 deletions src/App/interfaces.py
Expand Up @@ -15,7 +15,6 @@

from zope.interface import Attribute
from zope.interface import Interface
from zope.interface import implementer


class INavigation(Interface):
Expand All @@ -31,10 +30,9 @@ def manage_zmi_logout(REQUEST, RESPONSE):
"""Logout current user"""


class IRenderZMIEvent(Interface):
"""ZMI is rendered."""
class ICSSPaths(Interface):
"""Paths to CSS resources needed for the ZMI."""


@implementer(IRenderZMIEvent)
class RenderZMIEvent(object):
"""Event fired when the ZMI is rendered."""
class IJSPaths(Interface):
"""Paths to JAvaScript resources needed for the ZMI."""
3 changes: 1 addition & 2 deletions src/Zope2/App/configure.zcml
Expand Up @@ -17,7 +17,6 @@
<securityPolicy
component="AccessControl.security.SecurityPolicy" />

<subscriber
handler=".zmi.load_assets" />
<include package="zmi.styles" />

</configure>
27 changes: 0 additions & 27 deletions src/Zope2/App/zmi.py

This file was deleted.

0 comments on commit 14c22ff

Please sign in to comment.