merge branch master
This commit is contained in:
commit
3a332b368c
23 changed files with 208 additions and 91 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@
|
||||||
*.pydevproject
|
*.pydevproject
|
||||||
*.sublime-project
|
*.sublime-project
|
||||||
*.sublime-workspace
|
*.sublime-workspace
|
||||||
|
.settings
|
||||||
|
|
|
@ -52,6 +52,7 @@ from zope.traversing.browser import absoluteURL
|
||||||
from zope.traversing.api import getName, getParent, traverse
|
from zope.traversing.api import getName, getParent, traverse
|
||||||
|
|
||||||
from cybertools.ajax.dojo import dojoMacroTemplate
|
from cybertools.ajax.dojo import dojoMacroTemplate
|
||||||
|
from cybertools.browser.action import actions
|
||||||
from cybertools.browser.view import GenericView
|
from cybertools.browser.view import GenericView
|
||||||
from cybertools.meta.interfaces import IOptions
|
from cybertools.meta.interfaces import IOptions
|
||||||
from cybertools.meta.element import Element
|
from cybertools.meta.element import Element
|
||||||
|
@ -617,7 +618,6 @@ class BaseView(GenericView, I18NView):
|
||||||
for opt in (self.options, self.typeOptions, self.globalOptions):
|
for opt in (self.options, self.typeOptions, self.globalOptions):
|
||||||
if isinstance(opt, DummyOptions):
|
if isinstance(opt, DummyOptions):
|
||||||
continue
|
continue
|
||||||
#import pdb; pdb.set_trace()
|
|
||||||
v = opt
|
v = opt
|
||||||
for key in keys.split('.'):
|
for key in keys.split('.'):
|
||||||
if isinstance(v, list):
|
if isinstance(v, list):
|
||||||
|
@ -706,22 +706,37 @@ class BaseView(GenericView, I18NView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def states(self):
|
def states(self):
|
||||||
|
return self.getStates()
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def allStates(self):
|
||||||
|
return self.getStates(False)
|
||||||
|
|
||||||
|
def getStates(self, forDisplay=True):
|
||||||
result = []
|
result = []
|
||||||
if not checkPermission(self.viewStatesPermission, self.context):
|
if forDisplay and not checkPermission(self.viewStatesPermission, self.context):
|
||||||
|
# do not display state information
|
||||||
return result
|
return result
|
||||||
if IResource.providedBy(self.target):
|
if IResource.providedBy(self.target):
|
||||||
statesDefs = self.globalOptions('organize.stateful.resource', ())
|
statesDefs = (self.globalOptions('organize.stateful.resource') or [])
|
||||||
else:
|
else:
|
||||||
typeOptions = self.typeOptions('organize.stateful')
|
statesDefs = (self.globalOptions('organize.stateful.concept') or [])
|
||||||
if typeOptions is None:
|
statesDefs += (self.typeOptions('organize.stateful') or [])
|
||||||
typeOptions = []
|
|
||||||
statesDefs = (self.globalOptions('organize.stateful.concept', []) +
|
|
||||||
typeOptions)
|
|
||||||
for std in statesDefs:
|
for std in statesDefs:
|
||||||
stf = component.getAdapter(self.target, IStateful, name=std)
|
stf = component.getAdapter(self.target, IStateful, name=std)
|
||||||
result.append(stf)
|
result.append(stf)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def checkState(self):
|
||||||
|
if not self.allStates:
|
||||||
|
return True
|
||||||
|
for stf in self.allStates:
|
||||||
|
option = self.globalOptions(
|
||||||
|
'organize.stateful.restrict.' + stf.statesDefinition)
|
||||||
|
if option:
|
||||||
|
return stf.state in option
|
||||||
|
return True
|
||||||
|
|
||||||
# controlling actions and editing
|
# controlling actions and editing
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -732,10 +747,21 @@ class BaseView(GenericView, I18NView):
|
||||||
""" Return a list of actions that provide the view and edit actions
|
""" Return a list of actions that provide the view and edit actions
|
||||||
available for the context object.
|
available for the context object.
|
||||||
"""
|
"""
|
||||||
actions = []
|
acts = []
|
||||||
|
optKey = 'action.' + category
|
||||||
|
actNames = (self.options(optKey) or []) + (self.typeOptions(optKey) or [])
|
||||||
|
if actNames:
|
||||||
|
acts = list(actions.get(category, actNames,
|
||||||
|
view=self, page=page, target=target))
|
||||||
if category in self.actions:
|
if category in self.actions:
|
||||||
actions.extend(self.actions[category](self, page=page, target=target))
|
acts.extend(self.actions[category](self, page, target))
|
||||||
return actions
|
optKey = 'append_action.' + category
|
||||||
|
actNames = (self.options(optKey) or []) + (self.typeOptions(optKey) or [])
|
||||||
|
if actNames:
|
||||||
|
acts.extend(list(actions.get(category, actNames,
|
||||||
|
view=self, page=page, target=target)))
|
||||||
|
return acts
|
||||||
|
|
||||||
|
|
||||||
def getAdditionalActions(self, category='object', page=None, target=None):
|
def getAdditionalActions(self, category='object', page=None, target=None):
|
||||||
""" Provide additional actions; override by subclass.
|
""" Provide additional actions; override by subclass.
|
||||||
|
|
|
@ -535,17 +535,6 @@ class ConceptView(BaseView):
|
||||||
for node in self.context.getClients():
|
for node in self.context.getClients():
|
||||||
yield NodeView(node, self.request)
|
yield NodeView(node, self.request)
|
||||||
|
|
||||||
def getActions(self, category='object', page=None, target=None):
|
|
||||||
acts = []
|
|
||||||
optKey = 'action.' + category
|
|
||||||
actNames = (self.options(optKey) or []) + (self.typeOptions(optKey) or [])
|
|
||||||
if actNames:
|
|
||||||
acts = list(actions.get(category, actNames,
|
|
||||||
view=self, page=page, target=target))
|
|
||||||
if category in self.actions:
|
|
||||||
acts.extend(self.actions[category](self, page, target))
|
|
||||||
return acts
|
|
||||||
|
|
||||||
def getPortletActions(self, page=None, target=None):
|
def getPortletActions(self, page=None, target=None):
|
||||||
if self.portlet_actions:
|
if self.portlet_actions:
|
||||||
return actions.get('portlet', self.portlet_actions,
|
return actions.get('portlet', self.portlet_actions,
|
||||||
|
|
|
@ -64,10 +64,12 @@
|
||||||
</h1>
|
</h1>
|
||||||
<metal:block use-macro="view/concept_macros/filter_input" />
|
<metal:block use-macro="view/concept_macros/filter_input" />
|
||||||
</metal:title>
|
</metal:title>
|
||||||
<p metal:define-macro="conceptdescription"
|
<metal:desc define-macro="conceptdescription"
|
||||||
tal:define="description description|item/renderedDescription"
|
tal:define="description description|item/renderedDescription"
|
||||||
tal:condition="description">
|
tal:condition="description">
|
||||||
<i tal:content="structure description">Description</i></p>
|
<div class="description"
|
||||||
|
tal:content="structure description">Description</div>
|
||||||
|
</metal:desc>
|
||||||
</metal:title>
|
</metal:title>
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,7 +132,8 @@
|
||||||
<metal:children define-macro="conceptchildren">
|
<metal:children define-macro="conceptchildren">
|
||||||
<div tal:attributes="class string:content-$level;
|
<div tal:attributes="class string:content-$level;
|
||||||
ondblclick python: item.openEditWindow('configure.html')"
|
ondblclick python: item.openEditWindow('configure.html')"
|
||||||
tal:define="children python: list(item.unique(item.children()))"
|
tal:define="list_nested request/list_nested|nothing;
|
||||||
|
children children|python:list(item.unique(item.children()))"
|
||||||
tal:condition="children">
|
tal:condition="children">
|
||||||
<h2 i18n:translate=""
|
<h2 i18n:translate=""
|
||||||
tal:condition="show_headline|python:True">Children</h2>
|
tal:condition="show_headline|python:True">Children</h2>
|
||||||
|
@ -163,7 +166,7 @@
|
||||||
<td valign="top">
|
<td valign="top">
|
||||||
<a tal:attributes="href python: view.getUrlForTarget(related);
|
<a tal:attributes="href python: view.getUrlForTarget(related);
|
||||||
title related/relationInfo">
|
title related/relationInfo">
|
||||||
<span tal:replace="related/title">Resource Title</span>
|
<span tal:replace="related/title">Concept Title</span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="center"><span tal:content="related/typeTitle"
|
<td class="center"><span tal:content="related/typeTitle"
|
||||||
|
@ -180,6 +183,14 @@
|
||||||
tal:attributes="value related/uidToken" />
|
tal:attributes="value related/uidToken" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr tal:define="children python:list(related.unique(related.children()));
|
||||||
|
resources python:list(related.resources())"
|
||||||
|
tal:condition="python:list_nested and (children or resources)">
|
||||||
|
<td tal:condition="item/showCheckboxes|nothing" />
|
||||||
|
<td colspan="5">
|
||||||
|
<metal:list use-macro="item/template/macros/list_nested" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tal:item>
|
</tal:item>
|
||||||
</tal:items>
|
</tal:items>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -321,6 +332,20 @@
|
||||||
</metal:listing>
|
</metal:listing>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:listing define-macro="list_nested">
|
||||||
|
<div style="margin-left: 20px"
|
||||||
|
tal:define="item nocall:related;
|
||||||
|
level python:level + 1">
|
||||||
|
<tal:children condition="children">
|
||||||
|
<metal:list use-macro="item/template/macros/conceptchildren" />
|
||||||
|
</tal:children>
|
||||||
|
<tal:resources condition="resources">
|
||||||
|
<metal:list use-macro="item/template/macros/conceptresources" />
|
||||||
|
</tal:resources>
|
||||||
|
</div>
|
||||||
|
</metal:listing>
|
||||||
|
|
||||||
|
|
||||||
<!-- portlets -->
|
<!-- portlets -->
|
||||||
|
|
||||||
<metal:actions define-macro="parents">
|
<metal:actions define-macro="parents">
|
||||||
|
|
0
browser/form.py
Normal file → Executable file
0
browser/form.py
Normal file → Executable file
|
@ -318,7 +318,8 @@
|
||||||
<metal:buttons define-slot="buttons">
|
<metal:buttons define-slot="buttons">
|
||||||
<input value="Save" type="submit"
|
<input value="Save" type="submit"
|
||||||
i18n:attributes="value"
|
i18n:attributes="value"
|
||||||
tal:attributes="onClick python: view.closeAction(True) or
|
tal:attributes="value view/label_submit | string:Save;
|
||||||
|
onClick python: view.closeAction(True) or
|
||||||
'submit();; return false'">
|
'submit();; return false'">
|
||||||
<input type="button" value="Cancel" onClick="dlg.hide();"
|
<input type="button" value="Cancel" onClick="dlg.hide();"
|
||||||
i18n:attributes="value"
|
i18n:attributes="value"
|
||||||
|
|
|
@ -72,7 +72,8 @@
|
||||||
</tal:image>
|
</tal:image>
|
||||||
<div tal:condition="cell/renderedTextDescription"
|
<div tal:condition="cell/renderedTextDescription"
|
||||||
tal:attributes="class python:part.cssClass[1]">
|
tal:attributes="class python:part.cssClass[1]">
|
||||||
<span tal:content="structure cell/renderedTextDescription" />
|
<span class="description"
|
||||||
|
tal:content="structure cell/renderedTextDescription" />
|
||||||
</div>
|
</div>
|
||||||
<tal:break condition="python:part.showImage and cell.img">
|
<tal:break condition="python:part.showImage and cell.img">
|
||||||
<br style="clear: both" /> </tal:break>
|
<br style="clear: both" /> </tal:break>
|
||||||
|
|
|
@ -319,7 +319,8 @@
|
||||||
i18n:translate="">Log in</a></div>
|
i18n:translate="">Log in</a></div>
|
||||||
<div tal:define="register python:view.globalOptions('provideLogin')"
|
<div tal:define="register python:view.globalOptions('provideLogin')"
|
||||||
tal:condition="register">
|
tal:condition="register">
|
||||||
<a tal:attributes="href python:register[0]"
|
<a tal:condition="python:register != True"
|
||||||
|
tal:attributes="href python:register[0]"
|
||||||
i18n:translate="">Register new member</a></div>
|
i18n:translate="">Register new member</a></div>
|
||||||
</metal:login>
|
</metal:login>
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ from loops.browser.common import EditForm, BaseView
|
||||||
from loops.browser.concept import BaseRelationView, ConceptRelationView
|
from loops.browser.concept import BaseRelationView, ConceptRelationView
|
||||||
from loops.browser.concept import ConceptConfigureView
|
from loops.browser.concept import ConceptConfigureView
|
||||||
from loops.browser.node import NodeView, node_macros
|
from loops.browser.node import NodeView, node_macros
|
||||||
from loops.common import adapted, NameChooser
|
from loops.common import adapted, NameChooser, normalizeName
|
||||||
from loops.interfaces import IBaseResource, IDocument, ITextDocument
|
from loops.interfaces import IBaseResource, IDocument, ITextDocument
|
||||||
from loops.interfaces import IMediaAsset as legacy_IMediaAsset
|
from loops.interfaces import IMediaAsset as legacy_IMediaAsset
|
||||||
from loops.interfaces import ITypeConcept
|
from loops.interfaces import ITypeConcept
|
||||||
|
@ -214,7 +214,8 @@ class ResourceView(BaseView):
|
||||||
if self.typeOptions('no_normalize_download_filename'):
|
if self.typeOptions('no_normalize_download_filename'):
|
||||||
filename = '"%s"' % filename
|
filename = '"%s"' % filename
|
||||||
else:
|
else:
|
||||||
filename = NameChooser(getParent(self.context)).normalizeName(filename)
|
#filename = NameChooser(getParent(self.context)).normalizeName(filename)
|
||||||
|
filename = normalizeName(filename)
|
||||||
response.setHeader('Content-Disposition',
|
response.setHeader('Content-Disposition',
|
||||||
'attachment; filename=%s' % filename)
|
'attachment; filename=%s' % filename)
|
||||||
response.setHeader('Content-Length', len(data))
|
response.setHeader('Content-Length', len(data))
|
||||||
|
|
|
@ -12,9 +12,11 @@
|
||||||
<h1><a tal:omit-tag="python: level > 1"
|
<h1><a tal:omit-tag="python: level > 1"
|
||||||
tal:attributes="href request/URL"
|
tal:attributes="href request/URL"
|
||||||
tal:content="item/title">Title</a></h1>
|
tal:content="item/title">Title</a></h1>
|
||||||
<p tal:define="description description|item/renderedDescription"
|
<tal:desc define="description description|item/renderedDescription"
|
||||||
tal:condition="description">
|
condition="description">
|
||||||
<i tal:content="structure description">Description</i></p>
|
<div class="description"
|
||||||
|
tal:content="structure description">Description</div>
|
||||||
|
</tal:desc>
|
||||||
<metal:fields define-slot="fields" />
|
<metal:fields define-slot="fields" />
|
||||||
<div class="content-1" id="1.body"
|
<div class="content-1" id="1.body"
|
||||||
tal:attributes="id id;"
|
tal:attributes="id id;"
|
||||||
|
@ -53,7 +55,8 @@
|
||||||
tal:content="item/title">Title</a></h1><br />
|
tal:content="item/title">Title</a></h1><br />
|
||||||
<img tal:attributes="src
|
<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>
|
<div class="description"
|
||||||
|
tal:content="structure item/renderedDescription">Description</div>
|
||||||
<metal:fields use-macro="view/comment_macros/comments" />
|
<metal:fields use-macro="view/comment_macros/comments" />
|
||||||
</div>
|
</div>
|
||||||
</metal:block>
|
</metal:block>
|
||||||
|
@ -63,8 +66,10 @@
|
||||||
<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>
|
<h1 tal:content="item/title">Title</h1>
|
||||||
<p><i tal:content="structure item/renderedDescription">Description</i> </p>
|
<div class="description"
|
||||||
<p>
|
tal:content="structure item/renderedDescription">Description</div>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
<span class="button">
|
<span class="button">
|
||||||
<a i18n:translate=""
|
<a i18n:translate=""
|
||||||
tal:attributes="href
|
tal:attributes="href
|
||||||
|
@ -90,7 +95,7 @@
|
||||||
Open for editing
|
Open for editing
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</div>
|
||||||
<metal:fields use-macro="view/comment_macros/comments" />
|
<metal:fields use-macro="view/comment_macros/comments" />
|
||||||
</div>
|
</div>
|
||||||
</metal:block>
|
</metal:block>
|
||||||
|
|
|
@ -22,10 +22,6 @@ body {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.head-description, .legend {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.view-modes {
|
ul.view-modes {
|
||||||
padding: 0 0 0 2em;
|
padding: 0 0 0 2em;
|
||||||
margin: 0.7em 0 0 0;
|
margin: 0.7em 0 0 0;
|
||||||
|
@ -118,12 +114,23 @@ thead th {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.head-description{
|
||||||
|
/* font-style: italic; */
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
font-style: italic;
|
/* font-style: italic; */
|
||||||
/* margin-top: 0.5em;*/
|
/* margin-top: 0.5em;*/
|
||||||
|
font-size: 110%;
|
||||||
margin-bottom: 0.3em;
|
margin-bottom: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
/* font-style: italic; */
|
||||||
|
font-size: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
.infotext {
|
.infotext {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
@ -302,6 +309,10 @@ fieldset.box td {
|
||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nested {
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
.content-1 h1, h1 {
|
.content-1 h1, h1 {
|
||||||
padding-top: 0.5em;
|
padding-top: 0.5em;
|
||||||
font-size: 180%;
|
font-size: 180%;
|
||||||
|
|
|
@ -257,7 +257,7 @@ def normalizeName(baseName):
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
result.append('_')
|
result.append('_')
|
||||||
continue
|
continue
|
||||||
if c in '._':
|
if c in '._-':
|
||||||
# separator and special characters to keep
|
# separator and special characters to keep
|
||||||
result.append(c)
|
result.append(c)
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -95,6 +95,11 @@ class Base(object):
|
||||||
if self.editable:
|
if self.editable:
|
||||||
return 'index.html'
|
return 'index.html'
|
||||||
|
|
||||||
|
def children(self):
|
||||||
|
for c in self.getChildren():
|
||||||
|
if c.checkState():
|
||||||
|
yield c
|
||||||
|
|
||||||
def getResources(self):
|
def getResources(self):
|
||||||
relViews = super(Base, self).getResources()
|
relViews = super(Base, self).getResources()
|
||||||
return relViews
|
return relViews
|
||||||
|
@ -106,9 +111,10 @@ class Base(object):
|
||||||
idx = 0
|
idx = 0
|
||||||
for rv in self.getResources():
|
for rv in self.getResources():
|
||||||
if rv.context.contentType.startswith('text/'):
|
if rv.context.contentType.startswith('text/'):
|
||||||
idx += 1
|
if rv.checkState():
|
||||||
result.append(rv)
|
idx += 1
|
||||||
self.images.append([])
|
result.append(rv)
|
||||||
|
self.images.append([])
|
||||||
else:
|
else:
|
||||||
self.registerDojoLightbox()
|
self.registerDojoLightbox()
|
||||||
url = self.nodeView.getUrlForTarget(rv.context)
|
url = self.nodeView.getUrlForTarget(rv.context)
|
||||||
|
@ -130,7 +136,8 @@ class Base(object):
|
||||||
return IOptions(adapted(dt))(name)
|
return IOptions(adapted(dt))(name)
|
||||||
|
|
||||||
def getTitleForResource(self, r):
|
def getTitleForResource(self, r):
|
||||||
if self.getOptionsForResource(r, 'showtitle'):
|
if (IOptions(adapted(r.context.resourceType))('show_title_in_section') or
|
||||||
|
self.getOptionsForResource(r, 'show_title_in_section')):
|
||||||
return r.title
|
return r.title
|
||||||
|
|
||||||
def getIconForResource(self, r):
|
def getIconForResource(self, r):
|
||||||
|
@ -152,7 +159,9 @@ class Base(object):
|
||||||
|
|
||||||
def getParentsForResource(self, r):
|
def getParentsForResource(self, r):
|
||||||
for c in r.context.getConcepts([self.defaultPredicate]):
|
for c in r.context.getConcepts([self.defaultPredicate]):
|
||||||
if c != self.context and c.conceptType != self.documentTypeType:
|
if (c != self.context and
|
||||||
|
c.conceptType != self.documentTypeType and
|
||||||
|
self.getViewForObject(c).checkState()):
|
||||||
yield c
|
yield c
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,43 @@
|
||||||
<html i18n:domain="loops">
|
<html i18n:domain="loops">
|
||||||
|
|
||||||
|
|
||||||
<metal:children define-macro="children">
|
<metal:children define-macro="children"
|
||||||
<div tal:repeat="related item/children"
|
tal:define="children children|python:list(item.children())">
|
||||||
tal:define="level python:level + 1"
|
<tal:child repeat="related children">
|
||||||
tal:attributes="class string:content-$level">
|
<div tal:define="children python:list(related.children());
|
||||||
<h3>
|
resources python:list(related.resources());
|
||||||
<a tal:attributes="href python:view.getUrlForTarget(related)"
|
hideEmpty python:item.getOptions('hide_empty_children');
|
||||||
tal:content="related/title" />
|
level python:level + 1"
|
||||||
</h3>
|
tal:condition="python:not hideEmpty or children or resources"
|
||||||
<div tal:content="structure related/renderedDescription" />
|
tal:attributes="class string:content-$level">
|
||||||
<!-- TODO: show next level (+/-) -->
|
<h3><a tal:attributes="href python:view.getUrlForTarget(related)"
|
||||||
</div>
|
tal:content="related/title" />
|
||||||
|
</h3>
|
||||||
|
<div class="description"
|
||||||
|
tal:content="structure related/renderedDescription" />
|
||||||
|
<tal:nested condition="python:related.getOptions('show_nested_children')">
|
||||||
|
<metal:children use-macro="item/book_macros/nested_children" />
|
||||||
|
</tal:nested>
|
||||||
|
</div>
|
||||||
|
</tal:child>
|
||||||
</metal:children>
|
</metal:children>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:nested define-macro="nested_children"
|
||||||
|
tal:define="children children|python:list(item.children())">
|
||||||
|
<tal:child repeat="related children">
|
||||||
|
<div tal:define="level python:level + 1"
|
||||||
|
tal:attributes="class string:nested content-$level">
|
||||||
|
<h3>
|
||||||
|
<a tal:attributes="href python:view.getUrlForTarget(related)"
|
||||||
|
tal:content="related/title" />
|
||||||
|
</h3>
|
||||||
|
<div tal:content="structure related/renderedDescription" />
|
||||||
|
</div>
|
||||||
|
</tal:child>
|
||||||
|
</metal:nested>
|
||||||
|
|
||||||
|
|
||||||
<metal:book define-macro="book">
|
<metal:book define-macro="book">
|
||||||
<metal:info use-macro="view/concept_macros/concepttitle" />
|
<metal:info use-macro="view/concept_macros/concepttitle" />
|
||||||
<metal:info use-macro="item/book_macros/children" />
|
<metal:info use-macro="item/book_macros/children" />
|
||||||
|
@ -30,12 +54,13 @@
|
||||||
tal:attributes="href pred/targetUrl;
|
tal:attributes="href pred/targetUrl;
|
||||||
title pred/title">
|
title pred/title">
|
||||||
<img src="/@@/cybertools.icons/arrow_left.png" /></a>
|
<img src="/@@/cybertools.icons/arrow_left.png" /></a>
|
||||||
<a tal:attributes="href parent/targetUrl;
|
<a tal:condition="nocall:parent"
|
||||||
title parent/title">
|
tal:attributes="href parent/targetUrl;
|
||||||
|
title parent/title">
|
||||||
<img src="/@@/cybertools.icons/arrow_up.png" /></a>
|
<img src="/@@/cybertools.icons/arrow_up.png" /></a>
|
||||||
<a tal:condition="nocall:succ"
|
<a tal:condition="nocall:succ"
|
||||||
tal:attributes="href succ/targetUrl;
|
tal:attributes="href succ/targetUrl;
|
||||||
title succ/title">
|
title succ/title">
|
||||||
<img src="/@@/cybertools.icons/arrow_right.png" /></a>
|
<img src="/@@/cybertools.icons/arrow_right.png" /></a>
|
||||||
</div>
|
</div>
|
||||||
</metal:navigation>
|
</metal:navigation>
|
||||||
|
@ -103,15 +128,17 @@
|
||||||
</metal:section>
|
</metal:section>
|
||||||
|
|
||||||
|
|
||||||
<metal:topic define-macro="topic">
|
<metal:topic define-macro="topic"
|
||||||
|
tal:define="children children|python:list(item.children());
|
||||||
|
textResources textResources|item/textResources">
|
||||||
<metal:info use-macro="view/concept_macros/concepttitle" />
|
<metal:info use-macro="view/concept_macros/concepttitle" />
|
||||||
<h2 i18n:translate=""
|
<h2 i18n:translate=""
|
||||||
tal:condition="python: list(item.children())">Children</h2>
|
tal:condition="children">Children</h2>
|
||||||
<metal:children use-macro="item/book_macros/children" />
|
<metal:children use-macro="item/book_macros/children" />
|
||||||
<h2 i18n:translate=""
|
<h2 i18n:translate=""
|
||||||
tal:condition="item/textResources">Text Elements</h2>
|
tal:condition="textResources">Text Elements</h2>
|
||||||
<div>
|
<div>
|
||||||
<div tal:repeat="related item/textResources"
|
<div tal:repeat="related textResources"
|
||||||
tal:define="level python:level + 1"
|
tal:define="level python:level + 1"
|
||||||
tal:attributes="class string:content-$level">
|
tal:attributes="class string:content-$level">
|
||||||
<h3>
|
<h3>
|
||||||
|
|
|
@ -70,7 +70,9 @@ class QuickSearchResults(NodeView):
|
||||||
fv = FilterView(self.context, self.request)
|
fv = FilterView(self.context, self.request)
|
||||||
result = fv.apply(result)
|
result = fv.apply(result)
|
||||||
result.sort(key=lambda x: x.title.lower())
|
result.sort(key=lambda x: x.title.lower())
|
||||||
return self.viewIterator(result)
|
for v in self.viewIterator(result):
|
||||||
|
if v.checkState():
|
||||||
|
yield v
|
||||||
|
|
||||||
|
|
||||||
class Search(ConceptView):
|
class Search(ConceptView):
|
||||||
|
@ -257,8 +259,6 @@ class Search(ConceptView):
|
||||||
return self.viewIterator(result)
|
return self.viewIterator(result)
|
||||||
|
|
||||||
def checkStates(self, obj):
|
def checkStates(self, obj):
|
||||||
if not IResource.providedBy(obj):
|
|
||||||
return True
|
|
||||||
for std, states in self.selectedStates.items():
|
for std, states in self.selectedStates.items():
|
||||||
if std.startswith('state.resource.'):
|
if std.startswith('state.resource.'):
|
||||||
std = std[len('state.resource.'):]
|
std = std[len('state.resource.'):]
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
<zope:class class="loops.knowledge.survey.base.Questionnaire">
|
<zope:class class="loops.knowledge.survey.base.Questionnaire">
|
||||||
<require permission="zope.View"
|
<require permission="zope.View"
|
||||||
interface="loops.knowledge.survey.interfaces.IQuestionnaire" />
|
interface="loops.knowledge.survey.interfaces.IQuestionnaire" />
|
||||||
|
<require permission="zope.View"
|
||||||
|
attributes="context" />
|
||||||
<require permission="zope.ManageContent"
|
<require permission="zope.ManageContent"
|
||||||
set_schema="loops.knowledge.survey.interfaces.IQuestionnaire" />
|
set_schema="loops.knowledge.survey.interfaces.IQuestionnaire" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
@ -23,6 +25,8 @@
|
||||||
<zope:class class="loops.knowledge.survey.base.QuestionGroup">
|
<zope:class class="loops.knowledge.survey.base.QuestionGroup">
|
||||||
<require permission="zope.View"
|
<require permission="zope.View"
|
||||||
interface="loops.knowledge.survey.interfaces.IQuestionGroup" />
|
interface="loops.knowledge.survey.interfaces.IQuestionGroup" />
|
||||||
|
<require permission="zope.View"
|
||||||
|
attributes="context" />
|
||||||
<require permission="zope.ManageContent"
|
<require permission="zope.ManageContent"
|
||||||
set_schema="loops.knowledge.survey.interfaces.IQuestionGroup" />
|
set_schema="loops.knowledge.survey.interfaces.IQuestionGroup" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
@ -34,6 +38,8 @@
|
||||||
<zope:class class="loops.knowledge.survey.base.Question">
|
<zope:class class="loops.knowledge.survey.base.Question">
|
||||||
<require permission="zope.View"
|
<require permission="zope.View"
|
||||||
interface="loops.knowledge.survey.interfaces.IQuestion" />
|
interface="loops.knowledge.survey.interfaces.IQuestion" />
|
||||||
|
<require permission="zope.View"
|
||||||
|
attributes="context" />
|
||||||
<require permission="zope.ManageContent"
|
<require permission="zope.ManageContent"
|
||||||
set_schema="loops.knowledge.survey.interfaces.IQuestion" />
|
set_schema="loops.knowledge.survey.interfaces.IQuestion" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
@ -45,6 +51,8 @@
|
||||||
<zope:class class="loops.knowledge.survey.base.FeedbackItem">
|
<zope:class class="loops.knowledge.survey.base.FeedbackItem">
|
||||||
<require permission="zope.View"
|
<require permission="zope.View"
|
||||||
interface="loops.knowledge.survey.interfaces.IFeedbackItem" />
|
interface="loops.knowledge.survey.interfaces.IFeedbackItem" />
|
||||||
|
<require permission="zope.View"
|
||||||
|
attributes="context" />
|
||||||
<require permission="zope.ManageContent"
|
<require permission="zope.ManageContent"
|
||||||
set_schema="loops.knowledge.survey.interfaces.IFeedbackItem" />
|
set_schema="loops.knowledge.survey.interfaces.IFeedbackItem" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2009 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2013 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 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base classes for layout-based views.
|
Base classes for layout-based views.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.app.security.interfaces import IUnauthenticatedPrincipal
|
from zope.app.security.interfaces import IUnauthenticatedPrincipal
|
||||||
|
@ -29,9 +27,11 @@ from zope.proxy import removeAllProxies
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
from zope.traversing.browser import absoluteURL
|
from zope.traversing.browser import absoluteURL
|
||||||
|
|
||||||
|
from cybertools.meta.interfaces import IOptions
|
||||||
from cybertools.util import format
|
from cybertools.util import format
|
||||||
from loops.common import adapted
|
from loops.common import adapted, baseObject
|
||||||
from loops.i18n.browser import LanguageInfo
|
from loops.i18n.browser import LanguageInfo
|
||||||
|
from loops.browser.concept import ConceptView as BaseConceptView
|
||||||
from loops.browser.util import normalizeForUrl as normalize
|
from loops.browser.util import normalizeForUrl as normalize
|
||||||
from loops import util
|
from loops import util
|
||||||
|
|
||||||
|
@ -74,6 +74,10 @@ class BaseView(object):
|
||||||
def virtualTargetView(self):
|
def virtualTargetView(self):
|
||||||
return self.viewAnnotations.get('targetView')
|
return self.viewAnnotations.get('targetView')
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def baseConceptView(self):
|
||||||
|
return BaseConceptView(baseObject(self.context), self.request)
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def node(self):
|
def node(self):
|
||||||
return self.viewAnnotations.get('node')
|
return self.viewAnnotations.get('node')
|
||||||
|
@ -170,3 +174,7 @@ class BaseView(object):
|
||||||
def getMetaDescription(self):
|
def getMetaDescription(self):
|
||||||
return self.context.title
|
return self.context.title
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def globalOptions(self):
|
||||||
|
return IOptions(self.loopsRoot)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2013 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 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Layout node views.
|
Layout node views.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.app.security.interfaces import IUnauthenticatedPrincipal
|
from zope.app.security.interfaces import IUnauthenticatedPrincipal
|
||||||
|
@ -63,9 +61,12 @@ class LayoutNodeView(Page, BaseView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def headTitle(self):
|
def headTitle(self):
|
||||||
|
parts = [self.context.title]
|
||||||
if self.target is not None:
|
if self.target is not None:
|
||||||
targetView = component.getMultiAdapter((self.target, self.request),
|
targetView = component.getMultiAdapter((self.target, self.request),
|
||||||
name='layout')
|
name='layout')
|
||||||
return ' - '.join((self.context.title, targetView.title))
|
if targetView.title not in parts:
|
||||||
else:
|
parts.append(targetView.title)
|
||||||
return self.context.title
|
if self.globalOptions('reverseHeadTitle'):
|
||||||
|
parts.reverse()
|
||||||
|
return ' - '.join(parts)
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
tal:attributes="src
|
tal:attributes="src
|
||||||
string:${url}/@@mediaasset.html?version=this&v=medium" /></a>
|
string:${url}/@@mediaasset.html?version=this&v=medium" /></a>
|
||||||
</p>
|
</p>
|
||||||
<p><i tal:content="structure item/renderedDescription">Description</i></p>
|
<div class="description"
|
||||||
|
tal:content="structure item/renderedDescription">Description</div>
|
||||||
<metal:fields use-macro="view/comment_macros/comments" />
|
<metal:fields use-macro="view/comment_macros/comments" />
|
||||||
</div>
|
</div>
|
||||||
</metal:block>
|
</metal:block>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2013 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
|
||||||
|
@ -20,17 +20,16 @@
|
||||||
Views for displaying media assets.
|
Views for displaying media assets.
|
||||||
|
|
||||||
Authors: Johann Schimpf, Erich Seifert.
|
Authors: Johann Schimpf, Erich Seifert.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.security.interfaces import Unauthorized
|
from zope.security.interfaces import Unauthorized
|
||||||
|
from zope.traversing.api import getParent
|
||||||
|
|
||||||
from loops.browser.node import NodeView
|
from loops.browser.node import NodeView
|
||||||
from loops.browser.resource import ResourceView, resource_macros
|
from loops.browser.resource import ResourceView, resource_macros
|
||||||
from loops.common import adapted
|
from loops.common import adapted, normalizeName
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
from loops import util
|
from loops import util
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ class MediaAssetView(ResourceView):
|
||||||
if useAttachment:
|
if useAttachment:
|
||||||
filename = obj.localFilename or getName(self.context)
|
filename = obj.localFilename or getName(self.context)
|
||||||
#filename = urllib.quote(filename)
|
#filename = urllib.quote(filename)
|
||||||
filename = NameChooser(getParent(self.context)).normalizeName(filename)
|
filename = normalizeName(filename)
|
||||||
response.setHeader('Content-Disposition',
|
response.setHeader('Content-Disposition',
|
||||||
'attachment; filename=%s' % filename)
|
'attachment; filename=%s' % filename)
|
||||||
return data
|
return data
|
||||||
|
|
|
@ -112,7 +112,8 @@ class BaseMemberRegistration(NodeView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
return schema_macros.macros['form']
|
#return schema_macros.macros['form']
|
||||||
|
return organize_macros.macros['register']
|
||||||
|
|
||||||
def checkPermissions(self):
|
def checkPermissions(self):
|
||||||
personType = adapted(self.conceptManager['person'])
|
personType = adapted(self.conceptManager['person'])
|
||||||
|
|
|
@ -253,7 +253,8 @@ class BaseWorkItemsView(object):
|
||||||
tsTo += 3600 * 24 - 1 # include full end date
|
tsTo += 3600 * 24 - 1 # include full end date
|
||||||
if tsFrom or tsTo:
|
if tsFrom or tsTo:
|
||||||
result['timeFromTo'] = (tsFrom, tsTo)
|
result['timeFromTo'] = (tsFrom, tsTo)
|
||||||
state = form.get('wi_state') or self.options.wi_state
|
state = (form.get('wi_state') or
|
||||||
|
self.options.wi_state or self.typeOptions.wi_state)
|
||||||
if not state:
|
if not state:
|
||||||
result['state'] = ['planned', 'accepted', 'running', 'done',
|
result['state'] = ['planned', 'accepted', 'running', 'done',
|
||||||
'done_x', 'finished', 'delegated', 'moved', 'cancelled']
|
'done_x', 'finished', 'delegated', 'moved', 'cancelled']
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
<li><a tal:attributes="href row/url"
|
<li><a tal:attributes="href row/url"
|
||||||
tal:content="row/title">My Site</a>
|
tal:content="row/title">My Site</a>
|
||||||
<tal:description condition="row/description"><br />
|
<tal:description condition="row/description"><br />
|
||||||
<i tal:content="structure row/renderedDescription" />
|
<div class="description"
|
||||||
|
tal:content="structure row/renderedDescription" />
|
||||||
</tal:description>
|
</tal:description>
|
||||||
</li>
|
</li>
|
||||||
</tal:site>
|
</tal:site>
|
||||||
|
|
Loading…
Add table
Reference in a new issue