added description field; reorganize concept view: put parents in a portlet, concepts and resources vertically below one another

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1611 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-03-05 11:18:50 +00:00
parent 1572b89e8d
commit 06d69431d3
11 changed files with 151 additions and 94 deletions

View file

@ -40,6 +40,7 @@ from zope.schema.vocabulary import SimpleTerm
from zope.security import canAccess, canWrite from zope.security import canAccess, canWrite
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
from zope.traversing.browser import absoluteURL from zope.traversing.browser import absoluteURL
from zope.traversing.api import getName
from cybertools.browser.view import GenericView from cybertools.browser.view import GenericView
from cybertools.relation.interfaces import IRelationRegistry from cybertools.relation.interfaces import IRelationRegistry
@ -126,7 +127,11 @@ class BaseView(GenericView):
@Lazy @Lazy
def title(self): def title(self):
return self.context.title or zapi.getName(self.context) return self.context.title or getName(self.context)
@Lazy
def description(self):
return self.context.description
@Lazy @Lazy
def dcTitle(self): def dcTitle(self):

View file

@ -62,6 +62,12 @@ class ConceptEditForm(EditForm):
fields = FormFields(fields, typeInterface) fields = FormFields(fields, typeInterface)
return fields return fields
def setUpWidgets(self, ignore_request=False):
super(ConceptEditForm, self).setUpWidgets(ignore_request)
desc = self.widgets.get('description')
if desc:
desc.height = 2
class ConceptView(BaseView): class ConceptView(BaseView):
@ -71,6 +77,14 @@ class ConceptView(BaseView):
def macro(self): def macro(self):
return self.template.macros['conceptdata'] return self.template.macros['conceptdata']
def __init__(self, context, request):
super(ConceptView, self).__init__(context, request)
cont = self.controller
if cont is not None:
cont.macros.register('portlet_right', 'parents', title='Parents',
subMacro=self.template.macros['parents'],
position=0, info=self)
def fieldData(self): def fieldData(self):
ti = IType(self.context).typeInterface ti = IType(self.context).typeInterface
if not ti: return if not ti: return

View file

@ -1,21 +1,9 @@
<metal:data define-macro="conceptdata"> <metal:data define-macro="conceptdata">
<div tal:attributes="class string:content-$level;"> <div tal:attributes="class string:content-$level;">
<div class="subcolumn" style="width: 49%"> <metal:fields use-macro="item/template/macros/concepttitle" />
<div style="margin-right: 50px"> <metal:fields use-macro="item/template/macros/conceptfields" /><br />
<metal:fields use-macro="item/template/macros/conceptparents" /> <metal:fields use-macro="item/template/macros/conceptchildren" /><br />
</div>
<fieldset class="box"
style="margin: 30px 20px 15px 30px">
<metal:fields use-macro="item/template/macros/concepttitle" />
<metal:fields use-macro="item/template/macros/conceptfields" />
</fieldset>
<div style="margin-right: 50px">
<metal:fields use-macro="item/template/macros/conceptchildren" />
</div>
</div>
<div class="subcolumn" style="margin-top: 60px; width: 49%">
<metal:fields use-macro="item/template/macros/conceptresources" /> <metal:fields use-macro="item/template/macros/conceptresources" />
</div>
</div> </div>
</metal:data> </metal:data>
@ -39,41 +27,68 @@
<metal:parents define-macro="conceptparents"> <metal:parents define-macro="conceptparents">
<fieldset tal:attributes="class string:content-$level box; <div tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('configure.html')"> ondblclick python: item.openEditWindow('configure.html')">
<legend>Parents</legend> <h2>Parents</h2>
<div tal:repeat="related item/parents"> <div tal:repeat="related item/parents">
<a href="#" <a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId}" tal:attributes="href string:${view/url}/.target${related/uniqueId}"
tal:content="related/title">Concept Title</a> tal:content="related/title">Concept Title</a>
</div> </div>
</fieldset> </div>
</metal:parents> </metal:parents>
<metal:children define-macro="conceptchildren"> <metal:children define-macro="conceptchildren">
<fieldset tal:attributes="class string:content-$level box; <div tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('configure.html')"> ondblclick python: item.openEditWindow('configure.html')"
<legend>Children</legend> tal:define="children python: list(item.children())"
<div tal:repeat="related item/children"> tal:condition="children">
<h2>Children</h2><br />
<div tal:repeat="related children">
<a href="#" <a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId}" tal:attributes="href string:${view/url}/.target${related/uniqueId}"
tal:content="related/title">Concept Title</a> tal:content="related/title">Concept Title</a>
</div> </div>
</fieldset> </div>
</metal:children> </metal:children>
<metal:resources define-macro="conceptresources"> <metal:resources define-macro="conceptresources">
<fieldset tal:attributes="class string:content-$level box; <div tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('resources.html')"> ondblclick python: item.openEditWindow('resources.html')"
<legend>Resources</legend> tal:define="resources python: list(item.resources())"
<div tal:repeat="related item/resources"> tal:condition="resources">
<a href="#" <h2>Resources</h2><br />
tal:attributes="href string:${view/url}/.target${related/uniqueId}" <table class="listing">
tal:content="related/title">Resource Title</a> <tr>
</div> <th>Title</th>
</fieldset> <th>Type</th>
<th>Modification Date</th>
</tr>
<tal:items repeat="related resources">
<tal:item define="class python: repeat['related'].odd() and 'even' or 'odd'">
<tr tal:attributes="class class">
<td valign="top">
<a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId}">
<span tal:replace="related/title">Resource Title</span>
</a>
</td>
<td><span tal:replace="related/typeTitle">Type</span></td>
<td><span tal:replace="related/modified">Type</span></td>
</tr>
<tr tal:define="description related/description"
tal:condition="description"
tal:attributes="class class">
<td colspan="3" style="padding-left: 3em">
<span tal:replace="description">describing...</span>
</td>
</tr>
</tal:item>
</tal:items>
</table>
</div>
</metal:resources> </metal:resources>
@ -87,3 +102,18 @@
</metal:listing> </metal:listing>
</div> </div>
</metal:listing> </metal:listing>
<!-- portlets -->
<metal:actions define-macro="parents">
<div tal:repeat="concept macro/info/parents">
<a href="#"
tal:attributes="href string:${view/url}/.target${concept/uniqueId}">
<span tal:replace="concept/title">Concept</span>
(<i tal:content="concept/typeTitle">Type</i>)
</a>
</div>
</metal:actions>

