knowledge stuff working, including first view
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1231 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
8423fcea57
commit
b3ff0831d9
12 changed files with 211 additions and 37 deletions
|
@ -99,20 +99,22 @@ class ConceptView(BaseView):
|
|||
|
||||
@Lazy
|
||||
def view(self):
|
||||
ti = IType(self.context).typeInterface
|
||||
# TODO: check the interface (maybe for a base interface IViewProvider)
|
||||
# instead of the viewName attribute:
|
||||
if ti and 'viewName' in ti:
|
||||
typeAdapter = ti(self.context)
|
||||
viewName = typeAdapter.viewName
|
||||
viewName = self.request.get('loops.viewName') or getattr(self, '_viewName', None)
|
||||
if not viewName:
|
||||
ti = IType(self.context).typeInterface
|
||||
# TODO: check the interface (maybe for a base interface IViewProvider)
|
||||
# instead of the viewName attribute:
|
||||
if ti and 'viewName' in ti:
|
||||
typeAdapter = ti(self.context)
|
||||
viewName = typeAdapter.viewName
|
||||
if viewName:
|
||||
# ??? Would it make sense to use a somehow restricted interface
|
||||
# that should be provided by the view like IQuery?
|
||||
#viewInterface = getattr(typeAdapter, 'viewInterface', None) or IQuery
|
||||
if viewName:
|
||||
adapter = component.queryMultiAdapter((self.context, self.request),
|
||||
interface.Interface, name=viewName)
|
||||
if adapter is not None:
|
||||
return adapter
|
||||
adapter = component.queryMultiAdapter((self.context, self.request),
|
||||
interface.Interface, name=viewName)
|
||||
if adapter is not None:
|
||||
return adapter
|
||||
#elif type provides view: use this
|
||||
return self
|
||||
|
||||
|
|
|
@ -443,7 +443,7 @@
|
|||
name="AddLoopsNode.html"
|
||||
content_factory="loops.view.Node"
|
||||
schema="loops.interfaces.INode"
|
||||
fields="title description nodeType viewer body"
|
||||
fields="title description nodeType viewName body"
|
||||
template="add.pt"
|
||||
permission="zope.ManageContent">
|
||||
|
||||
|
@ -464,7 +464,7 @@
|
|||
label="Edit Node"
|
||||
name="edit.html"
|
||||
schema="loops.interfaces.INode"
|
||||
fields="title description nodeType viewer body"
|
||||
fields="title description nodeType viewName body"
|
||||
for="loops.interfaces.INode"
|
||||
template="edit.pt"
|
||||
permission="zope.ManageContent"
|
||||
|
@ -547,6 +547,16 @@
|
|||
name="node.html"
|
||||
/>
|
||||
|
||||
<zope:adapter
|
||||
name="listpages"
|
||||
for="loops.interfaces.INode
|
||||
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.browser.node.ListPages"
|
||||
permission="zope.View"
|
||||
/>
|
||||
|
||||
|
||||
<!-- render file or image assigned to a node as target -->
|
||||
|
||||
<page
|
||||
|
|
|
@ -55,23 +55,35 @@ class NodeView(BaseView):
|
|||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
macroName = self.request.get('viewer')
|
||||
if not macroName:
|
||||
macroName = self.context.viewer or 'content'
|
||||
return self.template.macros[macroName]
|
||||
return self.template.macros['content']
|
||||
#macroName = self.request.get('loops.viewName')
|
||||
#if not macroName:
|
||||
# macroName = self.context.viewName or 'content'
|
||||
#return self.template.macros[macroName]
|
||||
|
||||
@Lazy
|
||||
def view(self):
|
||||
viewName = self.request.get('loops.viewName') or self.context.viewName
|
||||
if viewName:
|
||||
adapter = component.queryMultiAdapter((self.context, self.request),
|
||||
interface.Interface, name=viewName)
|
||||
if adapter is not None:
|
||||
return adapter
|
||||
return self
|
||||
|
||||
@Lazy
|
||||
def item(self):
|
||||
target = self.request.annotations.get('loops.view', {}).get('target')
|
||||
# was there a .target... element in the URL?
|
||||
if target is not None:
|
||||
# .target.... traversal magic
|
||||
return zapi.getMultiAdapter((target, self.request))
|
||||
basicView = zapi.getMultiAdapter((target, self.request))
|
||||
return basicView.view
|
||||
return self.page
|
||||
|
||||
@Lazy
|
||||
def page(self):
|
||||
page = self.context.getPage()
|
||||
return page is not None and NodeView(page, self.request) or None
|
||||
return page is not None and NodeView(page, self.request).view or None
|
||||
|
||||
@Lazy
|
||||
def textItems(self):
|
||||
|
@ -107,8 +119,8 @@ class NodeView(BaseView):
|
|||
obj = self.targetObject
|
||||
if obj is not None:
|
||||
basicView = zapi.getMultiAdapter((obj, self.request))
|
||||
basicView._viewName = self.context.viewName
|
||||
return basicView.view
|
||||
#return zapi.getMultiAdapter((obj, self.request))
|
||||
|
||||
def renderTarget(self):
|
||||
target = self.target
|
||||
|
@ -212,6 +224,17 @@ class NodeView(BaseView):
|
|||
return zapi.getUtility(IIntIds).getId(target)
|
||||
|
||||
|
||||
class ListPages(NodeView):
|
||||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return self.template.macros['listpages']
|
||||
|
||||
@Lazy
|
||||
def view(self):
|
||||
return self
|
||||
|
||||
|
||||
class ConfigureView(NodeView):
|
||||
""" An editing view for configuring a node, optionally creating
|
||||
a target object.
|
||||
|
|
|
@ -315,6 +315,7 @@
|
|||
name="loops.PredicateSource"
|
||||
/>
|
||||
|
||||
<include package=".knowledge" />
|
||||
<include package=".organize" />
|
||||
<include package=".browser" />
|
||||
|
||||
|
|
|
@ -314,10 +314,10 @@ class IView(ILoopsObject):
|
|||
|
||||
target = Attribute('Target object that is referenced by this view')
|
||||
|
||||
viewer = schema.TextLine(
|
||||
title=_(u'Viewer Method Specification'),
|
||||
description=_(u'Name, path or relative URI specifying a viewer '
|
||||
'(template, macro, ...) for this object'),
|
||||
viewName = schema.TextLine(
|
||||
title=_(u'View name'),
|
||||
description=_(u'Name of a special view be used for presenting '
|
||||
'this object.'),
|
||||
default=u'',
|
||||
required=False)
|
||||
|
||||
|
|
|
@ -40,13 +40,18 @@ _ = MessageFactory('zope')
|
|||
|
||||
class MyKnowledge(BaseView):
|
||||
|
||||
def __init__(self, context, request):
|
||||
self.context = context
|
||||
self.request = request
|
||||
person = getPersonForLoggedInUser(request)
|
||||
template = NamedTemplate('loops.knowledge_macros')
|
||||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return self.template.macros['requirements']
|
||||
|
||||
@Lazy
|
||||
def person(self):
|
||||
person = getPersonForLoggedInUser(self.request)
|
||||
if person is not None:
|
||||
person = IPerson(person)
|
||||
self.person = person
|
||||
return person
|
||||
|
||||
def myKnowledge(self):
|
||||
if self.person is None:
|
||||
|
@ -57,8 +62,11 @@ class MyKnowledge(BaseView):
|
|||
def myKnowledgeProvidersForTask(self):
|
||||
if self.person is None:
|
||||
return ()
|
||||
request = self.request
|
||||
task = ITask(self.context)
|
||||
# TODO: check correct conceptType for context!
|
||||
providers = self.person.getProvidersNeeded(task)
|
||||
return providers
|
||||
return ({'required': BaseView(req.context, request),
|
||||
'providers': (BaseView(p.context, request) for p in prov)}
|
||||
for req, prov in providers)
|
||||
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
i18n_domain="zope"
|
||||
>
|
||||
|
||||
<!-- named templates -->
|
||||
|
||||
<zope:adapter
|
||||
factory="loops.knowledge.util.knowledge_macros"
|
||||
for="loops.browser.common.BaseView"
|
||||
name="loops.knowledge_macros" />
|
||||
|
||||
<!-- knowledge/learning management stuff -->
|
||||
|
||||
<zope:adapter factory="loops.knowledge.knowledge.Person"
|
||||
|
@ -15,6 +22,58 @@
|
|||
<zope:class class="loops.knowledge.knowledge.Person">
|
||||
<require permission="zope.View"
|
||||
interface="loops.knowledge.interfaces.IPerson" />
|
||||
<require permission="zope.ManageContent"
|
||||
set_schema="loops.knowledge.interfaces.IPerson" />
|
||||
</zope:class>
|
||||
|
||||
<zope:adapter factory="loops.knowledge.knowledge.Topic"
|
||||
provides="cybertools.knowledge.interfaces.IKnowledgeElement"
|
||||
trusted="True" />
|
||||
|
||||
<zope:class class="loops.knowledge.knowledge.Topic">
|
||||
<require permission="zope.View"
|
||||
interface="cybertools.knowledge.interfaces.IKnowledgeElement" />
|
||||
</zope:class>
|
||||
|
||||
<zope:adapter factory="loops.knowledge.knowledge.Task"
|
||||
provides="loops.knowledge.interfaces.ITask"
|
||||
trusted="True" />
|
||||
|
||||
<zope:class class="loops.knowledge.knowledge.Task">
|
||||
<require permission="zope.View"
|
||||
interface="loops.knowledge.interfaces.ITask" />
|
||||
<require permission="zope.ManageContent"
|
||||
set_schema="loops.knowledge.interfaces.ITask" />
|
||||
</zope:class>
|
||||
|
||||
<zope:adapter factory="loops.knowledge.knowledge.ConceptKnowledgeProvider"
|
||||
provides="cybertools.knowledge.interfaces.IKnowledgeProvider"
|
||||
trusted="True" />
|
||||
|
||||
<zope:class class="loops.knowledge.knowledge.ConceptKnowledgeProvider">
|
||||
<require permission="zope.View"
|
||||
interface="cybertools.knowledge.interfaces.IKnowledgeProvider" />
|
||||
</zope:class>
|
||||
|
||||
<zope:adapter factory="loops.knowledge.knowledge.ResourceKnowledgeProvider"
|
||||
provides="cybertools.knowledge.interfaces.IKnowledgeProvider"
|
||||
trusted="True" />
|
||||
|
||||
<zope:class class="loops.knowledge.knowledge.ResourceKnowledgeProvider">
|
||||
<require permission="zope.View"
|
||||
interface="cybertools.knowledge.interfaces.IKnowledgeProvider" />
|
||||
</zope:class>
|
||||
|
||||
<!-- views -->
|
||||
|
||||
<zope:adapter
|
||||
name="requirements"
|
||||
for="loops.interfaces.IConcept
|
||||
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||
provides="zope.interface.Interface"
|
||||
factory="loops.knowledge.browser.MyKnowledge"
|
||||
permission="zope.View"
|
||||
/>
|
||||
|
||||
|
||||
</configure>
|
||||
|
|
|
@ -34,6 +34,8 @@ from cybertools.organize.interfaces import ITask as IBaseTask
|
|||
|
||||
_ = MessageFactory('zope')
|
||||
|
||||
# TODO: separate interfaces for viewing and changing methods!
|
||||
|
||||
|
||||
class IPerson(IBasePerson, IKnowing):
|
||||
""" A person, including knowledge/learning management features.
|
||||
|
|
|
@ -32,7 +32,7 @@ from zope.cachedescriptors.property import Lazy
|
|||
from cybertools.typology.interfaces import IType
|
||||
from cybertools.knowledge.interfaces import IKnowledgeElement, IKnowledgeProvider
|
||||
from cybertools.knowledge.knowing import Knowing
|
||||
from loops.interfaces import IConcept
|
||||
from loops.interfaces import IConcept, IResource
|
||||
from loops.knowledge.interfaces import IPerson, ITask
|
||||
from loops.organize.party import Person as BasePerson
|
||||
from loops.organize.task import Task as BaseTask
|
||||
|
@ -41,7 +41,8 @@ from loops.type import TypeInterfaceSourceList, AdapterBase
|
|||
|
||||
# register type interfaces - (TODO: use a function for this)
|
||||
|
||||
TypeInterfaceSourceList.typeInterfaces += (IPerson, IKnowledgeElement, ITask)
|
||||
TypeInterfaceSourceList.typeInterfaces += (IPerson, IKnowledgeElement,
|
||||
ITask, IKnowledgeProvider)
|
||||
|
||||
|
||||
class KnowledgeAdapterMixin(object):
|
||||
|
@ -170,6 +171,7 @@ class ConceptKnowledgeProvider(AdapterBase, KnowledgeAdapterMixin):
|
|||
class ResourceKnowledgeProvider(AdapterBase, KnowledgeAdapterMixin):
|
||||
|
||||
implements(IKnowledgeProvider)
|
||||
adapts(IResource)
|
||||
|
||||
def getProvidedKnowledge(self):
|
||||
return (IKnowledgeElement(c)
|
||||
|
|
35
knowledge/knowledge_macros.pt
Normal file
35
knowledge/knowledge_macros.pt
Normal file
|
@ -0,0 +1,35 @@
|
|||
<metal:listing define-macro="requirements">
|
||||
<div>
|
||||
<h3 tal:attributes="class string:content-$level;
|
||||
ondblclick item/openEditWindow">
|
||||
<span i18n:translate="">Concept</span>:
|
||||
<span tal:content="item/title">Title</span>
|
||||
</h3>
|
||||
<metal:listing define-macro="requirementslisting2">
|
||||
<div tal:attributes="class string:content-$level;
|
||||
ondblclick python: item.openEditWindow('configure.html')">
|
||||
<h4>Requirements</h4>
|
||||
<table class="listing">
|
||||
<tr>
|
||||
<th i18n:translate="">Requirement</th>
|
||||
<th i18n:translate="">Providers</th>
|
||||
</tr>
|
||||
<tr tal:repeat="related item/myKnowledgeProvidersForTask">
|
||||
<td>
|
||||
<a href="#"
|
||||
tal:attributes="href string:${view/url}/.target${related/required/uniqueId}"
|
||||
tal:content="related/required/title">Concept Title</a>
|
||||
</td>
|
||||
<td>
|
||||
<tal:provider repeat="prov related/providers">
|
||||
<a href="#"
|
||||
tal:attributes="href string:${view/url}/.target${prov/uniqueId}"
|
||||
tal:content="prov/title">Provider Title</a>
|
||||
</tal:provider>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</metal:listing>
|
||||
</div>
|
||||
</metal:listing>
|
30
knowledge/util.py
Normal file
30
knowledge/util.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Utilities.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||
from zope.formlib.namedtemplate import NamedTemplateImplementation
|
||||
|
||||
|
||||
knowledge_macros = NamedTemplateImplementation(
|
||||
ViewPageTemplateFile('knowledge_macros.pt'))
|
10
view.py
10
view.py
|
@ -60,10 +60,12 @@ class View(object):
|
|||
def setDescription(self, description): self._description = description
|
||||
description = property(getDescription, setDescription)
|
||||
|
||||
_viewer = u''
|
||||
def getViewer(self): return self._viewer
|
||||
def setViewer(self, viewer): self._viewer = viewer
|
||||
viewer = property(getViewer, setViewer)
|
||||
_viewName = u''
|
||||
def getViewName(self): return self._viewName or getattr(self, '_viewer', u'')
|
||||
def setViewName(self, viewName): self._viewName = viewName
|
||||
viewName = property(getViewName, setViewName)
|
||||
|
||||
viewer = property(getViewName, setViewName) # BBB
|
||||
|
||||
def getTarget(self):
|
||||
rels = getRelations(first=self, relationships=[TargetRelation])
|
||||
|
|
Loading…
Add table
Reference in a new issue