allow view parameters for view names as node attributes to make views more selective

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2458 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2008-03-17 09:36:51 +00:00
parent ebefd631a2
commit 9043c0459e
4 changed files with 76 additions and 11 deletions

View file

@ -814,6 +814,26 @@ target object's view here:
'http://127.0.0.1/loops/views/m1/m11/m111/.target23'
Special views
-------------
We may set a special view for a node by providing a view name.
>>> from loops.browser.node import ListChildren
>>> component.provideAdapter(ListChildren, (INode, IBrowserRequest), Interface,
... name='listchildren')
>>> m112.viewName = 'listchildren?types=person'
>>> view = NodeView(m112, TestRequest())
>>> targetView = view.view
>>> targetView.macroName
'listchildren'
>>> targetView.params
{'types': ['person']}
Collecting Information about Parents
====================================

View file

@ -22,6 +22,7 @@ Common base class for loops browser view classes.
$Id$
"""
from cgi import parse_qs
from zope import component
from zope.app.form.browser.interfaces import ITerms
from zope.app.i18n.interfaces import ITranslationDomain
@ -126,6 +127,18 @@ class BaseView(GenericView, I18NView):
# allow for having a separate object the view acts upon
return self.context
@Lazy
def params(self):
result = {}
paramString = self.request.annotations.get('loops.view', {}).get('params')
if paramString:
result = parse_qs(paramString)
for k, v in result.items():
if len(v) == 1:
v = [x.strip() for x in v[0].split(',')]
result[k] = v
return result
def setSkin(self, skinName):
skin = None
if skinName and IView.providedBy(self.context):

View file

@ -266,12 +266,19 @@ class ConceptView(BaseView):
def getChildren(self, topLevelOnly=True, sort=True):
cm = self.loopsRoot.getConceptManager()
hasType = cm.getTypePredicate()
params = self.params
criteria = {}
if params.get('types'):
criteria['types'] = [cm.get(name) for name in params['types']]
standard = cm.getDefaultPredicate()
rels = (self.childViewFactory(r, self.request, contextIsSecond=True)
for r in self.context.getChildRelations(sort=None))
if sort:
rels = sorted(rels, key=lambda r: (r.order, r.title.lower()))
for r in rels:
if criteria:
if not self.checkCriteria(r, criteria):
continue
if topLevelOnly and r.predicate == hasType:
# only show top-level entries for type instances:
skip = False
@ -279,9 +286,18 @@ class ConceptView(BaseView):
if parent.conceptType == self.context:
skip = True
break
if skip: continue
if skip:
continue
yield r
def checkCriteria(self, relation, criteria):
result = True
for k, v in criteria.items():
if k == 'types':
v = [item for item in v if item is not None]
result = result and (relation.context.conceptType in v)
return result
# Override in subclass to control what is displayd in listings:
children = getChildren

View file

@ -110,10 +110,15 @@ class NodeView(BaseView):
@Lazy
def view(self):
viewName = self.request.get('loops.viewName') or self.context.viewName
if viewName:
name = self.request.get('loops.viewName', '') or self.context.viewName
if '?' in name:
name, params = name.split('?', 1)
ann = self.request.annotations.get('loops.view', {})
ann['params'] = params
self.request.annotations['loops.view'] = ann
if name:
adapter = component.queryMultiAdapter(
(self.context, self.request), name=viewName)
(self.context, self.request), name=name)
if adapter is not None:
return adapter
return self
@ -298,15 +303,21 @@ class NodeView(BaseView):
return None
def targetView(self, name='index.html', methodName='show'):
if '?' in name:
name, params = name.split('?', 1)
print '***', name, params
target = self.virtualTargetObject
if target is not None:
ti = IType(target).typeInterface
targetView = None
if ti is not None:
adapted = ti(target)
targetView = component.queryMultiAdapter((adapted, self.request),
name=name)
if targetView is None:
#targetView = None
#if ti is not None:
# adapted = ti(target)
# targetView = component.queryMultiAdapter((adapted, self.request),
# name=name)
#if targetView is None:
# targetView = component.getMultiAdapter((target, self.request),
# name=name)
target = adapted(target)
targetView = component.getMultiAdapter((target, self.request),
name=name)
if name == 'index.html' and hasattr(targetView, 'show'):
@ -537,12 +548,17 @@ class SpecialNodeView(NodeView):
class ListPages(SpecialNodeView):
macroName = 'listpages'
class ListResources(SpecialNodeView):
macroName = 'listresources'
class ListChildren(SpecialNodeView):
macroName = 'listchildren'