[z3-checkins] r9706 - z3/Five/trunk

faassen at codespeak.net faassen at codespeak.net
Tue Mar 8 16:13:29 MET 2005


Author: faassen
Date: Tue Mar  8 16:13:29 2005
New Revision: 9706

Added:
   z3/Five/trunk/add.pt
   z3/Five/trunk/adding.pt
   z3/Five/trunk/adding.py
Log:
Forgot to add these; needed for add view support.


Added: z3/Five/trunk/add.pt
==============================================================================
--- (empty file)
+++ z3/Five/trunk/add.pt	Tue Mar  8 16:13:29 2005
@@ -0,0 +1,72 @@
+<html metal:use-macro="here/main_template/macros/master">
+  <body>
+  <div metal:fill-slot="main">
+
+  <div metal:define-macro="addform">
+
+    <form action="." tal:attributes="action request/URL" method="post"
+          enctype="multipart/form-data">
+
+      <div metal:define-macro="formbody">
+
+        <h3 tal:condition="view/label"
+            tal:content="view/label"
+            metal:define-slot="heading"
+            >Edit something</h3>
+
+        <p tal:define="status view/update"
+           tal:condition="status"
+           tal:content="status" />
+
+        <p tal:condition="view/errors" i18n:translate="">
+          There are <strong tal:content="python:len(view.errors)"
+                            i18n:name="num_errors">6</strong> input errors.
+        </p>
+
+        <div metal:define-slot="extra_info" tal:replace="nothing">
+        </div>
+
+        <div class="row" metal:define-slot="extra_top" tal:replace="nothing">
+            <div class="label">Extra top</div>
+            <div class="label"><input type="text" style="width:100%" /></div>
+        </div>
+
+        <div metal:use-macro="context/@@widget_macros/widget_rows" />
+
+        <div class="separator"></div>
+
+        <div class="row"
+            metal:define-slot="extra_bottom" tal:replace="nothing">
+          <div class="label">Extra bottom</div>
+          <div class="field"><input type="text" style="width:100%" /></div>
+        </div>
+
+        <div class="separator"></div>
+
+      </div>
+      <br/><br/>
+      <div class="row">
+        <div class="controls"><hr />
+          <input type='submit' value='Refresh'
+                 i18n:attributes='value refresh-button' />
+          <input type='submit' value='Add' name='UPDATE_SUBMIT'
+                 i18n:attributes='value add-button' />
+          <span tal:condition="context/nameAllowed|nothing" tal:omit-tag="">
+               &nbsp;&nbsp;<b i18n:translate="">Object Name</b>&nbsp;&nbsp;
+              <input type='text' name='add_input_name'
+                     tal:attributes="value context/contentName" />
+          </span>
+        </div>
+      </div>
+
+      <div class="row" metal:define-slot="extra_buttons" tal:replace="nothing">
+      </div>
+
+      <div class="separator"></div>
+    </form>
+  </div>
+
+  </div>
+  </body>
+
+</html>

Added: z3/Five/trunk/adding.pt
==============================================================================
--- (empty file)
+++ z3/Five/trunk/adding.pt	Tue Mar  8 16:13:29 2005
@@ -0,0 +1,7 @@
+<html metal:use-macro="here/main_template/macros/master">
+<body>
+<div metal:fill-slot="main">
+  <p>+ screen not yet supported by Five</p>
+</div>
+</body>
+</html>

