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