[Checkins] SVN: Products.CMFDefault/branches/tseaver-ursine_skin/ Branch for "bare skin" work.

Tres Seaver tseaver at palladion.com
Mon Sep 15 22:22:57 EDT 2008


Log message for revision 91188:
  Branch for "bare skin" work.
  

Changed:
  A   Products.CMFDefault/branches/tseaver-ursine_skin/
  A   Products.CMFDefault/branches/tseaver-ursine_skin/browser/templates/ursa_main.pt
  A   Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/
  A   Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/__init__.py
  A   Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_doctests.py
  A   Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_ursa.py
  D   Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests.py
  A   Products.CMFDefault/branches/tseaver-ursine_skin/browser/ursa.py

-=-
Copied: Products.CMFDefault/branches/tseaver-ursine_skin (from rev 91187, Products.CMFDefault/trunk/Products/CMFDefault)

Added: Products.CMFDefault/branches/tseaver-ursine_skin/browser/templates/ursa_main.pt
===================================================================
--- Products.CMFDefault/branches/tseaver-ursine_skin/browser/templates/ursa_main.pt	                        (rev 0)
+++ Products.CMFDefault/branches/tseaver-ursine_skin/browser/templates/ursa_main.pt	2008-09-16 02:22:56 UTC (rev 91188)
@@ -0,0 +1,99 @@
+<metal:macro metal:define-macro="master"
+><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
+<html tal:define="globals context/@@ursine_globals"
+      i18n:domain="cmf_default">
+<head>
+ <title tal:content="globals/page_title">Title goes here</title>
+ <metal:slot define-slot="base" />
+ <metal:slot define-slot="styles" />
+</head>
+
+<body>
+
+ <div id="object_meta">
+  <img id="object_icon"
+       src="icon" align="left" title="Type" alt="[X]" height="16" width="16"
+       tal:condition="globals/icon"
+       tal:attributes="src globals/icon;
+                       alt globals/typename;
+                      "
+       i18n:attributes="alt" />
+  <div id="object_id"
+       tal:content="globals/trunc_id">ID</div>
+  <div id="object_type"
+       tal:content="globals/typename">TYPENAME</div>
+  <div id="workflow_state"
+       tal:content="globals/wf_state">WORKFLOW STATE</div>
+ </div>
+
+ <ul id="object_actions_menu">
+  <li tal:repeat="action globals/object_actions">
+  <a href="#object_action"
+      tal:attributes="href action/url"
+      tal:content="action/title"
+      i18n:translate="">OBJECT ACTION_TITLE</a><br />
+  </li>
+ </ul>
+
+ <ul id="workflow_actions_menu">
+  <li tal:repeat="action globals/workflow_actions">
+  <a href="#workflow_action"
+      tal:attributes="href action/url"
+      tal:content="action/title"
+      i18n:translate="">OBJECT ACTION_TITLE</a><br />
+  </li>
+ </ul>
+
+ <ul id="folder_actions_menu">
+  <li tal:repeat="action globals/folder_actions">
+  <a href="#folder_action"
+      tal:attributes="href action/url"
+      tal:content="action/title"
+      i18n:translate="">FOLDER ACTION_TITLE</a><br />
+  </li>
+ </ul>
+
+ <ul id="user_actions_menu">
+  <li tal:repeat="action globals/user_actions">
+   <a href="#user_action"
+      tal:attributes="href action/url"
+      tal:content="action/title" i18n:translate="">USER ACTION TITLE</a>
+  </li>
+ </ul>
+
+ <ul id="global_actions_menu">
+  <li tal:repeat="action globals/global_actions">
+   <a href="#global_action"
+      tal:attributes="href action/url"
+      tal:content="action/title" i18n:translate="">GLOBAL ACTION TITLE</a>
+  </li>
+ </ul>
+
+ <div id="Desktop">
+
+  <div id="Breadcrumbs">
+   <span class="breadcrumb"
+         tal:repeat="bc globals/breadcrumbs">
+    <a href="."
+        tal:attributes="href bc/url"
+        tal:content="bc/id">ID</a>
+   </span>
+  </div>
+
+  <p id="DesktopStatusBar"
+     tal:condition="globals/message"
+     tal:content="globals/message"
+     i18n:translate="">Status message.</p>
+
+  <metal:slot metal:define-slot="body">
+   <metal:slot metal:define-slot="header" />
+   <metal:slot metal:define-slot="main" />
+  </metal:slot>
+
+ </div>
+
+</div>
+
+</body>
+</html>
+</metal:macro>

