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:
helmutm 2006-01-29 20:21:10 +00:00
parent 21b6af48b9
commit 395e61a449
8 changed files with 244 additions and 72 deletions

View file

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

View file

@ -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
View 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();
}
}

View file

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

View file

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

View file

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