Skip to content

Commit

Permalink
Merge branch 'master' into issue_482
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Howitz committed Mar 7, 2019
2 parents 940cc4f + 2f97045 commit 2a3cb67
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 115 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.egg-info
*.py?
*.profraw
.Python
.coverage
.coverage.*
Expand Down
18 changes: 17 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ Fixes
- Resurrected copyright and license page
(`#482 <https://github.com/zopefoundation/Zope/issues/482>`_)

- Fix remove double quoting in ``ZPublisher.HTTPRequest.search_type``
(`#511 <https://github.com/zopefoundation/Zope/issues/511>`_)

- Fix subscript access on Page Template ``macros`` attribute
(`#210 <https://github.com/zopefoundation/Zope/issues/210>`_)

- Fix ``OFS.interfaces`` attribute declarations to match reality
(`#498 <https://github.com/zopefoundation/Zope/issues/498`_)
(`#498 <https://github.com/zopefoundation/Zope/issues/498>`_)

- Fix handling of DTML in Ace editor
(`#489 <https://github.com/zopefoundation/Zope/issues/489>`_)
Expand All @@ -34,12 +37,25 @@ Fixes

- Fix ZMI add handling of ``addItemSelect`` form
(`#506 <https://github.com/zopefoundation/Zope/issues/506>`_)

- Don't always flag PubBeforeAbort and PubBeforeAbort as retry
(`#502 <https://github.com/zopefoundation/Zope/pull/502>`_)

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

- Make sure the WSGI Response object respects lock semantics
(`#216 <https://github.com/zopefoundation/Zope/issues/216>`_)

- Specify supported Python versions using ``python_requires`` in setup.py
(`#481 <https://github.com/zopefoundation/Zope/issues/481>`_)

- Removed references to separate ``Products.ZCTextIndex``
(`516 <https://github.com/zopefoundation/Zope/issues/516>`_)

- Provide additional links on PyPI with ``project_urls`` in ``setup.py``
(`#434 <https://github.com/zopefoundation/Zope/issues/434>`_)


4.0b9 (2019-02-09)
------------------
Expand Down
3 changes: 1 addition & 2 deletions constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ AccessControl==4.0b6
Acquisition==4.5
AuthEncoding==4.1
BTrees==4.5.1
Chameleon==3.5
Chameleon==3.6
DateTime==4.3
DocumentTemplate==3.0b5
ExtensionClass==4.4
Expand All @@ -11,7 +11,6 @@ MultiMapping==4.1
PasteDeploy==2.0.1
Persistence==3.0b4
Products.BTreeFolder2==4.1
Products.ZCTextIndex==4.0.2
Products.ZCatalog==4.3
Record==3.5
RestrictedPython==4.0b8
Expand Down
100 changes: 47 additions & 53 deletions docs/zdgbook/ObjectPublishing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,125 +146,119 @@ Publishable Object Requirements

Zope has few restrictions on publishable objects. The basic rule is
that the object must have a doc string. This requirement goes for
method objects too.
methods, too.

Another requirement is that a publishable object must not have a name
that begin with an underscore. These two restrictions are designed to
that begins with an underscore. These two restrictions are designed to
keep private objects from being published.

Finally, published objects cannot be Python modules.

Finally, published objects cannot be Python module objects.

Traversal Methods
=================

During traversal, 'ZPublisher' cuts the URL into path elements
During traversal, *ZPublisher* cuts the URL into path elements
delimited by slashes, and uses each path element to traverse from the
current object to the next object. 'ZPublisher' locates the next
current object to the next object. *ZPublisher* locates the next
object in one of three ways:

1. Using '__bobo_traverse__'
1. Using ``__bobo_traverse__``.

2. Using 'getattr'
2. Using ``getattr``.

3. Using dictionary access.

