work in progress: wysiwyg editing with dojo - preparing node macros

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1297 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-08-12 22:11:47 +00:00
parent e05caedc38
commit 4c48396c13
10 changed files with 109 additions and 44 deletions

View file

@ -465,6 +465,14 @@ Node Views
... print item.url, view.selected(item)
http://127.0.0.1/loops/views/m1/m11 True
A NodeView provides an itemNum attribute that may be used to count elements
appearing on a page. Thus a template may construct unique ids for elements.
>>> view.itemNum
1
>>> view.itemNum
2
There is an openEditWindow() method that returns a JavaScript call for
opening a new browser window for editing; but only if the view is
editable:

View file

@ -169,7 +169,6 @@ class BaseView(object):
@Lazy
def uniqueId(self):
return zapi.getUtility(IRelationRegistry).getUniqueIdForObject(self.context)
#return zapi.getUtility(IIntIds).getId(self.context)
@Lazy
def editable(self):
@ -182,7 +181,8 @@ class BaseView(object):
@Lazy
def xeditable(self):
return getattr(self.context, 'contentType', '').startswith('text/')
return self.request.principal.id == 'rootadmin'
#return getattr(self.context, 'contentType', '').startswith('text/')
class LoopsTerms(object):

View file

@ -13,8 +13,7 @@
<metal:fields use-macro="item/template/macros/conceptchildren" />
</div>
</div>
<div class="subcolumn"
style="position: relative; top: 60px">
<div class="subcolumn" style="margin-top: 60px">
<metal:fields use-macro="item/template/macros/conceptresources" />
</div>
</div>

View file

@ -1,4 +1,4 @@
<tal:show i18n:domain="loops">
<tal:show i18n:domain="zope">
<html metal:use-macro="context/@@skin_macros/page">
<head></head>
<body>
@ -13,6 +13,14 @@
controller.macros.register('js', resourceName='ajax.dojo/dojo.js');" />
<metal:block fill-slot="ecmascript_slot"
tal:condition="nothing">
<script>
dojo.require("dojo.widget.Editor");
</script>
</metal:block>
<metal:block fill-slot="actions" />

View file

@ -31,7 +31,7 @@ from zope.app.container.browser.contents import JustContents
from zope.app.container.browser.adding import ContentAdding
from zope.app.event.objectevent import ObjectCreatedEvent, ObjectModifiedEvent
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.intid.interfaces import IIntIds
#from zope.app.intid.interfaces import IIntIds
from zope.dottedname.resolve import resolve
from zope.event import notify
from zope.formlib.namedtemplate import NamedTemplate
@ -51,15 +51,13 @@ from loops.browser.concept import ConceptView
class NodeView(BaseView):
_itemNum = 0
template = NamedTemplate('loops.node_macros')
@Lazy
def macro(self):
return self.template.macros['content']
#macroName = self.request.get('loops.viewName')
#if not macroName:
# macroName = self.context.viewName or 'content'
#return self.template.macros[macroName]
@Lazy
def view(self):
@ -95,6 +93,11 @@ class NodeView(BaseView):
return [NodeView(child, self.request)
for child in self.context.getPageItems()]
@property
def itemNum(self):
self._itemNum += 1
return self._itemNum
@Lazy
def nodeType(self):
return self.context.nodeType
@ -139,13 +142,13 @@ class NodeView(BaseView):
@Lazy
def bodyMacro(self):
# ?TODO: replace by: return self.target.macroName
# TODO: replace by: return self.target.macroName
target = self.targetObject
if target is None or IDocument.providedBy(target):
return 'textbody'
if IConcept.providedBy(target):
return 'conceptbody'
if IMediaAsset.providedBy(target) and target.contentType.startswith('image/'):
if IResource.providedBy(target) and target.contentType.startswith('image/'):
return 'imagebody'
return 'filebody'
@ -223,12 +226,39 @@ class NodeView(BaseView):
return targetView()
return u''
def targetId(self):
@Lazy
def virtualTarget(self):
target = self.request.annotations.get('loops.view', {}).get('target')
if target is None:
target = self.targetObject
return target
@Lazy
def targetId(self):
target = self.virtualTarget
if target is not None:
return zapi.getUtility(IIntIds).getId(target)
return BaseView(target, self.request).uniqueId
#return target.uniqueId
#return zapi.getUtility(IIntIds).getId(target)
@Lazy
def virtualTargetUrl(self):
targetId = self.targetId
if targetId is not None:
return '%s/.target%s' % (self.url, targetId)
@Lazy
def realTargetUrl(self):
target = self.virtualTarget
if target is not None:
return BaseView(target, self.request).url
@Lazy
def richEditable(self):
target = self.virtualTarget
if target is None:
return False
return canWrite(target, 'title')
class ListPages(NodeView):

View file