Added: Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/__init__.py
===================================================================
--- Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/__init__.py	                        (rev 0)
+++ Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/__init__.py	2008-09-16 02:22:56 UTC (rev 91188)
@@ -0,0 +1 @@
+# Unit tests for Products.CMFDefault.browser package.

Copied: Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_doctests.py (from rev 91187, Products.CMFDefault/trunk/Products/CMFDefault/browser/tests.py)
===================================================================
--- Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_doctests.py	                        (rev 0)
+++ Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_doctests.py	2008-09-16 02:22:56 UTC (rev 91188)
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""CMFDefault browser tests.
+
+$Id$
+"""
+
+import unittest
+from Testing import ZopeTestCase
+from zope.testing import doctest
+
+from Products.CMFDefault.testing import FunctionalLayer
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(doctest.DocFileSuite('../folder.txt',
+                                    optionflags=doctest.NORMALIZE_WHITESPACE))
+    s = ZopeTestCase.FunctionalDocFileSuite('../metadata.txt')
+    s.layer = FunctionalLayer
+    suite.addTest(s)
+    s = ZopeTestCase.FunctionalDocFileSuite('../document.txt')
+    s.layer = FunctionalLayer
+    suite.addTest(s)
+    s = ZopeTestCase.FunctionalDocFileSuite('../file.txt')
+    s.layer = FunctionalLayer
+    suite.addTest(s)
+    return suite
+
+if __name__ == '__main__':
+    from Products.CMFCore.testing import run
+    run(test_suite())

Added: Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_ursa.py
===================================================================
--- Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_ursa.py	                        (rev 0)
+++ Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests/test_ursa.py	2008-09-16 02:22:56 UTC (rev 91188)
@@ -0,0 +1,430 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Test Products.CMFDefault.browser.ursa
+
+$Id$
+"""
+import unittest
+from zope.component.testing import PlacelessSetup
+
+class UrsineGlobalsTests(unittest.TestCase, PlacelessSetup):
+
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+
+    def tearDown(self):
+        PlacelessSetup.tearDown(self)
+
+    def _getTargetClass(self):
+        from Products.CMFDefault.browser.ursa import UrsineGlobals
+        return UrsineGlobals
+
+    def _makeOne(self, context=None, request=None):
+        if context is None:
+            context = self._makeContext()
+        if request is None:
+            request = DummyRequest()
+        return self._getTargetClass()(context, request)
+
+    def _makeContext(self):
+        from zope.component import getSiteManager
+        from Products.CMFCore.interfaces import IPropertiesTool
+        context = DummyContext()
+        tool = context.portal_properties = DummyPropertiesTool()
+        sm = getSiteManager()
+        sm.registerUtility(tool, IPropertiesTool)
+        return context
+
+    def test_ctor_wo_def_charset_doesnt_set_content_type(self):
+        context = self._makeContext()
+        request = DummyRequest()
+        response = request.RESPONSE
+        view = self._makeOne(context, request)
+        self.assertEqual(len(response._set_headers), 0)
+
+    def test_ctor_w_resp_charset_doesnt_set_content_type(self):
+        context = self._makeContext()
+        request = DummyRequest()
+        response = request.RESPONSE
+        response._orig_headers['content-type'] = 'text/html; charset=UTF-8'
+        view = self._makeOne(context, request)
+        self.assertEqual(len(response._set_headers), 0)
+
+    def test_ctor_w_resp_charset_w_def_charset_doesnt_override_charset(self):
+        context = self._makeContext()
+        context.portal_properties.default_charset = 'latin1'
+        request = DummyRequest()
+        response = request.RESPONSE
+        response._orig_headers['content-type'] = 'text/html; charset=UTF-8'
+        view = self._makeOne(context, request)
+        self.assertEqual(len(response._set_headers), 0)
+
+    def test_ctor_wo_resp_charst_w_def_charset_sets_charset(self):
+        context = self._makeContext()
+        context.portal_properties.default_charset = 'latin1'
+        request = DummyRequest()
+        response = request.RESPONSE
+        response._orig_headers['content-type'] = 'text/html'
+        view = self._makeOne(context, request)
+        self.assertEqual(len(response._set_headers), 1)
+        self.assertEqual(response._set_headers[0],
+                         ('content-type', 'text/html; charset=latin1'))
+
+    def test_ptool(self):
+        view = self._makeOne()
+        tool = view.context.portal_properties
+        self.failUnless(view.ptool is tool)
+
+    def test_utool(self):
+        view = self._makeOne()
+        tool = view.context.portal_url = DummyURLTool()
+        self.failUnless(view.utool is tool)
+
+    def test_mtool(self):
+        view = self._makeOne()
+        tool = view.context.portal_membership = DummyMembershipTool()
+        self.failUnless(view.mtool is tool)
+
+    def test_atool(self):
+        view = self._makeOne()
+        tool = view.context.portal_actions = DummyActionsTool()
+        self.failUnless(view.atool is tool)
+
+    def test_wtool(self):
+        view = self._makeOne()
+        tool = view.context.portal_workflow = DummyWorkflowTool()
+        self.failUnless(view.wtool is tool)
+
+    def test_portal_object(self):
+        view = self._makeOne()
+        tool = view.context.portal_url = DummyURLTool()
+        portal = DummyContext()
+        tool.getPortalObject = lambda: portal
+        self.failUnless(view.portal_object is portal)
+
+    def test_portal_url(self):
+        view = self._makeOne()
+        tool = view.context.portal_url = DummyURLTool()
+        tool.__call__ = lambda: 'http://example.com/'
+        self.assertEqual(view.portal_url, 'http://example.com/')
+
+    def test_portal_title(self):
+        view = self._makeOne()
+        tool = view.context.portal_url = DummyURLTool()
+        portal = DummyContext()
+        portal.Title = lambda: 'TITLE'
+        tool.getPortalObject = lambda: portal
+        self.assertEqual(view.portal_title, 'TITLE')
+
+    def test_object_title(self):
+        view = self._makeOne()
+        view.context.Title = lambda: 'TITLE'
+        self.assertEqual(view.object_title, 'TITLE')
+
+    def test_object_description(self):
+        view = self._makeOne()
+        view.context.Title = lambda: 'TITLE'
+        self.assertEqual(view.object_title, 'TITLE')
+
+    def test_trunc_id(self):
+        view = self._makeOne()
+        view.context.getId = lambda: 'ID'
+        self.assertEqual(view.trunc_id, 'ID')
+
+    def test_trunc_id_w_long_id(self):
+        view = self._makeOne()
+        view.context.getId = lambda: 'X' * 20
+        self.assertEqual(view.trunc_id, 'X' * 15 + '...')
+
+    def test_icon_wo_getIcon_w_icon(self):
+        view = self._makeOne()
+        view.context.getIcon = lambda: 'ICON'
+        view.context.icon = 'ICON2'
+        self.assertEqual(view.icon, 'ICON')
+
+    def test_icon_wo_getIcon_w_icon(self):
+        view = self._makeOne()
+        view.context.icon = 'ICON'
+        self.assertEqual(view.icon, 'ICON')
+
+    def test_icon_wo_getIcon_wo_icon(self):
+        view = self._makeOne()
+        self.assertEqual(view.icon, '')
+
+    def test_typename(self):
+        view = self._makeOne()
+        view.context.getPortalTypeName = lambda: 'TYPENAME'
+        self.assertEqual(view.typename, 'TYPENAME')
+
+    def test_wf_state(self):
+        view = self._makeOne()
+        view.context.portal_workflow = DummyWorkflowTool()
+        self.assertEqual(view.wf_state, 'DUMMY')
+
+    def test_page_title_wo_match(self):
+        view = self._makeOne()
+        view.context.Title = lambda: 'CONTEXT'
+        tool = view.context.portal_url = DummyURLTool()
+        portal = DummyContext()
+        portal.Title = lambda: 'SITE'
+        tool.getPortalObject = lambda: portal
+        self.assertEqual(view.page_title, 'SITE: CONTEXT')
+
+    def test_page_title_w_match(self):
+        view = self._makeOne()
+        view.context.Title = lambda: 'MATCH'
+        tool = view.context.portal_url = DummyURLTool()
+        portal = DummyContext()
+        portal.Title = lambda: 'MATCH'
+        tool.getPortalObject = lambda: portal
+        self.assertEqual(view.page_title, 'MATCH')
+
+    def test_breadcrumbs_at_root(self):
+        PATHS_TO_CONTEXTS = []
+        site = DummySite(PATHS_TO_CONTEXTS)
+        ptool = site.portal_properties = DummyPropertiesTool()
+        ptool.title = lambda: 'SITE'
+        utool = site.portal_url = DummyURLTool(site, PATHS_TO_CONTEXTS)
+        utool.__call__ = lambda: 'http://example.com/'
+        view = self._makeOne(context=site)
+        crumbs = view.breadcrumbs
+        self.assertEqual(len(crumbs), 1)
+        self.assertEqual(crumbs[0]['id'], 'root')
+        self.assertEqual(crumbs[0]['title'], 'SITE')
+        self.assertEqual(crumbs[0]['url'], 'http://example.com/')
+
+    def test_breadcrumbs_not_root(self):
+        context = DummyContext()
+        context.Title = lambda: 'CONTEXT'
+        context.absolute_url = lambda: 'http://example.com/parent/child'
+        parent = DummyContext()
+        parent.Title = lambda: 'PARENT'
+        parent.absolute_url = lambda: 'http://example.com/parent'
+        PATHS_TO_CONTEXTS = [(('parent',), parent),
+                             (('parent', 'child'), context),
+                            ]
+        site = DummySite(PATHS_TO_CONTEXTS)
+        ptool = context.portal_properties = DummyPropertiesTool()
+        ptool.title = lambda: 'SITE'
+        utool = context.portal_url = DummyURLTool(site, PATHS_TO_CONTEXTS)
+        utool.__call__ = lambda: 'http://example.com/'
+
+        view = self._makeOne(context=context)
+
+        crumbs = view.breadcrumbs
+
+        self.assertEqual(len(crumbs), 3)
+        self.assertEqual(crumbs[0]['id'], 'root')
+        self.assertEqual(crumbs[0]['title'], 'SITE')
+        self.assertEqual(crumbs[0]['url'], 'http://example.com/')
+        self.assertEqual(crumbs[1]['id'], 'parent')
+        self.assertEqual(crumbs[1]['title'], 'PARENT')
+        self.assertEqual(crumbs[1]['url'], 'http://example.com/parent')
+        self.assertEqual(crumbs[2]['id'], 'child')
+        self.assertEqual(crumbs[2]['title'], 'CONTEXT')
+        self.assertEqual(crumbs[2]['url'], 'http://example.com/parent/child')
+
+    def test_member(self):
+        view = self._makeOne()
+        tool = view.context.portal_membership = DummyMembershipTool()
+        member = DummyUser()
+        tool.getAuthenticatedMember = lambda: member
+        self.failUnless(view.member is member)
+
+    def test_membersfolder(self):
+        view = self._makeOne()
+        tool = view.context.portal_membership = DummyMembershipTool()
+        membersfolder = object()
+        tool.getMembersFolder = lambda: membersfolder
+        self.failUnless(view.membersfolder is membersfolder)
+
+    def test_isAnon_tool_returns_True(self):
+        view = self._makeOne()
+        tool = view.context.portal_membership = DummyMembershipTool()
+        tool.isAnonymousUser = lambda: True
+        self.failUnless(view.isAnon)
+
+    def test_isAnon_tool_returns_False(self):
+        view = self._makeOne()
+        tool = view.context.portal_membership = DummyMembershipTool()
+        tool.isAnonymousUser = lambda: False
+        self.failIf(view.isAnon)
+
+    def test_uname_anonymous(self):
+        view = self._makeOne()
+        tool = view.context.portal_membership = DummyMembershipTool()
+        tool.isAnonymousUser = lambda: True
+        self.assertEqual(view.uname, 'Guest')
+
+    def test_uname_not_anonymous(self):
+        view = self._makeOne()
+        tool = view.context.portal_membership = DummyMembershipTool()
+        tool.isAnonymousUser = lambda: False
+        member = DummyUser()
+        member.getUserName = lambda: 'luser'
+        tool.getAuthenticatedMember = lambda: member
+        self.assertEqual(view.uname, 'luser')
+
+    def test_status_message_missing(self):
+        view = self._makeOne()
+        view.request.form = {}
+        self.assertEqual(view.status_message, None)
+
+    def test_status_message_missing(self):
+        view = self._makeOne()
+        view.request.form = {'portal_status_message': 'FOO'}
+        self.assertEqual(view.status_message, 'FOO')
+
+    def test_actions(self):
+        ACTIONS = {'global': [],
+                   'user': [],
+                   'object': [],
+                   'folder': [],
+                   'workflow': [],
+                  }
+        view = self._makeOne()
+        tool = view.context.portal_actions = DummyActionsTool(ACTIONS)
+        self.assertEqual(view.actions, ACTIONS)
+
+    def test_global_actions(self):
+        ACTIONS = {'global': [DummyAction('a'), DummyAction('b')],
+                   'user': [],
+                   'object': [],
+                   'folder': [],
+                   'workflow': [],
+                  }
+        view = self._makeOne()
+        tool = view.context.portal_actions = DummyActionsTool(ACTIONS)
+        self.assertEqual(view.global_actions, ACTIONS['global'])
+
+    def test_user_actions(self):
+        ACTIONS = {'global': [],
+                   'user': [DummyAction('a'), DummyAction('b')],
+                   'object': [],
+                   'folder': [],
+                   'workflow': [],
+                  }
+        view = self._makeOne()
+        tool = view.context.portal_actions = DummyActionsTool(ACTIONS)
+        self.assertEqual(view.user_actions, ACTIONS['user'])
+
+    def test_object_actions(self):
+        ACTIONS = {'global': [],
+                   'user': [],
+                   'object': [DummyAction('a'), DummyAction('b')],
+                   'folder': [],
+                   'workflow': [],
+                  }
+        view = self._makeOne()
+        tool = view.context.portal_actions = DummyActionsTool(ACTIONS)
+        self.assertEqual(view.object_actions, ACTIONS['object'])
+
+    def test_folder_actions(self):
+        ACTIONS = {'global': [],
+                   'user': [],
+                   'object': [],
+                   'folder': [DummyAction('a'), DummyAction('b')],
+                   'workflow': [],
+                  }
+        view = self._makeOne()
+        tool = view.context.portal_actions = DummyActionsTool(ACTIONS)
+        self.assertEqual(view.folder_actions, ACTIONS['folder'])
+
+    def test_workflow_actions(self):
+        ACTIONS = {'global': [],
+                   'user': [],
+                   'object': [],
+                   'folder': [],
+                   'workflow': [DummyAction('a'), DummyAction('b')],
+                  }
+        view = self._makeOne()
+        tool = view.context.portal_actions = DummyActionsTool(ACTIONS)
+        self.assertEqual(view.workflow_actions, ACTIONS['workflow'])
+
+class DummyContext:
+    pass
+
+class DummyAction:
+    def __init__(self, id):
+        self.id = id
+
+class DummySite:
+    def __init__(self, paths_to_contexts=()):
+        self.paths_to_contexts = paths_to_contexts[:]
+
+    def unrestrictedTraverse(self, path):
+        for known, context in self.paths_to_contexts:
+            if path == known:
+                return context
+        raise ValueError('Unknown path: %s' % path)
+
+class DummyPropertiesTool:
+    def getProperty(self, key, default):
+        return getattr(self, key, default)
+
+class DummyURLTool:
+    def __init__(self, site=None, paths_to_contexts=()):
+        self.site = site
+        self.paths_to_contexts = paths_to_contexts[:]
+
+    def getPortalObject(self):
+        return self.site
+
+    def getRelativeContentPath(self, context):
+        if context is self.site:
+            return ()
+        for path, known in self.paths_to_contexts:
+            if context is known:
+                return path
+        raise ValueError('Unknown context: %s' % context)
+
+class DummyMembershipTool:
+    pass
+
+class DummyActionsTool:
+    def __init__(self, actions=None):
+        if actions is None:
+            actions = {}
+        self.actions = actions.copy()
+
+    def listFilteredActionsFor(self, context):
+        return self.actions
+
+class DummyWorkflowTool:
+    review_state = 'DUMMY'
+    def getInfoFor(self, context, key, default):
+        if key == 'review_state':
+            return self.review_state
+
+class DummyUser:
+    pass
+
+class DummyResponse:
+    def __init__(self, **kw):
+        self._orig_headers = kw.copy()
+        self._set_headers = []
+
+    def getHeader(self, key):
+        return self._orig_headers.get(key, '')
+
+    def setHeader(self, key, value):
+        self._set_headers.append((key, value))
+
+class DummyRequest:
+    def __init__(self):
+        self.RESPONSE = DummyResponse()
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(UrsineGlobalsTests),
+    ))