View file

@ -333,27 +333,6 @@
permission="zope.View" permission="zope.View"
/> />
<!-- media asset -->
<!--<editform
label="Edit Media Asset"
name="edit.html"
schema="loops.interfaces.IMediaAssetSchema"
fields="title data contentType"
for="loops.interfaces.IMediaAsset"
template="edit.pt"
permission="zope.ManageContent"
menu="zmi_views" title="Edit Media Asset"
/>-->
<!--<page
name="edit.html"
for="loops.interfaces.IMediaAsset"
class="loops.browser.resource.MediaAssetEditForm"
permission="zope.ManageContent"
menu="zmi_views" title="Edit"
/>-->
<!-- view manager --> <!-- view manager -->
<addform <addform
@ -494,28 +473,6 @@
menu="zmi_views" title="Configure" menu="zmi_views" title="Configure"
/> />
<!--<editform
label="Edit Media Asset"
name="edit_target.html"
schema="loops.interfaces.IMediaAsset"
fields="title data contentType"
for="loops.interfaces.IMediaAssetView"
template="edit.pt"
permission="zope.ManageContent"
menu="zmi_views" title="Edit Media Asset"
/>
<editform
label="Edit Document"
name="edit_target.html"
schema="loops.interfaces.IDocument"
fields="title data contentType"
for="loops.interfaces.IDocumentView"
template="edit.pt"
permission="zope.ManageContent"
menu="zmi_views" title="Edit Document"
/>-->
<page <page
name="node.html" name="node.html"
for="loops.interfaces.INode" for="loops.interfaces.INode"

View file

@ -83,6 +83,9 @@ class ObjectForm(NodeView):
def setUp(self): def setUp(self):
self.setUpWidgets() self.setUpWidgets()
desc = self.widgets.get('description')
if desc:
desc.height = 2
if self.typeInterface in widgetControllers: if self.typeInterface in widgetControllers:
wc = widgetControllers[self.typeInterface]() wc = widgetControllers[self.typeInterface]()
wc.modifyWidgetSetup(self.widgets) wc.modifyWidgetSetup(self.widgets)
@ -110,6 +113,9 @@ class WidgetController(object):
class NoteWidgetController(WidgetController): class NoteWidgetController(WidgetController):
def modifyFormFields(self, formFields):
return formFields.omit('description')
def modifyWidgetSetup(self, widgets): def modifyWidgetSetup(self, widgets):
widgets['data'].height = 5 widgets['data'].height = 5

View file

