diff --git a/browser/concept_macros.pt b/browser/concept_macros.pt index d648679..3c700bc 100644 --- a/browser/concept_macros.pt +++ b/browser/concept_macros.pt @@ -173,7 +173,7 @@

Resources

+ description related/description; + predicate related/predicateTitle; + info python: ' | '.join( + t for t in (description, predicate) if t)"> + title info">
Resource Title
diff --git a/browser/folder.py b/browser/folder.py index 8177b85..e3c5025 100755 --- a/browser/folder.py +++ b/browser/folder.py @@ -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 # 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. - -$Id$ """ @@ -50,6 +48,7 @@ actions.register('editFolder', 'portlet', DialogAction, class FolderView(ConceptView): def getActions(self, category='concept', page=None, target=None): + # obsolete: define actions via type option if category == 'portlet': return actions.get(category, ['createFolder', 'editFolder'], view=self, page=page, target=target) diff --git a/browser/form.py b/browser/form.py index 192867e..481f30e 100644 --- a/browser/form.py +++ b/browser/form.py @@ -47,6 +47,7 @@ from cybertools.composer.schema.browser.common import schema_macros, schema_edit from cybertools.composer.schema.schema import FormState from cybertools.stateful.interfaces import IStateful from cybertools.typology.interfaces import IType, ITypeManager +from cybertools.util.format import toUnicode from loops.browser.node import NodeView from loops.browser.concept import ConceptRelationView from loops.common import adapted @@ -154,7 +155,7 @@ class ObjectForm(NodeView): for k, v in data.items(): #overwrite data with values from request.form if k in self.request.form: - data[k] = form[k] + data[k] = toUnicode(form[k]) return data @Lazy @@ -357,7 +358,7 @@ class CreateObjectPopup(CreateObjectForm): self.registerDojo() cm = self.controller.macros cm.register('css', identifier='popup.css', resourceName='popup.css', - media='all', position=4) + media='all', priority=90) #, position=4) jsCall = ('dojo.require("dojo.parser");' 'dojo.require("dijit.form.FilteringSelect");' 'dojo.require("dojox.data.QueryReadStore");') diff --git a/browser/lobo/standard.pt b/browser/lobo/standard.pt index bb655dc..40a8061 100644 --- a/browser/lobo/standard.pt +++ b/browser/lobo/standard.pt @@ -17,7 +17,7 @@ title cell/description">

- +
@@ -36,7 +36,7 @@
- +
diff --git a/browser/lobo/standard.py b/browser/lobo/standard.py index b70d4eb..7dcb317 100644 --- a/browser/lobo/standard.py +++ b/browser/lobo/standard.py @@ -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 # it under the terms of the GNU General Public License as published by @@ -18,8 +18,6 @@ """ View classes for lobo (blueprint-based) layouts. - -$Id$ """ from cgi import parse_qs @@ -66,8 +64,20 @@ class ConceptView(BaseConceptView): @Lazy 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=[]) - 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/'): result['texts'].append(r) if r.contentType.startswith('image/'): @@ -81,6 +91,10 @@ class ConceptView(BaseConceptView): for r in self.resources['images']: yield r + @Lazy + def representationPredicate(self): + return self.conceptManager.get('represents') + # properties from base class: title, description, renderedDescription @Lazy @@ -99,6 +113,12 @@ class ConceptView(BaseConceptView): return u'' 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 def targetUrl(self): return self.nodeView.getUrlForTarget(self.context) @@ -133,13 +153,15 @@ class Layout(Base, ConceptView): macroName = 'layout' def getParts(self): - result = [] parts = (self.params.get('parts') or [''])[0].split(',') # obsolete if not parts or not parts[0]: parts = (self.options('parts') or self.typeOptions('parts') or ['h1', 'g3']) - #ti = adapted(self.context.conceptType).typeInterface + return self.getPartViews(parts) + + def getPartViews(self, parts): + result = [] for p in parts: viewName = 'lobo_' + p view = component.queryMultiAdapter((self.context, self.request), diff --git a/browser/skin/configure.zcml b/browser/skin/configure.zcml index abb30ca..09ffedb 100644 --- a/browser/skin/configure.zcml +++ b/browser/skin/configure.zcml @@ -55,6 +55,8 @@ layer="loops.browser.skin.Lobo" /> + + + + + + diff --git a/expert/field.py b/expert/field.py index 7c500bd..d87165a 100644 --- a/expert/field.py +++ b/expert/field.py @@ -20,7 +20,10 @@ Field definitions for reports. """ +from zope.app.form.browser.interfaces import ITerms +from zope import component from zope.i18n.locales import locales +from zope.schema.interfaces import IVocabularyFactory, IContextSourceBinder from cybertools.composer.report.field import Field from cybertools.composer.report.result import ResultSet @@ -80,6 +83,52 @@ class DateField(Field): 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): renderer = 'target' diff --git a/external/element.py b/external/element.py index 5c48146..1490dd2 100644 --- a/external/element.py +++ b/external/element.py @@ -93,7 +93,7 @@ class ConceptElement(Element): formState = self.getInstance().applyTemplate(data=kw, ignoreValidation=True) # simple hack for resolving interface definition: pi = self.get('predicateInterface') - if pi is not None: + if pi: adapted(self.object).predicateInterface = resolve(pi) def getInstance(self, omit=['title']):