first working version of URL traversal over folders via publication and view

This commit is contained in:
Helmut Merz 2024-03-13 09:11:28 +01:00
parent 94ac7c81db
commit 0bda603f1e
3 changed files with 53 additions and 6 deletions

View file

@ -5,15 +5,18 @@ from zope.interface import Interface
class ITraversable(Interface):
def get(key, default):
"""Return the item addressed by `key`; return `default` if not found."""
class IContainer(ITraversable):
def items():
"""Return a sequence of key, value pairs of child objects."""
def keys():
"""Return a sequence of keys of child objects."""
def get(key, default):
"""Return the item addressed by `key`; return `default` if not found."""
def __getitem__(key):
"""Return the item addressed by `key`; rais KeyError if not found."""
@ -22,3 +25,10 @@ class ITraversable(Interface):
May modify `value` so that the attributes referencing this object
and the value object (e.g. `parent´ and `name`) are stored correctly."""
class IView(Interface):
def __call__():
"""Render the view data as HTML or JSON."""

View file

@ -1,10 +1,14 @@
# scopes.server.app
import json
from zope.interface import implementer
from zope.publisher.base import DefaultPublication
from zope.publisher.browser import BrowserRequest
from zope.publisher.interfaces import NotFound
from zope.publisher.publish import publish
from zope.traversing.publicationtraverse import PublicationTraverser
from scopes.interfaces import IContainer, ITraversable, IView
from scopes.storage.folder import Root
@ -15,7 +19,7 @@ def zope_app_factory(config):
appRoot = Root(storage, config)
request = BrowserRequest(environ['wsgi.input'], environ)
request.setPublication(Publication(appRoot))
request = publish(request, True)
request = publish(request, False)
response = request.response
start_response(response.getStatusString(), response.getHeaders())
return response.consumeBodyIter()
@ -24,5 +28,34 @@ def zope_app_factory(config):
class Publication(DefaultPublication):
pass
def traverseName(self, request, ob, name):
next = None
if ITraversable.providedBy(ob):
next = ob.get(name)
if next is None:
if name == 'index.html':
next = DefaultView(ob, request)
if next is None:
raise NotFound(ob, name, request)
return next
def getDefaultTraversal(self, request, ob):
if IView.providedBy(ob):
return ob, ()
return ob, ('index.html',)
@implementer(IView)
class DefaultView:
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self):
ob = self.context
result = dict(head=ob.head, data=ob.data)
if IContainer.providedBy(ob):
result['items'] = list(ob.keys())
return json.dumps(result)

View file

@ -1,9 +1,13 @@
# scopes.storage.folder
from zope.interface import implementer
from scopes.interfaces import IContainer
from scopes.storage.common import registerContainerClass
from scopes.storage.tracking import Container, Track
@implementer(IContainer)
class Folder(Track):
"""Needs docstring to be traversable."""
@ -33,7 +37,7 @@ class Folder(Track):
value.set('name', key)
self.container.save(value)
def __call__(self, request=None):
def __str__(self):
return 'folder: %s; keys: %s' % (self.name, list(self.keys()))