@ -5,28 +5,45 @@
<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" />
<metal:content use-macro="views/node_macros/content" />
</tal:items>
</tal:sub>
</metal:block>
<!-- dojoType="Editor"
items="formatblock;|;insertunorderedlist;insertorderedlist;|;bold;italic;|;createLink;"
-->
<metal:body define-macro="textbody">
<tal:body define="body item/body">
<div class="content-1"
<tal:body define="body item/body;
id string:${view/itemNum}.body">
<div class="content-1" id="1.body"
tal:condition="body"
tal:attributes="class string:content-$level;
id string:${view/itemNum}.body;
ondblclick item/openEditWindow"
tal:content="structure body">
The body
</div>
<div class="content-1"
tal:define="target item/target"
tal:condition="target"
tal:attributes="class string:content-$level;
ondblclick python: item.openEditWindow('configure.html')"
tal:content="structure item/renderTarget">
The body
<div>
<div class="subcolumn"
tal:condition="item/xeditable | nothing">
<a href="#" title="Edit" style="padding: 5px"
tal:attributes="href string:${item/realTargetUrl}/external_edit;
title string:Edit ${item/title}"><img
src="edit.gif" alt="Edit"
tal:attributes="src context/++resource++edit.gif" /></a>
</div>
<div class="content-1 subcolumn" id="1.body"
tal:define="target item/target"
tal:condition="target"
tal:attributes="class string:content-$level;
id id;
ondblclick python: item.openEditWindow('configure.html')"
tal:content="structure item/renderTarget">
The body
</div>
</div>
</tal:body>
</metal:body>
@ -34,8 +51,9 @@
<metal:body define-macro="conceptbody">
<tal:body define="body item/body;">
<div class="content-1"
<div class="content-1" id="1"
tal:attributes="class string:content-$level;
id string:${view/itemNum}.body;
ondblclick python: item.openEditWindow('configure.html')">
<span tal:content="structure body">Node Body</span>
</div>
@ -50,8 +68,9 @@
<metal:body define-macro="filebody">
<tal:body define="body item/body">
<div class="content-1"
<div class="content-1" id="1"
tal:attributes="class string:content-$level;
id string:${view/itemNum}.body;
ondblclick python: item.openEditWindow('edit_target.html')">
<a href="#"
tal:attributes="href string:${item/url}/.target/view"
@ -65,6 +84,7 @@
<tal:body define="body item/body">
<div class="content-1" style="margin-top: 12px"
tal:attributes="class string:content-$level;
id string:${view/itemNum}.body;
ondblclick python: item.openEditWindow('edit_target.html')">
<img src="target"
tal:attributes="src string:${item/url}/.target/view" />
@ -84,11 +104,12 @@
<metal:body define-macro="listpages">
<div class="content-1"
tal:content="structure view/body"
tal:attributes="ondblclick view/openEditWindow">
tal:content="structure item/body"
tal:attributes="ondblclick view/openEditWindow;
id string:${view/itemNum}.body;">
Listing
</div><br />
<div tal:repeat="item view/pageItems">
<div tal:repeat="item item/pageItems">
<a href="#"
tal:attributes="href item/url"
tal:content="item/title">Item</a>
@ -97,13 +118,18 @@
<metal:resources define-macro="listresources"
tal:define="item view/target">
tal:define="target item/target">
<div class="content-1"
tal:content="structure view/body"
tal:attributes="ondblclick python: item.openEditWindow('resources.html')">
tal:content="structure item/body"
tal:attributes="ondblclick python:
target and target.openEditWindow('resources.html')
or item.openEditWindow();
id string:${view/itemNum}.body;">
Listing
</div><br />
<div tal:attributes="ondblclick python: item.openEditWindow('resources.html')">
<div tal:attributes="ondblclick python: target.openEditWindow('resources.html')"
tal:define="item item/target"
tal:condition="nocall:target">
<div tal:repeat="related item/resources">
<a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId}"

View file

@ -78,6 +78,8 @@ class Resource(Image, Contained):
# TODO (?): check for multiple types (->Error)
return concepts and concepts[0] or cm.get('file', None)
def setResourceType(self, concept):
if concept is None:
return
current = self.getResourceType()
if current != concept:
typePred = self.getLoopsRoot().getConceptManager().getTypePredicate()

View file

@ -59,8 +59,6 @@ The search view provides values for identifying the search form itself
and the parameter rows; the rowNum is auto-incremented, so it should be
accessed exactly once per row:
>>> searchView.itemNum
1
>>> searchView.rowNum
1
>>> searchView.rowNum

View file

@ -48,16 +48,10 @@ class Search(BaseView):
def macro(self):
return self.template.macros['search']
@Lazy
def itemNum(self):
""" Return a number identifying the item (the current search form)
on the page.
"""
return self.request.get('loops.itemNum', 1)
@property
def rowNum(self):
""" Return the rowNum to be used for identifying the current row.
""" Return the rowNum to be used for identifying the current search
parameter row.
"""
n = self.request.get('loops.rowNum', 0)
if n: # if given directly we don't use the calculation

View file

@ -7,7 +7,7 @@
</h3>
<div metal:define-macro="search_form" class="searchForm"
tal:define="idPrefix string:${item/itemNum}.search;
tal:define="idPrefix string:${view/itemNum}.search;
formId string:$idPrefix.form">
<fieldset class="box">
<form action="." method="post" id="1.search.form"