First the publisher attempts to call the traversal hook method,
'__bobo_traverse__'. If the current object has this method it is
First, the publisher attempts to call the traversal hook method
``__bobo_traverse__``. If the current object has this method it is
called with the request and the current path element. The method
should return the next object or 'None' to indicate that a next object
can't be found. You can also return a tuple of objects from
'__bobo_traverse__' indicating a sequence of sub-objects. This allows
you to add additional parent objects into the request. This is almost
never necessary.
should return the next object or ``None`` to indicate that a next
object can't be found. You can also return a tuple of objects from
``__bobo_traverse__`` indicating a sequence of sub-objects. This
allows you to add additional parent objects into the request. This is
almost never necessary.


Here's an example of how to use '__bobo_traverse__'::
Here's an example of how to use ``__bobo_traverse__``::

def __bobo_traverse__(self, request, key):
# if there is a special cookie set, return special
# subobjects, otherwise return normal subobjects

"""Return subobjects depending on cookie contents."""
if request.cookies.has_key('special'):
# return a subobject from the special dict
return self.special_subobjects.get(key, None)

# otherwise return a subobject from the normal dict
return self.normal_subobjects.get(key, None)


This example shows how you can examine the request during the
traversal process.

If the current object does not define a '__bobo_traverse__' method,
then the next object is searched for using 'getattr'. This locates
sub-objects in the normal Python sense.
If the current object does not define a ``__bobo_traverse__`` method,
then the next object is searched for using ``getattr``. This locates
subobjects in the normal Python sense.

If the next object can't be found with 'getattr', 'ZPublisher' calls
If the next object can't be found with ``getattr``, *ZPublisher* calls
on the current object as though it were a dictionary. Note: the path
element will be a string, not an integer, so you cannot traverse
sequences using index numbers in the URL.

For example, suppose 'a' is the current object, and 'next' is the name
of the path element. Here are the three things that 'ZPublisher' will
try in order to find the next object:
For example, suppose ``a`` is the current object, and ``next`` is the
name of the path element. Here are the three things that *ZPublisher*
will try in order to find the next object:

1. 'a.__bobo_traverse__("next")'
1. ``a.__bobo_traverse__("next")``

2. 'a.next'

3. 'a["next"]'
2. ``a.next``

3. ``a["next"]``


Publishing Methods
==================

Once the published object is located with traversal, Zope *publishes*
it in one of three possible ways.
it in one of three possible ways:

- Calling the published object -- If the published object is a
function or method or other callable object, the publisher calls it.
Later in the chapter you'll find out how the publisher figures out
what arguments to pass when calling.

- Calling the default method -- If the published object is not
callable, the publisher uses the default method. For HTTP 'GET' and
'POST' requests the default method is 'index_html'. For other HTTP
requests such as 'PUT' the publisher looks for a method named by the
HTTP method. So for an HTTP 'HEAD' request, the publisher would
call the 'HEAD' method on the published object.
callable, the publisher uses the default method. For HTTP *GET* and
*POST* requests the default method is 'index_html'. For other HTTP
requests such as *PUT* the publisher looks for a method named by the
HTTP method. So for an HTTP *HEAD* request, the publisher would
call the *HEAD* method on the published object.

- Stringifying the published object -- If the published object isn't
callable, and doesn't have a default method, the publisher
publishes it using the Python 'str' function to turn it into a
publishes it using the Python ``str`` function to turn it into a
string.


After the response method has been determined and called, the
publisher must interpret the results.


Character Encodings for Responses
=================================

If the published method returns an object of type 'string', a plain
8-bit character string, the publisher will use it directly as the
body of the response.
If the published method returns an object of type *binary*, the
publisher will use it directly as the body of the response.

Things are different if the published method returns a unicode string,
because the publisher has to apply some character encoding. The
published method can choose which character encoding it uses by
setting a 'Content-Type' response header which includes a 'charset'
setting a *Content-Type* response header which includes a *charset*
property (setting response headers is explained later in this
chapter). A common choice of character encoding is UTF-8. To cause
the publisher to send unicode results as UTF-8 you need to set a
'Content-Type' header with the value 'text/html; charset=UTF-8'

If the 'Content-Type' header does not include a charser property (or
if this header has not been set by the published method) then the
publisher will choose a default character encoding. Today this
default is ISO-8859-1 (also known as Latin-1) for compatability with
old versions of Zope which did not include Unicode support. At some
time in the future this default is likely to change to UTF-8.
chapter). A common choice of character encoding is UTF-8, which is
also the default encoding.

