Merge branch 'master' into zmi-restrictions

This commit is contained in:
Helmut Merz 2011-10-20 09:59:02 +02:00
commit cfc87f13ba
14 changed files with 260 additions and 75 deletions

View file

@ -6,6 +6,9 @@ $Id$
1.1
---
- Lobo layout: provide new part: image grid; make sure image is not repeated if
it already appears in header part
- new special view 'listsubobjects' for nodes
- allow for adoption of relations to a predicate interface;
with example implementation for a 'has Role' predicate in loops.organize
- external collection: provide functionality for automatically populate

View file

@ -350,7 +350,12 @@ class ConceptView(BaseView):
#IOptions(adapted(pr.predicate))('hide_parents_for', [])):
IOptions(pr.predicate)('hide_parents_for', [])):
return True
hideRoles = IOptions(adapted(pr.first.conceptType))('hide_for', None)
hideRoles = None
options = component.queryAdapter(adapted(pr.first), IOptions)
if options is not None:
hideRoles = options('hide_for', None)
if not hideRoles:
hideRoles = IOptions(adapted(pr.first.conceptType))('hide_for', None)
if hideRoles is not None:
principal = self.request.principal
if (IUnauthenticatedPrincipal.providedBy(principal) and
@ -395,10 +400,28 @@ class ConceptView(BaseView):
fv = FilterView(self.context, self.request)
rels = self.context.getResourceRelations()
for r in rels:
#yield self.childViewFactory(r, self.request, contextIsSecond=True)
if fv.check(r.first):
yield ResourceRelationView(r, self.request, contextIsSecond=True)
@Lazy
def resourcesList(self):
from loops.browser.resource import ResourceRelationView
return [ResourceRelationView(r, self.request, contextIsSecond=True)
for r in self.context.getResourceRelations()]
@Lazy
def resourcesByType(self):
result = dict(texts=[], images=[], files=[])
for rv in self.resourcesList:
r = rv.context
if r.contentType.startswith('text/'):
result['texts'].append(r)
if r.contentType.startswith('image/'):
result['images'].append(r)
else:
result['files'].append(r)
return result
def unique(self, rels):
result = Jeep()
for r in rels:

View file

@ -509,6 +509,14 @@
factory="loops.browser.node.ListResources"
permission="zope.View" />
<zope:adapter
name="listsubobjects"
for="loops.interfaces.INode
zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.interface.Interface"
factory="loops.browser.node.ListSubobjects"
permission="zope.View" />
<zope:adapter
name="listchildren"
for="loops.interfaces.INode
@ -562,6 +570,12 @@
class="loops.browser.node.ObjectInfo"
permission="zope.View" />
<page
name="meta_info.html"
for="loops.interfaces.INode"
class="loops.browser.node.MetaInfo"
permission="zope.View" />
<page
name="create_object.html"
for="loops.interfaces.INode"

View file

@ -38,7 +38,29 @@
</tr>
<tr tal:repeat="info item/additionalInfos">
<td><span i18n:translate=""
tal:content="info/label">Creators</span>:</td>
tal:content="info/label">Meta</span>:</td>
<td tal:content="structure info/value"></td>
</tr>
<tr>
<td colspan="2"><br />
<input type="button" value="Close" onclick="closeDialog()"
i18n:attributes="value" />
</td>
</tr>
</table>
</metal:info>
<metal:info define-macro="meta_info"
tal:define="item nocall:view/item">
<table class="object_info" width="400">
<tr>
<td colspan="2">
<h2 tal:content="item/title">Information</h2></td>
</tr>
<tr tal:repeat="info item/additionalInfos">
<td><span i18n:translate=""
tal:content="info/label">Meta</span>:</td>
<td tal:content="structure info/value"></td>
</tr>
<tr>
@ -48,5 +70,4 @@
</td>
</tr>
</table>
</metal:info>

View file

@ -39,6 +39,14 @@
factory="loops.browser.lobo.standard.List2"
permission="zope.View" />
<zope:adapter
name="lobo_h0"
for="loops.interfaces.IConcept
loops.browser.skin.Lobo"
provides="zope.interface.Interface"
factory="loops.browser.lobo.standard.Header0"
permission="zope.View" />
<zope:adapter
name="lobo_h1"
for="loops.interfaces.IConcept
@ -66,11 +74,11 @@
<!-- parts for displaying resources -->
<zope:adapter
name="lobo_rg3"
name="lobo_ig3"
for="loops.interfaces.IConcept
loops.browser.skin.Lobo"
provides="zope.interface.Interface"
factory="loops.browser.lobo.standard.ResourceGrid3"
factory="loops.browser.lobo.standard.ImageGrid3"
permission="zope.View" />
</configure>

View file

@ -12,9 +12,9 @@
<tal:cell repeat="cell part/getChildren">
<div tal:attributes="class cell/cssClass;
style cell/style">
<metal:image use-macro="item/macros/image" />
<a tal:attributes="href cell/targetUrl;
title cell/description">
<metal:image use-macro="item/macros/image" />
<div class="legend">
<b tal:content="cell/title" /><br />
<i tal:content="cell/description" />
@ -29,10 +29,8 @@
<tal:cell repeat="cell part/getChildren">
<div tal:condition="cell/img"
tal:attributes="class python:cell.cssClass[0]">
<a tal:attributes="href cell/targetUrl;
title cell/description">
<metal:image use-macro="item/macros/image" />
</a><br />&nbsp;
<metal:image use-macro="item/macros/image" />
<br />&nbsp;
</div>
<div tal:attributes="class python:cell.cssClass[1]">
<a tal:attributes="href cell/targetUrl">
@ -48,14 +46,24 @@
<metal:block define-macro="header">
<div tal:define="cell part/getView">
<metal:headline use-macro="item/macros/headline" />
<div tal:define="showImageLink python:True"
tal:attributes="class python:part.cssClass[0]">
<metal:image use-macro="item/macros/image" />
</div>
<tal:image condition="part/showImage">
<div tal:define="showImageLink python:True"
tal:attributes="class python:part.cssClass[0]">
<metal:image use-macro="item/macros/image" />
<span tal:condition="cell/img/showInfo|nothing">
<a tal:define="url string:${cell/img/url}/meta_info.html"
tal:attributes="href url;
onclick string:objectDialog('', '$url');;
return false">
<img tal:attributes="src
string:${controller/resourceBase}/cybertools.icons/info.png" />
</a></span>
</div>
</tal:image>
<div tal:attributes="class python:part.cssClass[1]">
<span tal:content="structure cell/renderedTextDescription" />
</div>
<tal:break condition="cell/img">
<tal:break condition="python:part.showImage and cell.img">
<br style="clear: both" />&nbsp;</tal:break>
<div tal:condition="cell/renderedText"
tal:attributes="class python:part.cssClass[2]">
@ -67,18 +75,25 @@
<!-- resources listing macros -->
<metal:block define-macro="rgrid">
<tal:cell repeat="cell part/getResources">
<metal:block define-macro="imagegrid"
tal:define="showImageLink python:True">
<tal:cell repeat="cell part/getImages">
<div tal:attributes="class cell/cssClass;
style cell/style">
<a tal:attributes="href cell/targetUrl;
title cell/description">
<metal:image use-macro="item/macros/image" />
<div class="legend">
<b tal:content="cell/title" /><br />
<b tal:content="cell/title" />
<span tal:condition="cell/img/showInfo|nothing">
<a tal:define="url string:${cell/img/url}/meta_info.html"
tal:attributes="href url;
onclick string:objectDialog('', '$url');;
return false">
<img tal:attributes="src
string:${controller/resourceBase}/cybertools.icons/info.png" />
</a></span>
<br />
<i tal:content="cell/description" />
</div>
</a>
</div>
</tal:cell>
</metal:block>
@ -89,14 +104,21 @@
<metal:image define-macro="image">
<tal:img condition="cell/img">
<a title="Information about this object."
tal:omit-tag="not:showImageLink|python:False"
dojoType="dojox.image.Lightbox" group="mediasset"
i18n:attributes="title"
tal:define="url string:${cell/img/url}/object_info.html"
tal:attributes="href url;
onclick string:objectDialog('', '$url?dialog=');; return false">
<img tal:condition="cell/img"
tal:attributes="href cell/img/fullImageUrl;
title cell/img/title">
<img tal:condition="showImageLink|python:False"
tal:attributes="src cell/img/src;
class cell/img/cssClass" />
class cell/img/cssClass;
alt cell/title" />
</a>
<a tal:condition="not:showImageLink|python:False"
tal:attributes="href cell/targetUrl;
title cell/title">
<img tal:attributes="src cell/img/src;
class cell/img/cssClass;
alt cell/title" />
</a>
</tal:img>
</metal:image>

View file

@ -31,7 +31,6 @@ from cybertools.typology.interfaces import IType
from loops.browser.concept import ConceptView as BaseConceptView
from loops.browser.concept import ConceptRelationView as BaseConceptRelationView
from loops.browser.resource import ResourceView as BaseResourceView
from loops.browser.resource import ResourceRelationView as BaseResourceRelationView
from loops.common import adapted, baseObject
@ -64,7 +63,6 @@ class ConceptView(BaseConceptView):
def __init__(self, context, request):
super(ConceptView, self).__init__(baseObject(context), request)
self.adapted = context
@Lazy
def resources(self):
@ -78,6 +76,11 @@ class ConceptView(BaseConceptView):
result['files'].append(r)
return result
@Lazy
def images(self):
for r in self.resources['images']:
yield r
# properties from base class: title, description, renderedDescription
@Lazy
@ -113,23 +116,19 @@ class ConceptView(BaseConceptView):
@Lazy
def img(self):
self.registerDojoLightbox() # also provides access to info popup
for r in self.resources['images']:
url = self.nodeView.getUrlForTarget(r)
src = ('%s/mediaasset.html?v=%s' % (url, self.parentView.imageSize))
return dict(src=src, url=url,
cssClass=self.parentView.imageCssClass)
for r in self.parentView.parent.images:
# fetch from iterator on layout object: avoid duplicates
url = self.nodeView.getUrlForTarget(r)
src = ('%s/mediaasset.html?v=%s' % (url, self.parentView.imageSize))
fullSrc = ('%s/mediaasset.html?v=%s' % (url, self.parentView.fullImageSize))
adImg = adapted(r)
showInfo = adImg.showInfo and adImg.metaInfo
return dict(src=src, fullImageUrl=fullSrc, title=r.title,
url=url, cssClass=self.parentView.imageCssClass,
showInfo=showInfo)
class ConceptRelationView(BaseConceptRelationView, ConceptView):
def __init__(self, relation, request, contextIsSecond=False,
parent=None, idx=0):
BaseConceptRelationView.__init__(self, relation, request, contextIsSecond)
self.parentView = parent
self.idx = idx
class Layout(Base):
class Layout(Base, ConceptView):
macroName = 'layout'
@ -140,11 +139,13 @@ class Layout(Base):
parts = (self.options('parts') or
self.typeOptions('parts') or
['h1', 'g3'])
ti = adapted(self.context.conceptType).typeInterface
for p in parts:
viewName = 'lobo_' + p
view = component.queryMultiAdapter((self.context, self.request),
name=viewName)
if view is not None:
view.parent = self
result.append(view)
return result
@ -152,9 +153,11 @@ class Layout(Base):
class BasePart(Base):
imageSize = 'small'
fullImageSize = 'medium'
imageCssClass = ''
height = 260
gridPattern = []
showImage = True
def getChildren(self):
subtypeNames = (self.params.get('subtypes') or [''])[0].split(',')
@ -175,6 +178,12 @@ class BasePart(Base):
view.parentView = self
return view
def getImages(self):
result = []
for idx, img in enumerate(self.parent.images):
result.append(ResourceView(img, self.request, parent=self, idx=idx))
return result
class Grid3(BasePart):
@ -198,6 +207,14 @@ class List2(BasePart):
gridPattern = [['span-4 clear', 'span-2 last']]
class Header0(BasePart):
macroName = 'header'
cssClass = ['span-6 last', 'clear']
showImage = False
cssClass = ['', 'span-6 last', 'clear']
class Header1(BasePart):
macroName = 'header'
@ -212,13 +229,46 @@ class Header2(BasePart):
cssClass = ['span-4', 'span-2 last', 'clear']
# layout components for presenting lists of resources
# resource parts
class ResourceRelationView(BaseResourceRelationView):
class ImageGrid3(BasePart):
macroName = 'imagegrid'
imageSize = 'small'
height = 'auto; padding-bottom: 10px'
gridPattern = ['span-2', 'span-2', 'span-2 last']
# relation views, used for cells (components) of lists and grids
class ConceptRelationView(BaseConceptRelationView, ConceptView):
def __init__(self, relation, request, contextIsSecond=False,
parent=None, idx=0):
BaseResourceRelationView.__init__(self, relation, request, contextIsSecond)
BaseConceptRelationView.__init__(self, relation, request, contextIsSecond)
self.parentView = parent
self.idx = idx
@Lazy
def img(self):
self.registerDojoLightbox() # also provides access to info popup
for r in self.images:
# fetch from iterator on layout object: avoid duplicates
url = self.nodeView.getUrlForTarget(r)
src = ('%s/mediaasset.html?v=%s' % (url, self.parentView.imageSize))
fullSrc = ('%s/mediaasset.html?v=%s' % (url, self.parentView.fullImageSize))
adImg = adapted(r)
showInfo = adImg.showInfo and adImg.metaInfo
return dict(src=src, fullImageUrl=fullSrc, title=r.title,
url=url, cssClass=self.parentView.imageCssClass,
showInfo=showInfo)
class ResourceView(BaseResourceView):
def __init__(self, resource, request, parent=None, idx=0):
BaseResourceView.__init__(self, resource, request)
self.parentView = parent
self.idx = idx
@ -241,25 +291,10 @@ class ResourceRelationView(BaseResourceRelationView):
self.registerDojoLightbox() # also provides access to info popup
url = self.nodeView.getUrlForTarget(self.context)
src = ('%s/mediaasset.html?v=%s' % (url, self.parentView.imageSize))
return dict(src=src, url=url,
cssClass=self.parentView.imageCssClass)
class ResourcesPart(BasePart):
def getResources(self):
result = []
resourceRels = self.context.getResourceRelations()
for idx, r in enumerate(resourceRels):
result.append(ResourceRelationView(r, self.request,
contextIsSecond=True, parent=self, idx=idx))
return result
class ResourceGrid3(ResourcesPart):
macroName = 'rgrid'
imageSize = 'small'
height = 'auto; padding-bottom: 10px'
gridPattern = ['span-2', 'span-2', 'span-2 last']
fullSrc = ('%s/mediaasset.html?v=%s' % (url, self.parentView.fullImageSize))
adImg = adapted(self.context)
showInfo = adImg.showInfo and adImg.metaInfo
return dict(src=src, fullImageUrl=fullSrc, title=self.context.title,
url=url, cssClass=self.parentView.imageCssClass,
showInfo=showInfo)

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2010 Helmut Merz helmutm@cy55.de
# Copyright (c) 2011 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
@ -607,6 +607,15 @@ class ObjectInfo(NodeView):
return self.request.get('dialog', 'object_info')
class MetaInfo(ObjectInfo):
__call__ = innerHtml
@Lazy
def macro(self):
return self.macros['meta_info']
class InlineEdit(NodeView):
""" Provides inline editor as inner HTML"""
@ -676,6 +685,11 @@ class ListChildren(SpecialNodeView):
macroName = 'listchildren'
class ListSubobjects(SpecialNodeView):
macroName = 'listsubobjects'
class ConfigureView(NodeView):
""" An editing view for configuring a node, optionally creating
a target object.

View file

@ -166,12 +166,47 @@
<a href="#"
tal:attributes="href string:${view/url}/.${related/uniqueId};
title related/description"
tal:content="related/title">Resource Title</a>
tal:content="related/title">Concept Title</a>
</div>
</div>
</metal:children>
<metal:subobjects define-macro="listsubobjects"
tal:define="target nocall:item/targetObjectView">
<div class="content-1"
tal:content="structure item/body"
tal:attributes="ondblclick python:
target and target.openEditWindow('configure.html')
or item.openEditWindow();
id string:${view/itemNum}.body;">
Listing
</div>
<div tal:condition="nocall:target">
<div tal:attributes="ondblclick python: target.openEditWindow('configure.html')"
tal:define="children python:list(target.children())"
tal:condition="children">
<h3 i18n:translate="">Children</h3>
<div tal:repeat="related children">
<a tal:attributes="href python:view.getUrlForTarget(related);
title related/description"
tal:content="related/title">Concept Title</a>
</div>
</div>
<div tal:attributes="ondblclick python: target.openEditWindow('resources.html')"
tal:define="resources python:list(target.resources())"
tal:condition="resources">
<h3 i18n:translate="">Resources</h3>
<div tal:repeat="related resources">
<a tal:attributes="href python:view.getUrlForTarget(related);
title related/description"
tal:content="related/title">Resource Title</a>
</div>
</div>
</div>
</metal:subobjects>
<!-- menu -->
<metal:menu define-macro="menu"

View file

@ -243,8 +243,10 @@ class ResourceView(BaseView):
# actions
def getPortletActions(self, page=None, target=None):
return actions.get('portlet', ['edit_object'], view=self, page=page,
target=target)
if canWrite(target.context, 'data'):
return actions.get('portlet', ['edit_object'], view=self, page=page,
target=target)
return []
def getObjectActions(self, page=None, target=None):
acts = ['info']

View file

@ -443,7 +443,7 @@ img.notselected {
/* lobo layout-specific classes */
.legend {
margin-top: 3px;
margin-top: 1px;
}
/* comments */

View file

@ -296,6 +296,7 @@ class IBaseResource(ILoopsObject):
metaInfo = Attribute('Optional additional information about the resource '
'provided as text.')
showInfo = Attribute('Show object information in the standard user interface.')
def getType():
""" Return a concept that provides the object's type, i.e. the

View file

@ -1,6 +1,7 @@
<metal:block define-macro="asset">
<div tal:attributes="ondblclick python: item.openEditWindow('edit.html')">
<div metal:use-macro="views/node_macros/object_actions" />
<tal:actions condition="view/showObjectActions">
<div metal:use-macro="views/node_macros/object_actions" /></tal:actions>
<h1 tal:content="item/title">Title</h1><br />
<p tal:define="url python: view.getUrlForTarget(item)">
<a tal:omit-tag="view/isAnonymous"

View file

@ -39,3 +39,9 @@ class IMediaAsset(IMediaAsset, IExternalFile):
missing_value=u'',
required=False)
showInfo = schema.Bool(
title=_(u'Show Object Information'),
description=_(u'Show object information in the standard user interface.'),
default=False,
required=False)