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'
|
||||
|
||||
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
|
||||
====================================
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue