Skip to content

Commit

Permalink
Merge branch 'master' into issue_457
Browse files Browse the repository at this point in the history
  • Loading branch information
dataflake committed Jan 30, 2019
2 parents aa6e568 + c5176ba commit 83b9881
Show file tree
Hide file tree
Showing 18 changed files with 156 additions and 78 deletions.
18 changes: 18 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,27 @@ Fixes
- Improved showing/hiding of the left-hand tree pane
(`#457 <https://github.com/zopefoundation/Zope/issues/457>`_)

- Recreate ``App.version_txt.getZopeVersion``
(`#411 <https://github.com/zopefoundation/Zope/issues/411>`_)

- Restore the `View` ZMI tab on folders and their subclasses
(`#449 <https://github.com/zopefoundation/Zope/issues/449>`_)

- Don't error out when showing permissions for a non-existent user
(`#437 <https://github.com/zopefoundation/Zope/issues/437>`_)

Other changes
+++++++++++++

- Document filesystem caching for Chameleon page templates
(`#291 <https://github.com/zopefoundation/Zope/issues/291>`_)

Breaking changes
++++++++++++++++

- Removed support for ``management_page_charset``
(`#313 <https://github.com/zopefoundation/Zope/issues/313>`_)


4.0b8 (2018-12-14)
------------------
Expand Down
9 changes: 5 additions & 4 deletions docs/WHATSNEW.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ styling.
Unified encoding
----------------

As it is reasonable to have one unified encoding in ZMI and frontend,
``management_page_charset`` (as property of a folder) and ``default-zpublisher-
encoding`` in `zope.conf` have to define the same encoding, which is `utf-8`
by default for both.
As it is reasonable to have one unified encoding in ZMI and frontend, support
for ``management_page_charset`` (as property of a folder) has been removed.
``default-zpublisher-encoding`` in `zope.conf` is the only place where to
define the site encoding that governs how the ZPublisher and Zope Page
Templates handle encoding and decoding of text.
23 changes: 23 additions & 0 deletions docs/zope2book/AdvZPT.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,29 @@ caching for performance-critical applications.
For more information on caching in the context of Zope, see the
chapter entitled `Zope Services <ZopeServices.html>`_.

Filesystem caching for Chameleon-based templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Zope 4 introduced the `Chameleon HTML/XML template engine
<https://chameleon.readthedocs.io/>`_ as new backend for Zope Page
Templates. The Chameleon templating engine can compile templates and
cache them on the file system for faster startup and execution.

File system caching is activated by setting an environment variable
named ``CHAMELEON_CACHE`` to the path of a folder on the filesystem
where Chameleon can write its compiled template representation.

Look for or add a section named ``environment`` in ``etc/wsgi.conf``
and add a suitable filesystem path, for example::

<environment>
CHAMELEON_CACHE $INSTANCE/var/cache
</environment>

Make sure that folder exists before starting Zope.

How to configure Zope is explained in `Configuring Zope <../operation.html>`_.

Page Template Utilities
-----------------------

Expand Down
9 changes: 4 additions & 5 deletions src/App/dtml/manage_page_header.dtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
<!doctype html>
<html lang="en">
<head>
<dtml-unless management_page_charset
><dtml-call "REQUEST.set('management_page_charset','utf-8')"
></dtml-unless>

<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)">
<dtml-let charset="REQUEST.charset">
<meta http-equiv="content-type" content="text/html;charset=&dtml-charset;" />
<dtml-call "RESPONSE and RESPONSE.setHeader('content-type','text/html;charset='+charset)">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</dtml-let>

<title><dtml-if title_or_id><dtml-var title_or_id><dtml-else>Zope</dtml-if></title>
<dtml-in css_urls>
Expand Down
32 changes: 32 additions & 0 deletions src/App/tests/test_getZopeVersion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
##############################################################################
#
# Copyright (c) 2004 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for the recreated `getZopeVersion`."""

import unittest

from pkg_resources import get_distribution
from App.version_txt import getZopeVersion

