Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
dad37b5e
Commit
dad37b5e
authored
Aug 06, 2016
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
flake8'ed Five
parent
0c3ecbb0
Changes
68
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
68 changed files
with
441 additions
and
475 deletions
+441
-475
src/Products/Five/COPYING.txt
src/Products/Five/COPYING.txt
+0
-12
src/Products/Five/CREDITS.txt
src/Products/Five/CREDITS.txt
+0
-57
src/Products/Five/README.txt
src/Products/Five/README.txt
+0
-33
src/Products/Five/TODO.txt
src/Products/Five/TODO.txt
+0
-19
src/Products/Five/__init__.py
src/Products/Five/__init__.py
+3
-5
src/Products/Five/browser/adding.py
src/Products/Five/browser/adding.py
+17
-17
src/Products/Five/browser/metaconfigure.py
src/Products/Five/browser/metaconfigure.py
+87
-86
src/Products/Five/browser/pagetemplatefile.py
src/Products/Five/browser/pagetemplatefile.py
+9
-5
src/Products/Five/browser/resource.py
src/Products/Five/browser/resource.py
+19
-10
src/Products/Five/browser/tests/__init__.py
src/Products/Five/browser/tests/__init__.py
+0
-1
src/Products/Five/browser/tests/aqlegacy.py
src/Products/Five/browser/tests/aqlegacy.py
+12
-0
src/Products/Five/browser/tests/classes.py
src/Products/Five/browser/tests/classes.py
+4
-1
src/Products/Five/browser/tests/i18n.py
src/Products/Five/browser/tests/i18n.py
+3
-1
src/Products/Five/browser/tests/skin.py
src/Products/Five/browser/tests/skin.py
+1
-0
src/Products/Five/browser/tests/test_absoluteurl.py
src/Products/Five/browser/tests/test_absoluteurl.py
+2
-0
src/Products/Five/browser/tests/test_adding.py
src/Products/Five/browser/tests/test_adding.py
+1
-0
src/Products/Five/browser/tests/test_decode.py
src/Products/Five/browser/tests/test_decode.py
+2
-0
src/Products/Five/browser/tests/test_defaultview.py
src/Products/Five/browser/tests/test_defaultview.py
+2
-0
src/Products/Five/browser/tests/test_i18n.py
src/Products/Five/browser/tests/test_i18n.py
+3
-1
src/Products/Five/browser/tests/test_menu.py
src/Products/Five/browser/tests/test_menu.py
+4
-2
src/Products/Five/browser/tests/test_metaconfigure.py
src/Products/Five/browser/tests/test_metaconfigure.py
+6
-8
src/Products/Five/browser/tests/test_pages.py
src/Products/Five/browser/tests/test_pages.py
+3
-1
src/Products/Five/browser/tests/test_pagetemplatefile.py
src/Products/Five/browser/tests/test_pagetemplatefile.py
+26
-26
src/Products/Five/browser/tests/test_provider.py
src/Products/Five/browser/tests/test_provider.py
+1
-0
src/Products/Five/browser/tests/test_recurse.py
src/Products/Five/browser/tests/test_recurse.py
+2
-0
src/Products/Five/browser/tests/test_resource.py
src/Products/Five/browser/tests/test_resource.py
+6
-5
src/Products/Five/browser/tests/test_scriptsecurity.py
src/Products/Five/browser/tests/test_scriptsecurity.py
+5
-4
src/Products/Five/browser/tests/test_skin.py
src/Products/Five/browser/tests/test_skin.py
+1
-0
src/Products/Five/browser/tests/test_traversable.py
src/Products/Five/browser/tests/test_traversable.py
+7
-4
src/Products/Five/browser/tests/test_zope3security.py
src/Products/Five/browser/tests/test_zope3security.py
+3
-1
src/Products/Five/browser/tests/zope3security.py
src/Products/Five/browser/tests/zope3security.py
+1
-0
src/Products/Five/component/__init__.py
src/Products/Five/component/__init__.py
+5
-0
src/Products/Five/component/browser.py
src/Products/Five/component/browser.py
+3
-3
src/Products/Five/component/interfaces.py
src/Products/Five/component/interfaces.py
+0
-1
src/Products/Five/component/tests.py
src/Products/Five/component/tests.py
+1
-1
src/Products/Five/sizeconfigure.py
src/Products/Five/sizeconfigure.py
+11
-5
src/Products/Five/skin/__init__.py
src/Products/Five/skin/__init__.py
+0
-1
src/Products/Five/skin/standardmacros.py
src/Products/Five/skin/standardmacros.py
+11
-9
src/Products/Five/skin/tests/__init__.py
src/Products/Five/skin/tests/__init__.py
+0
-1
src/Products/Five/skin/tests/demomacros.py
src/Products/Five/skin/tests/demomacros.py
+5
-2
src/Products/Five/skin/tests/test_standardmacros.py
src/Products/Five/skin/tests/test_standardmacros.py
+3
-1
src/Products/Five/tests/README.txt
src/Products/Five/tests/README.txt
+0
-8
src/Products/Five/tests/__init__.py
src/Products/Five/tests/__init__.py
+0
-1
src/Products/Five/tests/adapters.py
src/Products/Five/tests/adapters.py
+14
-5
src/Products/Five/tests/boilerplate.py
src/Products/Five/tests/boilerplate.py
+0
-35
src/Products/Five/tests/classes.py
src/Products/Five/tests/classes.py
+4
-0
src/Products/Five/tests/metaconfigure.py
src/Products/Five/tests/metaconfigure.py
+10
-9
src/Products/Five/tests/test_directives.py
src/Products/Five/tests/test_directives.py
+1
-0
src/Products/Five/tests/test_i18n.py
src/Products/Five/tests/test_i18n.py
+1
-0
src/Products/Five/tests/test_size.py
src/Products/Five/tests/test_size.py
+4
-0
src/Products/Five/tests/testing/__init__.py
src/Products/Five/tests/testing/__init__.py
+6
-4
src/Products/Five/tests/testing/fancycontent.py
src/Products/Five/tests/testing/fancycontent.py
+7
-1
src/Products/Five/tests/testing/folder.py
src/Products/Five/tests/testing/folder.py
+4
-0
src/Products/Five/tests/testing/pythonproduct2/Extensions/somemodule.py
...ive/tests/testing/pythonproduct2/Extensions/somemodule.py
+1
-1
src/Products/Five/tests/testing/pythonproduct2/__init__.py
src/Products/Five/tests/testing/pythonproduct2/__init__.py
+1
-1
src/Products/Five/tests/testing/simplecontent.py
src/Products/Five/tests/testing/simplecontent.py
+9
-0
src/Products/Five/utilities/__init__.py
src/Products/Five/utilities/__init__.py
+0
-1
src/Products/Five/utilities/browser/__init__.py
src/Products/Five/utilities/browser/__init__.py
+0
-1
src/Products/Five/utilities/browser/marker.py
src/Products/Five/utilities/browser/marker.py
+4
-4
src/Products/Five/utilities/browser/tests/__init__.py
src/Products/Five/utilities/browser/tests/__init__.py
+0
-1
src/Products/Five/utilities/browser/tests/test_marker.py
src/Products/Five/utilities/browser/tests/test_marker.py
+2
-0
src/Products/Five/utilities/marker.py
src/Products/Five/utilities/marker.py
+6
-3
src/Products/Five/viewlet/__init__.py
src/Products/Five/viewlet/__init__.py
+0
-1
src/Products/Five/viewlet/directives.txt
src/Products/Five/viewlet/directives.txt
+1
-1
src/Products/Five/viewlet/manager.py
src/Products/Five/viewlet/manager.py
+9
-3
src/Products/Five/viewlet/metaconfigure.py
src/Products/Five/viewlet/metaconfigure.py
+48
-46
src/Products/Five/viewlet/tests.py
src/Products/Five/viewlet/tests.py
+26
-16
src/Products/Five/viewlet/viewlet.py
src/Products/Five/viewlet/viewlet.py
+14
-10
No files found.
src/Products/Five/COPYING.txt
deleted
100644 → 0
View file @
0c3ecbb0
Five is distributed under the provisions of the Zope Public License
(ZPL) v2.1. See doc/ZopePublicLicense.txt for the license text.
Copyright (C) 2005 Five Contributors. See CREDITS.txt for a list of
Five contributors.
Five contains source code derived from:
- Zope, copyright (C) 2001-2005 by Zope Corporation.
- TrustedExecutables. Dieter Mauer kindly allow licensing this under the
ZPL 2.1.
src/Products/Five/CREDITS.txt
deleted
100644 → 0
View file @
0c3ecbb0
Five contributors
-----------------
- Martijn Faassen (faassen@infrae.com)
- Sidnei da Silva (sidnei@awkly.org)
- Philipp von Weitershausen (philikon@philikon.de)
- Lennart Regebro (regebro@nuxeo.com)
- Tres Seaver (tseaver@palladion.com)
- Jan-Wijbrand Kolman (jw@infrae.com)
- Stefan Holek (ssh@epy.co.at)
- Florent Guillaume (fg@nuxeo.com)
- Godefroid Chapelle (gotcha@bubblenet.be)
- Andy Adiwidjaja (mail@adiwidjaja.com)
- Stuart Bishop (stuart@stuartbishop.net)
- Simon Eisenmann (simon@struktur.de)
- Dieter Maurer (dieter@handshake.de)
- Yvo Schubbe (y.2007-@wcm-solutions.de)
- Malcolm Cleaton (malcolm@jamkit.com)
- Tarek Ziad (tziade@nuxeo.com)
- Whit Morriss (whit@longnow.org)
- Brian Sutherland (jinty@web.de)
- Rocky Burt (rocky@serverzen.com)
Thank you
---------
Infrae for the initial development and continuing support.
Martijn Faassen would like to thank ETH Zurich for their support and
encouragement during the initial development of Five.
Nuxeo for significant contributions to making Five usable in the real
world.
Dieter Maurer for use of code from TrustedExecutables within Five
under the ZPL.
The Five developers would like to thank the Zope developers, in
particular Jim Fulton, for the mountain to stand on.
src/Products/Five/README.txt
deleted
100644 → 0
View file @
0c3ecbb0
Introduction
------------
"It was the dawn of the third age of Zope. The Five project was a dream
given form. Its goal: to use Zope 3 technologies in Zope 2.7 by
creating a Zope 2 product where Zope 3 and Zope 2 could work out their
differences peacefully." -- Babylon 5, creatively quoted
"The Law of Fives states simply that: ALL THINGS HAPPEN IN FIVES, OR
ARE DIVISIBLE BY OR ARE MULTIPLES OF FIVE, OR ARE SOMEHOW DIRECTLY OR
INDIRECTLY RELATED TO FIVE.
THE LAW OF FIVES IS NEVER WRONG." -- Principia Discordia
What is Five?
-------------
A couple of years back an attempt was made to rewrite Zope 2 from scratch and
provide an upgrade path from current Zope 2 to the new version. This project
used the name Zope 3. The attempt of writing a newer version of a full blown
application server similar to Zope 2 failed. Instead the project generated a
whole lot of underlying technologies and new concepts packaged up in reusable
libraries.
Five is the project that integrates those technologies and packages into
Zope 2. It's name is a pun on the original naming of Zope 2 + Zope 3 = Zope 5.
Among others, it allows you to use zope.interface, ZCML-based configuration,
adapters, browser pages (including layers, and resources), zope.schemas,
object events, as well as zope.i18n message catalogs.
We've tried to keep the Five experience as close to that of the integrated
Zope packages as possible, so this means that what you learn while using Five
should also be applicable to the Zope packages directly.
src/Products/Five/TODO.txt
deleted
100644 → 0
View file @
0c3ecbb0
====
TODO
====
- container events - get rid of deprecation warnings
- make rendering of resource urls support sites?
- HTTP/WebDAV: support dispatching of all HTTP/WebDAV methods to HTTP
views. If lookup fails, fall back to methods on the object (Zope 2
style). Security is implied by HTTP views.
- FTP: allow manage_FTPstat, manage_FTPget, manage_FTPlist to dispatch to
filerepresentation adapters. Make sure to handle security correctly.
- Grant security stuff through ZCML (<grant />)?
- top-level <require />, <allow /> directives as a ZCML spelling of
allowModule, allowClass
src/Products/Five/__init__.py
View file @
dad37b5e
...
...
@@ -14,16 +14,14 @@
"""Initialize the Five product
"""
# public API provided by Five
# usage: from Products.Five import <something>
from
Products.Five.browser
import
BrowserView
from
Products.Five.skin.standardmacros
import
StandardMacros
from
Products.Five.browser
import
BrowserView
# NOQA
from
Products.Five.skin.standardmacros
import
StandardMacros
# NOQA
# some convenience methods/decorators
def
fivemethod
(
func
):
func
.
__five_method__
=
True
return
func
def
isFiveMethod
(
m
):
return
hasattr
(
m
,
'__five_method__'
)
src/Products/Five/browser/adding.py
View file @
dad37b5e
...
...
@@ -19,7 +19,7 @@ factory screen.
(original: zope.app.container.browser.adding)
"""
__docformat__
=
'restructuredtext'
import
operator
from
zope.browser.interfaces
import
IAdding
from
zope.browsermenu.menu
import
getMenu
...
...
@@ -30,7 +30,7 @@ from zope.component import queryUtility
from
zope.component.interfaces
import
IFactory
from
zope.container.constraints
import
checkFactory
from
zope.container.constraints
import
checkObject
from
zope.container.i18n
import
ZopeMessageFactory
as
_
from
zope.container.i18n
import
ZopeMessageFactory
as
_
# NOQA
from
zope.container.interfaces
import
IContainerNamesContainer
from
zope.container.interfaces
import
INameChooser
from
zope.event
import
notify
...
...
@@ -80,10 +80,10 @@ class Adding(BrowserView):
content
.
id
=
name
container
.
_setObject
(
name
,
content
)
self
.
contentName
=
name
# Set the added object Name
self
.
contentName
=
name
# Set the added object Name
return
container
.
_getOb
(
name
)
contentName
=
None
# usually set by Adding traverser
contentName
=
None
# usually set by Adding traverser
def
nextURL
(
self
):
"""See zope.browser.interfaces.IAdding"""
...
...
@@ -133,7 +133,7 @@ class Adding(BrowserView):
view_name
=
type_name
if
queryMultiAdapter
((
self
,
self
.
request
),
name
=
view_name
)
is
not
None
:
name
=
view_name
)
is
not
None
:
url
=
"%s/%s=%s"
%
(
absoluteURL
(
self
,
self
.
request
),
type_name
,
id
)
self
.
request
.
response
.
redirect
(
url
)
...
...
@@ -176,10 +176,10 @@ class Adding(BrowserView):
if
not
checkFactory
(
container
,
None
,
factory
):
continue
elif
item
[
'extra'
][
'factory'
]
!=
item
[
'action'
]:
item
[
'has_custom_add_view'
]
=
True
item
[
'has_custom_add_view'
]
=
True
result
.
append
(
item
)
result
.
sort
(
lambda
a
,
b
:
cmp
(
a
[
'title'
],
b
[
'title'
]
))
result
.
sort
(
key
=
operator
.
itemgetter
(
'title'
))
return
result
def
isSingleMenuItem
(
self
):
...
...
@@ -187,12 +187,12 @@ class Adding(BrowserView):
return
len
(
self
.
addingInfo
())
==
1
def
hasCustomAddView
(
self
):
"This should be called only if there is `singleMenuItem` else return 0"
if
self
.
isSingleMenuItem
():
menu_item
=
self
.
addingInfo
()[
0
]
if
'has_custom_add_view'
in
menu_item
:
return
True
return
False
"This should be called only if there is `singleMenuItem` else return 0"
if
self
.
isSingleMenuItem
():
menu_item
=
self
.
addingInfo
()[
0
]
if
'has_custom_add_view'
in
menu_item
:
return
True
return
False
class
ContentAdding
(
Adding
,
SimpleItem
):
...
...
@@ -215,13 +215,13 @@ class ObjectManagerNameChooser:
try
:
name
=
name
.
encode
(
'ascii'
)
except
UnicodeDecodeError
:
raise
UserError
,
"Id must contain only ASCII characters."
raise
UserError
(
"Id must contain only ASCII characters."
)
try
:
self
.
context
.
_checkId
(
name
,
allow_dup
=
False
)
except
BadRequest
,
e
:
except
BadRequest
as
e
:
msg
=
' '
.
join
(
e
.
args
)
or
"Id is in use or invalid"
raise
UserError
,
msg
raise
UserError
(
msg
)
def
chooseName
(
self
,
name
,
object
):
if
not
name
:
...
...
@@ -230,7 +230,7 @@ class ObjectManagerNameChooser:
try
:
name
=
name
.
encode
(
'ascii'
)
except
UnicodeDecodeError
:
raise
UserError
,
"Id must contain only ASCII characters."
raise
UserError
(
"Id must contain only ASCII characters."
)
dot
=
name
.
rfind
(
'.'
)
if
dot
>=
0
:
...
...
src/Products/Five/browser/metaconfigure.py
View file @
dad37b5e
This diff is collapsed.
Click to expand it.
src/Products/Five/browser/pagetemplatefile.py
View file @
dad37b5e
...
...
@@ -27,9 +27,12 @@ from Products.PageTemplates.Expressions import createTrustedZopeEngine
from
Products.Five.bbb
import
AcquisitionBBB
_engine
=
createTrustedZopeEngine
()
def
getEngine
():
return
_engine
class
ViewPageTemplateFile
(
TrustedAppPT
,
PageTemplateFile
):
"""Page Template used as class variable of views defined as Python classes.
"""
...
...
@@ -57,7 +60,7 @@ class ViewPageTemplateFile(TrustedAppPT, PageTemplateFile):
namespace
,
showtal
=
getattr
(
debug_flags
,
'showTAL'
,
0
),
sourceAnnotations
=
getattr
(
debug_flags
,
'sourceAnnotations'
,
0
),
)
)
response
=
instance
.
request
.
response
if
not
response
.
getHeader
(
"Content-Type"
):
response
.
setHeader
(
"Content-Type"
,
self
.
content_type
)
...
...
@@ -87,8 +90,8 @@ class ViewPageTemplateFile(TrustedAppPT, PageTemplateFile):
root
=
root
,
modules
=
SecureModuleImporter
,
traverse_subpath
=
[],
# BBB, never really worked
user
=
getSecurityManager
().
getUser
()
)
user
=
getSecurityManager
().
getUser
(),
)
return
namespace
def
__get__
(
self
,
instance
,
type
):
...
...
@@ -104,9 +107,10 @@ class ViewMapper(object):
return
getMultiAdapter
((
self
.
ob
,
self
.
request
),
name
=
name
)
# When a view's template is accessed e.g. as template.view, a
# BoundPageTemplate object is retur
ed.
For BBB reasons, it needs to
# BoundPageTemplate object is retur
ned.
For BBB reasons, it needs to
# support the aq_* methods and attributes known from Acquisition. For
# that it also needs to be locatable thru __parent__.
# that it also needs to be locatable through __parent__.
class
BoundPageTemplate
(
AcquisitionBBB
):
def
__init__
(
self
,
pt
,
ob
):
...
...
src/Products/Five/browser/resource.py
View file @
dad37b5e
...
...
@@ -32,6 +32,7 @@ from Products.Five.browser import BrowserView
_marker
=
object
()
class
Resource
(
object
):
"""A mixin that changes the URL-rendering of resources (__call__).
...
...
@@ -53,6 +54,7 @@ class Resource(object):
name
=
'++resource++%s'
%
name
return
"%s/%s"
%
(
url
,
name
)
class
PageTemplateResource
(
Resource
,
BrowserView
):
implements
(
IBrowserPublisher
)
...
...
@@ -70,6 +72,7 @@ class PageTemplateResource(Resource, BrowserView):
pt
=
self
.
context
return
pt
(
self
.
request
)
class
FileResource
(
Resource
,
zope
.
browserresource
.
file
.
FileResource
):
pass
...
...
@@ -89,6 +92,7 @@ class ResourceFactory(object):
resource
=
self
.
resource
(
self
.
__rsrc
,
request
)
return
resource
def
_PageTemplate
(
self
,
path
,
name
):
# PageTemplate doesn't take a name parameter,
# which makes it different from FileResource.
...
...
@@ -97,18 +101,21 @@ def _PageTemplate(self, path, name):
template
.
__name__
=
name
return
template
class
PageTemplateResourceFactory
(
ResourceFactory
):
"""A factory for Page Template resources"""
factory
=
_PageTemplate
resource
=
PageTemplateResource
class
FileResourceFactory
(
ResourceFactory
):
"""A factory for File resources"""
factory
=
File
resource
=
FileResource
class
ImageResourceFactory
(
ResourceFactory
):
"""A factory for Image resources"""
...
...
@@ -117,24 +124,25 @@ class ImageResourceFactory(ResourceFactory):
# we only need this class a context for DirectoryResource
class
Directory
:
class
Directory
(
object
)
:
def
__init__
(
self
,
path
,
name
):
self
.
path
=
path
self
.
__name__
=
name
class
DirectoryResource
(
Resource
,
zope
.
browserresource
.
directory
.
DirectoryResource
):
resource_factories
=
{
'gif'
:
ImageResourceFactory
,
'png'
:
ImageResourceFactory
,
'jpg'
:
ImageResourceFactory
,
'pt'
:
PageTemplateResourceFactory
,
'zpt'
:
PageTemplateResourceFactory
,
'gif'
:
ImageResourceFactory
,
'png'
:
ImageResourceFactory
,
'jpg'
:
ImageResourceFactory
,
'pt'
:
PageTemplateResourceFactory
,
'zpt'
:
PageTemplateResourceFactory
,
'html'
:
PageTemplateResourceFactory
,
'htm'
:
PageTemplateResourceFactory
,
}
'htm'
:
PageTemplateResourceFactory
,
}
default_factory
=
FileResourceFactory
...
...
@@ -164,14 +172,15 @@ class DirectoryResource(Resource,
resource
=
factory
(
name
,
filename
)(
self
.
request
)
resource
.
__name__
=
name
resource
.
__parent__
=
self
# We need to propagate security so that restrictedTraverse() will
# work
if
hasattr
(
aq_base
(
self
),
'__roles__'
):
resource
.
__roles__
=
self
.
__roles__
return
resource
class
DirectoryResourceFactory
(
ResourceFactory
):
factory
=
Directory
...
...
src/Products/Five/browser/tests/__init__.py
View file @
dad37b5e
# import this
src/Products/Five/browser/tests/aqlegacy.py
View file @
dad37b5e
...
...
@@ -26,6 +26,7 @@ from zope.contentprovider.interfaces import IContentProvider
from
Products.Five
import
BrowserView
from
Products.Five.browser.pagetemplatefile
import
ViewPageTemplateFile
class
LegacyAttributes
(
BrowserView
):
"""Make sure that those old aq_* attributes on Five BrowserViews
still work, in particular aq_chain, even though BrowserView may
...
...
@@ -35,6 +36,7 @@ class LegacyAttributes(BrowserView):
def
__call__
(
self
):
return
repr
([
obj
for
obj
in
self
.
aq_chain
])
class
ExplicitLegacyAttributes
(
Acquisition
.
Explicit
):
"""Make sure that those old aq_* attributes work on browser views
that only inherit from Explicit as well."""
...
...
@@ -42,6 +44,7 @@ class ExplicitLegacyAttributes(Acquisition.Explicit):
def
__call__
(
self
):
return
repr
([
obj
for
obj
in
self
.
aq_chain
])
class
LegacyTemplate
(
BrowserView
):
template
=
ViewPageTemplateFile
(
'falcon.pt'
)
...
...
@@ -49,6 +52,7 @@ class LegacyTemplate(BrowserView):
def
__call__
(
self
):
return
self
.
template
()
class
LegacyTemplateTwo
(
BrowserView
):
def
__init__
(
self
,
context
,
request
):
...
...
@@ -60,21 +64,26 @@ class LegacyTemplateTwo(BrowserView):
def
__call__
(
self
):
return
self
.
template
()
class
Explicit
(
Acquisition
.
Explicit
):
def
render
(
self
):
return
'Explicit'
class
ExplicitWithTemplate
(
Acquisition
.
Explicit
):
template
=
ViewPageTemplateFile
(
'falcon.pt'
)
class
Implicit
(
Acquisition
.
Implicit
):
index_html
=
None
# we don't want to acquire this!
def
render
(
self
):
return
'Implicit'
class
ImplicitWithTemplate
(
Acquisition
.
Implicit
):
template
=
ViewPageTemplateFile
(
'falcon.pt'
)
...
...
@@ -96,6 +105,7 @@ class ExplicitContentProvider(Acquisition.Explicit):
def
render
(
self
):
return
'Content provider inheriting from Explicit'
class
ExplicitViewlet
(
Acquisition
.
Explicit
):
def
__init__
(
self
,
context
,
request
,
view
,
manager
):
...
...
@@ -111,6 +121,7 @@ class ExplicitViewlet(Acquisition.Explicit):
def
render
(
self
):
return
'Viewlet inheriting from Explicit'
class
BrowserViewViewlet
(
BrowserView
):
def
__init__
(
self
,
context
,
request
,
view
,
manager
):
...
...
@@ -139,6 +150,7 @@ class LegacyNamespace(object):
def
traverse
(
self
,
name
,
ignored
):
return
LegacyNamespaceObject
(
name
)
class
LegacyNamespaceObject
(
OFS
.
SimpleItem
.
SimpleItem
):
def
__init__
(
self
,
name
):
...
...
src/Products/Five/browser/tests/classes.py
View file @
dad37b5e
...
...
@@ -17,16 +17,19 @@
from
zope.interface
import
Interface
,
implements
from
Products.Five
import
BrowserView
class
IOne
(
Interface
):
"""This is an interface.
"""
class
One
(
object
):
'A class'
implements
(
IOne
)
class
ViewOne
(
BrowserView
):
'Yet another class'
def
my_method
(
self
,
arg1
,
arg2
,
kw1
=
None
,
kw2
=
'D'
):
print
"CALLED %s %s %s %s"
%
(
arg1
,
arg2
,
kw1
,
kw2
)
print
(
"CALLED %s %s %s %s"
%
(
arg1
,
arg2
,
kw1
,
kw2
)
)
src/Products/Five/browser/tests/i18n.py
View file @
dad37b5e
...
...
@@ -15,8 +15,10 @@
"""
from
zope.i18nmessageid
import
MessageFactory
_
=
MessageFactory
(
'fivetest'
)
from
Products.Five
import
BrowserView
_
=
MessageFactory
(
'fivetest'
)
class
I18nView
(
BrowserView
):
this_is_a_message
=
_
(
u'This is a message'
)
src/Products/Five/browser/tests/skin.py
View file @
dad37b5e
...
...
@@ -16,5 +16,6 @@
from
zope.publisher.interfaces.browser
import
IDefaultBrowserLayer
class
ITestSkin
(
IDefaultBrowserLayer
):
pass
src/Products/Five/browser/tests/test_absoluteurl.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test AbsoluteURL
"""
def
test_absoluteurl
():
"""This tests the absolute url view (IAbsoluteURL or @@absolute_url),
in particular the breadcrumb functionality.
...
...
@@ -83,6 +84,7 @@ def test_absoluteurl():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocTestSuite
return
ZopeDocTestSuite
()
src/Products/Five/browser/tests/test_adding.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test adding views
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocFileSuite
return
ZopeDocFileSuite
(
'adding.txt'
,
...
...
src/Products/Five/browser/tests/test_decode.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Unit tests for decode module.
"""
def
test_processInputs
():
"""
Testing processInputs
...
...
@@ -100,6 +101,7 @@ def test_processInputs():
"""
def
test_suite
():
from
doctest
import
DocTestSuite
return
DocTestSuite
()
src/Products/Five/browser/tests/test_defaultview.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test Default View functionality
"""
def
test_default_view
():
"""
Test default view functionality
...
...
@@ -176,6 +177,7 @@ def test_default_method_args_marshalling():
>>> cleanUp()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocTestSuite
return
FunctionalDocTestSuite
()
src/Products/Five/browser/tests/test_i18n.py
View file @
dad37b5e
...
...
@@ -14,12 +14,13 @@
"""Unit tests for the i18n framework
"""
def
test_zpt_i18n
():
"""
Test i18n functionality in ZPTs
>>> configure_zcml = '''
... <configure
... <configure
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser"
... xmlns:i18n="http://namespaces.zope.org/i18n">
...
...
@@ -81,6 +82,7 @@ def test_zpt_i18n():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocTestSuite
from
doctest
import
ELLIPSIS
...
...
src/Products/Five/browser/tests/test_menu.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test browser menus
"""
def
test_menu
():
"""
Test menus
...
...
@@ -39,7 +40,7 @@ def test_menu():
>>> request = TestRequest()
>>> menu = getMenu('testmenu', self.folder, request)
It should have
It should have
>>> len(menu)
4
...
...
@@ -149,7 +150,7 @@ def test_menu():
'description': u'This is a test menu item',
'extra': None,
'icon': None,
'selected': u'',
'selected': u'',
'submenu': None,
'title': u'Test Menu Item 2'}
...
...
@@ -169,6 +170,7 @@ def test_menu():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocTestSuite
return
ZopeDocTestSuite
()
src/Products/Five/browser/tests/test_metaconfigure.py
View file @
dad37b5e
import
unittest
class
ViewMixinForTemplatesTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
...
...
@@ -41,7 +42,7 @@ class ViewMixinForTemplatesTests(unittest.TestCase):
index
.
macros
=
{}
index
.
macros
[
'aaa'
]
=
aaa
=
object
()
self
.
assertTrue
(
view
[
'aaa'
]
is
aaa
)
def
test__getitem__gives_shortcut_to_index_macros
(
self
):
view
=
self
.
_makeOne
()
view
.
index
=
index
=
DummyTemplate
()
...
...
@@ -77,18 +78,15 @@ class ViewMixinForTemplatesTests(unittest.TestCase):
self
.
assertEqual
(
index
.
_called_with
,
((
'abc'
,),
{
'foo'
:
'bar'
}))
class
DummyContext
:
class
DummyContext
(
object
)
:
pass
class
DummyRequest
:
class
DummyRequest
(
object
):
pass
class
DummyTemplate
:
def
__call__
(
self
,
*
args
,
**
kw
):
self
.
_called_with
=
(
args
,
kw
)
return
self
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
ViewMixinForTemplatesTests
),
))
src/Products/Five/browser/tests/test_pages.py
View file @
dad37b5e
...
...
@@ -15,6 +15,7 @@
"""
import
unittest
def
test_view_with_unwrapped_context
():
"""
It may be desirable when writing tests for views themselves to
...
...
@@ -63,6 +64,7 @@ def test_view_with_unwrapped_context():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocFileSuite
from
Testing.ZopeTestCase
import
ZopeDocFileSuite
...
...
@@ -74,4 +76,4 @@ def test_suite():
package
=
'Products.Five.browser.tests'
),
FunctionalDocFileSuite
(
'aqlegacy_ftest.txt'
,
package
=
'Products.Five.browser.tests'
),
))
))
src/Products/Five/browser/tests/test_pagetemplatefile.py
View file @
dad37b5e
...
...
@@ -37,8 +37,6 @@ class ViewPageTemplateFileTests(unittest.TestCase):
def
test_pt_getEngine
(
self
):
from
zope.tales.expressions
import
DeferExpr
from
zope.tales.expressions
import
NotExpr
from
zope.tales.expressions
import
PathExpr
from
zope.tales.expressions
import
Undefs
from
zope.tales.pythonexpr
import
PythonExpr
from
zope.contentprovider.tales
import
TALESProviderExpression
from
Products.PageTemplates.DeferExpr
import
LazyExpr
...
...
@@ -85,8 +83,6 @@ class ViewPageTemplateFileTests(unittest.TestCase):
self
.
assertEqual
(
namespace
[
'user'
].
getId
(),
'a_user'
)
def
test_pt_getContext_w_physicalRoot
(
self
):
from
Products.Five.browser.pagetemplatefile
import
ViewMapper
from
Products.PageTemplates.Expressions
import
SecureModuleImporter
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
DummyUser
(
'a_user'
))
context
=
DummyContext
()
...
...
@@ -99,8 +95,6 @@ class ViewPageTemplateFileTests(unittest.TestCase):
self
.
assertTrue
(
namespace
[
'root'
]
is
root
)
def
test_pt_getContext_w_ignored_kw
(
self
):
from
Products.Five.browser.pagetemplatefile
import
ViewMapper
from
Products.PageTemplates.Expressions
import
SecureModuleImporter
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
DummyUser
(
'a_user'
))
context
=
DummyContext
()
...
...
@@ -112,8 +106,6 @@ class ViewPageTemplateFileTests(unittest.TestCase):
self
.
assertFalse
(
'foo'
in
namespace
[
'options'
])
def
test_pt_getContext_w_args_kw
(
self
):
from
Products.Five.browser.pagetemplatefile
import
ViewMapper
from
Products.PageTemplates.Expressions
import
SecureModuleImporter
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
DummyUser
(
'a_user'
))
context
=
DummyContext
()
...
...
@@ -124,8 +116,6 @@ class ViewPageTemplateFileTests(unittest.TestCase):
self
.
assertEqual
(
namespace
[
'args'
],
(
'bar'
,
'baz'
))
def
test_pt_getContext_w_options_kw
(
self
):
from
Products.Five.browser.pagetemplatefile
import
ViewMapper
from
Products.PageTemplates.Expressions
import
SecureModuleImporter
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
DummyUser
(
'a_user'
))
context
=
DummyContext
()
...
...
@@ -149,20 +139,22 @@ class ViewPageTemplateFileTests(unittest.TestCase):
context
=
DummyContext
()
request
=
DummyRequest
()
response
=
request
.
response
=
DummyResponse
(
{
'Content-Type'
:
'text/xhtml'
})
{
'Content-Type'
:
'text/xhtml'
})
view
=
self
.
_makeView
(
context
,
request
)
vptf
=
self
.
_makeOne
(
'templates/dirpage1.pt'
)
body
=
vptf
(
view
)
vptf
(
view
)
self
.
assertEqual
(
response
.
_headers
[
'Content-Type'
],
'text/xhtml'
)
def
test___get___
(
self
):
from
Products.Five.browser.pagetemplatefile
import
BoundPageTemplate
template
=
self
.
_makeOne
(
'templates/dirpage1.pt'
)
class
Foo
:
class
Foo
(
object
):
def
__init__
(
self
,
context
,
request
):
self
.
context
=
context
self
.
request
=
request
bar
=
template
context
=
DummyContext
()
request
=
DummyRequest
()
foo
=
Foo
(
context
,
request
)
...
...
@@ -171,6 +163,7 @@ class ViewPageTemplateFileTests(unittest.TestCase):
self
.
assertTrue
(
bound
.
im_func
is
template
)
self
.
assertTrue
(
bound
.
im_self
is
foo
)
class
ViewMapperTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
...
...
@@ -200,14 +193,17 @@ class ViewMapperTests(unittest.TestCase):
def
test___getitem___hit
(
self
):
from
zope.interface
import
Interface
from
zope.component
import
provideAdapter
def
_adapt
(
context
,
request
):
return
self
provideAdapter
(
_adapt
,
(
None
,
None
),
Interface
,
name
=
'test'
)
mapper
=
self
.
_makeOne
()
self
.
assertTrue
(
mapper
[
'test'
]
is
self
)
_marker
=
object
()
class
BoundPageTemplateTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
...
...
@@ -269,13 +265,16 @@ DIRPAGE1 = """\
</html>
"""
class
DummyContext
:
class
DummyContext
(
object
):
pass
class
DummyRequest
:
class
DummyRequest
(
object
):
debug
=
object
()
class
DummyResponse
:
class
DummyResponse
(
object
):
def
__init__
(
self
,
headers
=
None
):
if
headers
is
None
:
headers
=
{}
...
...
@@ -287,30 +286,31 @@ class DummyResponse:
def
setHeader
(
self
,
name
,
value
):
self
.
_headers
[
name
]
=
value
class
DummyTemplate
:
class
DummyTemplate
(
object
):
filename
=
'dummy.pt'
def
__init__
(
self
,
macros
=
None
):
if
macros
is
None
:
macros
=
{}
self
.
macros
=
macros
def
__call__
(
self
,
im_self
,
*
args
,
**
kw
):
self
.
_called_with
=
(
im_self
,
args
,
kw
)
return
'<h1>Dummy</h1>'
class
DummyView
:
class
DummyView
(
object
):
def
__init__
(
self
,
context
,
request
):
self
.
context
=
context
self
.
request
=
request
class
DummyUser
:
class
DummyUser
(
object
):
def
__init__
(
self
,
name
):
self
.
_name
=
name
def
getId
(
self
):
return
self
.
_name
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
ViewPageTemplateFileTests
),
unittest
.
makeSuite
(
ViewMapperTests
),
unittest
.
makeSuite
(
BoundPageTemplateTests
),
))
src/Products/Five/browser/tests/test_provider.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test browser pages
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocFileSuite
return
FunctionalDocFileSuite
(
'provider.txt'
,
...
...
src/Products/Five/browser/tests/test_recurse.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test default view recursion
"""
def
test_recursion
():
"""
Test recursion
...
...
@@ -59,6 +60,7 @@ def test_recursion():
>>> cleanUp()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocTestSuite
return
ZopeDocTestSuite
()
src/Products/Five/browser/tests/test_resource.py
View file @
dad37b5e
...
...
@@ -15,12 +15,13 @@
"""
import
unittest
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocFileSuite
from
Testing.ZopeTestCase
import
ZopeDocFileSuite
return
unittest
.
TestSuite
((
ZopeDocFileSuite
(
'resource.txt'
,
package
=
'Products.Five.browser.tests'
),
FunctionalDocFileSuite
(
'resource_ftest.txt'
,
package
=
'Products.Five.browser.tests'
),
))
ZopeDocFileSuite
(
'resource.txt'
,
package
=
'Products.Five.browser.tests'
),
FunctionalDocFileSuite
(
'resource_ftest.txt'
,
package
=
'Products.Five.browser.tests'
),
))
src/Products/Five/browser/tests/test_scriptsecurity.py
View file @
dad37b5e
...
...
@@ -18,7 +18,7 @@ def checkRestricted(folder, psbody):
addPythonScript
(
folder
,
'ps'
,
body
=
psbody
)
try
:
folder
.
ps
()
except
Unauthorized
,
e
:
except
Unauthorized
as
e
:
raise
AssertionError
(
e
)
...
...
@@ -94,7 +94,7 @@ def test_resource_restricted_code():
>>> self.folder.restrictedTraverse('++resource++fivetest_resources/resource.txt') is not None
True
>>> self.folder.restrictedTraverse('++resource++fivetest_resources/resource_subdir/resource.txt') is not None
True
...
...
@@ -104,6 +104,7 @@ def test_resource_restricted_code():
>>> tearDown()
"""
def
test_view_restricted_code
():
"""
Let's register a quite large amount of test pages:
...
...
@@ -128,7 +129,7 @@ def test_view_restricted_code():
>>> protected_view_names = [
... 'eagle.txt', 'falcon.html', 'owl.html', 'flamingo.html',
... 'condor.html', 'permission_view']
>>>
>>> public_view_names = [
... 'public_attribute_page',
... 'public_template_page',
...
...
@@ -181,7 +182,7 @@ def test_view_restricted_code():
def
test_suite
():
suite
=
unittest
.
TestSuite
()
try
:
import
Products.PythonScripts
import
Products.PythonScripts
# NOQA
except
ImportError
:
pass
else
:
...
...
src/Products/Five/browser/tests/test_skin.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test browser pages
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocFileSuite
return
FunctionalDocFileSuite
(
'skin.txt'
,
...
...
src/Products/Five/browser/tests/test_traversable.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test Five-traversable classes
"""
class
SimpleClass
(
object
):
"""Class with no __bobo_traverse__."""
...
...
@@ -48,7 +49,7 @@ def test_traversable():
... xmlns:meta="http://namespaces.zope.org/meta"
... xmlns:browser="http://namespaces.zope.org/browser"
... xmlns:five="http://namespaces.zope.org/five">
...
...
... <!-- make the zope2.Public permission work -->
... <meta:redefinePermission from="zope2.Public" to="zope.Public" />
...
...
...
@@ -129,7 +130,7 @@ def test_traversable():
Five's traversable monkeypatches the __bobo_traverse__ method to do view
lookup and then delegates back to the original __bobo_traverse__ or direct
attribute/item lookup to do normal lookup. In the Zope 2 ZPublisher, an
attribute/item lookup to do normal lookup. In the Zope 2 ZPublisher, an
object with a __bobo_traverse__ will not do attribute lookup unless the
__bobo_traverse__ method itself does it (i.e. the __bobo_traverse__ is the
only element used for traversal lookup). Let's demonstrate:
...
...
@@ -179,6 +180,7 @@ def test_traversable():
False
"""
def
test_view_doesnt_shadow_attribute
():
"""
Test that views don't shadow attributes, e.g. items in a folder.
...
...
@@ -265,7 +267,7 @@ def test_view_doesnt_shadow_attribute():
However, acquired attributes *should* be shadowed. See discussion on
http://codespeak.net/pipermail/z3-five/2006q2/001474.html
>>> manage_addIndexSimpleContent(self.folder, 'mouse', 'Mouse')
>>> print http(r'''
... GET /test_folder_1_/ftf/mouse HTTP/1.1
...
...
@@ -273,13 +275,14 @@ def test_view_doesnt_shadow_attribute():
HTTP/1.1 200 OK
...
The mouse has been eaten by the eagle
Clean up:
>>> from zope.component.testing import tearDown
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocTestSuite
return
FunctionalDocTestSuite
()
src/Products/Five/browser/tests/test_zope3security.py
View file @
dad37b5e
...
...
@@ -7,7 +7,7 @@ def test_check_permission():
work.
>>> configure_zcml = '''
... <configure
... <configure
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser">
... <securityPolicy
...
...
@@ -53,6 +53,7 @@ def test_check_permission():
"""
def
test_allowed_interface
():
"""This test demonstrates that allowed_interface security declarations work
as expected.
...
...
@@ -143,6 +144,7 @@ def test_allowed_interface():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
FunctionalDocTestSuite
from
doctest
import
ELLIPSIS
...
...
src/Products/Five/browser/tests/zope3security.py
View file @
dad37b5e
from
zope.publisher.browser
import
BrowserView
from
zope.security.management
import
checkPermission
class
Zope3SecurityView
(
BrowserView
):
def
__call__
(
self
,
permission
):
...
...
src/Products/Five/component/__init__.py
View file @
dad37b5e
...
...
@@ -32,6 +32,7 @@ from ZPublisher.BeforeTraverse import unregisterBeforeTraverse
from
zope.component.hooks
import
setHooks
setHooks
()
def
findSite
(
obj
,
iface
=
ISite
):
"""Find a site by walking up the object hierarchy, supporting both
the ``ILocation`` API and Zope 2 Acquisition."""
...
...
@@ -39,6 +40,7 @@ def findSite(obj, iface=ISite):
obj
=
aq_parent
(
aq_inner
(
obj
))
return
obj
@
zope
.
component
.
adapter
(
zope
.
interface
.
Interface
)
@
zope
.
interface
.
implementer
(
IComponentLookup
)
def
siteManagerAdapter
(
ob
):
...
...
@@ -51,6 +53,7 @@ def siteManagerAdapter(ob):
return
zope
.
component
.
getGlobalSiteManager
()
return
site
.
getSiteManager
()
class
LocalSiteHook
(
ExtensionClass
.
Base
):
def
__call__
(
self
,
container
,
request
):
...
...
@@ -58,6 +61,7 @@ class LocalSiteHook(ExtensionClass.Base):
HOOK_NAME
=
'__local_site_hook__'
def
enableSite
(
obj
,
iface
=
ISite
):
"""Install __before_traverse__ hook for Local Site
"""
...
...
@@ -73,6 +77,7 @@ def enableSite(obj, iface=ISite):
zope
.
interface
.
alsoProvides
(
obj
,
iface
)
def
disableSite
(
obj
,
iface
=
ISite
):
"""Remove __before_traverse__ hook for Local Site
"""
...
...
src/Products/Five/component/browser.py
View file @
dad37b5e
...
...
@@ -27,9 +27,9 @@ class ObjectManagerSiteView(BrowserView):
def
update
(
self
):
form
=
self
.
request
.
form
if
form
.
has_key
(
'MAKESITE'
)
:
if
'MAKESITE'
in
form
:
self
.
makeSite
()
elif
form
.
has_key
(
'UNMAKESITE'
)
:
elif
'UNMAKESITE'
in
form
:
self
.
unmakeSite
()
def
isSite
(
self
):
...
...
@@ -41,7 +41,7 @@ class ObjectManagerSiteView(BrowserView):
enableSite
(
self
.
context
,
iface
=
IObjectManagerSite
)
#TODO in the future we'll have to walk up to other site
#
TODO in the future we'll have to walk up to other site
# managers and put them in the bases
components
=
PersistentComponents
()
components
.
__bases__
=
(
base
,)
...
...
src/Products/Five/component/interfaces.py
View file @
dad37b5e
...
...
@@ -19,5 +19,4 @@ from OFS.interfaces import IObjectManager
class
IObjectManagerSite
(
IObjectManager
,
ISite
):
"""Object manager that is also a site."""
src/Products/Five/component/tests.py
View file @
dad37b5e
...
...
@@ -24,4 +24,4 @@ def test_suite():
DocFileSuite
(
'component.txt'
,
package
=
"Products.Five.component"
),
FunctionalDocFileSuite
(
'makesite.txt'
,
package
=
"Products.Five.component"
),
])
])
src/Products/Five/sizeconfigure.py
View file @
dad37b5e
...
...
@@ -21,6 +21,7 @@ from Products.Five import fivemethod, isFiveMethod
# holds classes that were monkeyed with; for clean up
_monkied
=
[]
@
fivemethod
def
get_size
(
self
):
size
=
ISized
(
self
,
None
)
...
...
@@ -32,6 +33,7 @@ def get_size(self):
if
method
is
not
None
:
return
self
.
__five_original_get_size
()
def
classSizable
(
class_
):
"""Monkey the class to be sizable through Five"""
# tuck away the original method if necessary
...
...
@@ -41,14 +43,15 @@ def classSizable(class_):
# remember class for clean up
_monkied
.
append
(
class_
)
def
sizable
(
_context
,
class_
):
_context
.
action
(
discriminator
=
(
'five:sizable'
,
class_
),
callable
=
classSizable
,
discriminator
=
(
'five:sizable'
,
class_
),
callable
=
classSizable
,
args
=
(
class_
,)
)
)
# clean up code
def
killMonkey
(
class_
,
name
,
fallback
,
attr
=
None
):
"""Die monkey, die!"""
method
=
getattr
(
class_
,
name
,
None
)
...
...
@@ -70,14 +73,17 @@ def killMonkey(class_, name, fallback, attr=None):
except
(
AttributeError
,
KeyError
):
pass
def
unsizable
(
class_
):
"""Restore class's initial state with respect to being sizable"""
killMonkey
(
class_
,
'get_size'
,
'__five_original_get_size'
)
def
cleanUp
():
for
class_
in
_monkied
:
unsizable
(
class_
)
from
zope.testing.cleanup
import
addCleanUp
from
zope.testing.cleanup
import
addCleanUp
# NOQA
addCleanUp
(
cleanUp
)
del
addCleanUp
src/Products/Five/skin/__init__.py
View file @
dad37b5e
# import this
src/Products/Five/skin/standardmacros.py
View file @
dad37b5e
...
...
@@ -18,9 +18,8 @@ import zope.interface
import
zope.component
from
Products.Five.browser
import
BrowserView
# this is a verbatim copy of zope.app.basicskin except that it doesn't
# derive from ``object``
class
Macros
:
class
Macros
(
object
):
zope
.
interface
.
implements
(
zope
.
interface
.
common
.
mapping
.
IItemMapping
)
macro_pages
=
()
...
...
@@ -28,24 +27,27 @@ class Macros:
'view'
:
'page'
,
'dialog'
:
'page'
,
'addingdialog'
:
'page'
}
}
def
__getitem__
(
self
,
key
):
key
=
self
.
aliases
.
get
(
key
,
key
)
context
=
self
.
context
request
=
self
.
request
for
name
in
self
.
macro_pages
:
page
=
zope
.
component
.
getMultiAdapter
((
context
,
request
),
name
=
name
)
page
=
zope
.
component
.
getMultiAdapter
(
(
context
,
request
),
name
=
name
)
try
:
v
=
page
[
key
]
except
KeyError
:
pass
else
:
return
v
raise
KeyError
,
key
raise
KeyError
(
key
)
class
StandardMacros
(
BrowserView
,
Macros
):
macro_pages
=
(
'five_template'
,
'widget_macros'
,
'form_macros'
,)
macro_pages
=
(
'five_template'
,
'widget_macros'
,
'form_macros'
,
)
src/Products/Five/skin/tests/__init__.py
View file @
dad37b5e
# import this
src/Products/Five/skin/tests/demomacros.py
View file @
dad37b5e
...
...
@@ -16,8 +16,11 @@
from
Products.Five
import
StandardMacros
as
BaseMacros
class
StandardMacros
(
BaseMacros
):
macro_pages
=
(
'bird_macros'
,
'dog_macros'
)
aliases
=
{
'flying'
:
'birdmacro'
,
'walking'
:
'dogmacro'
}
aliases
=
{
'flying'
:
'birdmacro'
,
'walking'
:
'dogmacro'
,
}
src/Products/Five/skin/tests/test_standardmacros.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test standard macros
"""
def
test_standard_macros
():
"""Test standard macros
...
...
@@ -27,7 +28,7 @@ def test_standard_macros():
>>> import Products.Five.skin.tests
>>> from Zope2.App import zcml
>>> zcml.load_config('configure.zcml', package=Products.Five)
>>> zcml.load_config('configure.zcml', package=Products.Five.skin.tests)
>>> zcml.load_config('configure.zcml', package=Products.Five.skin.tests)
Test macro access through our flavour of StandardMacros. First,
when looking up a non-existing macro, we get a KeyError:
...
...
@@ -71,6 +72,7 @@ def test_standard_macros():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocTestSuite
return
ZopeDocTestSuite
()
src/Products/Five/tests/README.txt
deleted
100644 → 0
View file @
0c3ecbb0
Five tests
==========
All you have to do is type::
$ bin/zopectl test -s Products.Five
to run the Five tests.
src/Products/Five/tests/__init__.py
View file @
dad37b5e
# import this
src/Products/Five/tests/adapters.py
View file @
dad37b5e
...
...
@@ -17,6 +17,7 @@
from
zope.interface
import
implements
,
Interface
from
zope.component
import
adapts
class
IAdaptable
(
Interface
):
"""This is a Zope interface.
"""
...
...
@@ -24,6 +25,7 @@ class IAdaptable(Interface):
"""This method will be adapted
"""
class
IAdapted
(
Interface
):
"""The interface we adapt to.
"""
...
...
@@ -32,22 +34,26 @@ class IAdapted(Interface):
"""A method to adapt.
"""
class
IOrigin
(
Interface
):
"""Something we'll adapt"""
class
IDestination
(
Interface
):
"""The result of an adaption"""
def
method
():
"""Do something"""
class
Adaptable
:
class
Adaptable
(
object
):
implements
(
IAdaptable
)
def
method
(
self
):
return
"The method"
class
Adapter
:
class
Adapter
(
object
):
implements
(
IAdapted
)
adapts
(
IAdaptable
)
...
...
@@ -57,10 +63,12 @@ class Adapter:
def
adaptedMethod
(
self
):
return
"Adapted: %s"
%
self
.
context
.
method
()
class
Origin
:
class
Origin
(
object
):
implements
(
IOrigin
)
class
OriginalAdapter
:
class
OriginalAdapter
(
object
):
implements
(
IDestination
)
def
__init__
(
self
,
context
):
...
...
@@ -69,7 +77,8 @@ class OriginalAdapter:
def
method
(
self
):
return
"Original"
class
OverrideAdapter
:
class
OverrideAdapter
(
object
):
implements
(
IDestination
)
def
__init__
(
self
,
context
):
...
...
src/Products/Five/tests/boilerplate.py
deleted
100644 → 0
View file @
0c3ecbb0
##############################################################################
#
# Copyright (c) 2005 Zope Foundation 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.
#
##############################################################################
"""Boiler plate test module
"""
def
test_boilerplate
():
"""
>>> from zope.component.testing import setUp, tearDown
>>> setUp()
>>> import Products.Five.tests
>>> from Zope2.App import zcml
>>> zcml.load_config('boilerplate.zcml', Products.Five.tests)
>>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
>>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
>>> from Products.Five.tests.testing.fancycontent import manage_addFancyContent
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocTestSuite
return
ZopeDocTestSuite
()
src/Products/Five/tests/classes.py
View file @
dad37b5e
...
...
@@ -16,16 +16,20 @@
from
zope.interface
import
Interface
class
One
(
object
):
'A class'
class
Two
(
object
):
'Another class'
class
IOne
(
Interface
):
"""This is a Zope interface.
"""
class
ITwo
(
Interface
):
"""This is another Zope interface.
"""
src/Products/Five/tests/metaconfigure.py
View file @
dad37b5e
...
...
@@ -18,27 +18,28 @@ from zope.interface import Interface
from
zope.configuration.fields
import
GlobalObject
from
zope.schema
import
TextLine
class
IParrotDirective
(
Interface
):
"""State that a class implements something.
"""
class_
=
GlobalObject
(
title
=
u"Class"
,
required
=
True
)
required
=
True
,
)
name
=
TextLine
(
title
=
u"Name"
,
description
=
u"The parrots name."
,
required
=
True
)
required
=
True
,
)
def
parrot
(
_context
,
class_
,
name
):
parrot
=
class_
()
parrot
.
pineForFjords
()
class
NorwegianBlue
(
object
):
def
pineForFjords
(
self
):
return
"This parrot is no more!"
src/Products/Five/tests/test_directives.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Test the basic ZCML directives
"""
def
test_directives
():
"""
Test ZCML directives
...
...
src/Products/Five/tests/test_i18n.py
View file @
dad37b5e
...
...
@@ -16,6 +16,7 @@
from
zope.component.testing
import
setUp
,
tearDown
def
test_directive
():
"""
Test the i18n directive. First, we need to register the ZCML
...
...
src/Products/Five/tests/test_size.py
View file @
dad37b5e
...
...
@@ -17,6 +17,7 @@
from
zope.interface
import
implements
from
zope.size.interfaces
import
ISized
class
SimpleContentSize
(
object
):
"""Size for ``SimpleContent`` objects."""
implements
(
ISized
)
...
...
@@ -30,6 +31,7 @@ class SimpleContentSize(object):
def
sizeForDisplay
(
self
):
return
"What is the meaning of life?"
class
FancyContentSize
(
object
):
"""Size for ``SimpleContent`` objects."""
implements
(
ISized
)
...
...
@@ -43,6 +45,7 @@ class FancyContentSize(object):
def
sizeForDisplay
(
self
):
return
"That's not the meaning of life!"
def
test_size
():
"""
Test size adapters
...
...
@@ -94,6 +97,7 @@ def test_size():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocTestSuite
return
ZopeDocTestSuite
()
src/Products/Five/tests/testing/__init__.py
View file @
dad37b5e
...
...
@@ -14,7 +14,9 @@
"""Test helpers
"""
from
Products.Five.tests.testing.folder
import
FiveTraversableFolder
from
Products.Five.tests.testing.folder
import
manage_addFiveTraversableFolder
from
Products.Five.tests.testing.folder
import
manage_addNoVerifyPasteFolder
from
Products.Five.tests.testing.folder
import
NoVerifyPasteFolder
from
Products.Five.tests.testing.folder
import
(
# NOQA
FiveTraversableFolder
,
manage_addFiveTraversableFolder
,
manage_addNoVerifyPasteFolder
,
NoVerifyPasteFolder
,
)
src/Products/Five/tests/testing/fancycontent.py
View file @
dad37b5e
...
...
@@ -22,9 +22,11 @@ from OFS.SimpleItem import SimpleItem
from
zope.interface
import
implements
from
zope.interface
import
Interface
class
IFancyContent
(
Interface
):
pass
class
FancyAttribute
(
Explicit
):
"""Doc test fanatics"""
...
...
@@ -40,6 +42,7 @@ class FancyAttribute(Explicit):
InitializeClass
(
FancyAttribute
)
class
FancyContent
(
SimpleItem
):
"""A class that already comes with its own __bobo_traverse__ handler.
Quite fancy indeed.
...
...
@@ -65,13 +68,14 @@ class FancyContent(SimpleItem):
InitializeClass
(
FancyContent
)
# A copy of the above class used to demonstrate some baseline behavior
class
NonTraversableFancyContent
(
SimpleItem
):
"""A class that already comes with its own __bobo_traverse__ handler.
Quite fancy indeed.
It also comes with its own get_size method.
"""
# A copy of the above class used to demonstrate some baseline behavior.
implements
(
IFancyContent
)
meta_type
=
"Fancy Content"
...
...
@@ -91,11 +95,13 @@ class NonTraversableFancyContent(SimpleItem):
InitializeClass
(
NonTraversableFancyContent
)
def
manage_addFancyContent
(
self
,
id
,
REQUEST
=
None
):
"""Add the fancy fancy content."""
id
=
self
.
_setObject
(
id
,
FancyContent
(
id
))
return
''
def
manage_addNonTraversableFancyContent
(
self
,
id
,
REQUEST
=
None
):
"""Add the fancy fancy content."""
id
=
self
.
_setObject
(
id
,
NonTraversableFancyContent
(
id
))
...
...
src/Products/Five/tests/testing/folder.py
View file @
dad37b5e
...
...
@@ -18,6 +18,7 @@ from OFS.Folder import Folder
from
OFS.interfaces
import
IFolder
from
zope.interface
import
implements
class
NoVerifyPasteFolder
(
Folder
):
"""Folder that does not perform paste verification.
Used by test_events
...
...
@@ -25,17 +26,20 @@ class NoVerifyPasteFolder(Folder):
def
_verifyObjectPaste
(
self
,
object
,
validate_src
=
1
):
pass
def
manage_addNoVerifyPasteFolder
(
container
,
id
,
title
=
''
):
container
.
_setObject
(
id
,
NoVerifyPasteFolder
())
folder
=
container
[
id
]
folder
.
id
=
id
folder
.
title
=
title
class
FiveTraversableFolder
(
Folder
):
"""Folder that is five-traversable
"""
implements
(
IFolder
)
def
manage_addFiveTraversableFolder
(
container
,
id
,
title
=
''
):
container
.
_setObject
(
id
,
FiveTraversableFolder
())
folder
=
container
[
id
]
...
...
src/Products/Five/tests/testing/pythonproduct2/Extensions/somemodule.py
View file @
dad37b5e
def
somemethod
(
self
):
print
"Executed somemethod"
print
(
"Executed somemethod"
)
src/Products/Five/tests/testing/pythonproduct2/__init__.py
View file @
dad37b5e
def
initialize
(
context
):
print
"pythonproduct2 initialized"
print
(
"pythonproduct2 initialized"
)
src/Products/Five/tests/testing/simplecontent.py
View file @
dad37b5e
...
...
@@ -21,15 +21,19 @@ from OFS.SimpleItem import SimpleItem
from
zope.interface
import
implements
from
zope.interface
import
Interface
class
ISimpleContent
(
Interface
):
pass
class
ICallableSimpleContent
(
ISimpleContent
):
pass
class
IIndexSimpleContent
(
ISimpleContent
):
pass
class
SimpleContent
(
SimpleItem
):
implements
(
ISimpleContent
)
...
...
@@ -52,6 +56,7 @@ class SimpleContent(SimpleItem):
InitializeClass
(
SimpleContent
)
class
CallableSimpleContent
(
SimpleItem
):
"""A Viewable piece of content"""
implements
(
ICallableSimpleContent
)
...
...
@@ -64,6 +69,7 @@ class CallableSimpleContent(SimpleItem):
InitializeClass
(
CallableSimpleContent
)
class
IndexSimpleContent
(
SimpleItem
):
"""A Viewable piece of content"""
implements
(
IIndexSimpleContent
)
...
...
@@ -76,14 +82,17 @@ class IndexSimpleContent(SimpleItem):
InitializeClass
(
IndexSimpleContent
)
def
manage_addSimpleContent
(
self
,
id
,
title
,
REQUEST
=
None
):
"""Add the simple content."""
self
.
_setObject
(
id
,
SimpleContent
(
id
,
title
))
def
manage_addCallableSimpleContent
(
self
,
id
,
title
,
REQUEST
=
None
):
"""Add the viewable simple content."""
self
.
_setObject
(
id
,
CallableSimpleContent
(
id
,
title
))
def
manage_addIndexSimpleContent
(
self
,
id
,
title
,
REQUEST
=
None
):
"""Add the viewable simple content."""
self
.
_setObject
(
id
,
IndexSimpleContent
(
id
,
title
))
src/Products/Five/utilities/__init__.py
View file @
dad37b5e
# make this directory a package
src/Products/Five/utilities/browser/__init__.py
View file @
dad37b5e
# make this directory a package
src/Products/Five/utilities/browser/marker.py
View file @
dad37b5e
...
...
@@ -17,8 +17,7 @@
from
Products.Five.utilities.interfaces
import
IMarkerInterfaces
class
EditView
:
class
EditView
(
object
):
"""Marker interface edit view.
"""
...
...
@@ -36,8 +35,9 @@ class EditView:
return
self
.
index
()
def
_getLinkToInterfaceDetailsView
(
self
,
interfaceName
):
return
(
self
.
context_url
+
'/views-details.html?iface=%s&type=zope.publisher.interfaces.browser.IBrowserRequest'
%
interfaceName
)
return
(
self
.
context_url
+
(
'/views-details.html?iface=%s&type=zope.publisher.'
'interfaces.browser.IBrowserRequest'
%
interfaceName
))
def
_getNameLinkDicts
(
self
,
interfaceNames
):
return
[
dict
(
name
=
name
,
...
...
src/Products/Five/utilities/browser/tests/__init__.py
View file @
dad37b5e
# make this directory a package
src/Products/Five/utilities/browser/tests/test_marker.py
View file @
dad37b5e
...
...
@@ -14,6 +14,7 @@
"""Unit tests for marker interface views.
"""
def
test_editview
():
"""
Set everything up:
...
...
@@ -84,6 +85,7 @@ def test_editview():
>>> tearDown()
"""
def
test_suite
():
from
Testing.ZopeTestCase
import
ZopeDocTestSuite
return
ZopeDocTestSuite
()
src/Products/Five/utilities/marker.py
View file @
dad37b5e
...
...
@@ -26,6 +26,7 @@ from zope.component.interface import searchInterface
from
interfaces
import
IMarkerInterfaces
def
interfaceStringCheck
(
f
):
def
wrapper
(
ob
,
interface
):
if
isinstance
(
interface
,
str
):
...
...
@@ -33,11 +34,13 @@ def interfaceStringCheck(f):
return
f
(
ob
,
interface
)
return
wrapper
def
mark
(
ob
,
interface
):
directlyProvides
(
ob
,
directlyProvidedBy
(
ob
),
interface
)
def
erase
(
ob
,
interface
):
directlyProvides
(
ob
,
directlyProvidedBy
(
ob
)
-
interface
)
directlyProvides
(
ob
,
directlyProvidedBy
(
ob
)
-
interface
)
mark
=
interfaceStringCheck
(
mark
)
erase
=
interfaceStringCheck
(
erase
)
...
...
@@ -74,8 +77,8 @@ class MarkerInterfacesAdapter(object):
todo
.
append
(
base
)
markers
=
self
.
_getDirectMarkersOf
(
interface
)
for
interface
in
markers
:
if
(
interface
not
in
results
and
not
interface
.
providedBy
(
self
.
context
)):
if
(
interface
not
in
results
and
not
interface
.
providedBy
(
self
.
context
)):
results
.
append
(
interface
)
todo
+=
markers
return
tuple
(
results
)
...
...
src/Products/Five/viewlet/__init__.py
View file @
dad37b5e
# A package for viewlet support
\ No newline at end of file
src/Products/Five/viewlet/directives.txt
View file @
dad37b5e
...
...
@@ -369,7 +369,7 @@ specified attribute:
Traceback (most recent call last):
...
ZopeXMLConfigurationError: File "<string>", line 3.2-9.8
ConfigurationError: The provided class doesn't have the specified attribute
ConfigurationError: The provided class doesn't have the specified attribute
.
================================
Viewlet Directive Security
...
...
src/Products/Five/viewlet/manager.py
View file @
dad37b5e
...
...
@@ -23,6 +23,7 @@ from zope.viewlet.manager import ViewletManagerBase as origManagerBase
from
Products.Five.browser.pagetemplatefile
import
ZopeTwoPageTemplateFile
class
ViewletManagerBase
(
origManagerBase
):
"""A base class for Viewlet managers to work in Zope2"""
...
...
@@ -38,14 +39,14 @@ class ViewletManagerBase(origManagerBase):
# If the viewlet was not found, then raise a lookup error
if
viewlet
is
None
:
raise
zope
.
interface
.
interfaces
.
ComponentLookupError
(
'No provider with name `%s` found.'
%
name
)
'No provider with name `%s` found.'
%
name
)
# If the viewlet cannot be accessed, then raise an
# unauthorized error
if
not
guarded_hasattr
(
viewlet
,
'render'
):
raise
zope
.
security
.
interfaces
.
Unauthorized
(
'You are not authorized to access the provider '
'called `%s`.'
%
name
)
'called `%s`.'
%
name
)
# Return the viewlet.
return
viewlet
...
...
@@ -73,7 +74,12 @@ class ViewletManagerBase(origManagerBase):
# By default, use the standard Python way of doing sorting. Unwrap the
# objects first so that they are sorted as expected. This is dumb
# but it allows the tests to have deterministic results.
return
sorted
(
viewlets
,
lambda
x
,
y
:
cmp
(
aq_base
(
x
[
1
]),
aq_base
(
y
[
1
])))
def
_key
(
info
):
return
aq_base
(
info
[
1
])
return
sorted
(
viewlets
,
key
=
_key
)
def
ViewletManager
(
name
,
interface
,
template
=
None
,
bases
=
()):
attrDict
=
{
'__name__'
:
name
}
...
...
src/Products/Five/viewlet/metaconfigure.py
View file @
dad37b5e
...
...
@@ -31,11 +31,12 @@ from AccessControl.security import protectName
from
Products.Five.viewlet
import
manager
from
Products.Five.viewlet
import
viewlet
def
viewletManagerDirective
(
_context
,
name
,
permission
,
for_
=
Interface
,
layer
=
IDefaultBrowserLayer
,
view
=
IBrowserView
,
provides
=
interfaces
.
IViewletManager
,
class_
=
None
,
template
=
None
,
allowed_interface
=
None
,
allowed_attributes
=
None
):
_context
,
name
,
permission
,
for_
=
Interface
,
layer
=
IDefaultBrowserLayer
,
view
=
IBrowserView
,
provides
=
interfaces
.
IViewletManager
,
class_
=
None
,
template
=
None
,
allowed_interface
=
None
,
allowed_attributes
=
None
):
# If class is not given we use the basic viewlet manager.
if
class_
is
None
:
...
...
@@ -69,36 +70,37 @@ def viewletManagerDirective(
# register a viewlet manager
_context
.
action
(
discriminator
=
(
'viewletManager'
,
for_
,
layer
,
view
,
name
),
callable
=
zcml
.
handler
,
args
=
(
'registerAdapter'
,
new_class
,
(
for_
,
layer
,
view
),
provides
,
name
,
_context
.
info
),)
discriminator
=
(
'viewletManager'
,
for_
,
layer
,
view
,
name
),
callable
=
zcml
.
handler
,
args
=
(
'registerAdapter'
,
new_class
,
(
for_
,
layer
,
view
),
provides
,
name
,
_context
.
info
),
)
_context
.
action
(
discriminator
=
(
'five:protectClass'
,
new_class
),
callable
=
protectClass
,
args
=
(
new_class
,
permission
)
)
discriminator
=
(
'five:protectClass'
,
new_class
),
callable
=
protectClass
,
args
=
(
new_class
,
permission
),
)
if
allowed_attributes
:
for
attr
in
allowed_attributes
:
_context
.
action
(
discriminator
=
(
'five:protectName'
,
new_class
,
attr
),
callable
=
protectName
,
args
=
(
new_class
,
attr
,
permission
)
)
discriminator
=
(
'five:protectName'
,
new_class
,
attr
),
callable
=
protectName
,
args
=
(
new_class
,
attr
,
permission
),
)
_context
.
action
(
discriminator
=
(
'five:initialize:class'
,
new_class
),
callable
=
InitializeClass
,
args
=
(
new_class
,)
)
discriminator
=
(
'five:initialize:class'
,
new_class
),
callable
=
InitializeClass
,
args
=
(
new_class
,
),
)
def
viewletDirective
(
_context
,
name
,
permission
,
for_
=
Interface
,
layer
=
IDefaultBrowserLayer
,
view
=
IBrowserView
,
manager
=
interfaces
.
IViewletManager
,
class_
=
None
,
template
=
None
,
attribute
=
'render'
,
allowed_interface
=
None
,
allowed_attributes
=
None
,
**
kwargs
):
_context
,
name
,
permission
,
for_
=
Interface
,
layer
=
IDefaultBrowserLayer
,
view
=
IBrowserView
,
manager
=
interfaces
.
IViewletManager
,
class_
=
None
,
template
=
None
,
attribute
=
'render'
,
allowed_interface
=
None
,
allowed_attributes
=
None
,
**
kwargs
):
# Either the class or template must be specified.
if
not
(
class_
or
template
):
...
...
@@ -135,8 +137,8 @@ def viewletDirective(
if
attribute
!=
'render'
:
if
not
hasattr
(
class_
,
attribute
):
raise
ConfigurationError
(
"The provided class doesn't have the specified attribute
"
)
"The provided class doesn't have the specified attribute
.
"
)
if
template
:
# Create a new class for the viewlet template and class.
new_class
=
viewlet
.
SimpleViewletClass
(
...
...
@@ -165,26 +167,26 @@ def viewletDirective(
# register viewlet
_context
.
action
(
discriminator
=
(
'viewlet'
,
for_
,
layer
,
view
,
manager
,
name
),
callable
=
zcml
.
handler
,
args
=
(
'registerAdapter'
,
new_class
,
(
for_
,
layer
,
view
,
manager
),
interfaces
.
IViewlet
,
name
,
_context
.
info
),)
discriminator
=
(
'viewlet'
,
for_
,
layer
,
view
,
manager
,
name
),
callable
=
zcml
.
handler
,
args
=
(
'registerAdapter'
,
new_class
,
(
for_
,
layer
,
view
,
manager
),
interfaces
.
IViewlet
,
name
,
_context
.
info
),
)
_context
.
action
(
discriminator
=
(
'five:protectClass'
,
new_class
),
callable
=
protectClass
,
args
=
(
new_class
,
permission
)
)
discriminator
=
(
'five:protectClass'
,
new_class
),
callable
=
protectClass
,
args
=
(
new_class
,
permission
)
)
if
allowed_attributes
:
for
attr
in
allowed_attributes
:
_context
.
action
(
discriminator
=
(
'five:protectName'
,
new_class
,
attr
),
callable
=
protectName
,
args
=
(
new_class
,
attr
,
permission
)
)
discriminator
=
(
'five:protectName'
,
new_class
,
attr
),
callable
=
protectName
,
args
=
(
new_class
,
attr
,
permission
)
)
_context
.
action
(
discriminator
=
(
'five:initialize:class'
,
new_class
),
callable
=
InitializeClass
,
args
=
(
new_class
,)
)
discriminator
=
(
'five:initialize:class'
,
new_class
),
callable
=
InitializeClass
,
args
=
(
new_class
,)
)
src/Products/Five/viewlet/tests.py
View file @
dad37b5e
...
...
@@ -21,54 +21,64 @@ from zope.interface import implements
from
zope.viewlet
import
interfaces
from
OFS.SimpleItem
import
SimpleItem
class
Content
(
SimpleItem
):
implements
(
Interface
)
class
UnitTestSecurityPolicy
:
"""
Stub out the existing security policy for unit testing purposes.
"""
#
# Standard SecurityPolicy interface
#
def
validate
(
self
,
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
context
=
None
,
roles
=
None
,
*
args
,
**
kw
):
# Standard SecurityPolicy interface
def
validate
(
self
,
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
context
=
None
,
roles
=
None
,
*
args
,
**
kw
):
return
1
def
checkPermission
(
self
,
permission
,
object
,
context
)
:
def
checkPermission
(
self
,
permission
,
object
,
context
)
:
return
1
class
ILeftColumn
(
interfaces
.
IViewletManager
):
"""Left column of my page."""
class
INewColumn
(
interfaces
.
IViewletManager
):
"""Left column of my page."""
class
WeightBasedSorting
(
object
):
def
sort
(
self
,
viewlets
):
return
sorted
(
viewlets
,
lambda
x
,
y
:
cmp
(
x
[
1
].
weight
,
y
[
1
].
weight
))
def
_key
(
info
):
return
getattr
(
info
[
1
],
'weight'
,
0
)
return
sorted
(
viewlets
,
key
=
_key
)
class
Weather
(
object
):
weight
=
0
class
Stock
(
object
):
weight
=
0
def
getStockTicker
(
self
):
return
u'SRC $5.19'
class
Sport
(
object
):
weight
=
0
def
__call__
(
self
):
return
u'Red Sox vs. White Sox'
class
DynamicTempBox
(
object
):
weight
=
0
city
=
{
'name'
:
'Los Angeles, CA'
,
'temp'
:
78
}
...
...
@@ -78,4 +88,4 @@ def test_suite():
return
unittest
.
TestSuite
([
FunctionalDocFileSuite
(
'README.txt'
),
FunctionalDocFileSuite
(
'directives.txt'
),
])
])
src/Products/Five/viewlet/viewlet.py
View file @
dad37b5e
...
...
@@ -19,19 +19,22 @@ import zope.viewlet.viewlet
from
Products.Five.bbb
import
AcquisitionBBB
from
Products.Five.browser.pagetemplatefile
import
ViewPageTemplateFile
class
ViewletBase
(
zope
.
viewlet
.
viewlet
.
ViewletBase
,
AcquisitionBBB
):
pass
class
SimpleAttributeViewlet
(
zope
.
viewlet
.
viewlet
.
SimpleAttributeViewlet
,
AcquisitionBBB
):
pass
class
simple
(
zope
.
viewlet
.
viewlet
.
simple
):
# We need to ensure that the proper __init__ is called.
__init__
=
ViewletBase
.
__init__
.
im_func
def
SimpleViewletClass
(
template
,
bases
=
(),
attributes
=
None
,
name
=
u''
):
def
SimpleViewletClass
(
template
,
bases
=
(),
attributes
=
None
,
name
=
u''
):
"""A function that can be used to generate a viewlet from a set of
information.
"""
...
...
@@ -39,8 +42,8 @@ def SimpleViewletClass(template, bases=(), attributes=None,
# Create the base class hierarchy
bases
+=
(
simple
,
ViewletBase
)
attrs
=
{
'index'
:
ViewPageTemplateFile
(
template
),
'__name__'
:
name
}
attrs
=
{
'index'
:
ViewPageTemplateFile
(
template
),
'__name__'
:
name
}
if
attributes
:
attrs
.
update
(
attributes
)
...
...
@@ -53,14 +56,14 @@ def SimpleViewletClass(template, bases=(), attributes=None,
class
ResourceViewletBase
(
zope
.
viewlet
.
viewlet
.
ResourceViewletBase
):
pass
def
JavaScriptViewlet
(
path
):
"""Create a viewlet that can simply insert a javascript link."""
src
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'javascript_viewlet.pt'
)
klass
=
type
(
'JavaScriptViewlet'
,
(
ResourceViewletBase
,
ViewletBase
),
{
'index'
:
ViewPageTemplateFile
(
src
),
'_path'
:
path
})
{
'index'
:
ViewPageTemplateFile
(
src
),
'_path'
:
path
})
return
klass
...
...
@@ -68,15 +71,16 @@ def JavaScriptViewlet(path):
class
CSSResourceViewletBase
(
zope
.
viewlet
.
viewlet
.
CSSResourceViewletBase
):
pass
def
CSSViewlet
(
path
,
media
=
"all"
,
rel
=
"stylesheet"
):
"""Create a viewlet that can simply insert a javascript link."""
src
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'css_viewlet.pt'
)
klass
=
type
(
'CSSViewlet'
,
(
CSSResourceViewletBase
,
ViewletBase
),
{
'index'
:
ViewPageTemplateFile
(
src
),
'_path'
:
path
,
'_media'
:
media
,
'_rel'
:
rel
})
{
'index'
:
ViewPageTemplateFile
(
src
),
'_path'
:
path
,
'_media'
:
media
,
'_rel'
:
rel
})
return
klass
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment