clean-up view control by node_macros; starting form input processing with FormController

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1354 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-09-20 20:40:57 +00:00
parent 980114d649
commit cb194f0f24
10 changed files with 133 additions and 46 deletions

View file

@ -536,6 +536,8 @@ A node object provides the targetSchema of its target:
A node's target is rendered using the NodeView's renderTargetBody() A node's target is rendered using the NodeView's renderTargetBody()
method. This makes use of a browser view registered for the target interface, method. This makes use of a browser view registered for the target interface,
and of a lot of other stuff needed for the rendering machine. and of a lot of other stuff needed for the rendering machine.
(Note: renderTarget is obsolete - we now use a macro provided by the target's
view for rendering.)
>>> from zope.component.interfaces import IFactory >>> from zope.component.interfaces import IFactory
>>> from zope.app.renderer import rest >>> from zope.app.renderer import rest

View file

@ -142,16 +142,11 @@ class BaseView(GenericView):
@Lazy @Lazy
def typeProvider(self): def typeProvider(self):
type = self.type return self.type.typeProvider
if type is not None:
return type.typeProvider
@Lazy @Lazy
def typeInterface(self): def typeInterface(self):
provider = self.typeProvider return self.type.typeInterface
if provider is not None:
tc = ITypeConcept(provider)
return tc.typeInterface
@Lazy @Lazy
def typeAdapter(self): def typeAdapter(self):
@ -161,8 +156,7 @@ class BaseView(GenericView):
@Lazy @Lazy
def typeTitle(self): def typeTitle(self):
type = self.type return self.type.title
return type is not None and type.title or None
@Lazy @Lazy
def typeUrl(self): def typeUrl(self):

View file

@ -562,7 +562,15 @@
<page <page
name="create_object.html" name="create_object.html"
for="loops.interfaces.INode" for="loops.interfaces.INode"
class="loops.browser.node.CreateObject" class="loops.browser.form.CreateObjectForm"
permission="zope.ManageContent"
/>
<zope:adapter
name="create_resource"
for="loops.browser.node.NodeView
zope.publisher.interfaces.browser.IBrowserRequest"
factory="loops.browser.form.CreateObject"
permission="zope.ManageContent" permission="zope.ManageContent"
/> />

61
browser/form.py Normal file
View file

@ -0,0 +1,61 @@
#
# 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
#
"""
View class for Node objects.
$Id$
"""
from zope import component, interface, schema
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from zope.formlib.form import Form, FormFields
from cybertools.ajax import innerHtml
from cybertools.browser.controller import FormController
from loops.browser.node import NodeView
class CreateObjectForm(NodeView, Form):
template = ViewPageTemplateFile('form_macros.pt')
@property
def macro(self): return self.template.macros['create']
form_fields = FormFields(
schema.TextLine(__name__='title', title=_(u'Title')),
schema.Text(__name__='body', title=_(u'Body Text')),
schema.TextLine(__name__='linkUrl', title=_(u'Link'), required=False),
)
title = _(u'Enter Note')
form_action = 'create_resource'
def __init__(self, context, request):
super(CreateObjectForm, self).__init__(context, request)
self.setUpWidgets()
self.widgets['body'].height = 3
def __call__(self):
return innerHtml(self)
class CreateObject(FormController):
def update(self):
print 'updating...'

View file

@ -34,12 +34,12 @@
<td colspan="4" class="headline">Assign Concept(s)</td> <td colspan="4" class="headline">Assign Concept(s)</td>
</tr> </tr>
<tr> <tr>
<td><label for="dlg.create.search.type">Type:</label></td> <td><label for="form.concept.search.type">Type:</label></td>
<td> <td>
<select name="dlg.create.search.type" id="dlg.create.search.type" <select name="form.concept.search.type" id="form.concept.search.type"
tal:attributes="onChange tal:attributes="onChange
string:setConceptTypeForComboBox( string:setConceptTypeForComboBox(
'dlg.create.search.type', 'dlg.create.search.text')"> 'form.concept.search.type', 'form.concept.search.text')">
<tal:types repeat="type view/conceptTypesForSearch"> <tal:types repeat="type view/conceptTypesForSearch">
<option value="loops:*" <option value="loops:*"
i18n:translate="" i18n:translate=""
@ -48,10 +48,10 @@
</tal:types> </tal:types>
</select>&nbsp;&nbsp; </select>&nbsp;&nbsp;
</td> </td>
<td><label for="dlg.create.search.text">Search text:</label></td> <td><label for="form.concept.search.text">Search text:</label></td>
<td> <td>
<input dojoType="comboBox" mode="remote" autoComplete="False" <input dojoType="comboBox" mode="remote" autoComplete="False"
name="dlg.create.search.text" id="dlg.create.search.text" name="form.concept.search.text" id="form.concept.search.text"
tal:attributes="dataUrl tal:attributes="dataUrl
string:${context/@@absolute_url}/listConceptsForComboBox.js?searchString=%{searchString}&searchType=" /> string:${context/@@absolute_url}/listConceptsForComboBox.js?searchString=%{searchString}&searchType=" />
</td> </td>

View file

@ -95,10 +95,12 @@ class NodeView(BaseView):
@Lazy @Lazy
def item(self): def item(self):
#target = self.virtualTargetObject # ignores page even for direktly assignd target
target = self.request.annotations.get('loops.view', {}).get('target') target = self.request.annotations.get('loops.view', {}).get('target')
# was there a .target... element in the URL? # was there a .target... element in the URL?
if target is not None: if target is not None:
basicView = zapi.getMultiAdapter((target, self.request)) basicView = zapi.getMultiAdapter((target, self.request))
# xxx: obsolete when self.targetObject is virtual target:
return basicView.view return basicView.view
return self.page return self.page
@ -139,6 +141,8 @@ class NodeView(BaseView):
@Lazy @Lazy
def targetObject(self): def targetObject(self):
# xxx: use virtualTargetObject
#return self.virtualTargetObject
return self.context.target return self.context.target
@Lazy @Lazy
@ -158,7 +162,6 @@ class NodeView(BaseView):
def renderTarget(self): def renderTarget(self):
target = self.target target = self.target
#targetAdapter = target.typeAdapter
return target is not None and target.render() or u'' return target is not None and target.render() or u''
@Lazy @Lazy
@ -242,9 +245,10 @@ class NodeView(BaseView):
return item.context == self.context or item.context in self.parents return item.context == self.context or item.context in self.parents
def targetDefaultView(self): def targetDefaultView(self):
target = self.request.annotations.get('loops.view', {}).get('target') target = self.virtualTargetObject
if target is None: #target = self.request.annotations.get('loops.view', {}).get('target')
target = self.targetObject #if target is None:
# target = self.targetObject
if target is not None: if target is not None:
name = zapi.getDefaultViewName(target, self.request) name = zapi.getDefaultViewName(target, self.request)
targetView = zapi.getMultiAdapter((target, self.request), targetView = zapi.getMultiAdapter((target, self.request),
@ -258,7 +262,7 @@ class NodeView(BaseView):
def virtualTargetObject(self): def virtualTargetObject(self):
target = self.request.annotations.get('loops.view', {}).get('target') target = self.request.annotations.get('loops.view', {}).get('target')
if target is None: if target is None:
target = self.targetObject target = self.context.target
return target return target
@Lazy @Lazy

View file

@ -25,30 +25,34 @@
</div> </div>
<div tal:define="target nocall:item/target" <div tal:define="target nocall:item/target"
tal:condition="nocall:target"> tal:condition="nocall:target">
<metal:editicons define-macro="editicons"> <tal:ignore condition="nothing">
<div class="subcolumn" id="xedit_icon" <metal:editicons define-macro="editicons">
tal:condition="item/xeditable | nothing"> <div class="subcolumn" id="xedit_icon"
<a href="#" title="Edit" style="padding: 5px" tal:condition="item/xeditable | nothing">
tal:attributes="href string:${item/realTargetUrl}/external_edit; <a href="#" title="Edit" style="padding: 5px"
title string:Edit '${target/title}' with External Editor"><img tal:attributes="href string:${item/realTargetUrl}/external_edit;
src="edit.gif" alt="Edit" title string:Edit '${target/title}' with External Editor"><img
tal:attributes="src context/++resource++edit.gif" /></a> src="edit.gif" alt="Edit"
</div> tal:attributes="src context/++resource++edit.gif" /></a>
<div class="subcolumn" id="inlineedit_icon" </div>
tal:condition="item/inlineEditable"> <div class="subcolumn" id="inlineedit_icon"
<a href="#" title="Edit" style="padding: 5px" tal:condition="item/inlineEditable">
tal:attributes="title string:Edit '${target/title}' with Inline Editor; <a href="#" title="Edit" style="padding: 5px"
onclick python: item.inlineEdit(id)"><img tal:attributes="title string:Edit '${target/title}' with Inline Editor;
src="edit.gif" alt="Edit" onclick python: item.inlineEdit(id)"><img
tal:attributes="src context/++resource++edit.gif" /></a> src="edit.gif" alt="Edit"
</div> tal:attributes="src context/++resource++edit.gif" /></a>
</metal:editicons> </div>
</metal:editicons>
</tal:ignore>
<div class="content-1 subcolumn" id="1.body" <div class="content-1 subcolumn" id="1.body"
tal:define="item nocall:target"
tal:attributes="class string:content-$level; tal:attributes="class string:content-$level;
id id; id id;
ondblclick python: item.openEditWindow('configure.html')" ondblclick python: target.openEditWindow('configure.html')">
tal:content="structure item/renderTarget"> <metal:body use-macro="item/macro">
The body The body
</metal:body>
</div> </div>
</div> </div>
</tal:body> </tal:body>

View file

@ -1,6 +1,6 @@
<metal:block define-macro="render"> <metal:block define-macro="render">
<div tal:attributes="ondblclick python: item.openEditWindow('configure.html')"> <div tal:attributes="ondblclick python: item.openEditWindow('configure.html')">
<h3 tal:content="item/title">Title</h3> <h1 tal:content="item/title">Title</h1>
<tal:body define="itemNum view/itemNum; <tal:body define="itemNum view/itemNum;
id string:$itemNum.body;"> id string:$itemNum.body;">
<tal:edit define="target nocall:item; <tal:edit define="target nocall:item;

View file

@ -277,6 +277,24 @@ i.e. the 'topic' concept, via an adapter:
True True
Simple access to type information with BaseView
-----------------------------------------------
loops browser views are typically based on a common parent class, BaseView.
BaseView provides simple access to a lot of information often needed for
browser views; among others also some important informations about the
context object's type:
>>> from loops.browser.common import BaseView
>>> view = BaseView(cc1, TestRequest)
>>> view.typeTitle
u'Topic'
>>> view.typeInterface
<InterfaceClass ...ITopic>
>>> view.typeAdapter
<Topic object ...>
Concepts as queries Concepts as queries
------------------- -------------------

View file

@ -84,10 +84,6 @@ class LoopsType(BaseType):
@Lazy @Lazy
def factory(self): def factory(self):
ti = self.typeInterface ti = self.typeInterface
#if ti is not None:
# fn = getattr(ti, 'factoryName', None)
# if fn:
# return self.factoryMapping.get(fn, Concept)
return self.factoryMapping.get(self.qualifiers[0], Concept) return self.factoryMapping.get(self.qualifiers[0], Concept)
@Lazy @Lazy