class Test(unittest.TestCase):
def test_major(self):
self.assertEqual(
getZopeVersion().major,
int(get_distribution("Zope").version.split(".")[0])
)

def test_types(self):
zv = getZopeVersion()
for i in (0, 1, 2, 4):
self.assertIsInstance(zv[i], int, str(i))
self.assertIsInstance(zv[3], str, '3')
34 changes: 33 additions & 1 deletion src/App/version_txt.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,54 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import collections
import re
import sys

import pkg_resources

_version_string = None
_zope_version = None

ZopeVersion = collections.namedtuple(
"ZopeVersion",
["major", "minor", "micro", "status", "release"]
)


def _prep_version_data():
global _version_string
global _version_string, _zope_version
if _version_string is None:
v = sys.version_info
pyver = "python %d.%d.%d, %s" % (v[0], v[1], v[2], sys.platform)
dist = pkg_resources.get_distribution('Zope')
_version_string = "%s, %s" % (dist.version, pyver)

expr = re.compile(
r'(?P<major>[0-9]+)\.(?P<minor>[0-9]+)(\.(?P<micro>[0-9]+))?'
'(?P<status>[A-Za-z]+)?(?P<release>[0-9]+)?')
version_dict = expr.match(dist.version).groupdict()
_zope_version = ZopeVersion(
int(version_dict.get('major') or -1),
int(version_dict.get('minor') or -1),
int(version_dict.get('micro') or -1),
version_dict.get('status') or '',
int(version_dict.get('release') or -1),
)




def version_txt():
_prep_version_data()
return '(%s)' % _version_string

