[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">
    &nbsp;<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">
    &nbsp;<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