Deleted: Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/tests.py	2008-09-16 00:24:18 UTC (rev 91187)
+++ Products.CMFDefault/branches/tseaver-ursine_skin/browser/tests.py	2008-09-16 02:22:56 UTC (rev 91188)
@@ -1,42 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""CMFDefault browser tests.
-
-$Id$
-"""
-
-import unittest
-from Testing import ZopeTestCase
-from zope.testing import doctest
-
-from Products.CMFDefault.testing import FunctionalLayer
-
-
-def test_suite():
-    suite = unittest.TestSuite()
-    suite.addTest(doctest.DocFileSuite('folder.txt',
-                                    optionflags=doctest.NORMALIZE_WHITESPACE))
-    s = ZopeTestCase.FunctionalDocFileSuite('metadata.txt')
-    s.layer = FunctionalLayer
-    suite.addTest(s)
-    s = ZopeTestCase.FunctionalDocFileSuite('document.txt')
-    s.layer = FunctionalLayer
-    suite.addTest(s)
-    s = ZopeTestCase.FunctionalDocFileSuite('file.txt')
-    s.layer = FunctionalLayer
-    suite.addTest(s)
-    return suite
-
-if __name__ == '__main__':
-    from Products.CMFCore.testing import run
-    run(test_suite())

Added: Products.CMFDefault/branches/tseaver-ursine_skin/browser/ursa.py
===================================================================
--- Products.CMFDefault/branches/tseaver-ursine_skin/browser/ursa.py	                        (rev 0)
+++ Products.CMFDefault/branches/tseaver-ursine_skin/browser/ursa.py	2008-09-16 02:22:56 UTC (rev 91188)
@@ -0,0 +1,192 @@
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
+from Products.CMFDefault.utils import Message as _
+from Products.CMFDefault.utils import getBrowserCharset
+from Products.CMFDefault.utils import decode
+from Products.CMFDefault.browser.utils import ViewBase
+from Products.CMFDefault.browser.utils import memoize
+
+class UrsineMainTemplate(ViewBase):
+
+    template = ViewPageTemplateFile('templates/ursa_main.pt')
+
+class UrsineGlobals(ViewBase):
+    """ Provide lazy / efficient template-level globals.
+
+    o Replaces 'getMainGlobals' in stock skin.
+    """
+    def __init__(self, context, request):
+        super(ViewBase, self).__init__(context, request)
+        ct = self.request.RESPONSE.getHeader('content-type') or ''
+        if not 'charset' in ct:
+            # Some newstyle views set a different charset - don't override it.
+            # Oldstyle views need the default_charset.
+            default_charset = self.ptool.getProperty('default_charset', None)
+            if default_charset:
+                self.request.RESPONSE.setHeader('content-type',
+                              '%s; charset=%s' % (ct, default_charset))
+
+    @property
+    @memoize
+    def ptool(self):
+        return self._getTool('portal_properties')
+
+    @property
+    @memoize
+    def utool(self):
+        return self._getTool('portal_url')
+
+    @property
+    @memoize
+    def mtool(self):
+        return self._getTool('portal_membership')
+
+    @property
+    @memoize
+    def atool(self):
+        return self._getTool('portal_actions')
+
+    @property
+    @memoize
+    def wtool(self):
+        return self._getTool('portal_workflow')
+
+    @property
+    @memoize
+    def portal_object(self):
+        return self.utool.getPortalObject()
+
+    @property
+    @memoize
+    def portal_url(self):
+        return self.utool()
+
+    @property
+    @memoize
+    def portal_title(self):
+        return self.portal_object.Title()
+
+    @property
+    @memoize
+    def object_title(self):
+        return self.context.Title()
+
+    @property
+    @memoize
+    def object_description(self):
+        return self.context.Description()
+
+    @property
+    @memoize
+    def trunc_id(self):
+        id = self.context.getId()
+        if len(id) > 15:
+            id = id[:15] + '...'
+        return id
+
+    @property
+    @memoize
+    def icon(self):
+        return getattr(self.context, 'getIcon',
+                        lambda: getattr(self.context, 'icon', ''))()
+    @property
+    @memoize
+    def typename(self):
+        return self.context.getPortalTypeName()
+
+    @property
+    @memoize
+    def wf_state(self):
+        return self.wtool.getInfoFor(self.context, 'review_state', '')
+
+    @property
+    @memoize
+    def page_title(self):
+        site_title = self.portal_title
+        page_title = self.object_title
+
+        if page_title != site_title:
+            page_title = site_title + ": " + page_title
+
+        return decode(page_title, self.context)
+
+    @property
+    @memoize
+    def breadcrumbs(self):
+        # XXX Shouldn't we just be walking up the aq_inner chain?
+        result = [{'id': _(u'root'),
+                   'title' : self.ptool.title(),
+                   'url' : self.portal_url,
+                  }]
+
+        relative = self.utool.getRelativeContentPath(self.context)
+        portal = self.portal_object
+
+        for i, token in enumerate(relative):
+            now = relative[:i+1]
+            obj = portal.unrestrictedTraverse(now)
+            if token != 'talkback':
+                result.append({'id': token,
+                               'title': obj.Title(),
+                               'url': obj.absolute_url(),
+                              })
+
+        return result
+
+    @property
+    @memoize
+    def member(self):
+        return self.mtool.getAuthenticatedMember()
+
+    @property
+    @memoize
+    def membersfolder(self):
+        return self.mtool.getMembersFolder()
+
+    @property
+    @memoize
+    def isAnon(self):
+        return self.mtool.isAnonymousUser()
+
+    @property
+    @memoize
+    def uname(self):
+        return self.isAnon and 'Guest' or self.member.getUserName()
+
+    @property
+    @memoize
+    def status_message(self):
+        message = self.request.form.get('portal_status_message')
+        if message is not None:
+            message = decode(message, self.context)
+        return message
+ 
+    @property
+    @memoize
+    def actions(self):
+        return self.atool.listFilteredActionsFor(self.context)
+    
+    @property
+    @memoize
+    def user_actions(self):
+        return self.actions['user']
+    
+    @property
+    @memoize
+    def object_actions(self):
+        return self.actions['object']
+    
+    @property
+    @memoize
+    def workflow_actions(self):
+        return self.actions['workflow']
+    
+    @property
+    @memoize
+    def folder_actions(self):
+        return self.actions['folder']
+    
+    @property
+    @memoize
+    def global_actions(self):
+        return self.actions['global']



More information about the Checkins mailing list