@ -67,6 +67,12 @@ class ResourceEditForm(EditForm):
fields = FormFields(fields.omit(*omit), typeInterface) fields = FormFields(fields.omit(*omit), typeInterface)
return fields return fields
def setUpWidgets(self, ignore_request=False):
super(ResourceEditForm, self).setUpWidgets(ignore_request)
desc = self.widgets.get('description')
if desc:
desc.height = 2
class DocumentEditForm(EditForm): class DocumentEditForm(EditForm):
form_fields = FormFields(IDocument) form_fields = FormFields(IDocument)

View file

@ -39,6 +39,7 @@
<metal:block define-macro="download"> <metal:block define-macro="download">
<div tal:attributes="ondblclick python: item.openEditWindow('edit.html')"> <div tal:attributes="ondblclick python: item.openEditWindow('edit.html')">
<h3 tal:content="item/title">Title</h3> <h3 tal:content="item/title">Title</h3>
<p tal:content="item/description">Description</p>
<p> <p>
<a href="#" <a href="#"
tal:attributes="href string:${view/url}/.target${view/targetId}/view"> tal:attributes="href string:${view/url}/.target${view/targetId}/view">

View file

@ -22,6 +22,7 @@ Definition of the Concept and related classes.
$Id$ $Id$
""" """
from zope import component, schema
from zope.app import zapi from zope.app import zapi
from zope.app.container.btree import BTreeContainer from zope.app.container.btree import BTreeContainer
from zope.app.container.contained import Contained from zope.app.container.contained import Contained
@ -29,8 +30,8 @@ from zope.cachedescriptors.property import Lazy
from zope.component import adapts from zope.component import adapts
from zope.interface import implements from zope.interface import implements
from zope.interface import alsoProvides, directlyProvides, directlyProvidedBy from zope.interface import alsoProvides, directlyProvides, directlyProvidedBy
from zope import schema
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
from zope.traversing.api import getName
from persistent import Persistent from persistent import Persistent
from cybertools.relation import DyadicRelation from cybertools.relation import DyadicRelation
@ -83,11 +84,19 @@ class Concept(Contained, Persistent):
proxyInterface = IConceptView proxyInterface = IConceptView
def __init__(self, title=u''):
self.title = title
_title = u'' _title = u''
def getTitle(self): return self._title def getTitle(self): return self._title
def setTitle(self, title): self._title = title def setTitle(self, title): self._title = title
title = property(getTitle, setTitle) title = property(getTitle, setTitle)
_description = u''
def getDescription(self): return self._description
def setDescription(self, description): self._description = description
description = property(getDescription, setDescription)
def getConceptType(self): def getConceptType(self):
typePred = self.getConceptManager().getTypePredicate() typePred = self.getConceptManager().getTypePredicate()
if typePred is None: if typePred is None:
@ -107,9 +116,6 @@ class Concept(Contained, Persistent):
self.assignParent(concept, typePred) self.assignParent(concept, typePred)
conceptType = property(getConceptType, setConceptType) conceptType = property(getConceptType, setConceptType)
def __init__(self, title=u''):
self.title = title
def getLoopsRoot(self): def getLoopsRoot(self):
return zapi.getParent(self).getLoopsRoot() return zapi.getParent(self).getLoopsRoot()
@ -299,9 +305,10 @@ class IndexAttributes(object):
def text(self): def text(self):
context = self.context context = self.context
# TODO: include attributes provided by concept type # TODO: include attributes provided by concept type
return ' '.join((zapi.getName(context), context.title,)) return ' '.join((getName(context), context.title,))
def title(self): def title(self):
context = self.context context = self.context
return ' '.join((zapi.getName(context), context.title,)) return ' '.join((getName(context),
context.title, context.description)).strip()

View file

