Merge branch 'master' into bbmaster
This commit is contained in:
commit
cebc045348
10 changed files with 129 additions and 14 deletions
|
@ -137,7 +137,7 @@ class BaseRelationView(BaseView):
|
||||||
return self.getData()
|
return self.getData()
|
||||||
|
|
||||||
def getData(self):
|
def getData(self):
|
||||||
return self.instance.applyTemplate()
|
return self.instance.applyTemplate(context=self.context, request=self.request)
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def instance(self):
|
def instance(self):
|
||||||
|
|
|
@ -693,6 +693,10 @@
|
||||||
for="loops.view.NodeTypeSourceList
|
for="loops.view.NodeTypeSourceList
|
||||||
zope.publisher.interfaces.browser.IBrowserRequest" />
|
zope.publisher.interfaces.browser.IBrowserRequest" />
|
||||||
|
|
||||||
|
<zope:adapter factory="loops.browser.common.SimpleTerms"
|
||||||
|
for="loops.table.DataTableSourceList
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest" />
|
||||||
|
|
||||||
<zope:view factory="loops.browser.node.NodeTraverser"
|
<zope:view factory="loops.browser.node.NodeTraverser"
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
type="zope.publisher.interfaces.http.IHTTPRequest"
|
type="zope.publisher.interfaces.http.IHTTPRequest"
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
style cell/style">
|
style cell/style">
|
||||||
<metal:image use-macro="item/macros/image" />
|
<metal:image use-macro="item/macros/image" />
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
<b tal:content="cell/title" />
|
<a tal:attributes="href cell/targetUrl"><b tal:content="cell/title" /></a>
|
||||||
<span tal:condition="cell/img/showInfo|nothing">
|
<span tal:condition="cell/img/showInfo|nothing">
|
||||||
<a tal:define="url string:${cell/img/url}/meta_info.html"
|
<a tal:define="url string:${cell/img/url}/meta_info.html"
|
||||||
tal:attributes="href url;
|
tal:attributes="href url;
|
||||||
|
|
|
@ -38,6 +38,7 @@ from zope.traversing.api import getName, getParent
|
||||||
from zope.traversing.browser import absoluteURL
|
from zope.traversing.browser import absoluteURL
|
||||||
|
|
||||||
from cybertools.browser.action import actions
|
from cybertools.browser.action import actions
|
||||||
|
from cybertools.meta.interfaces import IOptions
|
||||||
from cybertools.typology.interfaces import IType
|
from cybertools.typology.interfaces import IType
|
||||||
from cybertools.xedit.browser import ExternalEditorView, fromUnicode
|
from cybertools.xedit.browser import ExternalEditorView, fromUnicode
|
||||||
from loops.browser.action import DialogAction, TargetAction
|
from loops.browser.action import DialogAction, TargetAction
|
||||||
|
@ -51,6 +52,7 @@ from loops.interfaces import IMediaAsset as legacy_IMediaAsset
|
||||||
from loops.interfaces import ITypeConcept
|
from loops.interfaces import ITypeConcept
|
||||||
from loops.media.interfaces import IMediaAsset
|
from loops.media.interfaces import IMediaAsset
|
||||||
from loops.organize.stateful.browser import statefulActions
|
from loops.organize.stateful.browser import statefulActions
|
||||||
|
from loops.organize.util import getRolesForPrincipal
|
||||||
from loops.versioning.browser import version_macros
|
from loops.versioning.browser import version_macros
|
||||||
from loops.versioning.interfaces import IVersionable
|
from loops.versioning.interfaces import IVersionable
|
||||||
from loops import util
|
from loops import util
|
||||||
|
@ -270,15 +272,38 @@ class ResourceView(BaseView):
|
||||||
|
|
||||||
# relations
|
# relations
|
||||||
|
|
||||||
def concepts(self):
|
def isHidden(self, pr):
|
||||||
for r in self.context.getConceptRelations():
|
hideRoles = None
|
||||||
yield ConceptRelationView(r, self.request)
|
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
|
||||||
|
'zope.Anonymous' in hideRoles):
|
||||||
|
return True
|
||||||
|
roles = getRolesForPrincipal(principal.id, self.context)
|
||||||
|
for r in roles:
|
||||||
|
if r in hideRoles:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
#@Lazy
|
||||||
|
def conceptsForPortlet(self):
|
||||||
|
return [p for p in self.relatedConcepts() if not self.isHidden(p.relation)]
|
||||||
|
|
||||||
def relatedConcepts(self):
|
def relatedConcepts(self):
|
||||||
for c in self.concepts():
|
for c in self.concepts():
|
||||||
if c.isProtected: continue
|
if c.isProtected:
|
||||||
|
continue
|
||||||
yield c
|
yield c
|
||||||
|
|
||||||
|
def concepts(self):
|
||||||
|
for r in self.context.getConceptRelations():
|
||||||
|
yield ConceptRelationView(r, self.request)
|
||||||
|
|
||||||
def clients(self):
|
def clients(self):
|
||||||
for node in self.context.getClients():
|
for node in self.context.getClients():
|
||||||
yield NodeView(node, self.request)
|
yield NodeView(node, self.request)
|
||||||
|
|
|
@ -48,9 +48,10 @@
|
||||||
<metal:block define-macro="image">
|
<metal:block define-macro="image">
|
||||||
<div tal:attributes="ondblclick python: item.openEditWindow('edit.html')">
|
<div tal:attributes="ondblclick python: item.openEditWindow('edit.html')">
|
||||||
<div metal:use-macro="views/node_macros/object_actions" />
|
<div metal:use-macro="views/node_macros/object_actions" />
|
||||||
<h1 tal:content="item/title">Title</h1><br />
|
<h1><a tal:omit-tag="python: level > 1"
|
||||||
<img src="#"
|
tal:attributes="href request/URL"
|
||||||
tal:attributes="src
|
tal:content="item/title">Title</a></h1><br />
|
||||||
|
<img tal:attributes="src
|
||||||
string:${view/url}/.${view/targetId}/view?version=this" />
|
string:${view/url}/.${view/targetId}/view?version=this" />
|
||||||
<p><i tal:content="structure item/renderedDescription">Description</i></p>
|
<p><i tal:content="structure item/renderedDescription">Description</i></p>
|
||||||
<metal:fields use-macro="view/comment_macros/comments" />
|
<metal:fields use-macro="view/comment_macros/comments" />
|
||||||
|
@ -114,7 +115,7 @@
|
||||||
|
|
||||||
|
|
||||||
<metal:actions define-macro="related">
|
<metal:actions define-macro="related">
|
||||||
<div tal:repeat="concept macro/info/relatedConcepts">
|
<div tal:repeat="concept macro/info/conceptsForPortlet">
|
||||||
<a tal:attributes="href python: view.getUrlForTarget(concept);
|
<a tal:attributes="href python: view.getUrlForTarget(concept);
|
||||||
title concept/relationInfo">
|
title concept/relationInfo">
|
||||||
<span i18n:translate="" tal:content="concept/title">Concept</span>
|
<span i18n:translate="" tal:content="concept/title">Concept</span>
|
||||||
|
|
|
@ -43,6 +43,12 @@
|
||||||
template="lobo/body.pt"
|
template="lobo/body.pt"
|
||||||
permission="zope.Public" />
|
permission="zope.Public" />
|
||||||
|
|
||||||
|
<page name="controller"
|
||||||
|
for="zope.publisher.interfaces.browser.IBrowserView"
|
||||||
|
class="loops.browser.skin.controller.Controller"
|
||||||
|
permission="zope.Public"
|
||||||
|
layer="loops.browser.skin.Lobo" />
|
||||||
|
|
||||||
<resource name="loops.css" file="lobo/lobo.css"
|
<resource name="loops.css" file="lobo/lobo.css"
|
||||||
layer="loops.browser.skin.Lobo" />
|
layer="loops.browser.skin.Lobo" />
|
||||||
<resource name="print.css" file="lobo/print.css"
|
<resource name="print.css" file="lobo/print.css"
|
||||||
|
|
47
browser/skin/controller.py
Normal file
47
browser/skin/controller.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#-*- coding: UTF-8 -*-
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
View controller for the FuFo skin.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cybertools.browser.blue.controller import Controller as BaseController
|
||||||
|
|
||||||
|
|
||||||
|
metaTagNames = ('keywords', 'description', 'google-site-verification')
|
||||||
|
|
||||||
|
|
||||||
|
class Controller(BaseController):
|
||||||
|
|
||||||
|
def __init__(self, context, request):
|
||||||
|
super(Controller, self).__init__(context, request)
|
||||||
|
self.setupMetadata()
|
||||||
|
|
||||||
|
def setupMetadata(self):
|
||||||
|
macros = self.macros
|
||||||
|
target = self.view.virtualTarget
|
||||||
|
if target is not None:
|
||||||
|
desc = target.dcDescription
|
||||||
|
if desc:
|
||||||
|
for line in desc.splitlines():
|
||||||
|
if ':' in line:
|
||||||
|
name, value = line.split(':')
|
||||||
|
if name in metaTagNames:
|
||||||
|
macros.register('meta', name, metaName=name,
|
||||||
|
metaContent=value)
|
|
@ -2,7 +2,9 @@
|
||||||
<div tal:attributes="ondblclick python: item.openEditWindow('edit.html')">
|
<div tal:attributes="ondblclick python: item.openEditWindow('edit.html')">
|
||||||
<tal:actions condition="view/showObjectActions">
|
<tal:actions condition="view/showObjectActions">
|
||||||
<div metal:use-macro="views/node_macros/object_actions" /></tal:actions>
|
<div metal:use-macro="views/node_macros/object_actions" /></tal:actions>
|
||||||
<h1 tal:content="item/title">Title</h1><br />
|
<h1><a tal:omit-tag="python: level > 1"
|
||||||
|
tal:attributes="href request/URL"
|
||||||
|
tal:content="item/title">Title</a></h1><br />
|
||||||
<p tal:define="url python: view.getUrlForTarget(item)">
|
<p tal:define="url python: view.getUrlForTarget(item)">
|
||||||
<a tal:omit-tag="view/isAnonymous"
|
<a tal:omit-tag="view/isAnonymous"
|
||||||
tal:attributes="href string:${url}/view?version=this"><img
|
tal:attributes="href string:${url}/view?version=this"><img
|
||||||
|
|
|
@ -138,10 +138,12 @@ class MemberRegistration(NodeView, CreateForm):
|
||||||
return True
|
return True
|
||||||
login = form.get('loginName')
|
login = form.get('loginName')
|
||||||
regMan = IMemberRegistrationManager(self.context.getLoopsRoot())
|
regMan = IMemberRegistrationManager(self.context.getLoopsRoot())
|
||||||
|
phoneNumbers = [x.strip()
|
||||||
|
for x in (form.get('phoneNumbers') or u'').split('\n')]
|
||||||
result = regMan.register(login, pw,
|
result = regMan.register(login, pw,
|
||||||
form.get('lastName'), form.get('firstName'),
|
form.get('lastName'), form.get('firstName'),
|
||||||
email=form.get('email'),
|
email=form.get('email'),
|
||||||
phoneNumbers=form.get('phoneNumbers'))
|
phoneNumbers=[x for x in phoneNumbers if x])
|
||||||
if isinstance(result, dict):
|
if isinstance(result, dict):
|
||||||
fi = formState.fieldInstances[result['fieldName']]
|
fi = formState.fieldInstances[result['fieldName']]
|
||||||
fi.setError(result['error'], self.formErrors)
|
fi.setError(result['error'], self.formErrors)
|
||||||
|
|
32
table.py
32
table.py
|
@ -21,14 +21,15 @@ Data (keyword-based) table definition and implementation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from BTrees.OOBTree import OOBTree
|
from BTrees.OOBTree import OOBTree
|
||||||
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope import component, schema
|
from zope import component, schema
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.interface import implements, Interface, Attribute
|
from zope.interface import implements, Interface, Attribute
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.schema.interfaces import IContextSourceBinder, IIterableSource
|
||||||
|
|
||||||
from cybertools.composer.schema.factory import SchemaFactory
|
from cybertools.composer.schema.factory import SchemaFactory
|
||||||
from cybertools.composer.schema.grid.interfaces import KeyTable
|
from cybertools.composer.schema.grid.interfaces import KeyTable
|
||||||
from loops.common import AdapterBase
|
from loops.common import AdapterBase, adapted, baseObject
|
||||||
from loops.interfaces import IConcept, IConceptSchema, ILoopsAdapter
|
from loops.interfaces import IConcept, IConceptSchema, ILoopsAdapter
|
||||||
from loops.type import TypeInterfaceSourceList
|
from loops.type import TypeInterfaceSourceList
|
||||||
from loops import util
|
from loops import util
|
||||||
|
@ -101,3 +102,30 @@ class DataTableSchemaFactory(SchemaFactory):
|
||||||
schema.fields.remove('viewName')
|
schema.fields.remove('viewName')
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
|
||||||
|
class DataTableSourceBinder(object):
|
||||||
|
|
||||||
|
implements(IContextSourceBinder)
|
||||||
|
|
||||||
|
def __init__(self, tableName):
|
||||||
|
self.tableName = tableName
|
||||||
|
|
||||||
|
def __call__(self, context):
|
||||||
|
context = baseObject(context)
|
||||||
|
dt = context.getLoopsRoot().getConceptManager()[self.tableName]
|
||||||
|
return DataTableSourceList(adapted(dt))
|
||||||
|
|
||||||
|
|
||||||
|
class DataTableSourceList(object):
|
||||||
|
|
||||||
|
implements(IIterableSource)
|
||||||
|
|
||||||
|
def __init__(self, context):
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
items = [(k, v[0]) for k, v in self.context.data.items()]
|
||||||
|
return iter(sorted(items, key=lambda x: x[1]))
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.context.data)
|
||||||
|
|
Loading…
Add table
Reference in a new issue