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:
parent
ebefd631a2
commit
9043c0459e
4 changed files with 76 additions and 11 deletions
20
README.txt
20
README.txt
|
@ -814,6 +814,26 @@ target object's view here:
|
||||||
|
|
||||||
'http://127.0.0.1/loops/views/m1/m11/m111/.target23'
|
'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
|
Collecting Information about Parents
|
||||||
====================================
|
====================================
|
||||||
|
|
|
@ -22,6 +22,7 @@ Common base class for loops browser view classes.
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from cgi import parse_qs
|
||||||
from zope import component
|
from zope import component
|
||||||
from zope.app.form.browser.interfaces import ITerms
|
from zope.app.form.browser.interfaces import ITerms
|
||||||
from zope.app.i18n.interfaces import ITranslationDomain
|
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
|
# allow for having a separate object the view acts upon
|
||||||
return self.context
|
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):
|
def setSkin(self, skinName):
|
||||||
skin = None
|
skin = None
|
||||||
if skinName and IView.providedBy(self.context):
|
if skinName and IView.providedBy(self.context):
|
||||||
|
|
|
@ -266,12 +266,19 @@ class ConceptView(BaseView):
|
||||||
def getChildren(self, topLevelOnly=True, sort=True):
|
def getChildren(self, topLevelOnly=True, sort=True):
|
||||||
cm = self.loopsRoot.getConceptManager()
|
cm = self.loopsRoot.getConceptManager()
|
||||||
hasType = cm.getTypePredicate()
|
hasType = cm.getTypePredicate()
|
||||||
|
params = self.params
|
||||||
|
criteria = {}
|
||||||
|
if params.get('types'):
|
||||||
|
criteria['types'] = [cm.get(name) for name in params['types']]
|
||||||
standard = cm.getDefaultPredicate()
|
standard = cm.getDefaultPredicate()
|
||||||
rels = (self.childViewFactory(r, self.request, contextIsSecond=True)
|
rels = (self.childViewFactory(r, self.request, contextIsSecond=True)
|
||||||
for r in self.context.getChildRelations(sort=None))
|
for r in self.context.getChildRelations(sort=None))
|
||||||
if sort:
|
if sort:
|
||||||
rels = sorted(rels, key=lambda r: (r.order, r.title.lower()))
|
rels = sorted(rels, key=lambda r: (r.order, r.title.lower()))
|
||||||
for r in rels:
|
for r in rels:
|
||||||
|
if criteria:
|
||||||
|
if not self.checkCriteria(r, criteria):
|
||||||
|
continue
|
||||||
if topLevelOnly and r.predicate == hasType:
|
if topLevelOnly and r.predicate == hasType:
|
||||||
# only show top-level entries for type instances:
|
# only show top-level entries for type instances:
|
||||||
skip = False
|
skip = False
|
||||||
|
@ -279,9 +286,18 @@ class ConceptView(BaseView):
|
||||||
if parent.conceptType == self.context:
|
if parent.conceptType == self.context:
|
||||||
skip = True
|
skip = True
|
||||||
break
|
break
|
||||||
if skip: continue
|
if skip:
|
||||||
|
continue
|
||||||
yield r
|
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:
|
# Override in subclass to control what is displayd in listings:
|
||||||
children = getChildren
|
children = getChildren
|
||||||
|
|
||||||
|
|
|
@ -110,10 +110,15 @@ class NodeView(BaseView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def view(self):
|
def view(self):
|
||||||
viewName = self.request.get('loops.viewName') or self.context.viewName
|
name = self.request.get('loops.viewName', '') or self.context.viewName
|
||||||
if 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(
|
adapter = component.queryMultiAdapter(
|
||||||
(self.context, self.request), name=viewName)
|
(self.context, self.request), name=name)
|
||||||
if adapter is not None:
|
if adapter is not None:
|
||||||
return adapter
|
return adapter
|
||||||
return self
|
return self
|
||||||
|
@ -298,15 +303,21 @@ class NodeView(BaseView):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def targetView(self, name='index.html', methodName='show'):
|
def targetView(self, name='index.html', methodName='show'):
|
||||||
|
if '?' in name:
|
||||||
|
name, params = name.split('?', 1)
|
||||||
|
print '***', name, params
|
||||||
target = self.virtualTargetObject
|
target = self.virtualTargetObject
|
||||||
if target is not None:
|
if target is not None:
|
||||||
ti = IType(target).typeInterface
|
ti = IType(target).typeInterface
|
||||||
targetView = None
|
#targetView = None
|
||||||
if ti is not None:
|
#if ti is not None:
|
||||||
adapted = ti(target)
|
# adapted = ti(target)
|
||||||
targetView = component.queryMultiAdapter((adapted, self.request),
|
# targetView = component.queryMultiAdapter((adapted, self.request),
|
||||||
name=name)
|
# name=name)
|
||||||
if targetView is None:
|
#if targetView is None:
|
||||||
|
# targetView = component.getMultiAdapter((target, self.request),
|
||||||
|
# name=name)
|
||||||
|
target = adapted(target)
|
||||||
targetView = component.getMultiAdapter((target, self.request),
|
targetView = component.getMultiAdapter((target, self.request),
|
||||||
name=name)
|
name=name)
|
||||||
if name == 'index.html' and hasattr(targetView, 'show'):
|
if name == 'index.html' and hasattr(targetView, 'show'):
|
||||||
|
@ -537,12 +548,17 @@ class SpecialNodeView(NodeView):
|
||||||
|
|
||||||
|
|
||||||
class ListPages(SpecialNodeView):
|
class ListPages(SpecialNodeView):
|
||||||
|
|
||||||
macroName = 'listpages'
|
macroName = 'listpages'
|
||||||
|
|
||||||
|
|
||||||
class ListResources(SpecialNodeView):
|
class ListResources(SpecialNodeView):
|
||||||
|
|
||||||
macroName = 'listresources'
|
macroName = 'listresources'
|
||||||
|
|
||||||
|
|
||||||
class ListChildren(SpecialNodeView):
|
class ListChildren(SpecialNodeView):
|
||||||
|
|
||||||
macroName = 'listchildren'
|
macroName = 'listchildren'
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue