[Zope3-checkins] CVS: Zope3/src/zope/app/tree/browser -
__init__.py:1.1 configure.zcml:1.1 cookie.py:1.1
example1.pt:1.1 navigation_macros.pt:1.1 tests.py:1.1
Philipp von Weitershausen
philikon at philikon.de
Thu Feb 19 15:43:06 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/tree/browser
In directory cvs.zope.org:/tmp/cvs-serv12688/browser
Added Files:
__init__.py configure.zcml cookie.py example1.pt
navigation_macros.pt tests.py
Log Message:
Bring over zope.products.statictree to zope.app.
=== Added File Zope3/src/zope/app/tree/browser/__init__.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser views
$Id: __init__.py,v 1.1 2004/02/19 20:43:05 philikon Exp $
"""
from zope.app import zapi
from zope.app.publisher.browser import BrowserView
from zope.app.tree.interfaces import ITreeStateEncoder
from zope.app.tree.node import Node
class StatefulTreeView(BrowserView):
def statefulTree(self, root=None, filter=None, tree_state=None):
"""Build a tree with tree state information from a request.
"""
if root is None:
root = self.context
expanded_nodes = []
if tree_state is not None:
encoder = zapi.getUtility(root, ITreeStateEncoder)
expanded_nodes = encoder.decodeTreeState(tree_state)
node = Node(root, expanded_nodes, filter)
node.expand()
return node
=== Added File Zope3/src/zope/app/tree/browser/configure.zcml ===
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="zope"
>
<!-- Register icons -->
<browser:resourceDirectory
name="tree_images"
directory="images" />
<!-- Cookie tree -->
<browser:pages
for="*"
class=".cookie.CookieTreeView"
permission="zope.View"
>
<browser:page
name="cookie_tree"
attribute="cookieTree"
/>
<browser:page
name="folder_cookie_tree"
attribute="folderTree"
/>
<browser:page
name="site_cookie_tree"
attribute="siteTree"
/>
<browser:page
name="root_cookie_tree"
attribute="rootTree"
/>
</browser:pages>
<!-- Set up the skin -->
<browser:layer name="statictree" />
<browser:skin
name="StaticTree"
layers="statictree rotterdam default"
/>
<browser:page
for="*"
name="navigation_macros"
permission="zope.View"
layer="statictree"
template="navigation_macros.pt"
/>
</configure>
=== Added File Zope3/src/zope/app/tree/browser/cookie.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""Stateful cookie tree
$Id: cookie.py,v 1.1 2004/02/19 20:43:05 philikon Exp $
"""
from zope.app import zapi
from zope.app.interfaces.content.folder import IFolder
from zope.app.interfaces.services.service import ISite, ISiteManager
from zope.app.interfaces.traversing import IContainmentRoot
from zope.app.tree.filters import OnlyInterfacesFilter
from zope.app.tree.browser import StatefulTreeView
class CookieTreeView(StatefulTreeView):
"""A stateful tree view using cookies to remember the tree state
"""
request_variable = 'tree-state'
def cookieTree(self, root=None, filter=None):
"""Build a tree with tree state information from a request.
"""
request = self.request
tree_state = request.get(self.request_variable, "")
tree_state = str(tree_state)
tree_state = tree_state or None
if tree_state is not None:
# set a cookie right away
request.response.setCookie(self.request_variable,
tree_state)
return self.statefulTree(root, filter, tree_state)
def folderTree(self, root=None):
"""Cookie tree with only folders (and site managers).
"""
filter = OnlyInterfacesFilter(IFolder, ISiteManager)
return self.cookieTree(root, filter)
def siteTree(self):
"""Cookie tree with only folders and the nearest site as root
node.
"""
parent = self.context
for parent in zapi.getParents(self.context):
if ISite.isImplementedBy(parent):
break
return self.folderTree(parent)
def rootTree(self):
"""Cookie tree with only folders and the root container as
root node.
"""
root = zapi.getRoot(self.context)
return self.folderTree(root)
=== Added File Zope3/src/zope/app/tree/browser/example1.pt ===
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
metal:use-macro="views/standard_macros/page"
>
<body>
<!--
This example template demonstrates the direct use of the supplemented
browser view (context/@@static_cookie_tree). No extra python code was
required, only ZCML configuration.
Feel free to use this template or parts of it in your own works
without any license restrictions, but please give credit where credit
is due.
Tip: Change the 'context/@@cookie_tree' expression below to
'context/@@folder_cookie_tree' for a tree with only folders.
-->
<div metal:fill-slot="body">
<table cellspacing="0" cellpadding="0"
tal:define="root context/@@cookie_tree;
result root/getFlatDicts;
nodeDictList python:result[0];
maxDepth python:result[1]">
<!-- the root needs some special treatment, since it is not in nodeDictList -->
<tr>
<td width="16">
<img src="" tal:define="icon context/@@zmi_icon | nothing"
tal:replace="structure icon" />
</td>
<td class="list-item"
tal:attributes="colspan python:maxDepth+2">
<b tal:content="root/getId() | string:[top]"></b>
</td>
</tr>
<tr tal:repeat="nodeInfo nodeDictList">
<tal:block tal:define="node nodeInfo/node">
<!-- generate the lines that will point to the next node in the level -->
<td style="width:16px" tal:repeat="state nodeInfo/row-state">
<img tal:attributes="src context/++resource++tree_images/vline.png"
tal:condition="state" alt="|" border="0" />
</td>
<td style="width:16px">
<!-- if we have children, let's allow them to be expanded and collapsed -->
<a href=""
tal:attributes="href string:?tree-state=${nodeInfo/tree-state}"
tal:condition="node/hasChildren">
<!-- If the node is the last node of the level, then we need to use
different plus and minus that do not have a line going off
downward -->
<tal:block condition="not:nodeInfo/last-level-node">
<img tal:attributes="src context/++resource++tree_images/plus_vline.png"
tal:condition="not:node/expanded" alt="+" border="0" />
<img tal:attributes="src context/++resource++tree_images/minus_vline.png"
tal:condition="node/expanded" alt="-" border="0" />
</tal:block>
<tal:block condition="nodeInfo/last-level-node">
<img tal:attributes="src context/++resource++tree_images/plus.png"
tal:condition="not:node/expanded" alt="+" border="0" />
<img tal:attributes="src context/++resource++tree_images/minus.png"
tal:condition="node/expanded" alt="-" border="0" />
</tal:block>
</a>
<!-- this node has no children, so either display a T or L as
lines, depending on whether we're the last node in this level
or not -->
<tal:block condition="not:node/hasChildren">
<img tal:attributes="src context/++resource++tree_images/tline.png"
tal:condition="not:nodeInfo/last-level-node" alt="" border="0" />
<img tal:attributes="src context/++resource++tree_images/lline.png"
tal:condition="nodeInfo/last-level-node" alt="" border="0" />
</tal:block>
</td>
<td style="width:16px"
tal:define="object nocall:node/context;
icon object/@@zmi_icon | nothing">
<img src="" tal:replace="structure icon" />
</td>
<td class="list-item"
tal:attributes="colspan python:maxDepth-len(nodeInfo['row-state'])+1">
<a href=""
tal:attributes="href
string:${node/context/@@absolute_url}/@@SelectedManagementView.html"
tal:content="node/context/zope:name">
node/id
</a>
</td>
</tal:block>
</tr>
</table>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/tree/browser/navigation_macros.pt ===
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
i18n:domain="zope">
<body>
<!-- Java scripts for the navigation tree - none! -->
<metal:tree define-macro="navigation_tree_js">
</metal:tree>
<!-- Box containing the actual navigation tree -->
<metal:tree define-macro="navigation_tree_box">
<div class="box" id="navigationTree">
<h4 i18n:translate="">Navigation</h4>
<table cellspacing="0" cellpadding="0"
tal:define="root context/@@root_cookie_tree;
result root/getFlatDicts;
nodeDictList python:result[0];
maxDepth python:result[1]">
<tr>
<td width="16">
<img src="" tal:define="icon root/context/@@zmi_icon | nothing"
tal:replace="structure icon" />
</td>
<td class="list-item"
tal:attributes="colspan python:maxDepth+2">
<a href=""
tal:attributes="href
string:${root/context/@@absolute_url}/@@SelectedManagementView.html"
tal:content="root/getId() | string:[top]"></a>
</td>
</tr>
<tr tal:repeat="nodeInfo nodeDictList">
<tal:block tal:define="node nodeInfo/node">
<td style="width:16px" tal:repeat="state nodeInfo/row-state">
<img tal:attributes="src context/++resource++tree_images/vline.png"
tal:condition="state" alt="|" border="0" />
</td>
<td style="width:16px">
<a href=""
tal:attributes="href string:?tree-state=${nodeInfo/tree-state}"
tal:condition="node/hasChildren">
<tal:block condition="not:nodeInfo/last-level-node">
<img tal:attributes="src context/++resource++tree_images/plus_vline.png"
tal:condition="not:node/expanded" alt="+" border="0" />
<img tal:attributes="src context/++resource++tree_images/minus_vline.png"
tal:condition="node/expanded" alt="-" border="0" />
</tal:block>
<tal:block condition="nodeInfo/last-level-node">
<img tal:attributes="src context/++resource++tree_images/plus.png"
tal:condition="not:node/expanded" alt="+" border="0" />
<img tal:attributes="src context/++resource++tree_images/minus.png"
tal:condition="node/expanded" alt="-" border="0" />
</tal:block>
</a>
<tal:block condition="not:node/hasChildren">
<img tal:attributes="src context/++resource++tree_images/tline.png"
tal:condition="not:nodeInfo/last-level-node" alt="" border="0" />
<img tal:attributes="src context/++resource++tree_images/lline.png"
tal:condition="nodeInfo/last-level-node" alt="" border="0" />
</tal:block>
</td>
<td style="width:16px"
tal:define="object nocall:node/context;
icon object/@@zmi_icon | nothing">
<img src="" tal:replace="structure icon" />
</td>
<td class="list-item"
tal:attributes="colspan python:maxDepth-len(nodeInfo['row-state'])+1">
<a href=""
tal:attributes="href
string:${node/context/@@absolute_url}/@@SelectedManagementView.html"
tal:content="node/context/zope:name">
node/id
</a>
</td>
</tal:block>
</tr>
</table>
</div>
</metal:tree>
</body>
</html>
=== Added File Zope3/src/zope/app/tree/browser/tests.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""
$Id: tests.py,v 1.1 2004/02/19 20:43:05 philikon Exp $
"""
import unittest
from zope.publisher.browser import TestRequest
from zope.app import zapi
from zope.app.tests import ztapi
from zope.app.tree.utils import TreeStateEncoder
from zope.app.tree.browser import StatefulTreeView
from zope.app.tree.browser.cookie import CookieTreeView
from zope.app.tree.tests.basetest import BaseTestCase
class StatefulTreeViewTest(BaseTestCase):
def setUp(self):
super(StatefulTreeViewTest, self).setUp()
self.makeItems()
# provide the view for all objects (None)
ztapi.browserView(None, 'stateful_tree', [StatefulTreeView])
def makeRequest(self):
request = self.request = TestRequest()
# XXX test stateful tree view
class CookieTreeViewTest(StatefulTreeViewTest):
def setUp(self):
super(CookieTreeViewTest, self).setUp()
ztapi.browserView(None, 'cookie_tree', [CookieTreeView])
def makeRequestWithVar(self):
varname = CookieTreeView.request_variable
encoder = TreeStateEncoder()
tree_state = encoder.encodeTreeState(self.expanded_nodes)
environ = {varname: tree_state}
request = TestRequest(environ=environ)
return request
def test_cookie_tree_pre_expanded(self):
request = self.makeRequestWithVar()
view = zapi.getView(self.root_obj, 'cookie_tree', request)
cookie_tree = view.cookieTree()
self.assert_(self.root_node.expanded)
for node in self.root_node.getFlatNodes():
self.assertEqual(node.expanded, node.getId() in self.expanded_nodes)
def test_cookie_tree_sets_cookie(self):
request = self.makeRequestWithVar()
view = zapi.getView(self.root_obj, 'cookie_tree', request)
cookie_tree = view.cookieTree()
self.failIf(request.response.getCookie(view.request_variable) is None)
def test_suite():
suite = unittest.makeSuite(StatefulTreeViewTest)
suite.addTest(unittest.makeSuite(CookieTreeViewTest))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
More information about the Zope3-Checkins
mailing list