Added: z3/Five/trunk/adding.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/adding.py	Tue Mar  8 16:13:29 2005
@@ -0,0 +1,239 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Adding View
+
+The Adding View is used to add new objects to a container. It is sort of a
+factory screen.
+"""
+__docformat__ = 'restructuredtext'
+
+from warnings import warn
+from zope.interface import implements
+from zope.publisher.interfaces import IPublishTraverse
+from zope.component.interfaces import IFactory
+
+from zope.app.exception.interfaces import UserError
+from zope.app.container.interfaces import IAdding, INameChooser
+from zope.app.container.interfaces import IContainerNamesContainer
+from zope.app.container.constraints import checkFactory, checkObject
+
+from zope.app import zapi
+from zope.app.event.objectevent import ObjectCreatedEvent
+from zope.event import notify
+
+from zExceptions import BadRequest
+
+from Products.Five import BrowserView
+from Products.Five.traversable import Traversable
+from Products.Five.pagetemplatefile import ZopeTwoPageTemplateFile
+
+class BasicAdding(BrowserView):
+    implements(IAdding, IPublishTraverse)
+
+    def add(self, content):
+        """See zope.app.container.interfaces.IAdding
+        """
+        container = self.context
+        name = self.contentName
+        chooser = INameChooser(container)
+
+        # check precondition
+        checkObject(container, name, content)
+
+        if IContainerNamesContainer.providedBy(container):
+            # The container picks it's own names.
+            # We need to ask it to pick one.
+            name = chooser.chooseName(self.contentName or '', content)
+        else:
+            request = self.request
+            name = request.get('add_input_name', name)
+
+            if name is None:
+                name = chooser.chooseName(self.contentName or '', content)
+            elif name == '':
+                name = chooser.chooseName('', content)
+            chooser.checkName(name, container)
+
+        container._setObject(name, content)
+        self.contentName = name # Set the added object Name
+        return container._getOb(name)
+
+    contentName = None # usually set by Adding traverser
+
+    def nextURL(self):
+        """See zope.app.container.interfaces.IAdding"""
+        return (str(zapi.getView(self.context, "absolute_url", self.request))
+                + '/@@contents.html')
+
+    # set in BrowserView.__init__
+    request = None 
+    context = None
+
+    def renderAddButton(self):
+        warn("The renderAddButton method is deprecated, use nameAllowed",
+            DeprecationWarning, 2)
+    
+
+    def publishTraverse(self, request, name):
+        """See zope.app.container.interfaces.IAdding"""
+        if '=' in name:
+            view_name, content_name = name.split("=", 1)
+            self.contentName = content_name
+
+            if view_name.startswith('@@'):
+                view_name = view_name[2:]
+            return zapi.getView(self, view_name, request)
+
+        if name.startswith('@@'):
+            view_name = name[2:]
+        else:
+            view_name = name
+
+        view = zapi.queryView(self, view_name, request)
+        if view is not None:
+            return view
+
+        factory = zapi.queryUtility(IFactory, name)
+        if factory is None:
+            return super(BasicAdding, self).publishTraverse(request, name)
+
+        return factory
+
+    def action(self, type_name='', id=''):
+        if not type_name:
+            raise UserError("You must select the type of object to add.")
+
+        if type_name.startswith('@@'):
+            type_name = type_name[2:]
+
+        if '/' in type_name:
+            view_name  = type_name.split('/', 1)[0]
+        else:
+            view_name = type_name
+
+        if zapi.queryView(self, view_name, self.request) is not None:
+            url = "%s/%s=%s" % (
+                zapi.getView(self, "absolute_url", self.request),
+                type_name, id)
+            self.request.response.redirect(url)
+            return
+
+        if not self.contentName:
+            self.contentName = id
+
+        factory = zapi.getUtility(IFactory, type_name)
+        content = factory()
+
+        notify(ObjectCreatedEvent(content))
+        self.add(content)
+        self.request.response.redirect(self.nextURL())
+
+    def namesAccepted(self):
+        return not IContainerNamesContainer.providedBy(self.context)
+
+    def nameAllowed(self):
+        """Return whether names can be input by the user."""
+        return not IContainerNamesContainer.providedBy(self.context)
+    
+
+class Adding(BasicAdding):
+
+    menu_id = None
+    index = ZopeTwoPageTemplateFile("adding.pt")
+
+    def addingInfo(self):
+        """Return menu data.
+
+        This is sorted by title.
+        """
+        container = self.context
+        menu_service = zapi.getService("BrowserMenu")
+        result = []
+        for menu_id in (self.menu_id, 'zope.app.container.add'):
+            if not menu_id:
+                continue
+            for item in menu_service.getMenu(menu_id, self, self.request):
+                extra = item.get('extra')
+                if extra:
+                    factory = extra.get('factory')
+                    if factory:
+                        factory = zapi.getUtility(IFactory, factory)
+                        if not checkFactory(container, None, factory):
+                            continue
+                        elif item['extra']['factory'] != item['action']:
+                            item['has_custom_add_view']=True
+                result.append(item)
+
+        result.sort(lambda a, b: cmp(a['title'], b['title']))
+        return result
+
+    def isSingleMenuItem(self):
+        "Return whether there is single menu item or not."
+        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
+
+from OFS.SimpleItem import SimpleItem
+class ContentAdding(Adding, Traversable, SimpleItem):
+
+    menu_id = "add_content"
+
+class ObjectManagerNameChooser:
+    """A name chooser for a Zope object manager.
+    """
+    
+    implements(INameChooser)
+    
+    def __init__(self, context):
+        self.context = context
+
+    def checkName(self, name, object):
+        try:
+            self.context._checkId(name, allow_dup=False)
+        except BadRequest:
+            raise UserError, "Id is in use or invalid"
+
+    def chooseName(self, name, object):
+        if not name:
+            name = object.__class__.__name__
+
+        dot = name.rfind('.')
+        if dot >= 0:
+            suffix = name[dot:]
+            name = name[:dot]
+        else:
+            suffix = ''
+
+        n = name + suffix
+        i = 1
+        while True:
+            try:
+                container._getOb(n)
+            except AttributeError:
+                pass
+            else:
+                break
+            i += 1
+            n = name + '-' + str(i) + suffix
+            
+        # Make sure tha name is valid.  We may have started with something bad.
+        self.checkName(n, object)
+
+        return n


More information about the z3-checkins mailing list