@ -74,6 +74,14 @@ class IConcept(ILoopsObject, IPotentialTarget):
default=u'', default=u'',
required=True) required=True)
description = schema.Text(
title=_(u'Description'),
description=_(u'A medium-length description describing the '
'content and the purpose of the object'),
default=u'',
missing_value=u'',
required=False)
conceptType = schema.Choice( conceptType = schema.Choice(
title=_(u'Concept Type'), title=_(u'Concept Type'),
description=_(u"The type of the concept, specified by a relation to " description=_(u"The type of the concept, specified by a relation to "
@ -199,6 +207,14 @@ class IBaseResource(ILoopsObject):
missing_value=u'', missing_value=u'',
required=True) required=True)
description = schema.Text(
title=_(u'Description'),
description=_(u'A medium-length description describing the '
'content and the purpose of the object'),
default=u'',
missing_value=u'',
required=False)
resourceType = schema.Choice( resourceType = schema.Choice(
title=_(u'Resource Type'), title=_(u'Resource Type'),
description=_(u"The type of the resource, specified by a relation to " description=_(u"The type of the resource, specified by a relation to "
@ -237,6 +253,14 @@ class IResourceSchema(Interface):
missing_value=u'', missing_value=u'',
required=True) required=True)
description = schema.Text(
title=_(u'Description'),
description=_(u'A medium-length description describing the '
'content and the purpose of the object'),
default=u'',
missing_value=u'',
required=False)
data = schema.Bytes( data = schema.Bytes(
title=_(u'Data'), title=_(u'Data'),
description=_(u'Resource raw data'), description=_(u'Resource raw data'),
@ -312,7 +336,7 @@ class IDocument(IDocumentSchema, IResource):
""" """
# media asset is probably obsolete - replaced by plain Resource with # media asset is obsolete - replaced by plain Resource with
# resourceType = file. # resourceType = file.
class IMediaAssetView(IResourceSchema): class IMediaAssetView(IResourceSchema):

View file

@ -62,6 +62,7 @@ class MemberRegistrationManager(object):
# step 2: create a corresponding person concept: # step 2: create a corresponding person concept:
cm = self.context.getConceptManager() cm = self.context.getConceptManager()
id = baseId = 'person.' + userId id = baseId = 'person.' + userId
# TODO: use NameChooser
num = 0 num = 0
while id in cm: while id in cm:
num +=1 num +=1

View file

@ -22,19 +22,19 @@ Definition of the Concept class.
$Id$ $Id$
""" """
from zope import component from zope import component, schema
from zope.app import zapi from zope.app import zapi
from zope.app.container.btree import BTreeContainer from zope.app.container.btree import BTreeContainer
from zope.app.container.contained import Contained from zope.app.container.contained import Contained
from zope.app.file.image import Image from zope.app.file.image import Image
from zope.app.file.interfaces import IFile from zope.app.file.interfaces import IFile
from zope.filerepresentation.interfaces import IReadFile, IWriteFile from zope.filerepresentation.interfaces import IReadFile, IWriteFile
from zope.size.interfaces import ISized
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.component import adapts from zope.component import adapts
from zope.i18nmessageid import MessageFactory from zope.i18nmessageid import MessageFactory
from zope.interface import implements from zope.interface import implements
from zope import schema from zope.size.interfaces import ISized
from zope.traversing.api import getName
from persistent import Persistent from persistent import Persistent
from cStringIO import StringIO from cStringIO import StringIO
@ -78,7 +78,7 @@ class Resource(Image, Contained):
implements(IBaseResource, IResource, IResourceManagerContained, IRelatable, ISized) implements(IBaseResource, IResource, IResourceManagerContained, IRelatable, ISized)
proxyInterface = IMediaAssetView proxyInterface = IMediaAssetView # obsolete!
_size = _width = _height = 0 _size = _width = _height = 0
@ -86,6 +86,16 @@ class Resource(Image, Contained):
super(Resource, self).__init__() super(Resource, self).__init__()
self.title = title self.title = title
_title = u''
def getTitle(self): return self._title
def setTitle(self, title): self._title = title
title = property(getTitle, setTitle)
_description = u''
def getDescription(self): return self._description
def setDescription(self, description): self._description = description
description = property(getDescription, setDescription)
def getResourceType(self): def getResourceType(self):
cm = self.getLoopsRoot().getConceptManager() cm = self.getLoopsRoot().getConceptManager()
typePred = cm.getTypePredicate() typePred = cm.getTypePredicate()
@ -108,11 +118,6 @@ class Resource(Image, Contained):
self.assignConcept(concept, typePred) self.assignConcept(concept, typePred)
resourceType = property(getResourceType, setResourceType) resourceType = property(getResourceType, setResourceType)
_title = u''
def getTitle(self): return self._title
def setTitle(self, title): self._title = title
title = property(getTitle, setTitle)
def _setData(self, data): def _setData(self, data):
dataFile = StringIO(data) # let File tear it into pieces dataFile = StringIO(data) # let File tear it into pieces
super(Resource, self)._setData(dataFile) super(Resource, self)._setData(dataFile)
@ -342,7 +347,8 @@ class IndexAttributes(object):
def title(self): def title(self):
context = self.context context = self.context
return ' '.join((zapi.getName(context), context.title,)).strip() return ' '.join((getName(context),
context.title, context.description)).strip()
class ResourceTypeSourceList(object): class ResourceTypeSourceList(object):