[Checkins] SVN: zmi.core/trunk/s Copy browser package from zope.app.zptpage.
Yusei Tahara
yusei at domen.cx
Sat Nov 21 02:25:52 EST 2009
Log message for revision 105934:
Copy browser package from zope.app.zptpage.
Changed:
U zmi.core/trunk/setup.py
U zmi.core/trunk/src/zmi/core/configure.zcml
A zmi.core/trunk/src/zmi/core/zptpage/
A zmi.core/trunk/src/zmi/core/zptpage/__init__.py
A zmi.core/trunk/src/zmi/core/zptpage/collector266.txt
A zmi.core/trunk/src/zmi/core/zptpage/collector269.txt
A zmi.core/trunk/src/zmi/core/zptpage/configure.zcml
A zmi.core/trunk/src/zmi/core/zptpage/inlinecode.pt
A zmi.core/trunk/src/zmi/core/zptpage/preview.pt
A zmi.core/trunk/src/zmi/core/zptpage/tests.py
A zmi.core/trunk/src/zmi/core/zptpage/url.txt
A zmi.core/trunk/src/zmi/core/zptpage/zpt.gif
A zmi.core/trunk/src/zmi/core/zptpage/zptpage.py
-=-
Modified: zmi.core/trunk/setup.py
===================================================================
--- zmi.core/trunk/setup.py 2009-11-21 07:14:14 UTC (rev 105933)
+++ zmi.core/trunk/setup.py 2009-11-21 07:25:52 UTC (rev 105934)
@@ -69,11 +69,11 @@
'zope.app.sqlscript',
'zope.app.tree',
'zope.app.undo',
+ 'zope.app.zptpage',
],
extras_require=dict(test=['zope.app.testing',
'zope.securitypolicy',
'zope.testbrowser',
- 'zope.app.zptpage',
'zope.app.preference',
'zope.app.apidoc',
]),
Modified: zmi.core/trunk/src/zmi/core/configure.zcml
===================================================================
--- zmi.core/trunk/src/zmi/core/configure.zcml 2009-11-21 07:14:14 UTC (rev 105933)
+++ zmi.core/trunk/src/zmi/core/configure.zcml 2009-11-21 07:25:52 UTC (rev 105934)
@@ -20,4 +20,5 @@
<include package=".sqlscript" />
<include package=".tree" />
<include package=".undo" />
+ <include package=".zptpage" />
</configure>
Added: zmi.core/trunk/src/zmi/core/zptpage/__init__.py
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/__init__.py (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/__init__.py 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.
Added: zmi.core/trunk/src/zmi/core/zptpage/collector266.txt
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/collector266.txt (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/collector266.txt 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,232 @@
+http://collector.zope.org/Zope3-dev/266
+
+Two functions in zope.tal.taldefs -- getProgramMode and getProgramVersion --
+fail to work if the 'program' argument is security proxied, because they
+use isinstance. This can happen when a page template comes from the ZODB
+instead of the file system (i.e. inherits AppPT rather than TrustedAppPT,
+and therefore ZopePathExpr adds security proxes during object traversal).
+The symptom is an obscure exception like the following one:
+
+ METALError: macro u'view/macros/page' has incompatible version None,
+ at line 2, column 1
+
+
+We create a page that defines some macros:
+
+ >>> print http(r"""
+ ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 835
+ ... Content-Type: multipart/form-data; boundary=---------------------------78336869011025200592044897763
+ ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+ ...
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="field.source"
+ ...
+ ... <html>
+ ... <div metal:define-macro="hi">
+ ... Hi world
+ ... </div>
+ ... <div metal:define-macro="greet">
+ ... Hello <span metal:define-slot="name">world</span>
+ ... </div>
+ ... </html>
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="field.expand.used"
+ ...
+ ...
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+ ...
+ ...
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... macros
+ ... -----------------------------78336869011025200592044897763--
+ ... """)
+ HTTP/1.1 303 See Other
+ ...
+ Location: http://localhost/@@contents.html
+ ...
+
+We create a page that uses the non-slotted macro from the macros template:
+
+ >>> print http(r"""
+ ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 771
+ ... Content-Type: multipart/form-data; boundary=---------------------------196751392613651805401540383426
+ ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.source"
+ ...
+ ... <html>
+ ... <body>
+ ... <div metal:use-macro="container/macros/macros/hi" />
+ ... </body>
+ ... </html>
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.expand.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... page
+ ... -----------------------------196751392613651805401540383426--
+ ... """)
+ HTTP/1.1 303 See Other
+ ...
+ Location: http://localhost/@@contents.html
+ ...
+
+And run it.
+
+ >>> print http(r"""
+ ... GET /page HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 51
+ Content-Type: text/html;charset=utf-8
+ <BLANKLINE>
+ <html>
+ <body>
+ <div>
+ Hi world
+ </div>
+ </body>
+ </html>
+
+Let's create another page that uses the slotted macro, but doesn't
+fill it:
+
+ >>> print http(r"""
+ ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 771
+ ... Content-Type: multipart/form-data; boundary=---------------------------196751392613651805401540383426
+ ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.source"
+ ...
+ ... <html>
+ ... <body>
+ ... <div metal:use-macro="container/macros/macros/greet" />
+ ... </body>
+ ... </html>
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.expand.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... page2
+ ... -----------------------------196751392613651805401540383426--
+ ... """)
+ HTTP/1.1 303 See Other
+ ...
+ Location: http://localhost/@@contents.html
+ ...
+
+And run it.
+
+ >>> print http(r"""
+ ... GET /page2 HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 67
+ Content-Type: text/html;charset=utf-8
+ <BLANKLINE>
+ <html>
+ <body>
+ <div>
+ Hello <span>world</span>
+ </div>
+ </body>
+ </html>
+
+Finally, lets create a page that fills the macro:
+
+ >>> print http(r"""
+ ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 1771
+ ... Content-Type: multipart/form-data; boundary=---------------------------196751392613651805401540383426
+ ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.source"
+ ...
+ ... <html>
+ ... <body>
+ ... <div metal:use-macro="container/macros/macros/greet">
+ ... <span metal:fill-slot="name">bob</span>
+ ... </div>
+ ... </body>
+ ... </html>
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.expand.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... page3
+ ... -----------------------------196751392613651805401540383426--
+ ... """)
+ HTTP/1.1 303 See Other
+ ...
+ Location: http://localhost/@@contents.html
+ ...
+
+And run it.
+
+ >>> print http(r"""
+ ... GET /page3 HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 65
+ Content-Type: text/html;charset=utf-8
+ <BLANKLINE>
+ <html>
+ <body>
+ <div>
+ Hello <span>bob</span>
+ </div>
+ </body>
+ </html>
Property changes on: zmi.core/trunk/src/zmi/core/zptpage/collector266.txt
___________________________________________________________________
Added: svn:eol-style
+ native
Added: zmi.core/trunk/src/zmi/core/zptpage/collector269.txt
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/collector269.txt (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/collector269.txt 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,141 @@
+=========
+Issue 269
+=========
+
+http://collector.zope.org/Zope3-dev/269
+
+When you use TALES path expressions in a page template that is security
+proxied, you get ForbiddenAttribute errors for PathExpr methods. Other kinds
+of expressions are probably also affected.
+
+To see the error, apply the following diff to collector266.txt and run
+test.py zope.app.zptpage.browser (I'm too lazy to figure out how to
+demonstrate this problem manually in a web browser)::
+
+ Index: src/zope/app/zptpage/browser/collector266.txt
+ ===================================================================
+ --- src/zope/app/zptpage/browser/collector266.txt (revision 27388)
+ +++ src/zope/app/zptpage/browser/collector266.txt (working copy)
+ @@ -29,6 +29,7 @@
+ ... </div>
+ ... <div metal:define-macro="greet">
+ ... Hello <span metal:define-slot="name">world</span>
+ + ... <p tal:condition="nothing">Optional text</p>
+ ... </div>
+ ... </html>
+ ... -----------------------------78336869011025200592044897763
+
+
+We create a page that defines a macro:
+
+ >>> print http(r"""
+ ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 835
+ ... Content-Type: multipart/form-data; boundary=---------------------------78336869011025200592044897763
+ ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+ ...
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="field.source"
+ ...
+ ... <html>
+ ... <div metal:define-macro="greet">
+ ... Hello <span metal:define-slot="name">world</span>
+ ... <p tal:condition="nothing">Optional text</p>
+ ... <div tal:define="data python:{'foo': 1, 'bar': {'x': 1, 'y': 0}};
+ ... later defer:container">
+ ... <p tal:content="data/bar/x" />
+ ... <p tal:condition="not: data/foo" />
+ ... <p tal:content="string: string expr" />
+ ... </div>
+ ... </div>
+ ... </html>
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="field.expand.used"
+ ...
+ ...
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+ ...
+ ...
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------78336869011025200592044897763
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... macros
+ ... -----------------------------78336869011025200592044897763--
+ ... """)
+ HTTP/1.1 303 See Other
+ ...
+ Location: http://localhost/@@contents.html
+ ...
+
+
+Lets create a page that uses the macro:
+
+ >>> print http(r"""
+ ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 1771
+ ... Content-Type: multipart/form-data; boundary=---------------------------196751392613651805401540383426
+ ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.source"
+ ...
+ ... <html>
+ ... <body>
+ ... <div metal:use-macro="container/macros/macros/greet">
+ ... <span metal:fill-slot="name">bob</span>
+ ... </div>
+ ... </body>
+ ... </html>
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.expand.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+ ...
+ ...
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------196751392613651805401540383426
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... page
+ ... -----------------------------196751392613651805401540383426--
+ ... """)
+ HTTP/1.1 303 See Other
+ ...
+ Location: http://localhost/@@contents.html
+ ...
+
+And run it.
+
+ >>> print http(r"""
+ ... GET /page HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 118
+ Content-Type: text/html;charset=utf-8
+ <BLANKLINE>
+ <html>
+ <body>
+ <div>
+ Hello <span>bob</span>
+ <BLANKLINE>
+ <div>
+ <p>1</p>
+ <BLANKLINE>
+ <p> string expr</p>
+ </div>
+ </div>
+ </body>
+ </html>
Property changes on: zmi.core/trunk/src/zmi/core/zptpage/collector269.txt
___________________________________________________________________
Added: svn:eol-style
+ native
Added: zmi.core/trunk/src/zmi/core/zptpage/configure.zcml
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/configure.zcml (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/configure.zcml 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,75 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope"
+ >
+
+ <browser:page
+ name="index.html"
+ for="zope.app.zptpage.interfaces.IZPTPage"
+ class=".zptpage.ZPTPageEval"
+ attribute="index"
+ permission="zope.View"
+ />
+
+ <browser:page
+ name="source.html"
+ for="zope.app.zptpage.interfaces.IZPTPage"
+ class="zope.app.zptpage.zptpage.ZPTSourceView"
+ attribute="__call__"
+ permission="zope.ManageContent"
+ />
+
+ <browser:addMenuItem
+ class="zope.app.zptpage.ZPTPage"
+ title="ZPT Page"
+ description="A simple, content-based Page Template"
+ permission="zope.ManageContent"
+ view="zope.app.zptpage.ZPTPage"
+ />
+
+ <browser:addform
+ schema="zope.app.zptpage.interfaces.IZPTPage"
+ label="Add a ZPT Page"
+ content_factory="zope.app.zptpage.ZPTPage"
+ name="zope.app.zptpage.ZPTPage"
+ permission="zope.ManageContent"
+ />
+
+ <browser:page
+ for="zope.app.zptpage.interfaces.IZPTPage"
+ name="edit.html"
+ class=".zptpage.EditForm"
+ permission="zope.ManageContent"
+ menu="zmi_views" title="Edit"
+ />
+
+ <browser:editform
+ for="zope.app.zptpage.interfaces.IZPTPage"
+ schema="zope.app.zptpage.interfaces.IZPTPage"
+ name="inlineCode.html"
+ label="Inline Code"
+ fields="evaluateInlineCode"
+ template="inlinecode.pt"
+ permission="zope.ManageContent"
+ menu="zmi_views" title="Inline Code"
+ />
+
+ <browser:icon
+ name="zmi_icon"
+ for="zope.app.zptpage.interfaces.IZPTPage"
+ file="zpt.gif"
+ />
+
+
+ <!-- Preview view - requires zope.app.preview -->
+
+ <browser:page
+ for="zope.app.zptpage.interfaces.IZPTPage"
+ name="preview.html"
+ template="preview.pt"
+ permission="zope.ManageContent"
+ menu="zmi_views" title="Preview"
+ />
+
+</configure>
Added: zmi.core/trunk/src/zmi/core/zptpage/inlinecode.pt
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/inlinecode.pt (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/inlinecode.pt 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,78 @@
+<tal:tag condition="view/update"
+/><html metal:use-macro="context/@@standard_macros/view" i18n:domain="zope">
+ <body>
+ <div metal:fill-slot="body">
+
+ <div metal:define-macro="body">
+
+ <form action="." tal:attributes="action request/URL" method="post"
+ enctype="multipart/form-data">
+
+ <div metal:define-macro="formbody">
+
+ <h3 tal:condition="view/label"
+ tal:content="view/label"
+ metal:define-slot="heading"
+ i18n:translate=""
+ >Edit something</h3>
+
+ <div style="color:red; font-weight: bold">
+ <p i18n:translate="">
+ This screen allows you to activate Inline Code Evaluation. This
+ means that you can say
+ <span i18n:name="code-example-1"><pre>
+ <script type="text/server-python"><br/>
+ print "Hello World!"<br/>
+ </script>
+ </pre></span>
+ or
+ <span i18n:name="code-example-2"><pre>
+ <p tal:script="text/server-python"><br/>
+ print "Hello World!"<br/>
+ </p>
+ </pre></span>
+ </p>
+ <p i18n:translate="">
+ Many Zope 3 developers consider inline code blocks something
+ very bad, since it does not follow the design of Page Templates
+ or Zope 3 in general. However, application and application server
+ developers are not the only audience for Zope 3. Scripters are
+ used to inline code from other technologies like PHP and it fits
+ their brain, which is very important.
+ </p>
+ </div>
+
+ <p tal:define="status view/update"
+ tal:condition="status"
+ tal:content="status" i18n:translate=""/>
+
+ <p tal:condition="view/errors" i18n:translate="">
+ There are <strong tal:content="python:len(view.errors)"
+ i18n:name="num_errors">6</strong> input errors.
+ </p>
+
+ <tal:block repeat="error view/errors">
+ <div class="error" tal:content="error" i18n:translate="">error</div>
+ </tal:block>
+
+ <div metal:use-macro="context/@@form_macros/widget_rows" />
+
+ </div>
+
+ <div class="row">
+ <div class="controls">
+ <input type="submit" value="Refresh"
+ i18n:attributes="value refresh-button" />
+ <input type="submit" name="UPDATE_SUBMIT" value="Submit"
+ i18n:attributes="value submit-button"/>
+ </div>
+ </div>
+
+ </form>
+
+ </div>
+
+ </div>
+ </body>
+
+</html>
Added: zmi.core/trunk/src/zmi/core/zptpage/preview.pt
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/preview.pt (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/preview.pt 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,9 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+ <iframe src="." height="500" width="100%"></iframe>
+
+</div>
+</body>
+</html>
Added: zmi.core/trunk/src/zmi/core/zptpage/tests.py
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/tests.py (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/tests.py 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,224 @@
+##############################################################################
+#
+# Copyright (c) 2003, 2004 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.
+#
+##############################################################################
+"""Functional tests for ZPT Page.
+
+$Id: tests.py 87230 2008-06-07 18:01:59Z philikon $
+"""
+
+import re
+import unittest
+from zope.testing import renormalizing
+from zope.app.testing.functional import BrowserTestCase
+from zope.app.zptpage.zptpage import ZPTPage
+from xml.sax.saxutils import escape
+from zope.app.zptpage.testing import ZPTPageLayer
+
+
+class ZPTPageTest(BrowserTestCase):
+
+ content = u'<html><body><h1 tal:content="request/URL/1" /></body></html>'
+
+ def addZPTPage(self):
+ zptpage = ZPTPage()
+ zptpage.source = self.content
+ root = self.getRootFolder()
+ root['zptpage'] = zptpage
+ self.commit()
+
+ def testAddForm(self):
+ response = self.publish(
+ '/+/zope.app.zptpage.ZPTPage=',
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ body = response.getBody()
+ self.assert_('Add a ZPT Page' in body)
+ self.assert_('Source' in body)
+ self.assert_('Expand macros' in body)
+ self.assert_('Evaluate Inline Code' in body)
+ self.assert_('Object Name' in body)
+ self.assert_('"Add"' in body)
+ self.checkForBrokenLinks(body, '/+/zope.app.zptpage.ZPTPage=',
+ 'mgr:mgrpw')
+
+ def testAdd(self):
+ response = self.publish(
+ '/+/zope.app.zptpage.ZPTPage=',
+ form={'type_name': u'zope.app.zptpage.ZPTPage',
+ 'field.source': u'<h1>A ZPT Page</h1>',
+ 'field.expand.used': u'',
+ 'field.evaluateInlineCode.used': u'',
+ 'add_input_name': u'zptpage',
+ 'UPDATE_SUBMIT': u'Add'},
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 302)
+ self.assertEqual(response.getHeader('Location'),
+ 'http://localhost/@@contents.html')
+ root = self.getRootFolder()
+ self.assert_('zptpage' in root)
+ zptpage = root['zptpage']
+ self.assertEqual(zptpage.source, '<h1>A ZPT Page</h1>')
+ self.assertEqual(zptpage.expand, False)
+ self.assertEqual(zptpage.evaluateInlineCode, False)
+
+ response = self.publish(
+ '/+/zope.app.zptpage.ZPTPage=',
+ form={'type_name': u'zope.app.zptpage.ZPTPage',
+ 'field.source': u'<h1>A ZPT Page</h1>',
+ 'field.expand.used': u'',
+ 'field.expand': u'on',
+ 'field.evaluateInlineCode.used': u'',
+ 'field.evaluateInlineCode': u'on',
+ 'add_input_name': u'zptpage1',
+ 'UPDATE_SUBMIT': u'Add'},
+ basic='mgr:mgrpw')
+ root = self.getRootFolder()
+ zptpage = root['zptpage1']
+ self.assertEqual(zptpage.source, '<h1>A ZPT Page</h1>')
+ self.assertEqual(zptpage.expand, True)
+ self.assertEqual(zptpage.evaluateInlineCode, True)
+
+ def testEditForm(self):
+ self.addZPTPage()
+ response = self.publish(
+ '/zptpage/@@edit.html',
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ body = response.getBody()
+ self.assert_('Source' in body)
+ self.assert_('Expand macros' in body)
+ self.assert_('Content Type' in body)
+ self.assert_(escape(self.content) in body)
+ self.checkForBrokenLinks(body, '/zptpage/@@edit.html', 'mgr:mgrpw')
+
+ def testEdit(self):
+ self.addZPTPage()
+ response = self.publish(
+ '/zptpage/@@edit.html',
+ form={'form.source': u'<h1>A ZPT Page</h1>',
+ 'form.expand.used': u'',
+ 'form.expand': u'on',
+ 'form.content_type': u'text/html',
+ 'form.actions.apply': u'Apply'},
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ body = response.getBody()
+ self.assert_('Source' in body)
+ self.assert_(escape(u'<h1>A ZPT Page</h1>') in body)
+ root = self.getRootFolder()
+ zptpage = root['zptpage']
+ self.assertEqual(zptpage.source, '<h1>A ZPT Page</h1>')
+ self.assertEqual(zptpage.expand, True)
+ self.assertEqual(zptpage.content_type, 'text/html')
+
+ def testIssue199(self):
+ # This is a test to protect us against issue 199 in the future
+ self.addZPTPage()
+ source = u"""<html metal:use-macro="container/@@standard_macros/page">
+ <body>
+ <div metal:fill-slot="body">
+ write this in the body slot.
+ </div>
+ </body>
+ </html>"""
+
+ response = self.publish(
+ '/zptpage/@@edit.html',
+ form={'form.source': source,
+ 'form.expand.used': u'',
+ 'form.expand': u'on',
+ 'form.actions.apply': u'Apply'},
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ body = response.getBody()
+ # Check for a string from the default template
+ self.assert_(escape(u'Z3 UI') in body)
+ self.failIf(u"Macro expansion failed" in body)
+
+ def testIndex(self):
+ self.addZPTPage()
+ response = self.publish(
+ '/zptpage/@@index.html',
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(response.getBase(), '')
+ body = response.getBody()
+ self.assertEqual(
+ body,
+ '<html><body><h1>http://localhost/zptpage</h1></body></html>')
+ self.checkForBrokenLinks(body, '/zptpage/@@index.html', 'mgr:mgrpw')
+
+ def testPreview(self):
+ self.addZPTPage()
+ response = self.publish(
+ '/zptpage/@@preview.html',
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ body = response.getBody()
+ self.assert_('<iframe src="."' in body)
+ self.checkForBrokenLinks(body, '/zptpage/@@preview.html', 'mgr:mgrpw')
+
+ def testSource(self):
+ self.addZPTPage()
+ response = self.publish(
+ '/zptpage/@@source.html',
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ body = response.getBody()
+ self.assertEqual(body, self.content)
+
+ def testInlineCode(self):
+ self.addZPTPage()
+ response = self.publish(
+ '/zptpage/@@inlineCode.html',
+ form={'field.evaluateInlineCode.used': u'',
+ 'field.evaluateInlineCode': u'on',
+ 'UPDATE_SUBMIT': u'Edit'},
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ body = response.getBody()
+ self.assert_('Inline Code' in body)
+ self.assert_('Evaluate Inline Code' in body)
+ self.checkForBrokenLinks(body, '/zptpage/@@edit.html', 'mgr:mgrpw')
+
+ response = self.publish(
+ '/zptpage/@@inlineCode.html',
+ basic='mgr:mgrpw')
+ self.assertEqual(response.getStatus(), 200)
+ root = self.getRootFolder()
+ zptpage = root['zptpage']
+ self.assertEqual(zptpage.evaluateInlineCode, True)
+
+
+checker = renormalizing.RENormalizing([
+ (re.compile(r"HTTP/1\.1 (\d\d\d) .*"), r"HTTP/1.1 \1 <MESSAGE>"),
+ ])
+
+
+def test_suite():
+ from zope.app.testing.functional import FunctionalDocFileSuite
+ collector = FunctionalDocFileSuite(
+ 'collector266.txt', 'collector269.txt', checker=checker)
+ url = FunctionalDocFileSuite('url.txt', checker=checker)
+ collector.layer = ZPTPageLayer
+ ZPTPageTest.layer = ZPTPageLayer
+ url.layer = ZPTPageLayer
+ return unittest.TestSuite((
+ unittest.makeSuite(ZPTPageTest),
+ collector,
+ url,
+ ))
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Added: zmi.core/trunk/src/zmi/core/zptpage/url.txt
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/url.txt (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/url.txt 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,73 @@
+Special URL handling for DTML pages
+===================================
+
+When a ZPT page containing a head tag is visited, without a trailing
+slash, the base href isn't set. When visited with a slash, it is:
+
+ >>> print http(r"""
+ ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+ ... Authorization: Basic mgr:mgrpw
+ ... Content-Length: 764
+ ... Content-Type: multipart/form-data; boundary=---------------------------178869070917677183891223841261
+ ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+ ...
+ ... -----------------------------178869070917677183891223841261
+ ... Content-Disposition: form-data; name="field.source"
+ ...
+ ... <html>
+ ... <head></head>
+ ... <body>
+ ... <a href="eek.html">Eek</a>
+ ... </body>
+ ... </html>
+ ... -----------------------------178869070917677183891223841261
+ ... Content-Disposition: form-data; name="field.expand.used"
+ ...
+ ...
+ ... -----------------------------178869070917677183891223841261
+ ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+ ...
+ ...
+ ... -----------------------------178869070917677183891223841261
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------178869070917677183891223841261
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... zpt.html
+ ... -----------------------------178869070917677183891223841261--
+ ... """)
+ HTTP/1.1 303 See Other
+ ...
+
+ >>> print http(r"""
+ ... GET /zpt.html HTTP/1.1
+ ... Authorization: Basic mgr:mgrpw
+ ... """)
+ HTTP/1.1 200 OK
+ ...
+ <html>
+ <head></head>
+ <body>
+ <a href="eek.html">Eek</a>
+ </body>
+ </html>
+ <BLANKLINE>
+
+
+ >>> print http(r"""
+ ... GET /zpt.html/ HTTP/1.1
+ ... Authorization: Basic mgr:mgrpw
+ ... """)
+ HTTP/1.1 200 OK
+ ...
+ <html>
+ <head>
+ <base href="http://localhost/zpt.html" />
+ </head>
+ <body>
+ <a href="eek.html">Eek</a>
+ </body>
+ </html>
+ <BLANKLINE>
Property changes on: zmi.core/trunk/src/zmi/core/zptpage/url.txt
___________________________________________________________________
Added: svn:eol-style
+ native
Added: zmi.core/trunk/src/zmi/core/zptpage/zpt.gif
===================================================================
(Binary files differ)
Property changes on: zmi.core/trunk/src/zmi/core/zptpage/zpt.gif
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: zmi.core/trunk/src/zmi/core/zptpage/zptpage.py
===================================================================
--- zmi.core/trunk/src/zmi/core/zptpage/zptpage.py (rev 0)
+++ zmi.core/trunk/src/zmi/core/zptpage/zptpage.py 2009-11-21 07:25:52 UTC (rev 105934)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""Define view component for ZPT page eval results.
+
+$Id: zptpage.py 73434 2007-03-22 02:05:14Z yusei $
+"""
+
+import zope.formlib.form
+
+import zope.app.zptpage.interfaces
+
+class ZPTPageEval(object):
+
+ def index(self, **kw):
+ """Call a Page Template"""
+
+ template = self.context
+ request = self.request
+
+ request.response.setHeader('content-type',
+ template.content_type)
+
+ return template.render(request, **kw)
+
+class EditForm(zope.formlib.form.EditForm):
+ """Edit form for ZPT pages."""
+
+ form_fields = zope.formlib.form.Fields(
+ zope.app.zptpage.interfaces.IZPTPage,
+ zope.app.zptpage.interfaces.IRenderZPTPage,
+ render_context=True).omit('evaluateInlineCode')
+
+ def setUpWidgets(self, ignore_request=False):
+ self.adapters = {}
+
+ # We need to extract the data directly, as we can not pass on the
+ # request for macro expansion otherwise.
+ data = {}
+ data['source'] = self.context.getSource(self.request)
+
+ self.widgets = zope.formlib.form.setUpWidgets(
+ self.form_fields, self.prefix, self.context, self.request,
+ data=data, form=self, adapters=self.adapters,
+ ignore_request=ignore_request)
+
More information about the checkins
mailing list