Skip to content

Commit

Permalink
Fix XML Page template files in Python 3
Browse files Browse the repository at this point in the history
  • Loading branch information
ale-rt committed Sep 27, 2018
1 parent 6dcd4c7 commit 7a58724
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Expand Up @@ -22,6 +22,9 @@ New features
Bugfixes
++++++++

- Fix XML Page template files in Python 3
(`#319 <https://github.com/zopefoundation/Zope/issues/319>`_)

- Fix ZMI upload of `DTMLMethod` and `DTMLDocument` to store the DTML as a
native ``str`` on both Python versions.
(`#265 <https://github.com/zopefoundation/Zope/pull/265>`_)
Expand Down
16 changes: 12 additions & 4 deletions src/Products/PageTemplates/PageTemplateFile.py
Expand Up @@ -25,6 +25,7 @@
from OFS.Traversable import Traversable
from Products.PageTemplates.Expressions import SecureModuleImporter
from Products.PageTemplates.PageTemplate import PageTemplate
from Products.PageTemplates.utils import encodingFromXMLPreamble
from Shared.DC.Scripts.Script import Script
from Shared.DC.Scripts.Signature import FuncCode
from zope.contenttype import guess_content_type
Expand Down Expand Up @@ -98,7 +99,7 @@ def __init__(self, filename, _prefix=None, **kw):
def pt_getContext(self):
root = None
meth = aq_get(self, 'getPhysicalRoot', None)
if meth is not None:
if callable(meth):
root = meth()
context = self._getContext()
c = {'template': self,
Expand Down Expand Up @@ -157,7 +158,6 @@ def _cook_check(self):
if self._v_program is not None and mtime == self._v_last_read:
return
text, type_ = self._read_file()
# FIXME: text is a binary_type when it's XML.
self.pt_edit(text, type_)
self._cook()
if self._v_errors:
Expand All @@ -178,22 +178,30 @@ def _prepare_html(self, text):
text = text.decode(encoding)
return text, type_

def _prepare_xml(self, text):
try:
text = text.decode(encodingFromXMLPreamble(text))
except UnicodeDecodeError:
pass
return text, 'text/xml'

def _read_file(self):
__traceback_info__ = self.filename
f = open(self.filename, "rb")
try:
text = f.read(XML_PREFIX_MAX_LENGTH)
except:
except Exception:
f.close()
raise
type_ = sniff_type(text)
text += f.read()
if type_ != "text/xml":
text, type_ = self._prepare_html(text)
else:
text, type_ = self._prepare_xml(text)
f.close()
return text, type_


def document_src(self, REQUEST=None, RESPONSE=None):
"""Return expanded document source."""

Expand Down
5 changes: 2 additions & 3 deletions src/Products/PageTemplates/tests/testZopePageTemplate.py
Expand Up @@ -5,7 +5,6 @@
Ensures that adding a page template works correctly.
"""

import sys
import unittest
import transaction

Expand All @@ -26,7 +25,7 @@
import PreferredCharsetResolver
import Zope2

from six import text_type, binary_type
from six import text_type

ascii_binary = b'<html><body>hello world</body></html>'
iso885915_binary = u'<html><body>üöäÜÖÄß</body></html>'.encode('iso-8859-15')
Expand All @@ -39,7 +38,7 @@
'''

xml_binary_iso_8859_15 = (xml_template % 'iso-8859-15').encode('iso-8859-15')
xml_binary_utf8 = (xml_template % 'utf-8').encode('utf-8')
xml_binary_utf8 = (xml_template % 'utf-8').encode('utf-8')

html_template_w_header = u'''
<html>
Expand Down
14 changes: 14 additions & 0 deletions src/Products/PageTemplates/tests/test_ptfile.py
@@ -1,3 +1,4 @@
# coding=utf-8
"""Tests of PageTemplateFile."""

import os
Expand Down Expand Up @@ -210,3 +211,16 @@ def test_lazy(self):
f.close()
pt = PageTemplateFile(self.TEMPFILENAME)
self.assertTrue(not pt._text and not pt._v_program)


class RenderTestCase(unittest.TestCase):

def testXMLPageTemplateFile(self):
dirname = os.path.dirname(__file__)

filename = os.path.join(dirname, 'utf8.xml')
with open(filename, 'rb') as f:
self.assertEqual(
PageTemplateFile(filename).pt_render(),
f.read().decode('utf8'),
)
4 changes: 4 additions & 0 deletions src/Products/PageTemplates/tests/utf8.xml
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<foo>
üöäÜÖÄß
</foo>

0 comments on commit 7a58724

Please sign in to comment.