Do some heavy clean up in ZopePageTemplate which gets rid of a lot of temporary

hacks that were in there before.  Tried to reduce the diff to the Zope 2.9 code
a little and moved some content type guessing code to PageTemplateFile where it
really belongs (that also avoids a circular import problem).
parent 5990331e
...@@ -25,12 +25,18 @@ from Shared.DC.Scripts.Script import Script ...@@ -25,12 +25,18 @@ from Shared.DC.Scripts.Script import Script
from Shared.DC.Scripts.Signature import FuncCode from Shared.DC.Scripts.Signature import FuncCode
from Products.PageTemplates.Expressions import SecureModuleImporter from Products.PageTemplates.Expressions import SecureModuleImporter
from Products.PageTemplates.PageTemplate import PageTemplate from Products.PageTemplates.PageTemplate import PageTemplate
from Products.PageTemplates.ZopePageTemplate import guess_type
from zope.contenttype import guess_content_type from zope.contenttype import guess_content_type
from zope.pagetemplate.pagetemplatefile import sniff_type
LOG = getLogger('PageTemplateFile') LOG = getLogger('PageTemplateFile')
def guess_type(filename, text):
content_type, dummy = guess_content_type(filename, text)
if content_type in ('text/html', 'text/xml'):
return content_type
return sniff_type(text) or 'text/html'
class PageTemplateFile(SimpleItem, Script, PageTemplate, Traversable): class PageTemplateFile(SimpleItem, Script, PageTemplate, Traversable):
"""Zope 2 implementation of a PageTemplate loaded from a file.""" """Zope 2 implementation of a PageTemplate loaded from a file."""
......
...@@ -34,26 +34,32 @@ from AccessControl.Permissions import view_management_screens ...@@ -34,26 +34,32 @@ from AccessControl.Permissions import view_management_screens
from webdav.Lockable import ResourceLockedError from webdav.Lockable import ResourceLockedError
from webdav.WriteLockInterface import WriteLockInterface from webdav.WriteLockInterface import WriteLockInterface
from zope.contenttype import guess_content_type
from zope.pagetemplate.pagetemplatefile import sniff_type
from Products.PageTemplates.PageTemplate import PageTemplate from Products.PageTemplates.PageTemplate import PageTemplate
from Products.PageTemplates.Expressions import getEngine from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PageTemplates.PageTemplateFile import guess_type
from Products.PageTemplates.Expressions import SecureModuleImporter from Products.PageTemplates.Expressions import SecureModuleImporter
# regular expression to extract the encoding from the XML preamble # regular expression to extract the encoding from the XML preamble
encoding_reg= re.compile('<\?xml.*?encoding="(.*?)".*?\?>', re.M) encoding_reg = re.compile('<\?xml.*?encoding="(.*?)".*?\?>', re.M)
preferred_encodings = ['utf-8', 'iso-8859-15'] preferred_encodings = ['utf-8', 'iso-8859-15']
if os.environ.has_key('ZPT_PREFERRED_ENCODING'): if os.environ.has_key('ZPT_PREFERRED_ENCODING'):
preferred_encodings.insert(0, os.environ['ZPT_PREFERRED_ENCODING']) preferred_encodings.insert(0, os.environ['ZPT_PREFERRED_ENCODING'])
def sniffEncoding(text, default_encoding='utf-8'):
"""Try to determine the encoding from html or xml"""
if text.startswith('<?xml'):
mo = encoding_reg.search(text)
if mo:
return mo.group(1)
return default_encoding
class Src(Acquisition.Explicit): class Src(Acquisition.Explicit):
""" I am scary code """ """ I am scary code """
index_html = None
PUT = document_src = Acquisition.Acquired PUT = document_src = Acquisition.Acquired
index_html = None
def __before_publishing_traverse__(self, ob, request): def __before_publishing_traverse__(self, ob, request):
if getattr(request, '_hacked_path', 0): if getattr(request, '_hacked_path', 0):
...@@ -63,29 +69,9 @@ class Src(Acquisition.Explicit): ...@@ -63,29 +69,9 @@ class Src(Acquisition.Explicit):
" " " "
return self.document_src(REQUEST) return self.document_src(REQUEST)
def sniffEncoding(text, default_encoding='utf-8'):
""" try to determine the encoding from html or xml """
if text.startswith('<?xml'):
mo = encoding_reg.search(text)
if mo:
return mo.group(1)
return default_encoding
def guess_type(filename, text):
content_type, dummy = guess_content_type(filename, text)
if content_type in ('text/html', 'text/xml'):
return content_type
return sniff_type(text) or 'text/html'
_default_content_fn = os.path.join(package_home(globals()), 'pt', 'default.html')
class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
Traversable, PropertyManager): Traversable, PropertyManager):
""" Z2 wrapper class for Zope 3 page templates """ "Zope wrapper for Page Template using TAL, TALES, and METAL"
__implements__ = (WriteLockInterface,) __implements__ = (WriteLockInterface,)
...@@ -95,7 +81,8 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -95,7 +81,8 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
func_code = FuncCode((), 0) func_code = FuncCode((), 0)
_default_bindings = {'name_subpath': 'traverse_subpath'} _default_bindings = {'name_subpath': 'traverse_subpath'}
_default_content_fn = os.path.join(package_home(globals()), 'www', 'default.html') _default_content_fn = os.path.join(package_home(globals()),
'www', 'default.html')
manage_options = ( manage_options = (
{'label':'Edit', 'action':'pt_editForm', {'label':'Edit', 'action':'pt_editForm',
...@@ -114,27 +101,39 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -114,27 +101,39 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(view) security.declareObjectProtected(view)
# protect methods from base class(es)
security.declareProtected(view, '__call__') security.declareProtected(view, '__call__')
security.declareProtected(view_management_screens,
'read', 'ZScriptHTML_tryForm')
def __init__(self, id, text=None, content_type=None, encoding='utf-8', strict=False): def __init__(self, id, text=None, content_type=None, encoding='utf-8',
strict=False):
self.id = id self.id = id
self.expand = 0 self.expand = 0
self.strict = strict self.strict = strict
self.ZBindings_edit(self._default_bindings) self.ZBindings_edit(self._default_bindings)
if not text:
text = open(self._default_content_fn).read()
encoding = 'utf-8'
content_type = 'text/html'
self.pt_edit(text, content_type, encoding) self.pt_edit(text, content_type, encoding)
def pt_getEngine(self):
return getEngine()
security.declareProtected(change_page_templates, 'pt_edit') security.declareProtected(change_page_templates, 'pt_edit')
def pt_edit(self, text, content_type, encoding='utf-8'): def pt_edit(self, text, content_type, encoding='utf-8'):
text = text.strip() text = text.strip()
if self.strict and not isinstance(text, unicode): if self.strict and not isinstance(text, unicode):
text = unicode(text, encoding) text = unicode(text, encoding)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
PageTemplate.pt_edit(self, text, content_type) super(ZopePageTemplate, self).pt_edit(text, content_type)
pt_editForm = PageTemplateFile('www/ptEdit', globals(),
__name__='pt_editForm')
pt_editForm._owner = None
manage = manage_main = pt_editForm
source_dot_xml = Src()
security.declareProtected(change_page_templates, 'pt_editAction') security.declareProtected(change_page_templates, 'pt_editAction')
def pt_editAction(self, REQUEST, title, text, content_type, encoding, expand): def pt_editAction(self, REQUEST, title, text, content_type, encoding, expand):
...@@ -155,24 +154,17 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -155,24 +154,17 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
% '<br>'.join(self._v_warnings)) % '<br>'.join(self._v_warnings))
return self.pt_editForm(manage_tabs_message=message) return self.pt_editForm(manage_tabs_message=message)
security.declareProtected(change_page_templates, 'pt_setTitle') security.declareProtected(change_page_templates, 'pt_setTitle')
def pt_setTitle(self, title, encoding='utf-8'): def pt_setTitle(self, title, encoding='utf-8'):
if self.strict and not isinstance(title, unicode): if self.strict and not isinstance(title, unicode):
title = unicode(title, encoding) title = unicode(title, encoding)
self._setPropValue('title', title) self._setPropValue('title', title)
def _setPropValue(self, id, value): def _setPropValue(self, id, value):
""" set a property and invalidate the cache """ """ set a property and invalidate the cache """
PropertyManager._setPropValue(self, id, value) PropertyManager._setPropValue(self, id, value)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
def pt_getEngine(self):
return getEngine()
security.declareProtected(change_page_templates, 'pt_upload') security.declareProtected(change_page_templates, 'pt_upload')
def pt_upload(self, REQUEST, file='', encoding='utf-8'): def pt_upload(self, REQUEST, file='', encoding='utf-8'):
"""Replace the document with the text in file.""" """Replace the document with the text in file."""
...@@ -224,12 +216,12 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -224,12 +216,12 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
"""Parameters to test the script with.""" """Parameters to test the script with."""
return [] return []
# def manage_historyCompare(self, rev1, rev2, REQUEST, def manage_historyCompare(self, rev1, rev2, REQUEST,
# historyComparisonResults=''): historyComparisonResults=''):
# return ZopePageTemplate.inheritedAttribute( return ZopePageTemplate.inheritedAttribute(
# 'manage_historyCompare')( 'manage_historyCompare')(
# self, rev1, rev2, REQUEST, self, rev1, rev2, REQUEST,
# historyComparisonResults=html_diff(rev1._text, rev2._text) ) historyComparisonResults=html_diff(rev1._text, rev2._text) )
def pt_getContext(self, *args, **kw): def pt_getContext(self, *args, **kw):
root = self.getPhysicalRoot() root = self.getPhysicalRoot()
...@@ -246,8 +238,9 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -246,8 +238,9 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
} }
return c return c
security.declareProtected(view_management_screens, 'read', def write(self, text):
'ZScriptHTML_tryForm') self.ZCacheable_invalidate()
ZopePageTemplate.inheritedAttribute('write')(self, text)
def _exec(self, bound_names, args, kw): def _exec(self, bound_names, args, kw):
"""Call a Page Template""" """Call a Page Template"""
...@@ -297,7 +290,7 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -297,7 +290,7 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
""" Handle HTTP PUT requests """ """ Handle HTTP PUT requests """
self.dav__init(REQUEST, RESPONSE) self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1) self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
## XXX:this should be unicode or we must pass an encoding ## XXX this should be unicode or we must pass an encoding
self.pt_edit(REQUEST.get('BODY', '')) self.pt_edit(REQUEST.get('BODY', ''))
RESPONSE.setStatus(204) RESPONSE.setStatus(204)
return RESPONSE return RESPONSE
...@@ -306,7 +299,6 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -306,7 +299,6 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
manage_FTPput = PUT manage_FTPput = PUT
security.declareProtected(ftp_access, 'manage_FTPstat','manage_FTPlist') security.declareProtected(ftp_access, 'manage_FTPstat','manage_FTPlist')
security.declareProtected(ftp_access, 'manage_FTPget') security.declareProtected(ftp_access, 'manage_FTPget')
def manage_FTPget(self): def manage_FTPget(self):
"Get source for FTP download" "Get source for FTP download"
...@@ -350,7 +342,6 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -350,7 +342,6 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
'title': 'This template has an error'},) 'title': 'This template has an error'},)
return icons return icons
security.declareProtected(view, 'pt_source_file') security.declareProtected(view, 'pt_source_file')
def pt_source_file(self): def pt_source_file(self):
"""Returns a file name to be compiled into the TAL code.""" """Returns a file name to be compiled into the TAL code."""
...@@ -364,24 +355,17 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -364,24 +355,17 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
def wl_isLocked(self): def wl_isLocked(self):
return 0 return 0
security.declareProtected(view, 'strictUnicode') def manage_convertUnicode(self, preferred_encodings=preferred_encodings,
def strictUnicode(self): RESPONSE=None):
""" Return True if the ZPT enforces the use of unicode, """Convert non-unicode templates to unicode"""
False otherwise.
"""
return self.strict
def manage_convertUnicode(self, preferred_encodings=preferred_encodings, RESPONSE=None):
""" convert non-unicode templates to unicode """
if not isinstance(self._text, unicode): if not isinstance(self._text, unicode):
for encoding in preferred_encodings: for encoding in preferred_encodings:
try: try:
self._text = unicode(self._text, encoding) self._text = unicode(self._text, encoding)
if RESPONSE: if RESPONSE:
return RESPONSE.redirect(self.absolute_url() + '/pt_editForm?manage_tabs_message=ZPT+successfully+converted') return RESPONSE.redirect(self.absolute_url() +
'/pt_editForm?manage_tabs_message='
'ZPT+successfully+converted')
else: else:
return return
except UnicodeDecodeError: except UnicodeDecodeError:
...@@ -391,49 +375,23 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -391,49 +375,23 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
else: else:
if RESPONSE: if RESPONSE:
return RESPONSE.redirect(self.absolute_url() + '/pt_editForm?manage_tabs_message=ZPT+already+converted') return RESPONSE.redirect(self.absolute_url() +
'/pt_editForm?manage_tabs_message='
'ZPT+already+converted')
else: else:
return return
security.declareProtected(view_management_screens, 'getSource')
getSource = Src()
source_dot_xml = Src()
InitializeClass(ZopePageTemplate) InitializeClass(ZopePageTemplate)
setattr(ZopePageTemplate, 'source.xml', ZopePageTemplate.source_dot_xml) setattr(ZopePageTemplate, 'source.xml', ZopePageTemplate.source_dot_xml)
setattr(ZopePageTemplate, 'source.html', ZopePageTemplate.source_dot_xml) setattr(ZopePageTemplate, 'source.html', ZopePageTemplate.source_dot_xml)
# Product registration and Add support
manage_addPageTemplateForm = PageTemplateFile(
'www/ptAdd', globals(), __name__='manage_addPageTemplateForm')
def _newZPT(id, filename): def manage_addPageTemplate(self, id, title='', text='', encoding='utf-8',
""" factory to generate ZPT instances from the file-system submit=None, REQUEST=None, RESPONSE=None):
based templates (basically for internal purposes)
"""
zpt = ZopePageTemplate(id, open(filename).read(), 'text/html')
zpt.__name__= id
return zpt
class FSZPT(ZopePageTemplate):
""" factory to generate ZPT instances from the file-system
based templates (basically for internal purposes)
"""
def __init__(self, id, filename):
ZopePageTemplate.__init__(self, id, open(filename).read(), 'text/html')
self.__name__= id
InitializeClass(FSZPT)
ZopePageTemplate.pt_editForm = FSZPT('pt_editForm', os.path.join(package_home(globals()),'pt', 'ptEdit.pt'))
# this is scary, do we need this?
ZopePageTemplate.manage = ZopePageTemplate.pt_editForm
manage_addPageTemplateForm= FSZPT('manage_addPageTemplateForm', os.path.join(package_home(globals()), 'pt', 'ptAdd.pt'))
def manage_addPageTemplate(self, id, title='', text='', encoding='utf-8', submit=None, REQUEST=None, RESPONSE=None):
"Add a Page Template with optional file content." "Add a Page Template with optional file content."
filename = '' filename = ''
...@@ -461,11 +419,6 @@ def manage_addPageTemplate(self, id, title='', text='', encoding='utf-8', submit ...@@ -461,11 +419,6 @@ def manage_addPageTemplate(self, id, title='', text='', encoding='utf-8', submit
content_type = guess_type(filename, text) content_type = guess_type(filename, text)
encoding = sniffEncoding(text, encoding) encoding = sniffEncoding(text, encoding)
if not text:
text = open(_default_content_fn).read()
encoding = 'utf-8'
content_type = 'text/html'
zpt = ZopePageTemplate(id, text, content_type, encoding) zpt = ZopePageTemplate(id, text, content_type, encoding)
zpt.pt_setTitle(title, encoding) zpt.pt_setTitle(title, encoding)
self._setObject(id, zpt) self._setObject(id, zpt)
......
...@@ -12,7 +12,6 @@ import Zope2 ...@@ -12,7 +12,6 @@ import Zope2
import transaction import transaction
from Testing.makerequest import makerequest from Testing.makerequest import makerequest
from Products.PageTemplates.ZopePageTemplate import _default_content_fn
class ZPTRegressions(unittest.TestCase): class ZPTRegressions(unittest.TestCase):
...@@ -35,7 +34,7 @@ class ZPTRegressions(unittest.TestCase): ...@@ -35,7 +34,7 @@ class ZPTRegressions(unittest.TestCase):
def testAddWithoutParams(self): def testAddWithoutParams(self):
pt = self._addPT('pt1') pt = self._addPT('pt1')
default_text = open(_default_content_fn).read() default_text = open(pt._default_content_fn).read()
self.assertEqual(pt.title, '') self.assertEqual(pt.title, '')
self.assertEqual(pt.document_src().strip(), default_text.strip()) self.assertEqual(pt.document_src().strip(), default_text.strip())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment