Document and MediaAsset objects now embedded in node display
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1044 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
21b6af48b9
commit
395e61a449
8 changed files with 244 additions and 72 deletions
|
@ -8,6 +8,7 @@
|
||||||
<!-- resources -->
|
<!-- resources -->
|
||||||
|
|
||||||
<resource name="node.css" file="node.css" />
|
<resource name="node.css" file="node.css" />
|
||||||
|
<resource name="node.js" file="node.js" />
|
||||||
<resource name="edit.gif" file="edit.gif" />
|
<resource name="edit.gif" file="edit.gif" />
|
||||||
|
|
||||||
<!-- macros -->
|
<!-- macros -->
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
<page
|
<page
|
||||||
for="*"
|
for="*"
|
||||||
name="node_macros"
|
name="node_macros"
|
||||||
template="node.pt"
|
template="node_macros.pt"
|
||||||
permission="zope.View"
|
permission="zope.View"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -318,20 +319,34 @@
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
template="edit.pt"
|
template="edit.pt"
|
||||||
class="loops.browser.node.ConfigureView"
|
class="loops.browser.node.ConfigureView"
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent">
|
||||||
menu="zmi_views" title="Configure">
|
|
||||||
|
|
||||||
<widget field="description" height="2" />
|
<widget field="description" height="2" />
|
||||||
<widget field="body" height="15" />
|
<widget field="body" height="15" />
|
||||||
|
|
||||||
</editform>
|
</editform>
|
||||||
|
|
||||||
|
<menuItem
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
action="configure.html"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
menu="zmi_views" title="Configure"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<menuItem
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
action="contents.html"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
menu="zmi_views" title="Contents"
|
||||||
|
/>
|
||||||
|
|
||||||
<editform
|
<editform
|
||||||
label="Edit Media Asset"
|
label="Edit Media Asset"
|
||||||
name="edit_target.html"
|
name="edit_target.html"
|
||||||
schema="loops.interfaces.IMediaAsset"
|
schema="loops.interfaces.IMediaAsset"
|
||||||
fields="title data contentType"
|
fields="title data contentType"
|
||||||
for="loops.interfaces.IMediaAssetView"
|
for="loops.interfaces.IMediaAssetView"
|
||||||
|
template="edit.pt"
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
menu="zmi_views" title="Edit Media Asset"
|
menu="zmi_views" title="Edit Media Asset"
|
||||||
/>
|
/>
|
||||||
|
@ -342,6 +357,7 @@
|
||||||
schema="loops.interfaces.IDocument"
|
schema="loops.interfaces.IDocument"
|
||||||
fields="title data contentType"
|
fields="title data contentType"
|
||||||
for="loops.interfaces.IDocumentView"
|
for="loops.interfaces.IDocumentView"
|
||||||
|
template="edit.pt"
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
menu="zmi_views" title="Edit Document"
|
menu="zmi_views" title="Edit Document"
|
||||||
/>
|
/>
|
||||||
|
@ -354,6 +370,14 @@
|
||||||
permission="zope.View"
|
permission="zope.View"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<page
|
||||||
|
name="target"
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
class=".node.NodeView"
|
||||||
|
attribute="renderTarget"
|
||||||
|
permission="zope.View"
|
||||||
|
/>
|
||||||
|
|
||||||
<defaultView
|
<defaultView
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
name="node.html"
|
name="node.html"
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
<html metal:use-macro="context/@@standard_macros/view"
|
<html metal:use-macro="context/@@standard_macros/view"
|
||||||
i18n:domain="zope">
|
i18n:domain="zope">
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<metal:js fill-slot="ecmascript_slot">
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="node.js"
|
||||||
|
tal:attributes="src string:${context/++resource++node.js}">
|
||||||
|
</script>
|
||||||
|
</metal:js>
|
||||||
|
|
||||||
<div metal:fill-slot="body">
|
<div metal:fill-slot="body">
|
||||||
|
|
||||||
<div metal:define-macro="body">
|
<div metal:define-macro="body">
|
||||||
|
@ -12,10 +20,7 @@
|
||||||
<input type="hidden" name="form_submitted" value="true" />
|
<input type="hidden" name="form_submitted" value="true" />
|
||||||
<tal:control condition="request/form_submitted|nothing">
|
<tal:control condition="request/form_submitted|nothing">
|
||||||
<script language="JavaScript">
|
<script language="JavaScript">
|
||||||
if (typeof(opener) != 'undefined' && opener != null) {
|
focusOpener();
|
||||||
opener.location.reload();
|
|
||||||
opener.focus();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</tal:control>
|
</tal:control>
|
||||||
|
|
||||||
|
|
13
browser/node.js
Normal file
13
browser/node.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
function openEditWindow(url) {
|
||||||
|
zmi=window.open(url, 'zmi');
|
||||||
|
zmi.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function focusOpener() {
|
||||||
|
if (typeof(opener) != 'undefined' && opener != null) {
|
||||||
|
opener.location.reload();
|
||||||
|
opener.focus();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,13 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:js fill-slot="ecmascript_slot">
|
||||||
|
<script type="text/javascript" src="node.js"
|
||||||
|
tal:attributes="src string:${context/++resource++node.js}">
|
||||||
|
</script>
|
||||||
|
</metal:js>
|
||||||
|
|
||||||
|
|
||||||
<metal:css fill-slot="style_slot">
|
<metal:css fill-slot="style_slot">
|
||||||
<style type="text/css" media="all"
|
<style type="text/css" media="all"
|
||||||
tal:content="string:@import url(${context/++resource++node.css});">
|
tal:content="string:@import url(${context/++resource++node.css});">
|
||||||
|
@ -18,27 +25,7 @@
|
||||||
<metal:body fill-slot="body">
|
<metal:body fill-slot="body">
|
||||||
<tal:content define="item view/page;
|
<tal:content define="item view/page;
|
||||||
level level|python: 1">
|
level level|python: 1">
|
||||||
|
<metal:block use-macro="views/node_macros/content" />
|
||||||
<metal:block define-macro="content">
|
|
||||||
<tal:body define="body item/body"
|
|
||||||
condition="body">
|
|
||||||
<div class="content-1"
|
|
||||||
tal:define="onclick string:
|
|
||||||
zmi=window.open('${item/url}/@@edit.html', 'zmi');;
|
|
||||||
zmi.focus();; return false;;"
|
|
||||||
tal:attributes="class string:content-$level;
|
|
||||||
ondblclick python: item.editable and onclick or ''"
|
|
||||||
tal:content="structure body">
|
|
||||||
The body
|
|
||||||
</div>
|
|
||||||
</tal:body>
|
|
||||||
<tal:sub define="level python:level+1">
|
|
||||||
<tal:items repeat="item item/textItems">
|
|
||||||
<metal:portlet use-macro="views/node_macros/content" />
|
|
||||||
</tal:items>
|
|
||||||
</tal:sub>
|
|
||||||
</metal:block>
|
|
||||||
|
|
||||||
</tal:content>
|
</tal:content>
|
||||||
</metal:body>
|
</metal:body>
|
||||||
|
|
||||||
|
@ -48,25 +35,9 @@
|
||||||
<tal:menu define="item view/menu;
|
<tal:menu define="item view/menu;
|
||||||
level level|python: 1"
|
level level|python: 1"
|
||||||
condition="item">
|
condition="item">
|
||||||
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<metal:menu define-macro="menu">
|
<metal:menu use-macro="views/node_macros/menu" />
|
||||||
<div class="menu-3"
|
|
||||||
tal:attributes="class python: 'content '
|
|
||||||
+ (view.selected(item) and 'even' or 'odd')
|
|
||||||
+ ' menu-%i' % level">
|
|
||||||
<a href="#" class=""
|
|
||||||
tal:content="item/context/title"
|
|
||||||
tal:attributes="href item/url">Menu Text</a>
|
|
||||||
</div>
|
|
||||||
<tal:sub tal:define="level python:level+1">
|
|
||||||
<tal:items repeat="item item/menuItems">
|
|
||||||
<metal:portlet use-macro="views/node_macros/menu" />
|
|
||||||
</tal:items>
|
|
||||||
</tal:sub>
|
|
||||||
</metal:menu>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</tal:menu>
|
</tal:menu>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -76,22 +47,8 @@
|
||||||
tal:attributes="href string:${view/menu/url}/impressum">Impressum</a>
|
tal:attributes="href string:${view/menu/url}/impressum">Impressum</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
</tal:show>
|
</tal:show>
|
||||||
|
|
||||||
|
|
||||||
<tal:hide condition="nothing">
|
|
||||||
<metal:editlink define-macro="editlink">
|
|
||||||
<a target="zmi"
|
|
||||||
tal:define="url string:${item/url}/@@edit.html'"
|
|
||||||
tal:attributes="href url;
|
|
||||||
onclick string:
|
|
||||||
zmi=window.open('$url', 'zmi');;
|
|
||||||
zmi.focus();; return false;;">
|
|
||||||
<img src="edit.gif"
|
|
||||||
tal:attributes="src context/++resource++edit.gif" border="0" />
|
|
||||||
</a>
|
|
||||||
</metal:editlink>
|
|
||||||
</tal:hide>
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ from zope.proxy import removeAllProxies
|
||||||
from zope.security import canAccess, canWrite
|
from zope.security import canAccess, canWrite
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
|
from loops.interfaces import IDocument, IMediaAsset
|
||||||
from loops.resource import MediaAsset
|
from loops.resource import MediaAsset
|
||||||
|
|
||||||
class NodeView(object):
|
class NodeView(object):
|
||||||
|
@ -63,6 +64,14 @@ class NodeView(object):
|
||||||
def target(self):
|
def target(self):
|
||||||
return self.context.target
|
return self.context.target
|
||||||
|
|
||||||
|
def renderTarget(self):
|
||||||
|
target = self.target
|
||||||
|
if target is not None:
|
||||||
|
targetView = zapi.getMultiAdapter((target, self.request),
|
||||||
|
name=zapi.getDefaultViewName(target, self.request))
|
||||||
|
return targetView()
|
||||||
|
return u''
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def page(self):
|
def page(self):
|
||||||
page = self.context.getPage()
|
page = self.context.getPage()
|
||||||
|
@ -72,19 +81,19 @@ class NodeView(object):
|
||||||
for child in self.context.getTextItems():
|
for child in self.context.getTextItems():
|
||||||
yield NodeView(child, self.request)
|
yield NodeView(child, self.request)
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def menu(self):
|
|
||||||
menu = self.context.getMenu()
|
|
||||||
return menu is not None and NodeView(menu, self.request) or None
|
|
||||||
|
|
||||||
def menuItems(self):
|
|
||||||
for child in self.context.getMenuItems():
|
|
||||||
yield NodeView(child, self.request)
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def body(self):
|
def body(self):
|
||||||
return self.render()
|
return self.render()
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def bodyMacro(self):
|
||||||
|
target = self.target
|
||||||
|
if target is None or IDocument.providedBy(target):
|
||||||
|
return 'textbody'
|
||||||
|
if target.contentType.startswith('image/'):
|
||||||
|
return 'imagebody'
|
||||||
|
return 'filebody'
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def url(self):
|
def url(self):
|
||||||
return zapi.absoluteURL(self.context, self.request)
|
return zapi.absoluteURL(self.context, self.request)
|
||||||
|
@ -93,6 +102,15 @@ class NodeView(object):
|
||||||
def editable(self):
|
def editable(self):
|
||||||
return canWrite(self.context, 'body')
|
return canWrite(self.context, 'body')
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def menu(self):
|
||||||
|
menu = self.context.getMenu()
|
||||||
|
return menu is not None and NodeView(menu, self.request) or None
|
||||||
|
|
||||||
|
def menuItems(self):
|
||||||
|
for child in self.context.getMenuItems():
|
||||||
|
yield NodeView(child, self.request)
|
||||||
|
|
||||||
def selected(self, item):
|
def selected(self, item):
|
||||||
return item.context == self.context
|
return item.context == self.context
|
||||||
|
|
||||||
|
|
104
browser/node_macros.pt
Normal file
104
browser/node_macros.pt
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<!-- content macros -->
|
||||||
|
|
||||||
|
<metal:block define-macro="content"
|
||||||
|
tal:define="bodyMacro view/bodyMacro">
|
||||||
|
<metal:body use-macro="views/node_macros/?bodyMacro" />
|
||||||
|
<tal:sub define="level python:level+1">
|
||||||
|
<tal:items repeat="item item/textItems">
|
||||||
|
<metal:content use-macro="views/node_macros/content" />
|
||||||
|
</tal:items>
|
||||||
|
</tal:sub>
|
||||||
|
</metal:block>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:body define-macro="textbody">
|
||||||
|
<tal:body define="body item/body"
|
||||||
|
condition="body">
|
||||||
|
<div class="content-1"
|
||||||
|
tal:define="onclick string:openEditWindow('${item/url}/@@edit.html')"
|
||||||
|
tal:attributes="class string:content-$level;
|
||||||
|
ondblclick python: item.editable and onclick or ''"
|
||||||
|
tal:content="structure body">
|
||||||
|
The body
|
||||||
|
</div>
|
||||||
|
<div class="content-1"
|
||||||
|
tal:define="target view/target;
|
||||||
|
onclick string:openEditWindow('${item/url}/@@edit_target.html')"
|
||||||
|
tal:condition="target"
|
||||||
|
tal:attributes="class string:content-$level;
|
||||||
|
ondblclick python: item.editable and onclick or ''"
|
||||||
|
tal:content="structure target/data">
|
||||||
|
The body
|
||||||
|
</div>
|
||||||
|
</tal:body>
|
||||||
|
</metal:body>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:body define-macro="filebody">
|
||||||
|
<tal:body define="body item/body">
|
||||||
|
<div class="content-1"
|
||||||
|
tal:define="onclick string:openEditWindow('${item/url}/@@edit.html')"
|
||||||
|
tal:attributes="class string:content-$level;
|
||||||
|
ondblclick python: item.editable and onclick or ''">
|
||||||
|
<a href="#"
|
||||||
|
tal:attributes="href string:${item/url}/target"
|
||||||
|
tal:content="structure body">The body</a>
|
||||||
|
</div>
|
||||||
|
</tal:body>
|
||||||
|
</metal:body>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:body define-macro="imagebody">
|
||||||
|
<tal:body define="body item/body"
|
||||||
|
condition="body">
|
||||||
|
<div class="content-1"
|
||||||
|
tal:define="onclick string:openEditWindow('${item/url}/@@edit.html')"
|
||||||
|
tal:attributes="class string:content-$level;
|
||||||
|
ondblclick python: item.editable and onclick or ''"
|
||||||
|
tal:content="structure body">
|
||||||
|
The body
|
||||||
|
</div>
|
||||||
|
<div class="content-1"
|
||||||
|
tal:define="onclick string:openEditWindow('${item/url}/@@edit_target.html')"
|
||||||
|
tal:attributes="class string:content-$level;
|
||||||
|
ondblclick python: item.editable and onclick or ''">
|
||||||
|
<img src="target"
|
||||||
|
tal:attributes="src string:${item/url}/target" />
|
||||||
|
</div>
|
||||||
|
</tal:body>
|
||||||
|
</metal:body>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- menu -->
|
||||||
|
|
||||||
|
<metal:menu define-macro="menu">
|
||||||
|
<div class="menu-3"
|
||||||
|
tal:attributes="class python: 'content '
|
||||||
|
+ (view.selected(item) and 'even' or 'odd')
|
||||||
|
+ ' menu-%i' % level">
|
||||||
|
<a href="#" class=""
|
||||||
|
tal:content="item/context/title"
|
||||||
|
tal:attributes="href item/url">Menu Text</a>
|
||||||
|
</div>
|
||||||
|
<tal:sub tal:define="level python:level+1">
|
||||||
|
<tal:items repeat="item item/menuItems">
|
||||||
|
<metal:portlet use-macro="views/node_macros/menu" />
|
||||||
|
</tal:items>
|
||||||
|
</tal:sub>
|
||||||
|
</metal:menu>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- and other stuff -->
|
||||||
|
|
||||||
|
<metal:editlink define-macro="editlink">
|
||||||
|
<a target="zmi"
|
||||||
|
tal:define="url string:${item/url}/@@edit.html'"
|
||||||
|
tal:attributes="href url;
|
||||||
|
onclick string:
|
||||||
|
zmi=window.open('$url', 'zmi');;
|
||||||
|
zmi.focus();; return false;;">
|
||||||
|
<img src="edit.gif"
|
||||||
|
tal:attributes="src context/++resource++edit.gif" border="0" />
|
||||||
|
</a>
|
||||||
|
</metal:editlink>
|
||||||
|
|
51
browser/util.py
Normal file
51
browser/util.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 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
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Utilities.
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
"""
|
||||||
|
|
||||||
|
from zope.app import zapi
|
||||||
|
from zope.app.publisher.browser.menu import BrowserMenu
|
||||||
|
from zope.app.publisher.interfaces.browser import IBrowserSubMenuItem
|
||||||
|
|
||||||
|
|
||||||
|
class LoopsMenu(BrowserMenu):
|
||||||
|
""" Use this class in zope/app/menus.zcml for zmi_views for
|
||||||
|
getting a different order of menu items.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getMenuItems(self, object, request):
|
||||||
|
"""Return menu item entries in a TAL-friendly form."""
|
||||||
|
result = sorted([(item.order, item.action.lower(), item)
|
||||||
|
for name, item in zapi.getAdapters(
|
||||||
|
(object, request), self.getMenuItemType())
|
||||||
|
if item.available()])
|
||||||
|
return [
|
||||||
|
{'title': item.title,
|
||||||
|
'description': item.description,
|
||||||
|
'action': item.action,
|
||||||
|
'selected': (item.selected() and u'selected') or u'',
|
||||||
|
'icon': item.icon,
|
||||||
|
'extra': item.extra,
|
||||||
|
'submenu': (IBrowserSubMenuItem.providedBy(item) and
|
||||||
|
getMenu(item.submenuId, object, request)) or None}
|
||||||
|
for order, action, item in result]
|
||||||
|
|
|
@ -326,7 +326,7 @@ class ITargetProperties(Interface):
|
||||||
|
|
||||||
|
|
||||||
class INodeConfigSchema(INode, ITargetProperties):
|
class INodeConfigSchema(INode, ITargetProperties):
|
||||||
""" All fields that may be shown in the node add form.
|
""" All fields that may be shown in the node config form.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
createTarget = schema.Bool(
|
createTarget = schema.Bool(
|
||||||
|
|
Loading…
Add table
Reference in a new issue