[CMF-checkins]
SVN: CMF/branches/tseaver-viewification/CMFDefault/browser/
- Adding a proposed viewificaation for the Link content type
Jens Vagelpohl
jens at dataflake.org
Sat Oct 22 11:28:40 EDT 2005
Log message for revision 39558:
- Adding a proposed viewificaation for the Link content type
Changed:
U CMF/branches/tseaver-viewification/CMFDefault/browser/configure.zcml
A CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py
A CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt
A CMF/branches/tseaver-viewification/CMFDefault/browser/tests/test_linkviews.py
-=-
Modified: CMF/branches/tseaver-viewification/CMFDefault/browser/configure.zcml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/configure.zcml 2005-10-22 15:25:11 UTC (rev 39557)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/configure.zcml 2005-10-22 15:28:39 UTC (rev 39558)
@@ -7,7 +7,7 @@
for="Products.CMFCore.interfaces.IMutableDublinCore"
class=".metadata.MetadataView"
name="metadata.html"
- template="metadata.pt"
+ template="templates/metadata.pt"
permission="cmf.ModifyPortalContent"
layer="cmf"
/>
@@ -21,4 +21,31 @@
layer="cmf"
/>
+ <browser:page
+ for="Products.CMFDefault.interfaces.ILink"
+ class=".linkviews.LinkDisplayView"
+ name="view.html"
+ template="templates/content_view.pt"
+ permission="zope2.View"
+ layer="cmf"
+ />
+
+ <browser:page
+ for="Products.CMFDefault.interfaces.IMutableLink"
+ class=".linkviews.LinkEditingView"
+ name="edit.html"
+ template="templates/content_edit.pt"
+ permission="cmf.ModifyPortalContent"
+ layer="cmf"
+ />
+
+ <browser:page
+ for="Products.CMFDefault.interfaces.IMutableLink"
+ class=".linkviews.LinkEditingView"
+ name="edit.py"
+ attribute="controller"
+ permission="cmf.ModifyPortalContent"
+ layer="cmf"
+ />
+
</configure>
Added: CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py 2005-10-22 15:25:11 UTC (rev 39557)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py 2005-10-22 15:28:39 UTC (rev 39558)
@@ -0,0 +1,135 @@
+""" Browser views for CMFDefault.Link.Link
+
+$Id$
+"""
+
+from urllib import quote
+
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass
+
+from Products.CMFDefault.utils import MessageID as _
+from Products.CMFCore.permissions import View
+from Products.CMFCore.permissions import ModifyPortalContent
+
+from Products.Five import BrowserView
+from Products.PageTemplates.PageTemplate import PageTemplate
+
+_LINK_DISPLAY_TEMPLATE = """\
+<p i18n:translate="">Link:
+ <a href="" alt="TITLE"
+ tal:attributes="href options/remote_url;
+ alt options/title;
+ "
+ tal:content="options/remote_url"
+ i18n:name="link">http://www.example.com/</a>
+</p>
+"""
+
+_BUTTONS = {
+ 'change':
+ {'value': _('Change'),
+ 'redirect' : 'edit.html',
+ },
+ 'change_and_view':
+ {'value': _('Change and View'),
+ 'redirect': 'view.html',
+ },
+}
+
+_BUTTON_NAMES = ('change', 'change_and_view')
+
+class LinkDisplayView(BrowserView):
+
+ security = ClassSecurityInfo()
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ _link_display_template = PageTemplate()
+ _link_display_template.write(_LINK_DISPLAY_TEMPLATE)
+
+ security.declareProtected(View, 'renderContent')
+ def renderContent(self):
+ return self._link_display_template( remote_url=self.context.getRemoteUrl()
+ , title=self.context.title
+ )
+
+InitializeClass(LinkDisplayView)
+
+_LINK_EDITING_TEMPLATE = """\
+<form action="edit.py" method="post">
+ <table class="FormLayout">
+ <tr>
+ <th i18n:translate="">Title</th>
+ <td tal:content="options/title">Title</td>
+ </tr>
+ <tr>
+ <th i18n:translate="">URL</th>
+ <td>
+ <input type="text" name="remote_url" size="40" value=""
+ tal:attributes="value options/remote_url" />
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="FormButtons">
+ <tal:loop tal:repeat="button options/buttons"
+ ><input type="submit" name="ButtonName" value="ButtonValue"
+ tal:attributes="name button/name;
+ value button/value;
+ "
+ i18n:attributes="value" /></tal:loop>
+ </td>
+ </tr>
+ </table>
+</form>
+"""
+
+class LinkEditingView(BrowserView):
+
+ security = ClassSecurityInfo()
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ _link_editing_template = PageTemplate()
+ _link_editing_template.write(_LINK_EDITING_TEMPLATE)
+
+ security.declareProtected(View, 'renderContent')
+ def renderContent(self):
+ buttons = [{'name': name, 'value': _BUTTONS[name]['value']}
+ for name in _BUTTON_NAMES]
+ remote_url = self.context.getRemoteUrl()
+
+ return self._link_editing_template( remote_url=remote_url
+ , title=self.context.Title()
+ , buttons=buttons
+ )
+
+ security.declareProtected(ModifyPortalContent, 'update')
+ def update(self, form):
+ self.context.edit(form.get('remote_url', ''))
+
+ security.declareProtected(ModifyPortalContent, 'controller')
+ def controller(self, RESPONSE):
+ """ Process a form post and redirect, if needed.
+ """
+ context = self.context
+ form = self.request.form
+ for button in _BUTTONS.keys():
+ if button in form:
+ self.update(form)
+ goto = '%s/%s' % ( context.absolute_url()
+ , _BUTTONS[button]['redirect']
+ )
+ qs = 'portal_status_message=%s' % quote('Link updated.')
+ RESPONSE.redirect('%s?%s' % (goto, qs))
+ return
+
+ return self.index()
+
+InitializeClass(LinkEditingView)
+
Property changes on: CMF/branches/tseaver-viewification/CMFDefault/browser/linkviews.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt 2005-10-22 15:25:11 UTC (rev 39557)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt 2005-10-22 15:28:39 UTC (rev 39558)
@@ -0,0 +1,85 @@
+Link Views
+==========
+
+Display View
+------------
+
+First, let's create a "dummy" link class, to avoid dependencies on the
+actual content object.
+
+ >>> from Products.CMFDefault.interfaces import ILink
+ >>> class FauxLink:
+ ... def __init__(self, remote_url, title):
+ ... self._edit(remote_url)
+ ... self.title = title
+ ... def _edit(self, remote_url):
+ ... self.remote_url = remote_url
+ ... def edit(self, remote_url):
+ ... self._edit(remote_url)
+ ... def Title(self):
+ ... return self.title
+ ... def getRemoteUrl(self):
+ ... return self.remote_url
+
+Now, let's exercise the standard display view against an instance of
+our link class. Note that because views depend on both their content objects
+and on the request, we need a dummy request as well:
+
+ >>> link = FauxLink(remote_url='http://www.zope.org/', title='Zope.org')
+ >>> from Products.Five.traversable import FakeRequest
+ >>> display_request = FakeRequest()
+ >>> from Products.CMFDefault.browser.linkviews import LinkDisplayView
+ >>> display = LinkDisplayView(link, display_request)
+
+Rather than render the whole page (which would bring in lots of noise and
+unwanted dependencies), let's just exercise the conventional 'renderContent'
+method of the view, which is used to fill the "content well" slot of the
+page:
+
+ >>> print display.renderContent()
+ <p>...
+ <a href="http://www.zope.org/" alt="Zope.org">http://www.zope.org/</a>
+ ...
+
+Editing View
+------------
+
+Let's try editing our link, using the editing view. First, let's render
+the form in the "content well" slot:
+
+ >>> from Products.CMFDefault.browser.linkviews import LinkEditingView
+ >>> editing_request = FakeRequest()
+ >>> editing = LinkEditingView(link, editing_request)
+ >>> print editing.renderContent()
+ <form...
+ ...
+ ...<input type="text" name="remote_url" size="40"...value="http://www.zope.org/" />...
+ ...
+
+Now, let's edit the object. Because the editing handler
+needs to redirect the browser (to avoid spoofing the back button, etc.)
+we have to pass a response. Let's make one up which will allow us to
+test the redirection:
+
+ >>> link.absolute_url = lambda: 'http://example.com/path/to/link'
+ >>> class FauxResponse:
+ ... _redirected = None
+ ... def redirect(self, redirect_url):
+ ... self._redirected = redirect_url
+ >>> response = FauxResponse()
+
+The editing controller expects to get a HTML form, so we need to stuff one
+into the request already present in the LinkEditingView class:
+
+ >>> editing.request.form = { 'remote_url' : 'http://svn.zope.org/'
+ ... , 'change' : '1'
+ ... }
+
+Finally, call the editing handler.
+
+ >>> editing.controller(RESPONSE=response)
+ >>> print link.remote_url
+ http://svn.zope.org/
+ >>> print response._redirected
+ http://example.com/path/to/link/edit.html?portal_status_message=Link%20updated.
+
Property changes on: CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: CMF/branches/tseaver-viewification/CMFDefault/browser/tests/test_linkviews.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/tests/test_linkviews.py 2005-10-22 15:25:11 UTC (rev 39557)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/tests/test_linkviews.py 2005-10-22 15:28:39 UTC (rev 39558)
@@ -0,0 +1,15 @@
+""" Unit tests for Products.CMFDefault.browser.linkviews
+
+$Id$
+"""
+import unittest
+
+def test_suite():
+ from Testing.ZopeTestCase import ZopeDocFileSuite
+ return unittest.TestSuite((
+ ZopeDocFileSuite('linkviews.txt',
+ package="Products.CMFDefault.browser.tests"),
+ ))
+
+if __name__ == '__main__':
+ framework()
Property changes on: CMF/branches/tseaver-viewification/CMFDefault/browser/tests/test_linkviews.py
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the CMF-checkins
mailing list