def getZopeVersion():
"""return information about the Zope version as a named tuple.
Format of zope_version tuple:
(major <int>, minor <int>, micro <int>, status <string>, release <int>)
If unreleased, integers may be -1.
"""
_prep_version_data()
return _zope_version
1 change: 1 addition & 0 deletions src/OFS/Folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Folder(

manage_options = (
ObjectManager.manage_options
+ ({'label': 'View', 'action': ''}, )
+ PropertyManager.manage_options
+ RoleManager.manage_options
+ Item.manage_options
Expand Down
6 changes: 1 addition & 5 deletions src/OFS/Image.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,11 +506,7 @@ def update_data(self, data, content_type=None, size=None):

def _get_encoding(self):
"""Get the canonical encoding for ZMI."""
return getattr(
self,
'management_page_charset',
ZPublisher.HTTPRequest.default_encoding
)
return ZPublisher.HTTPRequest.default_encoding

@security.protected(change_images_and_files)
def manage_edit(
Expand Down
7 changes: 3 additions & 4 deletions src/OFS/dtml/access.dtml
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,12 @@
><dtml-let permmission_title="name"
><dtml-if "not (_['sequence-index']%10)">
<tr class="zmi-table-head">
<th colspan="2" class="zmi-akcquire-title" title="Acquire permission settings">
<th class="zmi-akcquire-title" title="Acquire?">
<dtml-unless isTopLevelPrincipiaApplicationObject>
<a href="manage_acquiredForm">Acquire
<dtml-unless sequence-index> <span class="d-none d-sm-block">permission settings</span></dtml-unless>
</a>
<a href="manage_acquiredForm">Acquire?</a>
</dtml-unless>
</th>
<th class="zmi-permission" title="Permission">Permission</th>
<dtml-in valid_roles>
<th class="zmi-rolename" title="&dtml-sequence-item;"><div><span>&dtml-sequence-item;</span></div></th>
</dtml-in>
Expand Down
2 changes: 1 addition & 1 deletion src/OFS/dtml/fileEdit.dtml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
name="filedata:text" wrap="off" rows="20"><dtml-var __str__ html_quote></textarea>
<dtml-except UnicodeDecodeError>
<div class="alert alert-warning" role="alert">
The file could not be decoded with '<dtml-var "error_value.encoding">'. Setting a different encoding as `management_page_charset` might help.
The file could not be decoded with '<dtml-var "error_value.encoding">'.
</div>
</dtml-try>
</div>
Expand Down
28 changes: 5 additions & 23 deletions src/OFS/dtml/properties.dtml
Original file line number Diff line number Diff line change
@@ -1,22 +1,4 @@
<dtml-if management_page_charset>
<dtml-comment>
A site-global encoding specification in a property.
Note that this feature only works if there are no unicode objects
around. This means that this feature is not likely to be supported
in all future versions of zope.
</dtml-comment>
<dtml-call "REQUEST.set('management_page_charset',_['management_page_charset'])">
<dtml-call "REQUEST.set('management_page_charset_tag','')">
<dtml-else>
<dtml-comment>
Thankfully no site-global encoding specification in a property.
We can set UTF-8, and unicode properties will work.
</dtml-comment>
<dtml-call "REQUEST.set('management_page_charset','UTF-8')">
<dtml-call "REQUEST.set('management_page_charset_tag','UTF-8:')">
</dtml-if>

<dtml-if "REQUEST.get('management_page_charset',None)=='UTF-8'"><dtml-var "u' '"></dtml-if>
<dtml-if "REQUEST.charset.lower()=='utf-8'"><dtml-var "u' '"></dtml-if>

<dtml-var manage_page_header>

Expand Down Expand Up @@ -44,7 +26,7 @@
<dtml-in propertyMap mapping>
<dtml-let type="not _.has_key('type') and 'string' or type"
pdesc="propertyDescription(id)"
charset_tag="REQUEST['management_page_charset_tag']">
charset_tag="REQUEST.charset.lower()=='utf-8' and 'UTF-8:' or ''">
<tr title="&dtml-pdesc;">
<!-- Checkbox column -->
<td>
Expand Down Expand Up @@ -188,7 +170,7 @@
property and click the <em>Add</em>-button.
</p>
<div class="form-group zmi-controls mt-2">
<input type="text" placeholder="Name" title="Name" class="form-control" name="id:<dtml-var "REQUEST['management_page_charset_tag']">string" value="" />
<input type="text" placeholder="Name" title="Name" class="form-control" name="id:<dtml-var "REQUEST.charset.lower()=='utf-8' and 'UTF-8:' or ''">string" value="" />
<select name="type" title="Data Type"placeholder="Type" class="form-control">
<option>boolean</option>
<option>date</option>
Expand All @@ -199,7 +181,7 @@
<option selected="selected">string</option>
<option>text</option>
<option>tokens</option>
<dtml-if "REQUEST['management_page_charset'] == 'UTF-8'">
<dtml-if "REQUEST.charset.lower() == 'utf-8'">
<option>ulines</option>
<option>ustring</option>
<option>utext</option>
Expand All @@ -209,7 +191,7 @@
<option>multiple selection</option>
</select>
<input type="text" title="Value" placeholder="Value" class="form-control"
<dtml-if "REQUEST['management_page_charset'] == 'UTF-8'"
<dtml-if "REQUEST.charset.lower() == 'utf-8'"
>name="value:UTF-8:ustring"
<dtml-else
>name="value:string"
Expand Down
12 changes: 0 additions & 12 deletions src/OFS/tests/testFileAndImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,18 +355,6 @@ def test_Image__manage_main__1(self):
text = self.browser.getControl(name='filedata:text').value
self.assertEqual(text, 'hällo')

@unittest.skipIf(six.PY2, "feature not supported on Python 2")
def test_Image__manage_main__2(self):
"""It shows the content of text files.
It respects the encoding in `management_page_charset`.
"""
self.app.management_page_charset = 'latin-1'
self.app.file.update_data(u'hällo'.encode('latin-1'))
self.browser.open('http://localhost/file/manage_main')
text = self.browser.getControl(name='filedata:text').value
self.assertEqual(text, 'hällo')

@unittest.skipIf(six.PY2, "feature not supported on Python 2")
def test_Image__manage_main__3(self):
"""It shows an error message if the file content cannot be decoded."""
Expand Down
4 changes: 1 addition & 3 deletions src/Products/PageTemplates/tests/testExpressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def _makeContext(self, bindings=None):

class Dummy(object):
__allow_access_to_unprotected_subobjects__ = 1
management_page_charset = 'utf-8'

def __call__(self):
return 'dummy'
Expand All @@ -51,8 +50,7 @@ def absolute_url(self, relative=0):
dummy2=DummyDocumentTemplate(),
eightbit=b'\xe4\xfc\xf6',
# ZopeContext needs 'context' and 'template' keys for unicode
# conflict resolution, and 'context' needs a
# 'management_page_charset'
# conflict resolution
context=Dummy(),
template=DummyDocumentTemplate(),
)
Expand Down
12 changes: 4 additions & 8 deletions src/Products/PageTemplates/tests/testZopePageTemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,12 @@ class PreferredCharsetUnicodeResolverTests(unittest.TestCase):
def testPreferredCharsetResolverWithoutRequestAndWithoutEncoding(self):
# This test checks the edgecase where the unicode conflict resolver
# is called with a context object having no REQUEST
# Since switching from ``management_page_charset`` set on the
# REQUEST to the ``default-zpublisher-encoding`` configuration
# setting that is always available, this test will return a
# correctly decoded value.
context = object()
result = PreferredCharsetResolver.resolve(context, 'üöä', None)
self.assertEqual(result, 'üöä')

def testPreferredCharsetResolverWithoutRequestAndWithEncoding(self):
# This test checks the edgecase where the unicode conflict resolver
# is called with a context object having no REQUEST
class ContextMock(object):
management_page_charset = 'utf-8'
result = PreferredCharsetResolver.resolve(ContextMock(), 'üöä', None)
self.assertEqual(result, u'üöä')


Expand Down
15 changes: 6 additions & 9 deletions src/Products/PageTemplates/unicodeconflictresolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
from zope.interface import implementer
from zope.i18n.interfaces import IUserPreferredCharsets
import ZPublisher

from six import text_type, binary_type

Expand All @@ -44,8 +45,8 @@ def resolve(self, context, text, expression):
@implementer(IUnicodeEncodingConflictResolver)
class Z2UnicodeEncodingConflictResolver(object):
""" This resolver tries to lookup the encoding from the
'management_page_charset' property and defaults to
sys.getdefaultencoding().
'default-zpublisher-encoding' setting in the Zope configuration
file and defaults to sys.getdefaultencoding().
"""

def __init__(self, mode='strict'):
Expand All @@ -58,8 +59,7 @@ def resolve(self, context, text, expression):
try:
return text.decode('ascii')
except UnicodeDecodeError:
encoding = getattr(
context, 'management_page_charset', default_encoding)
encoding = ZPublisher.HTTPRequest.default_encoding
try:
return text.decode(encoding, errors=self.mode)
except UnicodeDecodeError:
Expand All @@ -84,11 +84,8 @@ def resolve(self, context, text, expression):
# Python default encoding.

if request is None:
charsets = [default_encoding]
management_charset = getattr(
context, 'management_page_charset', None)
if management_charset:
charsets.insert(0, management_charset)
charsets = [ZPublisher.HTTPRequest.default_encoding,
default_encoding]
else:
# charsets might by cached within the request
charsets = getattr(request, '__zpt_available_charsets', None)
Expand Down
3 changes: 1 addition & 2 deletions src/Products/PageTemplates/www/ptEdit.zpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<h1 tal:replace="structure python:context.manage_page_header(management_page_charset='utf-8')"
>manage_page_header</h1>
<h1 tal:replace="structure context/manage_page_header">manage_page_header</h1>
<h2 tal:define="manage_tabs_message options/manage_tabs_message | nothing"
tal:replace="structure context/manage_tabs">manage_tabs</h2>
<tal:block define="global body request/other/text | request/form/text | context/read" />
Expand Down
Loading

0 comments on commit 83b9881

Please sign in to comment.