Merge branch 'master' into bbmaster
This commit is contained in:
commit
3132fc9947
6 changed files with 91 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2012 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
|
||||||
|
@ -58,6 +58,7 @@ from cybertools.relation.interfaces import IRelationRegistry
|
||||||
from cybertools.stateful.interfaces import IStateful
|
from cybertools.stateful.interfaces import IStateful
|
||||||
from cybertools.text import mimetypes
|
from cybertools.text import mimetypes
|
||||||
from cybertools.typology.interfaces import IType, ITypeManager
|
from cybertools.typology.interfaces import IType, ITypeManager
|
||||||
|
from cybertools.util.jeep import Jeep
|
||||||
from loops.browser.util import normalizeForUrl
|
from loops.browser.util import normalizeForUrl
|
||||||
from loops.common import adapted, baseObject
|
from loops.common import adapted, baseObject
|
||||||
from loops.config.base import DummyOptions
|
from loops.config.base import DummyOptions
|
||||||
|
@ -74,7 +75,7 @@ from loops.versioning.interfaces import IVersionable
|
||||||
|
|
||||||
|
|
||||||
concept_macros = ViewPageTemplateFile('concept_macros.pt')
|
concept_macros = ViewPageTemplateFile('concept_macros.pt')
|
||||||
conceptMacrosTemplate = concept_macros #
|
conceptMacrosTemplate = concept_macros
|
||||||
resource_macros = ViewPageTemplateFile('resource_macros.pt')
|
resource_macros = ViewPageTemplateFile('resource_macros.pt')
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,14 +85,28 @@ class NameField(schema.ASCIILine):
|
||||||
super(NameField, self)._validate(value)
|
super(NameField, self)._validate(value)
|
||||||
|
|
||||||
|
|
||||||
|
class ViewMode(object):
|
||||||
|
|
||||||
|
def __init__(self, name='view', title=None, url=None, active=False,
|
||||||
|
description=u''):
|
||||||
|
self.name = name
|
||||||
|
self.title = title
|
||||||
|
self.url = url
|
||||||
|
self.active = active
|
||||||
|
self.description = description
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cssClass(self):
|
||||||
|
return self.active and u'active' or u'inactive'
|
||||||
|
|
||||||
|
|
||||||
class IAddForm(Interface):
|
class IAddForm(Interface):
|
||||||
|
|
||||||
name = NameField(
|
name = NameField(
|
||||||
title=_(u'Object name'),
|
title=_(u'Object name'),
|
||||||
description=_(u'Name of the object - will be used for addressing the '
|
description=_(u'Name of the object - will be used for addressing the '
|
||||||
'object via a URL; should therefore be unique within '
|
u'object via a URL; should therefore be unique within '
|
||||||
'the container and not contain special characters')
|
u'the container and not contain special characters'))
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AddForm(form.AddForm):
|
class AddForm(form.AddForm):
|
||||||
|
@ -115,6 +130,7 @@ class BaseView(GenericView, I18NView):
|
||||||
|
|
||||||
actions = {}
|
actions = {}
|
||||||
icon = None
|
icon = None
|
||||||
|
modeName = 'view'
|
||||||
|
|
||||||
def __init__(self, context, request):
|
def __init__(self, context, request):
|
||||||
super(BaseView, self).__init__(context, request)
|
super(BaseView, self).__init__(context, request)
|
||||||
|
@ -148,6 +164,9 @@ class BaseView(GenericView, I18NView):
|
||||||
def breadcrumbs(self):
|
def breadcrumbs(self):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def viewModes(self):
|
||||||
|
return Jeep()
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def name(self):
|
def name(self):
|
||||||
return getName(self.context)
|
return getName(self.context)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2012 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
|
||||||
|
@ -48,10 +48,11 @@ from cybertools.browser.action import Action
|
||||||
from cybertools.browser.view import GenericView
|
from cybertools.browser.view import GenericView
|
||||||
from cybertools.stateful.interfaces import IStateful
|
from cybertools.stateful.interfaces import IStateful
|
||||||
from cybertools.typology.interfaces import IType, ITypeManager
|
from cybertools.typology.interfaces import IType, ITypeManager
|
||||||
|
from cybertools.util.jeep import Jeep
|
||||||
from cybertools.xedit.browser import ExternalEditorView
|
from cybertools.xedit.browser import ExternalEditorView
|
||||||
from loops.browser.action import actions, DialogAction
|
from loops.browser.action import actions, DialogAction
|
||||||
from loops.common import adapted, AdapterBase
|
from loops.common import adapted, AdapterBase
|
||||||
from loops.i18n.browser import i18n_macros
|
from loops.i18n.browser import i18n_macros, LanguageInfo
|
||||||
from loops.interfaces import IConcept, IResource, IDocument, IMediaAsset, INode
|
from loops.interfaces import IConcept, IResource, IDocument, IMediaAsset, INode
|
||||||
from loops.interfaces import IViewConfiguratorSchema
|
from loops.interfaces import IViewConfiguratorSchema
|
||||||
from loops.resource import MediaAsset
|
from loops.resource import MediaAsset
|
||||||
|
@ -113,6 +114,11 @@ class NodeView(BaseView):
|
||||||
data.extend(self.virtualTarget.breadcrumbs())
|
data.extend(self.virtualTarget.breadcrumbs())
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def viewModes(self):
|
||||||
|
if self.virtualTarget:
|
||||||
|
return self.virtualTarget.viewModes()
|
||||||
|
return Jeep()
|
||||||
|
|
||||||
def recordAccess(self, viewName=''):
|
def recordAccess(self, viewName=''):
|
||||||
target = self.virtualTargetObject
|
target = self.virtualTargetObject
|
||||||
targetUid = target is not None and util.getUidForObject(target) or ''
|
targetUid = target is not None and util.getUidForObject(target) or ''
|
||||||
|
@ -911,6 +917,15 @@ class NodeTraverser(ItemTraverser):
|
||||||
# we'll use the target object in the node's context
|
# we'll use the target object in the node's context
|
||||||
viewAnnotations['target'] = target
|
viewAnnotations['target'] = target
|
||||||
return self.context
|
return self.context
|
||||||
|
target = viewAnnotations.get('target')
|
||||||
|
if target is not None: # name may be a view name for target
|
||||||
|
langInfo = LanguageInfo(self.context, request)
|
||||||
|
adTarget = adapted(target, langInfo)
|
||||||
|
view = component.queryMultiAdapter((adTarget, request), name=name)
|
||||||
|
if view is not None:
|
||||||
|
viewAnnotations['targetView'] = view
|
||||||
|
view.logInfo('NodeTraverser:targetView = %r' % view)
|
||||||
|
return self.context
|
||||||
obj = super(NodeTraverser, self).publishTraverse(request, name)
|
obj = super(NodeTraverser, self).publishTraverse(request, name)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
|
@ -240,6 +240,21 @@
|
||||||
</metal:actions>
|
</metal:actions>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:actions define-macro="view_modes">
|
||||||
|
<ul class="view-modes"
|
||||||
|
tal:define="viewModes view/viewModes"
|
||||||
|
tal:condition="viewModes">
|
||||||
|
<li tal:repeat="mode viewModes"
|
||||||
|
tal:attributes="class mode/cssClass">
|
||||||
|
<a tal:attributes="href mode/url;
|
||||||
|
title mode/description"
|
||||||
|
tal:content="mode/title"
|
||||||
|
i18n:translate="" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</metal:actions>
|
||||||
|
|
||||||
|
|
||||||
<metal:actions define-macro="page_actions">
|
<metal:actions define-macro="page_actions">
|
||||||
<div class="page-actions"
|
<div class="page-actions"
|
||||||
tal:define="pageActions python:view.globalOptions('action.page') or []"
|
tal:define="pageActions python:view.globalOptions('action.page') or []"
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
</metal:breadcrumbs>
|
</metal:breadcrumbs>
|
||||||
<div metal:define-slot="actions"></div>
|
<div metal:define-slot="actions"></div>
|
||||||
<div metal:define-slot="message"></div>
|
<div metal:define-slot="message"></div>
|
||||||
|
<metal:tabs use-macro="views/node_macros/view_modes" />
|
||||||
<metal:content define-slot="content">
|
<metal:content define-slot="content">
|
||||||
<tal:content define="item nocall:view/item;
|
<tal:content define="item nocall:view/item;
|
||||||
level level|python: 1;
|
level level|python: 1;
|
||||||
|
|
|
@ -4,12 +4,42 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* positioning of page sections */
|
/* page sections */
|
||||||
|
|
||||||
#portlets {
|
#portlets {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.view-modes {
|
||||||
|
padding: 0 0 0 2em;
|
||||||
|
margin: 0.7em 0 0 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
list-style-type: none;
|
||||||
|
border-bottom: #ccc 1px solid;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.view-modes li {
|
||||||
|
display: inline
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.view-modes li a {
|
||||||
|
padding: 0.15em 1.25em 0.15em 1.25em;
|
||||||
|
margin: 0 0.5em 0 0;
|
||||||
|
text-decoration: none;
|
||||||
|
border: #ccc 1px solid;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.view-modes li.active a {
|
||||||
|
border-bottom: #eee 1px solid;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.view-modes li.inactive a:hover {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
/* general */
|
/* general */
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
"""
|
"""
|
||||||
Set up a loops site for testing.
|
Set up a loops site for testing.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope import component
|
from zope import component
|
||||||
|
@ -57,13 +55,14 @@ from cybertools.wiki.dcu.rstx import Parser as DocutilsRstxParser
|
||||||
from loops.base import Loops
|
from loops.base import Loops
|
||||||
from loops import util
|
from loops import util
|
||||||
from loops.browser.node import ViewPropertiesConfigurator
|
from loops.browser.node import ViewPropertiesConfigurator
|
||||||
|
from loops.browser.concept import ConceptView
|
||||||
from loops.common import NameChooser
|
from loops.common import NameChooser
|
||||||
from loops.concept import Concept
|
from loops.concept import Concept
|
||||||
from loops.concept import IndexAttributes as ConceptIndexAttributes
|
from loops.concept import IndexAttributes as ConceptIndexAttributes
|
||||||
from loops.config.base import GlobalOptions, LoopsOptions
|
from loops.config.base import GlobalOptions, LoopsOptions
|
||||||
from loops.config.base import QueryOptions, PredicateOptions, TypeOptions
|
from loops.config.base import QueryOptions, PredicateOptions, TypeOptions
|
||||||
from loops.interfaces import ILoopsObject, IIndexAttributes
|
from loops.interfaces import ILoopsObject, IIndexAttributes
|
||||||
from loops.interfaces import IDocument, IFile, ITextDocument
|
from loops.interfaces import IConcept, IDocument, IFile, ITextDocument
|
||||||
from loops.interfaces import IIsSubtype
|
from loops.interfaces import IIsSubtype
|
||||||
from loops.layout.base import LayoutNode
|
from loops.layout.base import LayoutNode
|
||||||
from loops.organize.memberinfo import MemberInfoProvider
|
from loops.organize.memberinfo import MemberInfoProvider
|
||||||
|
@ -133,6 +132,7 @@ class TestSite(object):
|
||||||
name='zope.source.rest')
|
name='zope.source.rest')
|
||||||
component.provideAdapter(ReStructuredTextToHTMLRenderer,
|
component.provideAdapter(ReStructuredTextToHTMLRenderer,
|
||||||
(IReStructuredTextSource, IBrowserRequest), Interface)
|
(IReStructuredTextSource, IBrowserRequest), Interface)
|
||||||
|
component.provideAdapter(ConceptView, (IConcept, IBrowserRequest), Interface)
|
||||||
|
|
||||||
component.provideAdapter(LoopsType)
|
component.provideAdapter(LoopsType)
|
||||||
component.provideAdapter(ConceptType)
|
component.provideAdapter(ConceptType)
|
||||||
|
|
Loading…
Add table
Reference in a new issue