merge branch master

This commit is contained in:
Helmut Merz 2013-11-16 13:19:01 +01:00
commit 3a332b368c
23 changed files with 208 additions and 91 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
*.pydevproject *.pydevproject
*.sublime-project *.sublime-project
*.sublime-workspace *.sublime-workspace
.settings

View file

@ -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.

View file

@ -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,

View file

@ -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
View file

View 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"

View file

@ -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" />&nbsp;</tal:break> <br style="clear: both" />&nbsp;</tal:break>

View file

@ -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>

View file

@ -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))

View file

@ -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>&nbsp;</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>

View file

@ -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%;

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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.'):]

View file

@ -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>

View file

@ -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)

View file

@ -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)

View file

@ -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>

View file

@ -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

View file

@ -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'])

View file

@ -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']

View file

@ -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>