[CMF-checkins]
SVN: CMF/branches/tseaver-viewification/CMFDefault/browser/
- added decode and memoize decorator functions to utils
Yvo Schubbe
y.2006_ at wcm-solutions.de
Tue Jan 31 12:47:30 EST 2006
Log message for revision 41515:
- added decode and memoize decorator functions to utils
- added ViewBase to utils
- refactored FormViewBase to make it more helpful for folder_contents and to get rid of setStatus
- updated document and link edit views
Changed:
U CMF/branches/tseaver-viewification/CMFDefault/browser/documentviews.py
U CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py
U CMF/branches/tseaver-viewification/CMFDefault/browser/templates/document_edit.pt
U CMF/branches/tseaver-viewification/CMFDefault/browser/templates/link_edit.pt
U CMF/branches/tseaver-viewification/CMFDefault/browser/utils.py
-=-
Modified: CMF/branches/tseaver-viewification/CMFDefault/browser/documentviews.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/documentviews.py 2006-01-31 17:37:30 UTC (rev 41514)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/documentviews.py 2006-01-31 17:47:30 UTC (rev 41515)
@@ -21,7 +21,9 @@
from Products.CMFDefault.utils import MessageID as _
from Products.CMFDefault.utils import scrubHTML
+from utils import decode
from utils import FormViewBase
+from utils import memoize
class DocumentEditView(FormViewBase):
@@ -29,56 +31,66 @@
""" Edit view for IMutableDocument.
"""
- _BUTTONS = ({'name': 'change',
- 'value': _(u'Change'),
- 'transform': ('validateTextFile', 'validateHTML', 'update'),
+ _BUTTONS = ({'id': 'change',
+ 'title': _(u'Change'),
+ 'transform': ('validateTextFile', 'validateHTML',
+ 'document_edit_control'),
'redirect': ('context', 'object/edit')},
- {'name': 'change_and_view',
- 'value': _(u'Change and View'),
- 'transform': ('validateTextFile', 'validateHTML', 'update'),
+ {'id': 'change_and_view',
+ 'title': _(u'Change and View'),
+ 'transform': ('validateTextFile', 'validateHTML',
+ 'document_edit_control'),
'redirect': ('context', 'object/view')})
- def title(self):
- return self.context.Title()
+ #helpers
- def description(self):
- return self.context.Description()
+ @memoize
+ def _getHiddenVars(self):
+ belt = self.request.form.get('SafetyBelt', self.context.SafetyBelt())
+ return {'SafetyBelt': belt}
- def SafetyBelt(self):
- return self.request.form.get('SafetyBelt', self.context.SafetyBelt())
+ # interface
+ @memoize
def text_format(self):
return self.request.form.get('text_format', self.context.text_format)
+ @memoize
+ @decode
def text(self):
return self.request.form.get('text', self.context.EditableBody())
+ # validators
+
def validateTextFile(self, file='', **kw):
try:
upload = file.read()
except AttributeError:
- return self.setStatus(True)
+ return True
else:
if upload:
- return self.setStatus(True, text=upload)
+ self.request.form['text'] = upload
+ return True
else:
- return self.setStatus(True)
+ return True
def validateHTML(self, text, description='', **kw):
try:
- description = scrubHTML(description)
- text = scrubHTML(text)
- return self.setStatus(True, text=text, description=description)
+ self.request.form['description'] = scrubHTML(description)
+ self.request.form['text'] = scrubHTML(text)
+ return True
except IllegalHTML, errmsg:
- return self.setStatus(False, errmsg)
+ return False, errmsg
- def update(self, text_format, text, SafetyBelt='', **kw):
+ # controllers
+
+ def document_edit_control(self, text_format, text, SafetyBelt='', **kw):
context = self.context
if text_format != context.text_format or text != context.text:
try:
context.edit(text_format, text, safety_belt=SafetyBelt)
- return self.setStatus(True, _(u'Document changed.'))
+ return True, _(u'Document changed.')
except (ResourceLockedError, EditingConflict), errmsg:
- return self.setStatus(False, errmsg)
+ return False, errmsg
else:
- return self.setStatus(False, _(u'Nothing to change.'))
+ return False, _(u'Nothing to change.')
Modified: CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py 2006-01-31 17:37:30 UTC (rev 41514)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py 2006-01-31 17:47:30 UTC (rev 41515)
@@ -138,47 +138,38 @@
#
import urlparse
-from Products.CMFDefault.exceptions import EditingConflict
from Products.CMFDefault.exceptions import ResourceLockedError
from Products.CMFDefault.utils import MessageID as _
+from utils import decode
from utils import FormViewBase
+from utils import memoize
+
class IllegalURL(ValueError):
pass
+
class LinkEditView(FormViewBase):
- """ Edit view for IMutableDocument.
+ """ Edit view for IMutableLink.
"""
- # XXX: _BUTTONS should become configurable
- _BUTTONS = ({'name': 'change',
- 'value': _(u'Change'),
- 'transform': ('validateURL', 'update'),
+ _BUTTONS = ({'id': 'change',
+ 'title': _(u'Change'),
+ 'transform': ('validateURL', 'link_edit_control'),
'redirect': ('context', 'object/edit'),
},
- {'name': 'change_and_view',
- 'value': _(u'Change and View'),
- 'transform': ('validateURL', 'update'),
+ {'id': 'change_and_view',
+ 'title': _(u'Change and View'),
+ 'transform': ('validateURL', 'link_edit_control'),
'redirect': ('context', 'object/view'),
},
)
- def remote_url(self):
- if 'remote_url' in self.request.form:
- return self.request['remote_url']
- else:
- return self.context.remote_url
+ # helpers
- def validateURL(self, remote_url='', **kw):
- try:
- remote_url = self._normalizeURL(remote_url)
- except IllegalURL, errmsg:
- return self.setStatus(False, errmsg)
- else:
- return self.setStatus(True, remote_url=remote_url)
-
+ @memoize
def _normalizeURL(self, remote_url):
tokens = urlparse.urlparse( remote_url, 'http' )
if tokens[0] == 'http':
@@ -197,13 +188,33 @@
url = urlparse.urlunparse(tokens)
return url
- def update(self, remote_url, **kw):
+ # interface
+
+ @memoize
+ @decode
+ def remote_url(self):
+ return self.request.form.get('remote_url', self.context.remote_url)
+
+ # validators
+
+ def validateURL(self, remote_url='', **kw):
+ try:
+ remote_url = self._normalizeURL(remote_url)
+ except IllegalURL, errmsg:
+ return False, errmsg
+ else:
+ self.request.form[remote_url] = remote_url
+ return True
+
+ # controllers
+
+ def link_edit_control(self, remote_url, **kw):
context = self.context
if remote_url != context.remote_url:
try:
- context.remote_url = remote_url
- return self.setStatus(True, _(u'Link changed.'))
- except (ResourceLockedError, EditingConflict), errmsg:
- return self.setStatus(False, errmsg)
+ context.edit(remote_url=remote_url)
+ return True, _(u'Link changed.')
+ except ResourceLockedError, errmsg:
+ return False, errmsg
else:
- return self.setStatus(False, _(u'Nothing to change.'))
+ return False, _(u'Nothing to change.')
Modified: CMF/branches/tseaver-viewification/CMFDefault/browser/templates/document_edit.pt
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/templates/document_edit.pt 2006-01-31 17:37:30 UTC (rev 41514)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/templates/document_edit.pt 2006-01-31 17:47:30 UTC (rev 41515)
@@ -7,12 +7,9 @@
</metal:slot>
<metal:slot metal:fill-slot="body" i18n:domain="cmf_default">
-<div class="Desktop">
-
<form action="document_edit_form" method="post" enctype="multipart/form-data"
- tal:attributes="action request/ACTUAL_URL">
- <input type="hidden" name="SafetyBelt" value=""
- tal:attributes="value view/SafetyBelt" />
+ tal:attributes="action view/form_action"
+><metal:macro metal:use-macro="context/@@form_widget/hidden_vars" />
<table class="FormLayout">
<tr>
<th i18n:translate="">Title</th>
@@ -57,8 +54,6 @@
</tr>
</table>
</form>
-
-</div>
</metal:slot>
</body>
Modified: CMF/branches/tseaver-viewification/CMFDefault/browser/templates/link_edit.pt
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/templates/link_edit.pt 2006-01-31 17:37:30 UTC (rev 41514)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/templates/link_edit.pt 2006-01-31 17:47:30 UTC (rev 41515)
@@ -3,24 +3,22 @@
<metal:slot metal:fill-slot="header" i18n:domain="cmf_default">
<h1 i18n:translate="">Edit: <tal:span
- tal:content="context/Title" i18n:name="obj_title">Title</tal:span></h1>
+ tal:content="view/title" i18n:name="obj_title">Title</tal:span></h1>
</metal:slot>
<metal:slot metal:fill-slot="body" i18n:domain="cmf_default">
-<div class="Desktop">
-
<form action="link_edit_form" method="post"
- tal:attributes="action request/ACTUAL_URL">
+ tal:attributes="action view/form_action">
<table class="FormLayout">
<tr>
<th i18n:translate="">Title</th>
- <td tal:content="context/Title">Title</td>
+ <td tal:content="view/title">Title</td>
</tr>
<tr>
<th i18n:translate="">URL</th>
<td>
<input type="text" name="remote_url" value=""
- tal:attributes="value view/remote_url" />
+ tal:attributes="value view/remote_url" />
</td>
</tr>
<tr>
@@ -31,8 +29,6 @@
</tr>
</table>
</form>
-
-</div>
</metal:slot>
</body>
Modified: CMF/branches/tseaver-viewification/CMFDefault/browser/utils.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/utils.py 2006-01-31 17:37:30 UTC (rev 41514)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/utils.py 2006-01-31 17:47:30 UTC (rev 41515)
@@ -1,53 +1,161 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Browser view utilities.
+
+$Id$
+"""
+
from ZTUtils import make_query
from Products.CMFCore.utils import getToolByName
+from Products.CMFDefault.utils import html_marshal
+from Products.CMFDefault.utils import toUnicode
+from Products.CMFDefault.utils import MessageID as _
-class FormViewBase:
+def decode(meth):
+ def decoded_meth(self, *args, **kw):
+ return toUnicode(meth(self, *args, **kw), self._getDefaultCharset())
+ return decoded_meth
- def __call__(self, **kw):
- form = self.request.form
- for button in self._BUTTONS:
- if button['name'] in form:
- for transform in button['transform']:
- if not getattr(self, transform)(**form):
- return self.index()
- if self.setRedirect(*button['redirect']):
- return
- return self.index()
+def memoize(meth):
+ def memoized_meth(self, *args):
+ if not hasattr(self, '__memo__'):
+ self.__memo__ = {}
+ sig = (meth, args)
+ if sig not in self.__memo__:
+ self.__memo__[sig] = meth(self, *args)
+ return self.__memo__[sig]
+ return memoized_meth
- def listButtonInfos(self):
- return self._BUTTONS
- def setStatus(self, success, message='', **kw):
- if message:
- self.request.other['portal_status_message'] = message
- if kw:
- for k, v in kw.items():
- self.request.form[k] = v
+class ViewBase:
- return success
+ # helpers
- def setRedirect(self, provider_id, action_path, **kw):
- utool = getToolByName(self.context, 'portal_url')
- portal_url = utool()
+ @memoize
+ def _getTool(self, name):
+ return getToolByName(self.context, name)
+ @memoize
+ def _checkPermission(self, permission):
+ mtool = self._getTool('portal_membership')
+ return mtool.checkPermission(permission, self.context)
+
+ @memoize
+ def _getPortalURL(self):
+ utool = self._getTool('portal_url')
+ return utool()
+
+ @memoize
+ def _getViewURL(self):
+ return self.request['ACTUAL_URL']
+
+ @memoize
+ def _getDefaultCharset(self):
+ ptool = self._getTool('portal_properties')
+ return ptool.getProperty('default_charset', None)
+
+ # interface
+
+ @memoize
+ @decode
+ def title(self):
+ return self.context.Title()
+
+ @memoize
+ @decode
+ def description(self):
+ return self.context.Description()
+
+
+class FormViewBase(ViewBase):
+
+ # helpers
+
+ def _setRedirect(self, provider_id, action_path, keys=''):
if provider_id == 'context':
provider = self.context
else:
- provider = getToolByName(self.context, provider_id)
+ provider = self._getTool(provider_id)
try:
target = provider.getActionInfo(action_path)['url']
except ValueError:
- target = portal_url
+ target = self._getPortalURL()
+ kw = {}
message = self.request.other.get('portal_status_message', '')
- kw['portal_status_message'] = message
- for k, v in kw.items():
- if not v:
- del kw[k]
+ if message:
+ kw['portal_status_message'] = message
+ for k in keys.split(','):
+ k = k.strip()
+ v = self.request.form.get(k, None)
+ if v:
+ kw[k] = v
query = kw and ( '?%s' % make_query(kw) ) or ''
self.request.RESPONSE.redirect( '%s%s' % (target, query) )
return True
+
+ # interface
+
+ def __call__(self, **kw):
+ form = self.request.form
+ for button in self._BUTTONS:
+ if button['id'] in form:
+ for permission in button.get('permissions', ()):
+ if not self._checkPermission(permission):
+ break
+ else:
+ for transform in button.get('transform', ()):
+ status = getattr(self, transform)(**form)
+ if isinstance(status, bool):
+ status = (status,)
+ if len(status) > 1:
+ self.request.other['portal_status_message'] = status[1]
+ if not status[0]:
+ return self.index()
+ if self._setRedirect(*button['redirect']):
+ return
+ return self.index()
+
+ @memoize
+ def form_action(self):
+ return self._getViewURL()
+
+ @memoize
+ def listButtonInfos(self):
+ form = self.request.form
+ buttons = []
+ for button in self._BUTTONS:
+ if button.get('title', None):
+ for permission in button.get('permissions', ()):
+ if not self._checkPermission(permission):
+ break
+ else:
+ for condition in button.get('conditions', ()):
+ if not getattr(self, condition)():
+ break
+ else:
+ buttons.append({'name': button['id'],
+ 'value': button['title']})
+ return tuple(buttons)
+
+ @memoize
+ @decode
+ def listHiddenVarInfos(self):
+ kw = self._getHiddenVars()
+ vars = [ {'name': name, 'value': value}
+ for name, value in html_marshal(**kw) ]
+ return tuple(vars)
More information about the CMF-checkins
mailing list