Merge branch 'master' into bbmaster

This commit is contained in:
Helmut Merz 2012-01-23 11:11:31 +01:00
commit 3132fc9947
6 changed files with 91 additions and 11 deletions

View file

@ -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
# 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.text import mimetypes
from cybertools.typology.interfaces import IType, ITypeManager
from cybertools.util.jeep import Jeep
from loops.browser.util import normalizeForUrl
from loops.common import adapted, baseObject
from loops.config.base import DummyOptions
@ -74,7 +75,7 @@ from loops.versioning.interfaces import IVersionable
concept_macros = ViewPageTemplateFile('concept_macros.pt')
conceptMacrosTemplate = concept_macros #
conceptMacrosTemplate = concept_macros
resource_macros = ViewPageTemplateFile('resource_macros.pt')
@ -84,14 +85,28 @@ class NameField(schema.ASCIILine):
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):
name = NameField(
title=_(u'Object name'),
description=_(u'Name of the object - will be used for addressing the '
'object via a URL; should therefore be unique within '
'the container and not contain special characters')
)
u'object via a URL; should therefore be unique within '
u'the container and not contain special characters'))
class AddForm(form.AddForm):
@ -115,6 +130,7 @@ class BaseView(GenericView, I18NView):
actions = {}
icon = None
modeName = 'view'
def __init__(self, context, request):
super(BaseView, self).__init__(context, request)
@ -148,6 +164,9 @@ class BaseView(GenericView, I18NView):
def breadcrumbs(self):
return []
def viewModes(self):
return Jeep()
@Lazy
def name(self):
return getName(self.context)

View file

@ -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
# 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.stateful.interfaces import IStateful
from cybertools.typology.interfaces import IType, ITypeManager
from cybertools.util.jeep import Jeep
from cybertools.xedit.browser import ExternalEditorView
from loops.browser.action import actions, DialogAction
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 IViewConfiguratorSchema
from loops.resource import MediaAsset
@ -113,6 +114,11 @@ class NodeView(BaseView):
data.extend(self.virtualTarget.breadcrumbs())
return data
def viewModes(self):
if self.virtualTarget:
return self.virtualTarget.viewModes()
return Jeep()
def recordAccess(self, viewName=''):
target = self.virtualTargetObject
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
viewAnnotations['target'] = target
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)
return obj

View file

@ -240,6 +240,21 @@
</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">
<div class="page-actions"
tal:define="pageActions python:view.globalOptions('action.page') or []"

View file

@ -44,6 +44,7 @@
</metal:breadcrumbs>
<div metal:define-slot="actions"></div>
<div metal:define-slot="message"></div>
<metal:tabs use-macro="views/node_macros/view_modes" />
<metal:content define-slot="content">
<tal:content define="item nocall:view/item;
level level|python: 1;

View file

@ -4,12 +4,42 @@
*/
/* positioning of page sections */
/* page sections */
#portlets {
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 */
h1, h2, h3, h4, h5, h6 {

View file

@ -1,7 +1,5 @@
"""
Set up a loops site for testing.
$Id$
"""
from zope import component
@ -57,13 +55,14 @@ from cybertools.wiki.dcu.rstx import Parser as DocutilsRstxParser
from loops.base import Loops
from loops import util
from loops.browser.node import ViewPropertiesConfigurator
from loops.browser.concept import ConceptView
from loops.common import NameChooser
from loops.concept import Concept
from loops.concept import IndexAttributes as ConceptIndexAttributes
from loops.config.base import GlobalOptions, LoopsOptions
from loops.config.base import QueryOptions, PredicateOptions, TypeOptions
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.layout.base import LayoutNode
from loops.organize.memberinfo import MemberInfoProvider
@ -133,6 +132,7 @@ class TestSite(object):
name='zope.source.rest')
component.provideAdapter(ReStructuredTextToHTMLRenderer,
(IReStructuredTextSource, IBrowserRequest), Interface)
component.provideAdapter(ConceptView, (IConcept, IBrowserRequest), Interface)
component.provideAdapter(LoopsType)
component.provideAdapter(ConceptType)