If the *Content-Type* header does not include a charset or is not set
at all, the default encoding is set.

If you want to manually set a *Content-Type* header you have to set a
value like ``text/html; charset=UTF-8``.


HTTP Responses
==============
Expand Down
3 changes: 1 addition & 2 deletions requirements-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ AccessControl==4.0b6
Acquisition==4.5
AuthEncoding==4.1
BTrees==4.5.1
Chameleon==3.5
Chameleon==3.6
DateTime==4.3
DocumentTemplate==3.0b5
ExtensionClass==4.4
Expand All @@ -12,7 +12,6 @@ MultiMapping==4.1
PasteDeploy==2.0.1
Persistence==3.0b4
Products.BTreeFolder2==4.1
Products.ZCTextIndex==4.0.2
Products.ZCatalog==4.3
Record==3.5
RestrictedPython==4.0b8
Expand Down
6 changes: 6 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def _read_file(filename):
name='Zope',
version=version,
url='https://zope.readthedocs.io/en/latest/',
project_urls={
'Documentation': 'https://zope.readthedocs.io',
'Issue Tracker': 'https://github.com/zopefoundation/Zope/issues',
'Sources': 'https://github.com/zopefoundation/Zope',
},
license='ZPL 2.1',
description='Zope application server / web framework',
author='Zope Foundation and Contributors',
Expand Down Expand Up @@ -63,6 +68,7 @@ def _read_file(filename):
packages=find_packages('src'),
namespace_packages=['Products', 'Shared', 'Shared.DC', 'zmi'],
package_dir={'': 'src'},
python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*',
install_requires=[
'AccessControl >= 4.0b4',
'Acquisition',
Expand Down
1 change: 0 additions & 1 deletion sources.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ Products.BTreeFolder2 = git ${remotes:github}/Products.BTreeFolder2 pushurl=${re
Products.MailHost = git ${remotes:github}/Products.MailHost pushurl=${remotes:github_push}/Products.MailHost
Products.PythonScripts = git ${remotes:github}/Products.PythonScripts pushurl=${remotes:github_push}/Products.PythonScripts
Products.ZCatalog = git ${remotes:github}/Products.ZCatalog pushurl=${remotes:github_push}/Products.ZCatalog
Products.ZCTextIndex = git ${remotes:github}/Products.ZCTextIndex pushurl=${remotes:github_push}/Products.ZCTextIndex
Products.Sessions = git ${remotes:github}/Products.Sessions pushurl=${remotes:github_push}/Products.Sessions
Products.TemporaryFolder = git ${remotes:github}/Products.TemporaryFolder pushurl=${remotes:github_push}/Products.TemporaryFolder
Products.SiteErrorLog = git ${remotes:github}/Products.SiteErrorLog pushurl=${remotes:github_push}/Products.SiteErrorLog
Expand Down
46 changes: 25 additions & 21 deletions src/App/dtml/manage_navbar.dtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<header class="navbar navbar-nav navbar-expand navbar-dark flex-row bd-navbar">
<div id="toggle_tabs" class="collapsed"
role="button"
data-toggle="collapse"
data-target="#tabs_items"
aria-controls="tabs_items" aria-expanded="false" aria-label="Toggle Tab-Navigation">
Expand All @@ -20,8 +21,7 @@
title="Show/Hide Tree Menu of the Navigation Context"
data-title_inactive="STATUS INACTIVE: Tree Menu Button is only active on List Views. Navigate up a level to show the tree view again."
data-is_folderish="<dtml-var "(manage_main != manage) and 1 or 0">"
>
<a href="<dtml-var "(manage_main != manage) and './' or '../'">manage?came_from=<dtml-var URL>" target="_parent" onclick="javascript:if ( manage_menu ) {window.parent.frames[0].menu_toggle();return false;} else { return true; }">
><a href="<dtml-var "(manage_main != manage) and './' or '../'">manage?came_from=<dtml-var URL>" target="_parent" onclick="javascript:if ( manage_menu ) {window.parent.frames[0].menu_toggle();return false;} else { return true; }">
<i class="fa fa-sitemap"></i>
</a>
</li>
Expand All @@ -31,28 +31,32 @@
<i class="fa fa-cog"></i> <span class="zmi-label">Control&nbsp;Panel</span>
</a>
</li>
<dtml-if "aq_explicit"><dtml-if "hasattr(aq_explicit, 'filtered_meta_types')">
<li class="form-inline zmi-addItemSelect">
<form method="get" class="form-group">
<label for="addItemSelect" class="ml-2 sr-only">Select type to add</label>
<select id="addItemSelect" class="form-control-sm" name=":action"
data-title-active="Select type to add"
data-title-inactive="STATUS INACTIVE: New Object can only be Added in the List View"
title="Select type to add"
<li class="form-inline zmi-addItemSelect">
<form method="get" class="form-group">
<label for="addItemSelect" class="ml-2 sr-only">Select type to add</label>
<select id="addItemSelect" name=":action"
<dtml-if "aq_explicit"
><dtml-if "hasattr(aq_explicit, 'filtered_meta_types')"
>class="form-control-sm" title="Select type to add"
onchange="addItem( elm=this, base_url='<dtml-var "REQUEST.get('URL1','')">'); this.selectedIndex = 0;"
><option value="" selected="selected">Select type to add</option>
<dtml-in filtered_meta_types mapping sort=name
><dtml-if action><option value="&dtml.html_quote-action;">&dtml-name;</option>
</dtml-if
></dtml-in>
</select>
</form>
</li>
</dtml-if></dtml-if>
<dtml-else
>class="form-control-sm disabled" title="No type to add" disabled="disabled"
</dtml-if>
</dtml-if>
><option value="" selected="selected">Select type to add</option>
<dtml-if "hasattr(aq_explicit, 'filtered_meta_types')"
><dtml-in filtered_meta_types mapping sort=name
><dtml-if action
><option value="&dtml.html_quote-action;">&dtml-name;</option>
</dtml-if>
</dtml-in>
</dtml-if>
</select>
</form>
</li>
</ul>

<a href="manage_zmi_logout" title="Logout"
class="ml-4">
<a href="manage_zmi_logout" title="Logout" class="ml-4">
<i class="fas fa-sign-out-alt"></i>
</a>

Expand Down
20 changes: 10 additions & 10 deletions src/App/dtml/manage_page_footer.dtml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<dtml-unless "REQUEST.get('zmi_dialog','window')=='modal'">
</body>
<dtml-unless "'/manage_menu' in REQUEST.URL">
<script>
// Helpers for Menu Handling <dtml-var "REQUEST.URL">
var manage_menu = typeof window.parent.frames!="undefined"&&typeof window.parent.frames.manage_menu!="undefined";
window.parent.history.replaceState('','Main','<dtml-var URL>')
</script>
</dtml-unless>
<dtml-unless "REQUEST.get('zmi_dialog','window')=='modal'"
><dtml-unless "'/manage_menu' in REQUEST.URL">
<script>
// Helpers for Menu Handling <dtml-var "REQUEST.URL">
var manage_menu = typeof window.parent.frames!="undefined"&&typeof window.parent.frames.manage_menu!="undefined";
window.parent.history.replaceState('','Main','<dtml-var URL>')
</script>
</dtml-unless>
</body>
</html>
</dtml-unless>
</dtml-unless>
2 changes: 1 addition & 1 deletion src/ZPublisher/HTTPRequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
tainting_env = str(os.environ.get('ZOPE_DTML_REQUEST_AUTOQUOTE', '')).lower()
TAINTING_ENABLED = tainting_env not in ('disabled', '0', 'no')

search_type = re.compile(r'(:[a-zA-Z][-a-zA-Z0-9_]+|\\.[xy])$').search
search_type = re.compile(r'(:[a-zA-Z][-a-zA-Z0-9_]+|\.[xy])$').search

_marker = []

Expand Down
Loading

0 comments on commit 2a3cb67

Please sign in to comment.