work in progress: action/link management for portlets and icon bars

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2184 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-11-18 18:34:45 +00:00
parent 4b239e150a
commit 9fa0cc512c
11 changed files with 194 additions and 39 deletions

View file

@ -561,6 +561,48 @@ cybertools.relation package.)
>>> IMediaAssetView.providedBy(m111)
False
Target views
------------
We can directly retrieve a target's view by using the NodeView's
``targetObjectView`` property. If the target is a concept we get a ConceptView
that provides methods e.g. for retrieving the concept's relations.
These are again wrapped as views, i.e. as instances of the
ConceptRelationView class.
>>> from loops.interfaces import IConcept
>>> component.provideAdapter(ConceptView, (IConcept, IBrowserRequest), Interface)
>>> m112.target = cc1
>>> view = NodeView(m112, TestRequest())
>>> childRels = list(view.targetObjectView.children())
>>> childRels[0]
<loops.browser.concept.ConceptRelationView object ...>
A fairly useful method for providing links to target objects of a node
is ``NodeView.getUrlForTarget()`` that expects a ConceptView, ResourceView,
or ConceptRelationView as its argument.
>>> view.getUrlForTarget(childRels[0])
'http://127.0.0.1/loops/views/m1/m11/m112/.target39'
Actions
-------
>>> from cybertools.browser.liquid.controller import Controller
>>> request = TestRequest()
>>> view = NodeView(m112, request)
>>> view.controller = Controller(view, request)
>>> view.setupController()
>>> actions = view.getActions('portlet')
>>> len(actions)
1
Clean-up:
>>> m112.target = None
Ordering Nodes
--------------
@ -761,11 +803,10 @@ In order to provide suitable links for viewing or editing a target you may
ask a view which view and edit actions it supports. We directly use the
target object's view here:
>>> view.virtualTarget.getActions()
[<loops.browser.common.Action object ...>]
>>> action = view.virtualTarget.getActions()[0]
>>> action.url
'http://127.0.0.1/loops/views/m1/m11/m111/.target23'
>>> actions = view.virtualTarget.getActions('object', page=view)
>>> #actions[0].url
'http://127.0.0.1/loops/views/m1/m11/m111/.target23'
Collecting Information about Parents

66
browser/action.py Normal file
View file

