Commit 7b406710 authored by Andreas Jung's avatar Andreas Jung

merging Z3 ZPT implementation

parents 9d98ceec 592534b9
##############################################################################
#
# Copyright (c) 2002 Zope Corporation 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
#
##############################################################################
from GlobalTranslationService import getGlobalTranslationService
from zope.tales.tales import ExpressionEngine
from zope.tales.expressions import PathExpr, StringExpr, NotExpr, DeferExpr, SubPathExpr
from zope.tales.expressions import SimpleModuleImporter, _marker
from zope.tales.pythonexpr import PythonExpr
from zope.tales.tales import _valid_name, _parse_expr, NAME_RE, Undefined, Context
from zope.i18n import translate
GTS = getGlobalTranslationService()
def BoboTraverseAwareSimpleTraverse(object, path_items, econtext):
""" a slightly modified version of zope.tales.expressions.simpleTraverse()
that interacts correctly with objects implementing bobo_traverse().
"""
for name in path_items:
next = getattr(object, name, _marker)
if next is not _marker:
object = next
else:
try:
object = object.restrictedTraverse(name)
except (KeyError, AttributeError):
try:
object = object[name]
except:
object = getattr(object, name)
return object
class PathExpr(PathExpr):
"""We need to subclass PathExpr at this point since there is no other
away to pass our own traverser because we do not instantiate
PathExpr on our own...this sucks!
"""
def __init__(self, name, expr, engine, traverser=BoboTraverseAwareSimpleTraverse):
self._s = expr
self._name = name
paths = expr.split('|')
self._subexprs = []
add = self._subexprs.append
for i in range(len(paths)):
path = paths[i].lstrip()
if _parse_expr(path):
# This part is the start of another expression type,
# so glue it back together and compile it.
add(engine.compile('|'.join(paths[i:]).lstrip()))
break
add(SubPathExpr(path, traverser, engine)._eval)
class Context(Context):
def translate(self, msgid, domain=None, mapping=None, default=None):
# import pdb
# pdb.set_trace()
return GTS.translate(msgid, domain, mapping,
context=self.contexts['context'], default=default)
def translate(self, domain, msgid, mapping=None,
context=None, target_language=None, default=None):
if context is None:
context = self.contexts.get('here')
return getGlobalTranslationService().translate(
domain, msgid, mapping=mapping,
context=context,
default=default,
target_language=target_language)
class ExpressionEngine(ExpressionEngine):
def getContext(self, contexts=None, **kwcontexts):
if contexts is not None:
if kwcontexts:
kwcontexts.update(contexts)
else:
kwcontexts = contexts
return Context(self, kwcontexts)
def Engine():
e = ExpressionEngine()
reg = e.registerType
for pt in PathExpr._default_type_names:
reg(pt, PathExpr)
reg('string', StringExpr)
reg('python', PythonExpr)
reg('not', NotExpr)
reg('defer', DeferExpr)
e.registerBaseName('modules', SimpleModuleImporter())
return e
Engine = Engine()
...@@ -10,34 +10,35 @@ ...@@ -10,34 +10,35 @@
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE
# #
############################################################################## ##############################################################################
"""Filesystem Page Template module
Zope object encapsulating a Page Template from the filesystem. import os
"""
__version__ = '$Revision: 1.30 $'[11:-2] from Globals import package_home, InitializeClass
from App.config import getConfiguration
from Acquisition import aq_parent, aq_inner
from ZopePageTemplate import ZopePageTemplate
from zope.app.content_types import guess_content_type
import AccessControl
import os, AccessControl
from logging import getLogger
from Globals import package_home, DevelopmentMode
from Shared.DC.Scripts.Script import Script
from Shared.DC.Scripts.Signature import FuncCode
from AccessControl import getSecurityManager
from OFS.Traversable import Traversable
from PageTemplate import PageTemplate
from Expressions import SecureModuleImporter
from ComputedAttribute import ComputedAttribute from ComputedAttribute import ComputedAttribute
from Acquisition import aq_parent, aq_inner from OFS.SimpleItem import SimpleItem
from App.config import getConfiguration from Expressions import SecureModuleImporter
from OFS.SimpleItem import Item_w__name__ from OFS.Traversable import Traversable
from zope.pagetemplate.pagetemplatefile import PageTemplateFile as PTF
from zope.pagetemplate.pagetemplate import PageTemplate as PT
from Shared.DC.Scripts.Script import Script
from OFS.SimpleItem import Item_w__name__
from Shared.DC.Scripts.Signature import FuncCode
LOG = getLogger('PageTemplateFile') from Engine import Engine
class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable):
"Zope wrapper for filesystem Page Template using TAL, TALES, and METAL"
meta_type = 'Page Template (File)' class PageTemplateFile(SimpleItem, Script, PT, Traversable):
""" A Zope 2-aware wrapper class around the Zope 3 ZPT
PageTemplateFile implementation.
"""
func_defaults = None func_defaults = None
func_code = FuncCode((), 0) func_code = FuncCode((), 0)
...@@ -53,32 +54,47 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable): ...@@ -53,32 +54,47 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable):
security.declareProtected('View management screens', security.declareProtected('View management screens',
'read', 'document_src') 'read', 'document_src')
_default_bindings = {'name_subpath': 'traverse_subpath'}
def __init__(self, filename, _prefix=None, **kw): def __init__(self, filename, _prefix=None, **kw):
self.ZBindings_edit(self._default_bindings)
if _prefix is None: name = None
_prefix = getConfiguration().softwarehome if kw.has_key('__name__'):
elif not isinstance(_prefix, str): name = kw['__name__']
_prefix = package_home(_prefix) del kw['__name__']
name = kw.get('__name__')
basepath, ext = os.path.splitext(filename) basepath, ext = os.path.splitext(filename)
if name: if name:
self._need__name__ = 0 self.id = self.__name__ = name
self.__name__ = name
else: else:
self.__name__ = os.path.basename(basepath) self.id = self.__name__ = os.path.basename(basepath)
if _prefix:
if isinstance(_prefix, str):
filename = os.path.join(_prefix, filename)
else:
filename = os.path.join(package_home(_prefix), filename)
if not ext: if not ext:
# XXX This is pretty bogus, but can't be removed since
# it's been released this way.
filename = filename + '.zpt' filename = filename + '.zpt'
self.filename = os.path.join(_prefix, filename)
def getId(self): self.filename = filename
"""return the ID of this object"""
return self.__name__ content = open(filename).read()
from ZopePageTemplate import guess_type
self.pt_edit( content, guess_type(filename, content))
def pt_getEngine(self):
return Engine
def pt_getContext(self): def pt_getContext(self):
root = self.getPhysicalRoot() root = self.getPhysicalRoot()
context = self._getContext() context = self._getContext()
from DateTime.DateTime import DateTime
c = {'template': self, c = {'template': self,
'here': context, 'here': context,
'context': context, 'context': context,
...@@ -86,6 +102,7 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable): ...@@ -86,6 +102,7 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable):
'nothing': None, 'nothing': None,
'options': {}, 'options': {},
'root': root, 'root': root,
'DateTime' : DateTime,
'request': getattr(root, 'REQUEST', None), 'request': getattr(root, 'REQUEST', None),
'modules': SecureModuleImporter, 'modules': SecureModuleImporter,
} }
...@@ -106,11 +123,14 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable): ...@@ -106,11 +123,14 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable):
pass pass
# Execute the template in a new security context. # Execute the template in a new security context.
security = getSecurityManager() security = AccessControl.getSecurityManager()
bound_names['user'] = security.getUser() bound_names['user'] = security.getUser()
security.addContext(self) security.addContext(self)
try: try:
return self.pt_render(extra_context=bound_names) context = self.pt_getContext()
context.update(bound_names)
return self.pt_render(context)
finally: finally:
security.removeContext(self) security.removeContext(self)
...@@ -187,20 +207,4 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable): ...@@ -187,20 +207,4 @@ class PageTemplateFile(Item_w__name__, Script, PageTemplate, Traversable):
raise StorageError, ("Instance of AntiPersistent class %s " raise StorageError, ("Instance of AntiPersistent class %s "
"cannot be stored." % self.__class__.__name__) "cannot be stored." % self.__class__.__name__)
InitializeClass(PageTemplateFile)
XML_PREFIXES = [
"<?xml", # ascii, utf-8
"\xef\xbb\xbf<?xml", # utf-8 w/ byte order mark
"\0<\0?\0x\0m\0l", # utf-16 big endian
"<\0?\0x\0m\0l\0", # utf-16 little endian
"\xfe\xff\0<\0?\0x\0m\0l", # utf-16 big endian w/ byte order mark
"\xff\xfe<\0?\0x\0m\0l\0", # utf-16 little endian w/ byte order mark
]
XML_PREFIX_MAX_LENGTH = max(map(len, XML_PREFIXES))
def sniff_type(text):
for prefix in XML_PREFIXES:
if text.startswith(prefix):
return "text/xml"
return None
...@@ -38,7 +38,8 @@ from webdav.WriteLockInterface import WriteLockInterface ...@@ -38,7 +38,8 @@ from webdav.WriteLockInterface import WriteLockInterface
from zope.pagetemplate.pagetemplate import PageTemplate from zope.pagetemplate.pagetemplate import PageTemplate
from zope.pagetemplate.pagetemplatefile import sniff_type from zope.pagetemplate.pagetemplatefile import sniff_type
from Products.PageTemplates.Expressions import getEngine from Engine import Engine
# 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)
...@@ -188,6 +189,10 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable, ...@@ -188,6 +189,10 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
def pt_getEngine(self):
return Engine
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."""
......
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