Commit 731bdd24 authored by Tres Seaver's avatar Tres Seaver

LP #496941: Remove all mention of ``standard_html_header`` and

``standard_html_footer`` from default DTML content.
parent 8bc9075e
...@@ -40,6 +40,9 @@ Features Added ...@@ -40,6 +40,9 @@ Features Added
Bugs Fixed Bugs Fixed
++++++++++ ++++++++++
- LP #496941: Remove all mention of ``standard_html_header`` and
``standard_html_footer`` from default DTML content.
- Fixed a regression in Products.PageTemplates that meant filesystem templates - Fixed a regression in Products.PageTemplates that meant filesystem templates
using Products.Five.browser.pagetemplatefile would treat TALES path using Products.Five.browser.pagetemplatefile would treat TALES path
expressions (but not python expressions) as protected code and so attempt expressions (but not python expressions) as protected code and so attempt
......
...@@ -175,10 +175,14 @@ class DTMLDocumentTopic(HelpTopicBase, DTMLDocument): ...@@ -175,10 +175,14 @@ class DTMLDocumentTopic(HelpTopicBase, DTMLDocument):
default_topic_content="""\ default_topic_content="""\
<dtml-var standard_html_header> <html>
<head><title><dtml-var title_or_id></title>
</head>
<body bgcolor="#FFFFFF">
<h2><dtml-var title></h2> <h2><dtml-var title></h2>
<p>This is the <dtml-var id> Help Topic.</p> <p>This is the <dtml-var id> Help Topic.</p>
<dtml-var standard_html_footer> </body>
</html>
""" """
class DTMLTopic(HelpTopic): class DTMLTopic(HelpTopic):
...@@ -239,9 +243,13 @@ class STXTopic(TextTopic): ...@@ -239,9 +243,13 @@ class STXTopic(TextTopic):
return self.htmlfile(self, REQUEST) return self.htmlfile(self, REQUEST)
htmlfile = HTML("""\ htmlfile = HTML("""\
<dtml-var standard_html_header> <html>
<dtml-var obj fmt="structured-text"> <head><title><dtml-var title_or_id></title>
<dtml-var standard_html_footer>""") </head>
<body bgcolor="#FFFFFF">
<dtml-var obj fmt="structured-text">
</body>
</html>""")
class ReSTTopic(TextTopic): class ReSTTopic(TextTopic):
...@@ -261,9 +269,13 @@ class ReSTTopic(TextTopic): ...@@ -261,9 +269,13 @@ class ReSTTopic(TextTopic):
return self.htmlfile(self, REQUEST) return self.htmlfile(self, REQUEST)
htmlfile = HTML("""\ htmlfile = HTML("""\
<dtml-var standard_html_header> <html>
<dtml-var obj fmt="restructured-text"> <head><title><dtml-var title_or_id></title>
<dtml-var standard_html_footer>""") </head>
<body bgcolor="#FFFFFF">
<dtml-var obj fmt="restructured-text">
</body>
</html>""")
class ImageTopic(HelpTopic): class ImageTopic(HelpTopic):
......
...@@ -11,30 +11,24 @@ ...@@ -11,30 +11,24 @@
# #
############################################################################## ##############################################################################
"""DTML Document objects. """DTML Document objects.
$Id$
""" """
from sgmllib import SGMLParser
from urllib import quote from urllib import quote
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl.Permissions import change_dtml_methods from AccessControl.Permissions import change_dtml_methods
from AccessControl.Permissions import change_dtml_documents from AccessControl.Permissions import change_dtml_documents
from App.class_init import InitializeClass from App.class_init import InitializeClass
from App.Dialogs import MessageDialog
from App.special_dtml import DTMLFile from App.special_dtml import DTMLFile
from App.special_dtml import HTML from App.special_dtml import HTML
from OFS.DTMLMethod import decapitate from OFS.DTMLMethod import decapitate
from OFS.DTMLMethod import DTMLMethod from OFS.DTMLMethod import DTMLMethod
from webdav.common import rfc1123_date from OFS.PropertyManager import PropertyManager
from webdav.Lockable import ResourceLockedError from webdav.Lockable import ResourceLockedError
from zExceptions.TracebackSupplement import PathTracebackSupplement from zExceptions.TracebackSupplement import PathTracebackSupplement
from zope.contenttype import guess_content_type from zope.contenttype import guess_content_type
from ZPublisher.Converters import type_converters
from OFS.PropertyManager import PropertyManager
done='done' done = 'done'
_marker = [] # Create a new marker object. _marker = [] # Create a new marker object.
...@@ -42,10 +36,10 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -42,10 +36,10 @@ class DTMLDocument(PropertyManager, DTMLMethod):
"""DTML Document objects are DocumentTemplate.HTML objects that act """DTML Document objects are DocumentTemplate.HTML objects that act
as methods whose 'self' is the DTML Document itself.""" as methods whose 'self' is the DTML Document itself."""
meta_type='DTML Document' meta_type = 'DTML Document'
icon ='p_/dtmldoc' icon = 'p_/dtmldoc'
manage_options=( manage_options = (
DTMLMethod.manage_options[:2] + DTMLMethod.manage_options[:2] +
PropertyManager.manage_options + PropertyManager.manage_options +
DTMLMethod.manage_options[2:] DTMLMethod.manage_options[2:]
...@@ -58,10 +52,13 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -58,10 +52,13 @@ class DTMLDocument(PropertyManager, DTMLMethod):
or perms or perms
for perms in DTMLMethod.__ac_permissions__]) for perms in DTMLMethod.__ac_permissions__])
def manage_edit(self,data,title,SUBMIT='Change',dtpref_cols='100%', def manage_edit(self, data, title,
dtpref_rows='20',REQUEST=None): SUBMIT='Change',
""" dtpref_cols='100%',
Replaces a Documents contents with Data, Title with Title. dtpref_rows='20',
REQUEST=None
):
""" Replace contents with 'data', title with 'title'.
The SUBMIT parameter is also used to change the size of the editing The SUBMIT parameter is also used to change the size of the editing
area on the default Document edit screen. If the value is "Smaller", area on the default Document edit screen. If the value is "Smaller",
...@@ -71,41 +68,45 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -71,41 +68,45 @@ class DTMLDocument(PropertyManager, DTMLMethod):
""" """
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
if self._size_changes.has_key(SUBMIT): if self._size_changes.has_key(SUBMIT):
return self._er(data,title,SUBMIT,dtpref_cols,dtpref_rows,REQUEST) return self._er(data, title,
SUBMIT, dtpref_cols, dtpref_rows, REQUEST)
if self.wl_isLocked(): if self.wl_isLocked():
raise ResourceLockedError, ( raise ResourceLockedError(
'This document has been locked via WebDAV.') 'This document has been locked via WebDAV.')
self.title=str(title) self.title = str(title)
if type(data) is not type(''): data=data.read() if type(data) is not type(''):
data = data.read()
self.munge(data) self.munge(data)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message="Content changed." message = "Content changed."
return self.manage_main(self,REQUEST,manage_tabs_message=message) return self.manage_main(self, REQUEST, manage_tabs_message=message)
def manage_upload(self,file='', REQUEST=None): def manage_upload(self, file='', REQUEST=None):
"""Replace the contents of the document with the text in file.""" """ Replace the contents of the document with the text in 'file'.
"""
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
if self.wl_isLocked(): if self.wl_isLocked():
raise ResourceLockedError, ( raise ResourceLockedError(
'This document has been locked via WebDAV.') 'This document has been locked via WebDAV.')
if type(file) is not type(''): if type(file) is not type(''):
if REQUEST and not file: if REQUEST and not file:
raise ValueError, 'No file specified' raise ValueError, 'No file specified'
file=file.read() file = file.read()
self.munge(file) self.munge(file)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message="Content uploaded." message = "Content uploaded."
return self.manage_main(self,REQUEST,manage_tabs_message=message) return self.manage_main(self, REQUEST, manage_tabs_message=message)
def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw): def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
"""Render the document given a client object, REQUEST mapping, """Render the document with the given client object.
Response, and key word arguments."""
o If supplied, use REQUEST mapping, Response, and key word arguments.
"""
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
data = self.ZCacheable_get(default=_marker) data = self.ZCacheable_get(default=_marker)
if data is not _marker: if data is not _marker:
...@@ -113,26 +114,27 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -113,26 +114,27 @@ class DTMLDocument(PropertyManager, DTMLMethod):
return data return data
__traceback_supplement__ = (PathTracebackSupplement, self) __traceback_supplement__ = (PathTracebackSupplement, self)
kw['document_id'] =self.getId() kw['document_id'] = self.getId()
kw['document_title']=self.title kw['document_title'] =self.title
if hasattr(self, 'aq_explicit'): if hasattr(self, 'aq_explicit'):
bself=self.aq_explicit bself = self.aq_explicit
else: bself=self else:
bself = self
security=getSecurityManager() security = getSecurityManager()
security.addContext(self) security.addContext(self)
try: try:
if client is None: if client is None:
# Called as subtemplate, so don't need error propigation! # Called as subtemplate, so don't need error propigation!
r=apply(HTML.__call__, (self, bself, REQUEST), kw) r = apply(HTML.__call__, (self, bself, REQUEST), kw)
if RESPONSE is None: result = r if RESPONSE is None: result = r
else: result = decapitate(r, RESPONSE) else: result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
self.ZCacheable_set(result) self.ZCacheable_set(result)
return result return result
r=apply(HTML.__call__, (self, (client, bself), REQUEST), kw) r = apply(HTML.__call__, (self, (client, bself), REQUEST), kw)
if type(r) is not type('') or RESPONSE is None: if type(r) is not type('') or RESPONSE is None:
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
self.ZCacheable_set(r) self.ZCacheable_set(r)
...@@ -140,12 +142,12 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -140,12 +142,12 @@ class DTMLDocument(PropertyManager, DTMLMethod):
finally: security.removeContext(self) finally: security.removeContext(self)
have_key=RESPONSE.headers.has_key have_key = RESPONSE.headers.has_key
if not (have_key('content-type') or have_key('Content-Type')): if not (have_key('content-type') or have_key('Content-Type')):
if self.__dict__.has_key('content_type'): if self.__dict__.has_key('content_type'):
c=self.content_type c = self.content_type
else: else:
c, e=guess_content_type(self.__name__, r) c, e = guess_content_type(self.__name__, r)
RESPONSE.setHeader('Content-Type', c) RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE) result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
...@@ -156,12 +158,16 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -156,12 +158,16 @@ class DTMLDocument(PropertyManager, DTMLMethod):
InitializeClass(DTMLDocument) InitializeClass(DTMLDocument)
default_dd_html="""<dtml-var standard_html_header> default_dd_html="""<html>
<h2><dtml-var title_or_id></h2> <head><title><dtml-var title_or_id></title>
</head>
<body bgcolor="#FFFFFF">
<h2><dtml-var title_or_id></h2>
<p> <p>
This is the <dtml-var id> Document. This is the <dtml-var id> Document.
</p> </p>
<dtml-var standard_html_footer>""" </body>
</html>"""
addForm=DTMLFile('dtml/documentAdd', globals()) addForm=DTMLFile('dtml/documentAdd', globals())
...@@ -169,16 +175,21 @@ def addDTMLDocument(self, id, title='', file='', REQUEST=None, submit=None): ...@@ -169,16 +175,21 @@ def addDTMLDocument(self, id, title='', file='', REQUEST=None, submit=None):
"""Add a DTML Document object with the contents of file. If """Add a DTML Document object with the contents of file. If
'file' is empty, default document text is used. 'file' is empty, default document text is used.
""" """
if type(file) is not type(''): file=file.read() if type(file) is not type(''):
if not file: file=default_dd_html file = file.read()
id=str(id) if not file:
title=str(title) file = default_dd_html
ob=DTMLDocument(file, __name__=id) id =str(id)
ob.title=title title = str(title)
id=self._setObject(id, ob) ob = DTMLDocument(file, __name__=id)
ob.title = title
id = self._setObject(id, ob)
if REQUEST is not None: if REQUEST is not None:
try: u=self.DestinationURL() try:
except: u=REQUEST['URL1'] u = self.DestinationURL()
if submit==" Add and Edit ": u="%s/%s" % (u,quote(id)) except:
u = REQUEST['URL1']
if submit == " Add and Edit ":
u = "%s/%s" % (u,quote(id))
REQUEST.RESPONSE.redirect(u+'/manage_main') REQUEST.RESPONSE.redirect(u+'/manage_main')
return '' return ''
...@@ -11,17 +11,13 @@ ...@@ -11,17 +11,13 @@
# #
############################################################################## ##############################################################################
"""DTML Method objects. """DTML Method objects.
$Id$
""" """
import sys
from urllib import quote from urllib import quote
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.Role import RoleManager from AccessControl.Role import RoleManager
from Acquisition import Implicit from Acquisition import Implicit
from App.class_init import InitializeClass from App.class_init import InitializeClass
from App.Dialogs import MessageDialog
from App.special_dtml import DTMLFile from App.special_dtml import DTMLFile
from App.special_dtml import HTML from App.special_dtml import HTML
from DateTime.DateTime import DateTime from DateTime.DateTime import DateTime
...@@ -33,20 +29,17 @@ from AccessControl.Permissions import view as View ...@@ -33,20 +29,17 @@ from AccessControl.Permissions import view as View
from AccessControl.Permissions import ftp_access from AccessControl.Permissions import ftp_access
from AccessControl.DTML import RestrictedDTML from AccessControl.DTML import RestrictedDTML
from AccessControl.requestmethod import requestmethod from AccessControl.requestmethod import requestmethod
from webdav.common import rfc1123_date from OFS.Cache import Cacheable
from OFS.History import Historical
from OFS.History import html_diff
from OFS.SimpleItem import Item_w__name__
from OFS.ZDOM import ElementWithTitle
from webdav.Lockable import ResourceLockedError from webdav.Lockable import ResourceLockedError
from zExceptions import Forbidden from zExceptions import Forbidden
from zExceptions.TracebackSupplement import PathTracebackSupplement from zExceptions.TracebackSupplement import PathTracebackSupplement
from ZPublisher.Iterators import IStreamIterator from ZPublisher.Iterators import IStreamIterator
from zope.contenttype import guess_content_type from zope.contenttype import guess_content_type
from OFS.Cache import Cacheable
from OFS.History import Historical
from OFS.History import html_diff
from OFS.PropertyManager import PropertyManager
from OFS.SimpleItem import Item_w__name__
from OFS.SimpleItem import pretty_tb
from OFS.ZDOM import ElementWithTitle
_marker = [] # Create a new marker object. _marker = [] # Create a new marker object.
...@@ -59,12 +52,12 @@ class DTMLMethod(RestrictedDTML, ...@@ -59,12 +52,12 @@ class DTMLMethod(RestrictedDTML,
Historical, Historical,
Cacheable, Cacheable,
): ):
"""DTML Method objects are DocumentTemplate.HTML objects that act """ DocumentTemplate.HTML objects that act as methods of their containers.
as methods of their containers.""" """
meta_type='DTML Method' meta_type = 'DTML Method'
_proxy_roles=() _proxy_roles = ()
index_html=None # Prevent accidental acquisition index_html = None # Prevent accidental acquisition
_cache_namespace_keys=() _cache_namespace_keys = ()
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(View) security.declareObjectProtected(View)
...@@ -72,21 +65,18 @@ class DTMLMethod(RestrictedDTML, ...@@ -72,21 +65,18 @@ class DTMLMethod(RestrictedDTML,
# Documents masquerade as functions: # Documents masquerade as functions:
class func_code: class func_code:
pass pass
func_code=func_code() func_code = func_code()
func_code.co_varnames = 'self','REQUEST','RESPONSE' func_code.co_varnames = 'self', 'REQUEST', 'RESPONSE'
func_code.co_argcount = 3 func_code.co_argcount = 3
manage_options = ( manage_options = (
( (
{'label':'Edit', 'action':'manage_main', {'label': 'Edit', 'action': 'manage_main',
'help':('OFSP','DTML-DocumentOrMethod_Edit.stx')}, 'help': ('OFSP', 'DTML-DocumentOrMethod_Edit.stx')},
#upload is deprecated {'label': 'View', 'action': '',
#{'label':'Upload', 'action':'manage_uploadForm', 'help': ('OFSP', 'DTML-DocumentOrMethod_View.stx')},
# 'help':('OFSP','DTML-DocumentOrMethod_Upload.stx')}, {'label': 'Proxy', 'action': 'manage_proxyForm',
{'label':'View', 'action':'', 'help': ('OFSP', 'DTML-DocumentOrMethod_Proxy.stx')},
'help':('OFSP','DTML-DocumentOrMethod_View.stx')},
{'label':'Proxy', 'action':'manage_proxyForm',
'help':('OFSP','DTML-DocumentOrMethod_Proxy.stx')},
) )
+ Historical.manage_options + Historical.manage_options
+ RoleManager.manage_options + RoleManager.manage_options
...@@ -94,21 +84,25 @@ class DTMLMethod(RestrictedDTML, ...@@ -94,21 +84,25 @@ class DTMLMethod(RestrictedDTML,
+ Cacheable.manage_options + Cacheable.manage_options
) )
# Careful in permissiong changes--used by DTMLDocument! # Careful in permission changes--used by DTMLDocument!
security.declareProtected(change_dtml_methods, 'manage_historyCopy') security.declareProtected(change_dtml_methods, 'manage_historyCopy')
security.declareProtected(change_dtml_methods, 'manage_beforeHistoryCopy') security.declareProtected(change_dtml_methods, 'manage_beforeHistoryCopy')
security.declareProtected(change_dtml_methods, 'manage_afterHistoryCopy') security.declareProtected(change_dtml_methods, 'manage_afterHistoryCopy')
# support a more reasonable default for content-type # More reasonable default for content-type for http HEAD requests.
# for http HEAD requests. default_content_type = 'text/html'
default_content_type='text/html'
security.declareProtected(View, '__call__') security.declareProtected(View, '__call__')
def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw): def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
"""Render the document given a client object, REQUEST mapping, """Render using the given client object
Response, and key word arguments."""
o If client is not passed, we are being called as a sub-template:
don't do any error propagation.
o If supplied, use the REQUEST mapping, Response, and key word
arguments.
"""
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
data = self.ZCacheable_get(default=_marker) data = self.ZCacheable_get(default=_marker)
if data is not _marker: if data is not _marker:
...@@ -129,10 +123,10 @@ class DTMLMethod(RestrictedDTML, ...@@ -129,10 +123,10 @@ class DTMLMethod(RestrictedDTML,
return data return data
__traceback_supplement__ = (PathTracebackSupplement, self) __traceback_supplement__ = (PathTracebackSupplement, self)
kw['document_id'] =self.getId() kw['document_id'] = self.getId()
kw['document_title']=self.title kw['document_title'] = self.title
security=getSecurityManager() security = getSecurityManager()
security.addContext(self) security.addContext(self)
if self.__dict__.has_key('validate'): if self.__dict__.has_key('validate'):
first_time_through = 0 first_time_through = 0
...@@ -143,14 +137,16 @@ class DTMLMethod(RestrictedDTML, ...@@ -143,14 +137,16 @@ class DTMLMethod(RestrictedDTML,
if client is None: if client is None:
# Called as subtemplate, so don't need error propagation! # Called as subtemplate, so don't need error propagation!
r=apply(HTML.__call__, (self, client, REQUEST), kw) r = apply(HTML.__call__, (self, client, REQUEST), kw)
if RESPONSE is None: result = r if RESPONSE is None:
else: result = decapitate(r, RESPONSE) result = r
else:
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
self.ZCacheable_set(result) self.ZCacheable_set(result)
return result return result
r=apply(HTML.__call__, (self, client, REQUEST), kw) r = apply(HTML.__call__, (self, client, REQUEST), kw)
if type(r) is not type('') or RESPONSE is None: if type(r) is not type('') or RESPONSE is None:
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
self.ZCacheable_set(r) self.ZCacheable_set(r)
...@@ -161,12 +157,12 @@ class DTMLMethod(RestrictedDTML, ...@@ -161,12 +157,12 @@ class DTMLMethod(RestrictedDTML,
if first_time_through: if first_time_through:
del self.__dict__['validate'] del self.__dict__['validate']
have_key=RESPONSE.headers.has_key have_key = RESPONSE.headers.has_key
if not (have_key('content-type') or have_key('Content-Type')): if not (have_key('content-type') or have_key('Content-Type')):
if self.__dict__.has_key('content_type'): if self.__dict__.has_key('content_type'):
c=self.content_type c = self.content_type
else: else:
c, e=guess_content_type(self.getId(), r) c, e = guess_content_type(self.getId(), r)
RESPONSE.setHeader('Content-Type', c) RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE) result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
...@@ -183,8 +179,10 @@ class DTMLMethod(RestrictedDTML, ...@@ -183,8 +179,10 @@ class DTMLMethod(RestrictedDTML,
# cache entry. # cache entry.
kw = {} kw = {}
for key in self._cache_namespace_keys: for key in self._cache_namespace_keys:
try: val = md[key] try:
except: val = None val = md[key]
except:
val = None
kw[key] = val kw[key] = val
return self.ZCacheable_get(keywords=kw, default=default) return self.ZCacheable_get(keywords=kw, default=default)
return default return default
...@@ -194,8 +192,10 @@ class DTMLMethod(RestrictedDTML, ...@@ -194,8 +192,10 @@ class DTMLMethod(RestrictedDTML,
if self._cache_namespace_keys: if self._cache_namespace_keys:
kw = {} kw = {}
for key in self._cache_namespace_keys: for key in self._cache_namespace_keys:
try: val = md[key] try:
except: val = None val = md[key]
except:
val = None
kw[key] = val kw[key] = val
self.ZCacheable_set(result, keywords=kw) self.ZCacheable_set(result, keywords=kw)
...@@ -204,17 +204,14 @@ class DTMLMethod(RestrictedDTML, ...@@ -204,17 +204,14 @@ class DTMLMethod(RestrictedDTML,
security.declareProtected(change_dtml_methods, 'getCacheNamespaceKeys') security.declareProtected(change_dtml_methods, 'getCacheNamespaceKeys')
def getCacheNamespaceKeys(self): def getCacheNamespaceKeys(self):
''' """ Return the cacheNamespaceKeys.
Returns the cacheNamespaceKeys. """
'''
return self._cache_namespace_keys return self._cache_namespace_keys
security.declareProtected(change_dtml_methods, 'setCacheNamespaceKeys') security.declareProtected(change_dtml_methods, 'setCacheNamespaceKeys')
def setCacheNamespaceKeys(self, keys, REQUEST=None): def setCacheNamespaceKeys(self, keys, REQUEST=None):
''' """ Set the list of names looked up to provide a cache key.
Sets the list of names that should be looked up in the """
namespace to provide a cache key.
'''
ks = [] ks = []
for key in keys: for key in keys:
key = str(key).strip() key = str(key).strip()
...@@ -229,34 +226,34 @@ class DTMLMethod(RestrictedDTML, ...@@ -229,34 +226,34 @@ class DTMLMethod(RestrictedDTML,
return len(self.raw) return len(self.raw)
# deprecated; use get_size! # deprecated; use get_size!
getSize=get_size getSize = get_size
security.declareProtected(change_dtml_methods, 'manage') security.declareProtected(change_dtml_methods, 'manage')
security.declareProtected(change_dtml_methods, 'manage_editForm') security.declareProtected(change_dtml_methods, 'manage_editForm')
manage_editForm=DTMLFile('dtml/documentEdit', globals()) manage_editForm = DTMLFile('dtml/documentEdit', globals())
manage_editForm._setName('manage_editForm') manage_editForm._setName('manage_editForm')
# deprecated! # deprecated!
manage_uploadForm=manage_editForm manage_uploadForm = manage_editForm
security.declareProtected(change_dtml_methods, 'manage_main') security.declareProtected(change_dtml_methods, 'manage_main')
manage=manage_main=manage_editDocument=manage_editForm manage = manage_main = manage_editDocument = manage_editForm
security.declareProtected(change_proxy_roles, 'manage_proxyForm') security.declareProtected(change_proxy_roles, 'manage_proxyForm')
manage_proxyForm=DTMLFile('dtml/documentProxy', globals()) manage_proxyForm = DTMLFile('dtml/documentProxy', globals())
_size_changes={ _size_changes = {
'Bigger': (5,5), 'Bigger': (5, 5),
'Smaller': (-5,-5), 'Smaller': (-5, -5),
'Narrower': (0,-5), 'Narrower': (0, -5),
'Wider': (0,5), 'Wider': (0, 5),
'Taller': (5,0), 'Taller': (5, 0),
'Shorter': (-5,0), 'Shorter': (-5, 0),
} }
def _er(self,data,title,SUBMIT,dtpref_cols,dtpref_rows,REQUEST): def _er(self, data, title, SUBMIT, dtpref_cols, dtpref_rows, REQUEST):
dr,dc = self._size_changes[SUBMIT] dr, dc = self._size_changes[SUBMIT]
rows = str(max(1, int(dtpref_rows) + dr)) rows = str(max(1, int(dtpref_rows) + dr))
cols = str(dtpref_cols) cols = str(dtpref_cols)
if cols.endswith('%'): if cols.endswith('%'):
...@@ -267,15 +264,17 @@ class DTMLMethod(RestrictedDTML, ...@@ -267,15 +264,17 @@ class DTMLMethod(RestrictedDTML,
setCookie = REQUEST["RESPONSE"].setCookie setCookie = REQUEST["RESPONSE"].setCookie
setCookie("dtpref_rows", rows, path='/', expires=e) setCookie("dtpref_rows", rows, path='/', expires=e)
setCookie("dtpref_cols", cols, path='/', expires=e) setCookie("dtpref_cols", cols, path='/', expires=e)
REQUEST.other.update({"dtpref_cols":cols, "dtpref_rows":rows}) REQUEST.other.update({"dtpref_cols": cols, "dtpref_rows": rows})
return self.manage_main(self, REQUEST, title=title, return self.manage_main(self, REQUEST, title=title,
__str__=self.quotedHTML(data)) __str__=self.quotedHTML(data))
security.declareProtected(change_dtml_methods, 'manage_edit') security.declareProtected(change_dtml_methods, 'manage_edit')
def manage_edit(self,data,title,SUBMIT='Change',dtpref_cols='100%', def manage_edit(self, data, title,
dtpref_rows='20',REQUEST=None): SUBMIT='Change',
""" dtpref_cols='100%',
Replaces a Documents contents with Data, Title with Title. dtpref_rows='20',
REQUEST=None):
""" Replace contents with 'data', title with 'title'.
The SUBMIT parameter is also used to change the size of the editing The SUBMIT parameter is also used to change the size of the editing
area on the default Document edit screen. If the value is "Smaller", area on the default Document edit screen. If the value is "Smaller",
...@@ -285,56 +284,63 @@ class DTMLMethod(RestrictedDTML, ...@@ -285,56 +284,63 @@ class DTMLMethod(RestrictedDTML,
""" """
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
if self._size_changes.has_key(SUBMIT): if self._size_changes.has_key(SUBMIT):
return self._er(data,title,SUBMIT,dtpref_cols,dtpref_rows,REQUEST) return self._er(data, title,
SUBMIT, dtpref_cols, dtpref_rows, REQUEST)
if self.wl_isLocked(): if self.wl_isLocked():
raise ResourceLockedError, 'This DTML Method is locked via WebDAV' raise ResourceLockedError('This DTML Method is locked via WebDAV')
self.title=str(title) self.title = str(title)
if type(data) is not type(''): data=data.read() if type(data) is not type(''):
data = data.read()
self.munge(data) self.munge(data)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message="Saved changes." message = "Saved changes."
return self.manage_main(self,REQUEST,manage_tabs_message=message) return self.manage_main(self, REQUEST, manage_tabs_message=message)
security.declareProtected(change_dtml_methods, 'manage_upload') security.declareProtected(change_dtml_methods, 'manage_upload')
def manage_upload(self,file='', REQUEST=None): def manage_upload(self, file='', REQUEST=None):
"""Replace the contents of the document with the text in file.""" """ Replace the contents of the document with the text in 'file'.
"""
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
if self.wl_isLocked(): if self.wl_isLocked():
raise ResourceLockedError, 'This DTML Method is locked via WebDAV' raise ResourceLockedError('This DTML Method is locked via WebDAV')
if type(file) is not type(''): if type(file) is not type(''):
if REQUEST and not file: if REQUEST and not file:
raise ValueError, 'No file specified' raise ValueError('No file specified')
file=file.read() file = file.read()
self.munge(file) self.munge(file)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message="Saved changes." message = "Saved changes."
return self.manage_main(self,REQUEST,manage_tabs_message=message) return self.manage_main(self, REQUEST, manage_tabs_message=message)
def manage_haveProxy(self,r): return r in self._proxy_roles def manage_haveProxy(self, r):
return r in self._proxy_roles
def _validateProxy(self, request, roles=None): def _validateProxy(self, request, roles=None):
if roles is None: roles=self._proxy_roles if roles is None:
if not roles: return roles = self._proxy_roles
user=u=getSecurityManager().getUser() if not roles:
user=user.allowed return
user = u = getSecurityManager().getUser()
user = user.allowed
for r in roles: for r in roles:
if r and not user(self, (r,)): if r and not user(self, (r,)):
user=None user = None
break break
if user is not None: return if user is not None:
return
raise Forbidden, ( raise Forbidden(
'You are not authorized to change <em>%s</em> because you ' 'You are not authorized to change <em>%s</em> because you '
'do not have proxy roles.\n<!--%s, %s-->' % (self.__name__, u, roles)) 'do not have proxy roles.\n<!--%s, %s-->'
% (self.__name__, u, roles))
security.declareProtected(change_proxy_roles, 'manage_proxy') security.declareProtected(change_proxy_roles, 'manage_proxy')
@requestmethod('POST') @requestmethod('POST')
...@@ -342,20 +348,23 @@ class DTMLMethod(RestrictedDTML, ...@@ -342,20 +348,23 @@ class DTMLMethod(RestrictedDTML,
"Change Proxy Roles" "Change Proxy Roles"
self._validateProxy(REQUEST, roles) self._validateProxy(REQUEST, roles)
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
self._proxy_roles=tuple(roles) self._proxy_roles = tuple(roles)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message="Saved changes." message = "Saved changes."
return self.manage_proxyForm(self,REQUEST,manage_tabs_message=message) return self.manage_proxyForm(self, REQUEST,
manage_tabs_message=message)
security.declareProtected(view_management_screens, 'PrincipiaSearchSource') security.declareProtected(view_management_screens, 'PrincipiaSearchSource')
def PrincipiaSearchSource(self): def PrincipiaSearchSource(self):
"Support for searching - the document's contents are searched." """ Support for searching - the document's contents are searched.
"""
return self.read() return self.read()
security.declareProtected(view_management_screens, 'document_src') security.declareProtected(view_management_screens, 'document_src')
def document_src(self, REQUEST=None, RESPONSE=None): def document_src(self, REQUEST=None, RESPONSE=None):
"""Return unprocessed document source.""" """ Return unprocessed document source.
"""
if RESPONSE is not None: if RESPONSE is not None:
RESPONSE.setHeader('Content-Type', 'text/plain') RESPONSE.setHeader('Content-Type', 'text/plain')
return self.read() return self.read()
...@@ -364,10 +373,11 @@ class DTMLMethod(RestrictedDTML, ...@@ -364,10 +373,11 @@ class DTMLMethod(RestrictedDTML,
security.declareProtected(change_dtml_methods, 'PUT') security.declareProtected(change_dtml_methods, 'PUT')
def PUT(self, REQUEST, RESPONSE): def PUT(self, REQUEST, RESPONSE):
"""Handle HTTP PUT requests.""" """ Handle FTP / 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)
body=REQUEST.get('BODY', '') body = REQUEST.get('BODY', '')
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
self.munge(body) self.munge(body)
self.ZCacheable_invalidate() self.ZCacheable_invalidate()
...@@ -379,7 +389,8 @@ class DTMLMethod(RestrictedDTML, ...@@ -379,7 +389,8 @@ class DTMLMethod(RestrictedDTML,
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.
"""
return self.read() return self.read()
...@@ -419,7 +430,8 @@ def decapitate(html, RESPONSE=None): ...@@ -419,7 +430,8 @@ def decapitate(html, RESPONSE=None):
eolen = 2 eolen = 2
else: else:
eol = html.find( '\n', spos) eol = html.find( '\n', spos)
if eol < 0: return html if eol < 0:
return html
eolen = 1 eolen = 1
header.append(html[spos:eol].strip()) header.append(html[spos:eol].strip())
spos = eol + eolen spos = eol + eolen
...@@ -430,13 +442,17 @@ def decapitate(html, RESPONSE=None): ...@@ -430,13 +442,17 @@ def decapitate(html, RESPONSE=None):
return html[spos + eolen:] return html[spos + eolen:]
default_dm_html="""<dtml-var standard_html_header> default_dm_html="""<html>
<head><title><dtml-var title_or_id></title>
</head>
<body bgcolor="#FFFFFF">
<h2><dtml-var title_or_id> <dtml-var document_title></h2> <h2><dtml-var title_or_id> <dtml-var document_title></h2>
<p> <p>
This is the <dtml-var document_id> Document This is the <dtml-var document_id> Document
in the <dtml-var title_and_id> Folder. in the <dtml-var title_and_id> Folder.
</p> </p>
<dtml-var standard_html_footer>""" </body>
</html>"""
addForm=DTMLFile('dtml/methodAdd', globals()) addForm=DTMLFile('dtml/methodAdd', globals())
...@@ -444,16 +460,21 @@ def addDTMLMethod(self, id, title='', file='', REQUEST=None, submit=None): ...@@ -444,16 +460,21 @@ def addDTMLMethod(self, id, title='', file='', REQUEST=None, submit=None):
"""Add a DTML Method object with the contents of file. If """Add a DTML Method object with the contents of file. If
'file' is empty, default document text is used. 'file' is empty, default document text is used.
""" """
if type(file) is not type(''): file=file.read() if type(file) is not type(''):
if not file: file=default_dm_html file = file.read()
id=str(id) if not file:
title=str(title) file = default_dm_html
ob=DTMLMethod(file, __name__=id) id = str(id)
ob.title=title title = str(title)
id=self._setObject(id, ob) ob = DTMLMethod(file, __name__=id)
ob.title = title
id = self._setObject(id, ob)
if REQUEST is not None: if REQUEST is not None:
try: u=self.DestinationURL() try:
except: u=REQUEST['URL1'] u = self.DestinationURL()
if submit==" Add and Edit ": u="%s/%s" % (u,quote(id)) except:
u = REQUEST['URL1']
if submit == " Add and Edit ":
u = "%s/%s" % (u, quote(id))
REQUEST.RESPONSE.redirect(u+'/manage_main') REQUEST.RESPONSE.redirect(u+'/manage_main')
return '' return ''
...@@ -15,9 +15,32 @@ class DTMLDocumentTests(unittest.TestCase): ...@@ -15,9 +15,32 @@ class DTMLDocumentTests(unittest.TestCase):
verifyClass(IWriteLock, self._getTargetClass()) verifyClass(IWriteLock, self._getTargetClass())
class FactoryTests(unittest.TestCase):
def test_defaults_no_standard_html_header(self):
# see LP #496961
from OFS.DTMLDocument import addDTMLDocument
from OFS.DTMLDocument import DTMLDocument
dispatcher = DummyDispatcher()
addDTMLDocument(dispatcher, 'id')
method = dispatcher._set['id']
self.failUnless(isinstance(method, DTMLDocument))
self.failIf('standard_html_header' in method.read())
self.failIf('standard_html_footer' in method.read())
class DummyDispatcher:
def __init__(self):
self._set = {}
def _setObject(self, key, value):
self._set[key] = value
def test_suite(): def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
unittest.makeSuite(DTMLDocumentTests), unittest.makeSuite(DTMLDocumentTests),
unittest.makeSuite(FactoryTests),
)) ))
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -15,9 +15,33 @@ class DTMLMethodTests(unittest.TestCase): ...@@ -15,9 +15,33 @@ class DTMLMethodTests(unittest.TestCase):
verifyClass(IWriteLock, self._getTargetClass()) verifyClass(IWriteLock, self._getTargetClass())
class FactoryTests(unittest.TestCase):
def test_defaults_no_standard_html_header(self):
# see LP #496961
from OFS.DTMLMethod import addDTMLMethod
from OFS.DTMLMethod import DTMLMethod
dispatcher = DummyDispatcher()
addDTMLMethod(dispatcher, 'id')
method = dispatcher._set['id']
self.failUnless(isinstance(method, DTMLMethod))
self.failIf('standard_html_header' in method.read())
self.failIf('standard_html_footer' in method.read())
class DummyDispatcher:
def __init__(self):
self._set = {}
def _setObject(self, key, value):
self._set[key] = value
def test_suite(): def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
unittest.makeSuite(DTMLMethodTests), unittest.makeSuite(DTMLMethodTests),
unittest.makeSuite(FactoryTests),
)) ))
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -79,8 +79,9 @@ def manage_addZSearch(self, report_id, report_title, report_style, ...@@ -79,8 +79,9 @@ def manage_addZSearch(self, report_id, report_title, report_style,
self.manage_addDocument( self.manage_addDocument(
report_id,report_title, report_id,report_title,
('<dtml-var standard_html_header>\n%s\n' ('<html><head><title><dtml-var title_or_id></title>'
'<dtml-var standard_html_footer>' % '</head><body bgcolor="#FFFFFF">\n%s\n'
'</body></html>' %
join(map(lambda q, report_style=report_style: join(map(lambda q, report_style=report_style:
custom_default_report(q.id, q, no_table=report_style), qs), custom_default_report(q.id, q, no_table=report_style), qs),
'\n<hr>\n'))) '\n<hr>\n')))
...@@ -166,7 +167,8 @@ def default_input_form(arguments,action='query', ...@@ -166,7 +167,8 @@ def default_input_form(arguments,action='query',
items=arguments.items() items=arguments.items()
return ( return (
"%s\n%s%s" % ( "%s\n%s%s" % (
'<dtml-var standard_html_header>\n%s\n' '<html><head><title><dtml-var title_or_id></title>'
'</head><body bgcolor="#FFFFFF">\n%s\n'
'<form action="%s" method="get">\n' '<form action="%s" method="get">\n'
'<h2><dtml-var document_title></h2>\n' '<h2><dtml-var document_title></h2>\n'
'Enter query parameters:<br>' 'Enter query parameters:<br>'
...@@ -193,18 +195,19 @@ def default_input_form(arguments,action='query', ...@@ -193,18 +195,19 @@ def default_input_form(arguments,action='query',
'\n<tr><td colspan=2 align=center>\n' '\n<tr><td colspan=2 align=center>\n'
'<input type="SUBMIT" name="SUBMIT" value="Submit Query">\n' '<input type="SUBMIT" name="SUBMIT" value="Submit Query">\n'
'</td></tr>\n</table>\n</form>\n' '</td></tr>\n</table>\n</form>\n'
'<dtml-var standard_html_footer>\n' '</body></html>\n'
) )
) )
else: else:
return ( return (
'<dtml-var standard_html_header>\n%s\n' '<html><head><title><dtml-var title_or_id></title>'
'</head><body bgcolor="#FFFFFF">\n%s\n'
'<form action="%s" method="get">\n' '<form action="%s" method="get">\n'
'<h2><dtml-var document_title></h2>\n' '<h2><dtml-var document_title></h2>\n'
'This query requires no input.<p>\n' 'This query requires no input.<p>\n'
'<input type="SUBMIT" name="SUBMIT" value="Submit Query">\n' '<input type="SUBMIT" name="SUBMIT" value="Submit Query">\n'
'</form>\n' '</form>\n'
'<dtml-var standard_html_footer>\n' '</body></html>\n'
% (tabs, action) % (tabs, action)
) )
......
...@@ -245,8 +245,9 @@ def upload_html(object, f): ...@@ -245,8 +245,9 @@ def upload_html(object, f):
body = ("<!--#var standard_html_header-->\n\n" + body = ("<!--#var standard_html_header-->\n\n" +
body + "\n\n<!--#var standard_html_footer-->") body + "\n\n<!--#var standard_html_footer-->")
else: else:
body = ("<dtml-var standard_html_header>\n\n" + body = ("<html><head><title><dtml-var title_or_id></title>
body + "\n\n<dtml-var standard_html_footer>") </head><body bgcolor="#FFFFFF">\n\n" +
body + "\n\n</body></html>")
else: else:
if old: f=f.read() if old: f=f.read()
......
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