Merge branch 'master' into bbmaster

This commit is contained in:
Helmut Merz 2012-03-11 17:19:28 +01:00
commit d496dc001a
12 changed files with 171 additions and 34 deletions

View file

@ -173,7 +173,7 @@
<metal:resources define-macro="conceptresources"> <metal:resources define-macro="conceptresources">
<div tal:attributes="class string:content-$level; <div tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('resources.html')" ondblclick python: item.openEditWindow('resources.html')"
tal:define="resources python: list(item.resources())" tal:define="resources resources|python:list(item.resources())"
tal:condition="resources"> tal:condition="resources">
<h2 i18n:translate="">Resources</h2> <h2 i18n:translate="">Resources</h2>
<form method="post" <form method="post"
@ -201,7 +201,10 @@
item.editable and 'dojo.dnd.Source' or ''"> item.editable and 'dojo.dnd.Source' or ''">
<tal:items repeat="related resources"> <tal:items repeat="related resources">
<tal:item define="class python: repeat['related'].odd() and 'even' or 'odd'; <tal:item define="class python: repeat['related'].odd() and 'even' or 'odd';
description related/description"> description related/description;
predicate related/predicateTitle;
info python: ' | '.join(
t for t in (description, predicate) if t)">
<tr tal:attributes="class string:$class dojoDndItem dojoDndHandle; <tr tal:attributes="class string:$class dojoDndItem dojoDndHandle;
id related/uniqueId"> id related/uniqueId">
<td tal:condition="item/showCheckboxes|nothing" <td tal:condition="item/showCheckboxes|nothing"
@ -218,7 +221,7 @@
<img tal:attributes="src icon/src" /> <img tal:attributes="src icon/src" />
</a> </a>
<a tal:attributes="href python: view.getUrlForTarget(related); <a tal:attributes="href python: view.getUrlForTarget(related);
title description"> title info">
<div tal:content="related/title">Resource Title</div> <div tal:content="related/title">Resource Title</div>
</a> </a>
</td> </td>

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # Copyright (c) 2012 Helmut Merz helmutm@cy55.de
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -18,8 +18,6 @@
""" """
Elements for handling and presentation of pseudo folders. Elements for handling and presentation of pseudo folders.
$Id$
""" """
@ -50,6 +48,7 @@ actions.register('editFolder', 'portlet', DialogAction,
class FolderView(ConceptView): class FolderView(ConceptView):
def getActions(self, category='concept', page=None, target=None): def getActions(self, category='concept', page=None, target=None):
# obsolete: define actions via type option
if category == 'portlet': if category == 'portlet':
return actions.get(category, ['createFolder', 'editFolder'], return actions.get(category, ['createFolder', 'editFolder'],
view=self, page=page, target=target) view=self, page=page, target=target)

View file

@ -47,6 +47,7 @@ from cybertools.composer.schema.browser.common import schema_macros, schema_edit
from cybertools.composer.schema.schema import FormState from cybertools.composer.schema.schema import FormState
from cybertools.stateful.interfaces import IStateful from cybertools.stateful.interfaces import IStateful
from cybertools.typology.interfaces import IType, ITypeManager from cybertools.typology.interfaces import IType, ITypeManager
from cybertools.util.format import toUnicode
from loops.browser.node import NodeView from loops.browser.node import NodeView
from loops.browser.concept import ConceptRelationView from loops.browser.concept import ConceptRelationView
from loops.common import adapted from loops.common import adapted
@ -154,7 +155,7 @@ class ObjectForm(NodeView):
for k, v in data.items(): for k, v in data.items():
#overwrite data with values from request.form #overwrite data with values from request.form
if k in self.request.form: if k in self.request.form:
data[k] = form[k] data[k] = toUnicode(form[k])
return data return data
@Lazy @Lazy
@ -357,7 +358,7 @@ class CreateObjectPopup(CreateObjectForm):
self.registerDojo() self.registerDojo()
cm = self.controller.macros cm = self.controller.macros
cm.register('css', identifier='popup.css', resourceName='popup.css', cm.register('css', identifier='popup.css', resourceName='popup.css',
media='all', position=4) media='all', priority=90) #, position=4)
jsCall = ('dojo.require("dojo.parser");' jsCall = ('dojo.require("dojo.parser");'
'dojo.require("dijit.form.FilteringSelect");' 'dojo.require("dijit.form.FilteringSelect");'
'dojo.require("dojox.data.QueryReadStore");') 'dojo.require("dojox.data.QueryReadStore");')

View file

@ -17,7 +17,7 @@
title cell/description"> title cell/description">
<div class="legend"> <div class="legend">
<b tal:content="cell/title" /><br /> <b tal:content="cell/title" /><br />
<i tal:content="structure cell/renderedDescription" /> <i tal:content="structure cell/textRepresentation" />
</div> </div>
</a> </a>
</div> </div>
@ -36,7 +36,7 @@
<a tal:attributes="href cell/targetUrl"> <a tal:attributes="href cell/targetUrl">
<b tal:content="cell/title" /></a><br /> <b tal:content="cell/title" /></a><br />
<tal:desc condition="cell/description"> <tal:desc condition="cell/description">
<span tal:content="structure cell/renderedDescription" /></tal:desc> <span tal:content="structure cell/textRepresentation" /></tal:desc>
<br /> <br />
</div> </div>
</tal:cell> </tal:cell>

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de # Copyright (c) 2012 Helmut Merz helmutm@cy55.de
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -18,8 +18,6 @@
""" """
View classes for lobo (blueprint-based) layouts. View classes for lobo (blueprint-based) layouts.
$Id$
""" """
from cgi import parse_qs from cgi import parse_qs
@ -66,8 +64,20 @@ class ConceptView(BaseConceptView):
@Lazy @Lazy
def resources(self): def resources(self):
return self.getResources()
@Lazy
def representingResources(self):
pred = self.representationPredicate
if pred is None:
return {}
return self.getResources([pred])
def getResources(self, predicates=None):
result = dict(texts=[], images=[], files=[]) result = dict(texts=[], images=[], files=[])
for r in self.context.getResources([self.defaultPredicate]): if predicates is None:
predicates = [self.defaultPredicate]
for r in self.context.getResources(predicates):
if r.contentType.startswith('text/'): if r.contentType.startswith('text/'):
result['texts'].append(r) result['texts'].append(r)
if r.contentType.startswith('image/'): if r.contentType.startswith('image/'):
@ -81,6 +91,10 @@ class ConceptView(BaseConceptView):
for r in self.resources['images']: for r in self.resources['images']:
yield r yield r
@Lazy
def representationPredicate(self):
return self.conceptManager.get('represents')
# properties from base class: title, description, renderedDescription # properties from base class: title, description, renderedDescription
@Lazy @Lazy
@ -99,6 +113,12 @@ class ConceptView(BaseConceptView):
return u'' return u''
return self.renderDescription(self.textDescription) return self.renderDescription(self.textDescription)
@Lazy
def textRepresentation(self):
for r in self.representingResources.get('texts', []):
return self.renderText(r.data, r.contentType)
return self.renderedDescription
@Lazy @Lazy
def targetUrl(self): def targetUrl(self):
return self.nodeView.getUrlForTarget(self.context) return self.nodeView.getUrlForTarget(self.context)
@ -133,13 +153,15 @@ class Layout(Base, ConceptView):
macroName = 'layout' macroName = 'layout'
def getParts(self): def getParts(self):
result = []
parts = (self.params.get('parts') or [''])[0].split(',') # obsolete parts = (self.params.get('parts') or [''])[0].split(',') # obsolete
if not parts or not parts[0]: if not parts or not parts[0]:
parts = (self.options('parts') or parts = (self.options('parts') or
self.typeOptions('parts') or self.typeOptions('parts') or
['h1', 'g3']) ['h1', 'g3'])
#ti = adapted(self.context.conceptType).typeInterface return self.getPartViews(parts)
def getPartViews(self, parts):
result = []
for p in parts: for p in parts:
viewName = 'lobo_' + p viewName = 'lobo_' + p
view = component.queryMultiAdapter((self.context, self.request), view = component.queryMultiAdapter((self.context, self.request),

View file

@ -55,6 +55,8 @@
layer="loops.browser.skin.Lobo" /> layer="loops.browser.skin.Lobo" />
<resource name="custom.css" file="lobo/custom.css" <resource name="custom.css" file="lobo/custom.css"
layer="loops.browser.skin.Lobo" /> layer="loops.browser.skin.Lobo" />
<resource name="popup.css" file="lobo/popup.css"
layer="loops.browser.skin.Lobo" />
<resource name="favicon.png" file="loops_favicon.png" <resource name="favicon.png" file="loops_favicon.png"
layer="loops.browser.skin.Lobo" /> layer="loops.browser.skin.Lobo" />
<resource name="logo.png" file="loops_logo.png" <resource name="logo.png" file="loops_logo.png"

View file

@ -0,0 +1,9 @@
/*
$Id$
*/
body {
padding-left: 30px;
padding-right: 30px;
}

View file

@ -0,0 +1,16 @@
type(u'book', u'Buch', viewName=u'', typeInterface=u'',
options=u'action.portlet:create_subtype,edit_concept')
type(u'page', u'Seite', viewName=u'', typeInterface=u'',
options=u'action.portlet:edit_concept')
type(u'section', u'Kapitel', viewName=u'', typeInterface=u'',
options=u'action.portlet:create_subtype,edit_concept')
concept(u'ispartof', u'is Part of', u'predicate', options=u'', predicateInterface=u'')
concept(u'issubtype', u'is Subtype', u'predicate', options=u'', predicateInterface=u'')
concept(u'maintext', u'Haupttext', u'documenttype')
concept(u'quote', u'Zitat', u'documenttype')
child(u'book', u'section', u'issubtype')
child(u'section', u'section', u'issubtype')
child(u'section', u'page', u'issubtype')
child(u'system', u'personal_info', u'standard')

View file

@ -1,3 +1,4 @@
# types
type(u'query', u'Abfrage', options=u'', type(u'query', u'Abfrage', options=u'',
typeInterface='loops.expert.concept.IQueryConcept', viewName=u'') typeInterface='loops.expert.concept.IQueryConcept', viewName=u'')
type(u'task', u'Aufgabe', options=u'', type(u'task', u'Aufgabe', options=u'',
@ -5,55 +6,84 @@ type(u'task', u'Aufgabe', options=u'',
type(u'domain', u'Bereich', options=u'', typeInterface=u'', viewName=u'') type(u'domain', u'Bereich', options=u'', typeInterface=u'', viewName=u'')
type(u'classifier', u'Classifier', options=u'', type(u'classifier', u'Classifier', options=u'',
typeInterface='loops.classifier.interfaces.IClassifier', viewName=u'classifier.html') typeInterface='loops.classifier.interfaces.IClassifier', viewName=u'classifier.html')
type(u'documenttype', u'Document Type', options=u'', typeInterface=u'', viewName=u'') type(u'documenttype', u'Dokumentenart', options=u'', typeInterface=u'', viewName=u'')
type(u'extcollection', u'External Collection', options=u'', type(u'extcollection', u'External Collection', options=u'',
typeInterface='loops.integrator.interfaces.IExternalCollection', typeInterface='loops.integrator.interfaces.IExternalCollection',
viewName=u'collection.html') viewName=u'collection.html')
type(u'folder', u'Ordner', options=u'', typeInterface=u'', viewName=u'')
type(u'glossaryitem', u'Glossareintrag', options=u'', type(u'glossaryitem', u'Glossareintrag', options=u'',
typeInterface='loops.knowledge.interfaces.ITopic', viewName=u'glossaryitem.html') typeInterface='loops.knowledge.interfaces.ITopic', viewName=u'glossaryitem.html')
type(u'media_asset', u'Media Asset', type(u'media_asset', u'Media Asset',
options=u'storage:varsubdir\nstorage_parameters:extfiles/sites_zzz\nasset_transform.minithumb: size(105)\nasset_transform.small: size(230)\nasset_transform.medium: size(480)', typeInterface='loops.media.interfaces.IMediaAsset', viewName=u'image_medium.html') options=u'storage:varsubdir\nstorage_parameters:extfiles/sites_zzz\nasset_transform.minithumb: size(105)\nasset_transform.small: size(230)\nasset_transform.medium: size(480)', typeInterface='loops.media.interfaces.IMediaAsset', viewName=u'image_medium.html')
type(u'note', u'Note', options=u'', typeInterface='loops.interfaces.INote', type(u'note', u'Notiz', options=u'', typeInterface='loops.interfaces.INote',
viewName='note.html') viewName='note.html')
type(u'person', u'Person', options=u'', type(u'person', u'Person', options=u'',
typeInterface='loops.knowledge.interfaces.IPerson', viewName=u'') typeInterface='loops.knowledge.interfaces.IPerson', viewName=u'')
type(u'predicate', u'Predicate', options=u'', type(u'predicate', u'Prädikat', options=u'',
typeInterface=u'loops.interfaces.IPredicate', viewName=u'') typeInterface=u'loops.interfaces.IPredicate', viewName=u'')
type(u'event', u'Termin', options=u'', typeInterface='loops.organize.interfaces.ITask', type(u'event', u'Termin', options=u'', typeInterface='loops.organize.interfaces.ITask',
viewName=u'task.html') viewName=u'task.html')
type(u'textdocument', u'Text', options=u'', typeInterface='loops.interfaces.ITextDocument', viewName=u'') type(u'textdocument', u'Text', options=u'', typeInterface='loops.interfaces.ITextDocument', viewName=u'')
type(u'topic', u'Thema', options=u'', typeInterface='loops.knowledge.interfaces.ITopic', type(u'topic', u'Thema', options=u'action.portlet:createTopic,editTopic',
viewName=u'') typeInterface='loops.knowledge.interfaces.ITopic', viewName=u'')
type(u'type', u'Type', options=u'', typeInterface='loops.interfaces.ITypeConcept', type(u'type', u'Typ', options=u'', typeInterface='loops.interfaces.ITypeConcept',
viewName=u'') viewName=u'')
# domains
concept(u'general', u'Allgemein', u'domain')
concept(u'system', u'System', u'domain')
# predicates
concept(u'depends', u'depends', u'predicate') concept(u'depends', u'depends', u'predicate')
concept(u'follows', u'follows', u'predicate') concept(u'follows', u'follows', u'predicate')
concept(u'general', u'Allgemein', u'domain')
concept(u'glossary', u'Glossar', u'query', options=u'', viewName=u'glossary.html')
concept(u'hasType', u'has Type', u'predicate') concept(u'hasType', u'has Type', u'predicate')
concept(u'ispartof', u'is Part of', u'predicate') concept(u'ispartof', u'is Part of', u'predicate')
concept(u'issubtype', u'is Subtype', u'predicate') concept(u'issubtype', u'is Subtype', u'predicate')
concept(u'knows', u'knows', u'predicate') concept(u'knows', u'knows', u'predicate')
concept(u'ownedby', u'owned by', u'predicate') concept(u'ownedby', u'owned by', u'predicate')
concept(u'personal_info', u'Pers\xf6nliche Information', u'query', options=u'',
viewName=u'personal_info.html')
concept(u'provides', u'provides', u'predicate') concept(u'provides', u'provides', u'predicate')
concept(u'querytarget', u'is Query Target', u'predicate') concept(u'querytarget', u'is Query Target', u'predicate')
concept(u'requires', u'requires', u'predicate') concept(u'requires', u'requires', u'predicate')
concept(u'search', u'Suche', u'query', options=u'', viewName=u'search')
concept(u'standard', u'subobject', u'predicate') concept(u'standard', u'subobject', u'predicate')
concept(u'system', u'System', u'domain')
# queries
concept(u'events', u'Termine', u'query', options=u'delta:2',
viewName=u'list_events.html')
concept(u'glossary', u'Glossar', u'query', options=u'', viewName=u'glossary.html')
concept(u'personal_info', u'Pers\xf6nliche Informationen', u'query', options=u'',
viewName=u'personal_info.html')
concept(u'participants', u'Teilnehmer', u'query', options=u'',
viewName=u'list_children.html')
concept(u'recenct_changes', u'Aktuelle \xc4nderungen', u'query',
options=u'types:concept:*,resource:*',
viewName=u'recent_changes.html')
concept(u'search', u'Suche', u'query', options=u'', viewName=u'search')
concept(u'topics', u'Themen', u'query', options=u'action.portlet:createTopic',
viewName=u'list_children.html')
# child assignments
child(u'general', u'documenttype', u'standard') child(u'general', u'documenttype', u'standard')
child(u'general', u'event', u'standard') child(u'general', u'event', u'standard')
child(u'general', u'events', u'standard')
child(u'general', u'participants', u'standard')
child(u'general', u'topics', u'standard')
child(u'system', u'classifier', u'standard') child(u'system', u'classifier', u'standard')
child(u'system', u'extcollection', u'standard') child(u'system', u'extcollection', u'standard')
child(u'system', u'issubtype', u'standard') child(u'system', u'issubtype', u'standard')
child(u'system', u'media_asset', u'standard') child(u'system', u'media_asset', u'standard')
child(u'system', u'personal_info', u'standard') child(u'system', u'personal_info', u'standard')
node(u'home', u'Startseite', '', 'menu', body=u'Willkommen\n==========') child(u'topic', u'topic', u'issubtype', 1)
node(u'participants', u'Teilnehmer', u'home', 'page', body=u'Teilnehmer\n==========',
target=u'concepts/person', viewName=u'listchildren') resource(u'homepage', u'Willkommen', u'textdocument', contentType='text/restructured')
node(u'topics', u'Themen', u'home', 'page', body=u'Themen\n======', resource(u'impressum', u'Impressum', u'textdocument', contentType='text/restructured')
target=u'concepts/topic', viewName=u'listchildren')
#nodes
node(u'home', u'Startseite', '', 'menu')
node(u'willkommen', u'Willkommen', u'home', u'text')
node(u'willkommen', u'Willkommen', u'home/willkommen', u'text',
target=u'resources/homepage')
node(u'participants', u'Teilnehmer', u'home', 'page', target=u'concepts/participants')
node(u'topics', u'Themen', u'home', 'page', target=u'concepts/topics')
node(u'glossary', u'Glossar', u'home', 'page', target=u'concepts/glossary') node(u'glossary', u'Glossar', u'home', 'page', target=u'concepts/glossary')
node(u'search', u'Suche', u'home', 'page', target=u'concepts/search') node(u'search', u'Suche', u'home', 'page', target=u'concepts/search')
node(u'impressum', u'Impressum', u'home', u'info', target=u'resources/impressum')

View file

@ -42,6 +42,12 @@
</metal:standard> </metal:standard>
<metal:right define-macro="center">
<td style="text-align: center"
tal:content="python:col.getDisplayValue(row)" />
</metal:right>
<metal:right define-macro="right"> <metal:right define-macro="right">
<td style="text-align: right" <td style="text-align: right"
tal:content="python:col.getDisplayValue(row)" /> tal:content="python:col.getDisplayValue(row)" />

View file

@ -20,7 +20,10 @@
Field definitions for reports. Field definitions for reports.
""" """
from zope.app.form.browser.interfaces import ITerms
from zope import component
from zope.i18n.locales import locales from zope.i18n.locales import locales
from zope.schema.interfaces import IVocabularyFactory, IContextSourceBinder
from cybertools.composer.report.field import Field from cybertools.composer.report.field import Field
from cybertools.composer.report.result import ResultSet from cybertools.composer.report.result import ResultSet
@ -80,6 +83,52 @@ class DateField(Field):
return value.isoformat()[:10] return value.isoformat()[:10]
class VocabularyField(Field):
vocabulary = None
def getDisplayValue(self, row):
value = self.getRawValue(row)
if self.vocabulary is None:
return value
items = self.getVocabularyItems(row)
for item in items:
if item['token'] == value:
return item['title']
def getVocabularyItems(self, row):
context = row.context
request = row.parent.context.view.request
voc = self.vocabulary
if isinstance(voc, basestring):
terms = self.getVocabularyTerms(voc, context, request)
if terms is not None:
return terms
voc = voc.splitlines()
return [dict(token=t, title=t) for t in voc if t.strip()]
elif IContextSourceBinder.providedBy(voc):
source = voc(row.parent.context)
terms = component.queryMultiAdapter((source, request), ITerms)
if terms is not None:
termsList = [terms.getTerm(value) for value in source]
return [dict(token=t.token, title=t.title) for t in termsList]
else:
return []
return [dict(token=t.token, title=t.title or t.value) for t in voc]
def getVocabularyTerms(self, name, context, request):
if context is None or request is None:
return None
source = component.queryUtility(IVocabularyFactory, name=name)
if source is not None:
source = source(context)
terms = component.queryMultiAdapter((source, request), ITerms)
if terms is not None:
termsList = [terms.getTerm(value) for value in source]
return [dict(token=t.token, title=t.title) for t in termsList]
return None
class UrlField(Field): class UrlField(Field):
renderer = 'target' renderer = 'target'

2
external/element.py vendored
View file

@ -93,7 +93,7 @@ class ConceptElement(Element):
formState = self.getInstance().applyTemplate(data=kw, ignoreValidation=True) formState = self.getInstance().applyTemplate(data=kw, ignoreValidation=True)
# simple hack for resolving interface definition: # simple hack for resolving interface definition:
pi = self.get('predicateInterface') pi = self.get('predicateInterface')
if pi is not None: if pi:
adapted(self.object).predicateInterface = resolve(pi) adapted(self.object).predicateInterface = resolve(pi)
def getInstance(self, omit=['title']): def getInstance(self, omit=['title']):