@ -0,0 +1,66 @@
#
# Copyright (c) 2007 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
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Base classes (sort of views) for action portlet items.
$Id$
"""
from zope import component
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
action_macros = ViewPageTemplateFile('action_macros.pt')
class Action(object):
template = action_macros
macroName = 'action'
condition = True
permission = None
url = '.'
targetWindow = ''
title = ''
description = ''
icon = ''
cssClass = ''
onClick = ''
innerHtmlId = ''
def __init__(self, view, **kw):
self.view = view
for k, v in kw.items():
setattr(self, k, v)
@Lazy
def macro(self):
return self.template.macros[self.macroName]
@Lazy
def url(self):
return self.view.url
class TargetAction(object):
@Lazy
def url(self):
return self.view.virtualTargetUrl

23
browser/action_macros.pt Normal file
View file

@ -0,0 +1,23 @@
<!-- action macros -->
<metal:action define-macro="action">
<div tal:condition="action/condition">
<a href="#" target="target_window" title="Description text"
i18n:attributes="title"
tal:attributes="href action/url;
target action/targetWindow;
title action/description;
onClick action/onClick;"><img
src="#" alt="icon"
tal:condition="action/icon"
tal:attributes="src action/icon;
alt action/description" /><span
i18n:translate=""
tal:condition="action/title"
tal:content="action/title">Action Title</span>
</a>
</div>
<span id="inner.Id"
tal:condition="action/innerHtmlId"
tal:attributes="id action/innerHtmlId"></span>
</metal:action>

View file

@ -97,6 +97,8 @@ class EditForm(form.EditForm):
class BaseView(GenericView):
actions = {} # default only, don't update
def __init__(self, context, request):
super(BaseView, self).__init__(context, request)
# TODO: get rid of removeSecurityProxy() call
@ -329,11 +331,14 @@ class BaseView(GenericView):
def editable(self):
return canWrite(self.context, 'title')
def getActions(self, category):
def getActions(self, category='object', page=None):
""" Return a list of actions that provide the view and edit actions
available for the context object.
"""
return []
actions = []
if category in self.actions:
actions.extend(self.actions[category](self, page=page))
return actions
def openEditWindow(self, viewName='edit.html'):
if self.editable:

View file

@ -46,7 +46,7 @@ from cybertools.typology.interfaces import IType, ITypeManager
from loops.interfaces import IConcept
from loops.interfaces import ITypeConcept
from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList
from loops.browser.common import EditForm, BaseView, LoopsTerms
from loops.browser.common import EditForm, BaseView, LoopsTerms, conceptMacrosTemplate
from loops import util
from loops.util import _
from loops.versioning.util import getVersion
@ -75,12 +75,16 @@ class ConceptEditForm(EditForm):
class ConceptView(BaseView):
template = NamedTemplate('loops.concept_macros')
template = ViewPageTemplateFile('concept_macros.pt')
@Lazy
def macro(self):
return self.template.macros['conceptdata']
@Lazy
def conceptMacros(self):
return conceptMacrosTemplate.macros
def __init__(self, context, request):
super(ConceptView, self).__init__(context, request)
cont = self.controller

View file

@ -394,13 +394,15 @@ class CreateObject(EditObject):
name = name.rsplit('\\', 1)[-1]
else:
name = None
# TODO: validate fields
name = INameChooser(container).chooseName(name, obj)
container[name] = obj
tc = form.get('form.type') or '.loops/concepts/note'
obj.resourceType = self.loopsRoot.loopsTraverse(tc)
notify(ObjectCreatedEvent(obj))
self.object = obj
self.updateFields()
self.request.response.redirect(self.view.virtualTargetUrl)
self.updateFields() # TODO: suppress validation
#self.request.response.redirect(self.view.virtualTargetUrl)
self.request.response.redirect(self.view.request.URL)
return False

View file

@ -51,6 +51,7 @@ from loops.interfaces import IViewConfiguratorSchema
from loops.resource import MediaAsset
from loops import util
from loops.util import _
from loops.browser.action import Action, TargetAction
from loops.browser.common import BaseView
from loops.browser.concept import ConceptView
from loops.versioning.util import getVersion
@ -162,11 +163,6 @@ class NodeView(BaseView):
basicView._viewName = self.context.viewName
return basicView.view
#@Lazy
#def target(self):
# # obsolete and confusing - TODO: remove...
# return self.targetObjectView
@Lazy
def targetUrl(self):
t = self.targetObjectView
@ -334,11 +330,31 @@ class NodeView(BaseView):
# target viewing and editing support
def getUrlForTarget(self, target):
""" Return URL of given target view given as .targetXXX URL.
"""
return '%s/.target%s' % (self.url, target.uniqueId)
def getActions(self, category='object'):
#target = self.virtualTarget
#if target is not None:
# return target.getActions(category)
return [] # TODO: what about editing the node itself?
actions = []
self.registerDojo()
if category in self.actions:
actions.extend(self.actions[category](self))
target = self.virtualTarget
if target is not None:
actions.extend(target.getActions(category, page=self))
return actions
def getPortletActions(self):
actions = []
actions.append(Action(self,
targetWindow='loops_cme',
title='Edit Concept Map',
description='Open concept map editor in new window',
url=self.conceptMapEditorUrl))
return actions
actions = dict(portlet=getPortletActions)
@Lazy
def hasEditableTarget(self):

View file

@ -208,17 +208,11 @@
<metal:actions define-macro="actions">
<tal:actions repeat="action python:view.getActions('portlet')">
<metal:action use-macro="action/macro" />
</tal:actions>
<tal:actions define="dummy view/registerDojo;
url view/virtualTargetUrl">
<div tal:define="cmUrl view/conceptMapEditorUrl"
tal:condition="url">
<a href="#" target="loops_cme" i18n:translate=""
i18n:attributes="title"
title="Open concept map editor in new window"
tal:attributes="href cmUrl">
Edit Concept Map
</a>
</div>
<div>
<a href="create_object.html" i18n:translate=""
onclick="objectDialog('create', 'create_object.html'); return false;"

View file

@ -41,7 +41,8 @@ from zope.traversing.api import getName, getParent
from cybertools.typology.interfaces import IType
from cybertools.xedit.browser import ExternalEditorView, fromUnicode
from loops.browser.common import EditForm, BaseView, Action
from loops.browser.action import Action, TargetAction
from loops.browser.common import EditForm, BaseView
from loops.browser.concept import ConceptRelationView, ConceptConfigureView
from loops.browser.node import NodeView, node_macros
from loops.browser.util import html_quote
@ -181,15 +182,15 @@ class ResourceView(BaseView):
ct = self.context.contentType
return ct.startswith('image/') or ct == 'application/pdf'
def getActions(self, category='object'):
renderer = node_macros.macros['external_edit']
node = self.request.annotations.get('loops.view', {}).get('node')
if node is not None:
nodeView = NodeView(node, self.request)
url = nodeView.virtualTargetUrl
def getObjectActions(self, page=None):
actions = []
if page is None:
factory, view = Action, self
else:
url = self.url
return [Action(renderer, url)]
factory, view = TargetAction, page
#if self.xeditable:
# actions.append(factory(self, page=view,))
return actions
def concepts(self):
for r in self.context.getConceptRelations():

Binary file not shown.

View file

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: $Id$\n"
"POT-Creation-Date: 2007-05-22 12:00 CET\n"
"PO-Revision-Date: 2007-05-23 12:00 CET\n"
"PO-Revision-Date: 2007-11-18 12:00 CET\n"
"Last-Translator: Helmut Merz <helmutm@cy55.de>\n"
"Language-Team: loops developers <helmutm@cy55.de>\n"
"MIME-Version: 1.0\n"
@ -194,6 +194,9 @@ msgstr "major"
msgid "minor"
msgstr "minor"
msgid "see"
msgstr "siehe"
msgid "Change Password"
msgstr "Passwort ändern"