From d9694f711caee6e1a308835a64f2bfd32ea51745 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sat, 3 Dec 2011 09:46:51 +0100 Subject: [PATCH 1/3] improve reporting: additional field for HTML-rendered text; CSS class for tabular report --- browser/skin/lobo/lobo.css | 4 ++++ expert/browser/results.pt | 3 ++- expert/field.py | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/browser/skin/lobo/lobo.css b/browser/skin/lobo/lobo.css index 185692d..5439bb4 100644 --- a/browser/skin/lobo/lobo.css +++ b/browser/skin/lobo/lobo.css @@ -176,6 +176,10 @@ table.records th, table.records td { border: 1px solid black; } +table.report td { + vertical-align: top; +} + dl.docutils dt { font-weight: bold; margin-top: 0.3em; diff --git a/expert/browser/results.pt b/expert/browser/results.pt index 227913c..7cdd6ee 100644 --- a/expert/browser/results.pt +++ b/expert/browser/results.pt @@ -15,7 +15,8 @@
- +
Date: Sat, 3 Dec 2011 17:07:20 +0100 Subject: [PATCH 2/3] work in progress: basic procedure for determining breadcrumbs list --- README.txt | 4 +++- browser/common.py | 4 ++-- browser/concept.py | 13 +++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.txt b/README.txt index 2d862e4..8140683 100755 --- a/README.txt +++ b/README.txt @@ -659,7 +659,9 @@ Breadcrumbs >>> loopsRoot.options = ['showBreadcrumbs'] >>> m114.nodeType = 'page' >>> m114.target = cc1 - >>> view = NodeView(m114, TestRequest()) + >>> request = TestRequest() + >>> view = NodeView(m114, request) + >>> request.annotations.setdefault('loops.view', {})['nodeView'] = view >>> view.breadcrumbs() [{'url': 'http://127.0.0.1/loops/views/m1', 'label': u'Menu'}, {'url': 'http://127.0.0.1/loops/views/m1/m11', 'label': u'Zope'}, diff --git a/browser/common.py b/browser/common.py index 659fc11..8cc21ab 100644 --- a/browser/common.py +++ b/browser/common.py @@ -416,8 +416,8 @@ class BaseView(GenericView, I18NView): if contentType == u'text/html': return text return u'
%s
' % util.html_quote(text) - source = component.createObject(typeKey, text) - view = component.getMultiAdapter((removeAllProxies(source), self.request)) + source = removeAllProxies(component.createObject(typeKey, text)) + view = component.getMultiAdapter((source, self.request)) return view.render() def renderDescription(self, text=None): diff --git a/browser/concept.py b/browser/concept.py index c4bf3e6..98a013e 100644 --- a/browser/concept.py +++ b/browser/concept.py @@ -234,6 +234,19 @@ class ConceptView(BaseView): def description(self): return self.adapted.description + def breadcrumbs(self): + data = [] + if self.breadcrumbsParent is not None: + data.extend(self.breadcrumbsParent.breadcrumbs()) + if self.context != self.nodeView.targetObject: + data.append(dict(label=self.title, + url=self.nodeView.getUrlForTarget(self.context))) + return data + + @Lazy + def breadcrumbsParent(self): + return None + def getData(self, omit=('title', 'description')): data = self.instance.applyTemplate() for k in omit: From 2c7e2f0e5b0c71a6a5b23ad2bdc1b685d4bd520a Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sat, 3 Dec 2011 17:09:27 +0100 Subject: [PATCH 3/3] minor fixes - URL field for reports - set reStructuredText renderer in DocTests - import type and predicate interfaces correctly (backport from bbmaster branch) --- expert/field.py | 4 +++- external/element.py | 9 +++++++-- tests/setup.py | 9 ++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/expert/field.py b/expert/field.py index 5c52525..d386298 100644 --- a/expert/field.py +++ b/expert/field.py @@ -21,6 +21,7 @@ Field definitions for reports. """ from cybertools.composer.report.field import Field +from loops.common import baseObject from loops import util @@ -39,7 +40,8 @@ class UrlField(Field): def getDisplayValue(self, row): nv = row.parent.context.view.nodeView - return dict(title=self.getValue(row), url=nv.getUrlForTarget(row.context)) + return dict(title=self.getValue(row), + url=nv.getUrlForTarget(baseObject(row.context))) class TargetField(Field): diff --git a/external/element.py b/external/element.py index b9eac6d..7ce33fc 100644 --- a/external/element.py +++ b/external/element.py @@ -90,10 +90,12 @@ class ConceptElement(Element): type = loader.concepts[self['type']] kw = dict((k, v) for k, v in self.items() if k not in self.posArgs) - # use IInstance adapter (name='editor') for unmarshalling values - #self.object = loader.addConcept(self['name'], self['title'], type, **kw) self.object = loader.addConcept(self['name'], self['title'], type) formState = self.getInstance().applyTemplate(data=kw, ignoreValidation=True) + # simple hack for resolving interface definition: + pi = self.get('predicateInterface') + if pi is not None: + adapted(self.object).predicateInterface = resolve(pi) def getInstance(self, omit=['title']): adObject = adapted(self.object) @@ -126,6 +128,9 @@ class TypeElement(ConceptElement): loader.typeConcept, **kw) instance = self.getInstance(omit=['title', 'typeInterface']) formState = instance.applyTemplate(data=kw, ignoreValidation=True) + if ti: + # overwrite type interface, might have been ignored in addConcept + adapted(self.object).typeInterface = kw['typeInterface'] class ChildElement(Element): diff --git a/tests/setup.py b/tests/setup.py index 9bd43bd..77250d3 100644 --- a/tests/setup.py +++ b/tests/setup.py @@ -14,6 +14,8 @@ from zope.app.catalog.text import TextIndex from zope.app.container.interfaces import IObjectRemovedEvent from zope.app.principalannotation import PrincipalAnnotationUtility from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility +from zope.app.renderer.rest import IReStructuredTextSource,\ + ReStructuredTextToHTMLRenderer, ReStructuredTextSourceFactory from zope.app.security.principalregistry import principalRegistry from zope.app.security.interfaces import IAuthentication from zope.app.securitypolicy.zopepolicy import ZopeSecurityPolicy @@ -122,8 +124,13 @@ class TestSite(object): component.provideUtility(principalRegistry, IAuthentication) component.provideAdapter(session.ClientId) component.provideAdapter(session.Session) - component.provideUtility(session.RAMSessionDataContainer(), ISessionDataContainer) + component.provideUtility(session.RAMSessionDataContainer(), + ISessionDataContainer) component.provideUtility(ClientIdManager()) + component.provideUtility(ReStructuredTextSourceFactory, + name='zope.source.rest') + component.provideAdapter(ReStructuredTextToHTMLRenderer, + (IReStructuredTextSource, IBrowserRequest), Interface) component.provideAdapter(LoopsType) component.provideAdapter(ConceptType)