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()
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.
(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.app.renderer import rest

View file

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

View file

@ -562,7 +562,15 @@
<page
name="create_object.html"
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"
/>

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>
</tr>
<tr>
<td><label for="dlg.create.search.type">Type:</label></td>
<td><label for="form.concept.search.type">Type:</label></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
string:setConceptTypeForComboBox(
'dlg.create.search.type', 'dlg.create.search.text')">
'form.concept.search.type', 'form.concept.search.text')">
<tal:types repeat="type view/conceptTypesForSearch">
<option value="loops:*"
i18n:translate=""
@ -48,10 +48,10 @@
</tal:types>
</select>&nbsp;&nbsp;
</td>
<td><label for="dlg.create.search.text">Search text:</label></td>
<td><label for="form.concept.search.text">Search text:</label></td>
<td>
<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
string:${context/@@absolute_url}/listConceptsForComboBox.js?searchString=%{searchString}&searchType=" />
</td>

View file

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

View file

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

View file

@ -1,6 +1,6 @@
<metal:block define-macro="render">
<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;
id string:$itemNum.body;">
<tal:edit define="target nocall:item;

View file

@ -277,6 +277,24 @@ i.e. the 'topic' concept, via an adapter:
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
-------------------

View file

@ -84,10 +84,6 @@ class LoopsType(BaseType):
@Lazy
def factory(self):
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)
@Lazy