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.proxy import removeSecurityProxy
from zope.traversing.browser import absoluteURL
from zope.traversing.api import getName
from cybertools.browser.view import GenericView
from cybertools.relation.interfaces import IRelationRegistry
@ -126,7 +127,11 @@ class BaseView(GenericView):
@Lazy
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
def dcTitle(self):

View file

@ -62,6 +62,12 @@ class ConceptEditForm(EditForm):
fields = FormFields(fields, typeInterface)
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):
@ -71,6 +77,14 @@ class ConceptView(BaseView):
def macro(self):
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):
ti = IType(self.context).typeInterface
if not ti: return

View file

@ -1,21 +1,9 @@
<metal:data define-macro="conceptdata">
<div tal:attributes="class string:content-$level;">
<div class="subcolumn" style="width: 49%">
<div style="margin-right: 50px">
<metal:fields use-macro="item/template/macros/conceptparents" />
</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/concepttitle" />
<metal:fields use-macro="item/template/macros/conceptfields" /><br />
<metal:fields use-macro="item/template/macros/conceptchildren" /><br />
<metal:fields use-macro="item/template/macros/conceptresources" />
</div>
</div>
</metal:data>
@ -39,41 +27,68 @@
<metal:parents define-macro="conceptparents">
<fieldset tal:attributes="class string:content-$level box;
ondblclick python: item.openEditWindow('configure.html')">
<legend>Parents</legend>
<div tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('configure.html')">
<h2>Parents</h2>
<div tal:repeat="related item/parents">
<a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId}"
tal:content="related/title">Concept Title</a>
</div>
</fieldset>
</div>
</metal:parents>
<metal:children define-macro="conceptchildren">
<fieldset tal:attributes="class string:content-$level box;
ondblclick python: item.openEditWindow('configure.html')">
<legend>Children</legend>
<div tal:repeat="related item/children">
<div tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('configure.html')"
tal:define="children python: list(item.children())"
tal:condition="children">
<h2>Children</h2><br />
<div tal:repeat="related children">
<a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId}"
tal:content="related/title">Concept Title</a>
</div>
</fieldset>
</div>
</metal:children>
<metal:resources define-macro="conceptresources">
<fieldset tal:attributes="class string:content-$level box;
ondblclick python: item.openEditWindow('resources.html')">
<legend>Resources</legend>
<div tal:repeat="related item/resources">
<a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId}"
tal:content="related/title">Resource Title</a>
</div>
</fieldset>
<div tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('resources.html')"
tal:define="resources python: list(item.resources())"
tal:condition="resources">
<h2>Resources</h2><br />
<table class="listing">
<tr>
<th>Title</th>
<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>
@ -87,3 +102,18 @@
</metal:listing>
</div>
</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"
/>
<!-- 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 -->
<addform
@ -494,28 +473,6 @@
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
name="node.html"
for="loops.interfaces.INode"

View file

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

View file

@ -67,6 +67,12 @@ class ResourceEditForm(EditForm):
fields = FormFields(fields.omit(*omit), typeInterface)
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):
form_fields = FormFields(IDocument)

View file

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

View file

@ -22,6 +22,7 @@ Definition of the Concept and related classes.
$Id$
"""
from zope import component, schema
from zope.app import zapi
from zope.app.container.btree import BTreeContainer
from zope.app.container.contained import Contained
@ -29,8 +30,8 @@ from zope.cachedescriptors.property import Lazy
from zope.component import adapts
from zope.interface import implements
from zope.interface import alsoProvides, directlyProvides, directlyProvidedBy
from zope import schema
from zope.security.proxy import removeSecurityProxy
from zope.traversing.api import getName
from persistent import Persistent
from cybertools.relation import DyadicRelation
@ -83,11 +84,19 @@ class Concept(Contained, Persistent):
proxyInterface = IConceptView
def __init__(self, title=u''):
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 getConceptType(self):
typePred = self.getConceptManager().getTypePredicate()
if typePred is None:
@ -107,9 +116,6 @@ class Concept(Contained, Persistent):
self.assignParent(concept, typePred)
conceptType = property(getConceptType, setConceptType)
def __init__(self, title=u''):
self.title = title
def getLoopsRoot(self):
return zapi.getParent(self).getLoopsRoot()
@ -299,9 +305,10 @@ class IndexAttributes(object):
def text(self):
context = self.context
# TODO: include attributes provided by concept type
return ' '.join((zapi.getName(context), context.title,))
return ' '.join((getName(context), context.title,))
def title(self):
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'',
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(
title=_(u'Concept Type'),
description=_(u"The type of the concept, specified by a relation to "
@ -199,6 +207,14 @@ class IBaseResource(ILoopsObject):
missing_value=u'',
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(
title=_(u'Resource Type'),
description=_(u"The type of the resource, specified by a relation to "
@ -237,6 +253,14 @@ class IResourceSchema(Interface):
missing_value=u'',
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(
title=_(u'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.
class IMediaAssetView(IResourceSchema):

View file

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

View file

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