First working version: add resource (note) via dojo.Dialog

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1358 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-09-23 10:54:32 +00:00
parent 2743e01d78
commit 63a13d6854
7 changed files with 137 additions and 35 deletions

View file

@ -346,20 +346,15 @@ We first need a view manager:
>>> nodeChecker = NamesChecker(('body',))
>>> defineChecker(Node, nodeChecker)
>>> loopsRoot['views'] = ViewManager()
>>> views = loopsRoot['views']
>>> views = loopsRoot['views'] = ViewManager()
The view space is typically built up with nodes; a node may be a top-level
menu that may contain other nodes as menu or content items:
>>> m1 = Node(u'Menu')
>>> views['m1'] = m1
>>> m11 = Node(u'Zope')
>>> m1['m11'] = m11
>>> m111 = Node(u'Zope in General')
>>> m11['m111'] = m111
>>> m112 = Node(u'Zope 3')
>>> m11['m112'] = m112
>>> m1 = views['m1'] = Node(u'Menu')
>>> m11 = m1['m11'] = Node(u'Zope')
>>> m111 = m11['m111'] = Node(u'Zope in General')
>>> m112 = m11['m112'] = Node(u'Zope 3')
>>> m112.title
u'Zope 3'
>>> m112.description
@ -616,8 +611,56 @@ to the bottom, and to the top.
>>> m11.keys()
['m111', 'm114', 'm112', 'm113']
End-user Forms
==============
The browser.form and related modules provide additional support for forms
that are shown in the end-user interface.
>>> from loops.browser.form import CreateObjectForm, CreateObject, ResourceNameChooser
>>> form = CreateObjectForm(m112, TestRequest)
>>> from loops.interfaces import INote, ITypeConcept
>>> from loops.type import TypeConcept
>>> from loops.resource import NoteAdapter
>>> component.provideAdapter(TypeConcept)
>>> component.provideAdapter(NoteAdapter)
>>> note_tc = concepts['note'] = Concept('Note')
>>> note_tc.conceptType = typeObject
>>> ITypeConcept(note_tc).typeInterface = INote
>>> component.provideAdapter(ResourceNameChooser)
>>> request = TestRequest(form={'form.title': 'Test Note'})
>>> view = NodeView(m112, request)
>>> cont = CreateObject(view, request)
>>> cont.update()
True
>>> sorted(resources.keys())
[...u'test_note'...]
>>> resources['test_note'].title
'Test Note'
If there is a concept selected in the combo box we assign this to the newly
created object:
>>> from loops import util
>>> topicUid = util.getUidForObject(topic)
>>> request = TestRequest(form={'form.title': 'Test Note',
... 'form.concept.search.text_selected': topicUid})
>>> view = NodeView(m112, request)
>>> cont = CreateObject(view, request)
>>> cont.update()
True
>>> sorted(resources.keys())
[...u'test_note-2'...]
>>> note = resources['test_note-2']
>>> sorted(t.__name__ for t in note.getConcepts())
[u'note', u'topic']
Import/Export
-------------
=============
Nodes may be exported to and loaded from external sources, typically
file representations that allow the transfer of nodes from one Zope

View file

@ -574,6 +574,8 @@
permission="zope.ManageContent"
/>
<zope:adapter factory="loops.browser.form.ResourceNameChooser" />
<!-- inner HTML views -->
<page

View file

@ -23,12 +23,25 @@ $Id$
"""
from zope import component, interface, schema
from zope.component import adapts
from zope.event import notify
from zope.app.event.objectevent import ObjectCreatedEvent, ObjectModifiedEvent
from zope.app.container.interfaces import INameChooser
from zope.app.container.contained import NameChooser
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from zope.formlib.form import Form, FormFields
from zope.publisher.interfaces import BadRequest
from cybertools.ajax import innerHtml
from cybertools.browser.controller import FormController
from cybertools.browser.form import FormController
from cybertools.typology.interfaces import IType
from loops.interfaces import IResourceManager
from loops.browser.node import NodeView
from loops.resource import Resource
from loops import util
from loops.util import _
class CreateObjectForm(NodeView, Form):
@ -39,7 +52,7 @@ class CreateObjectForm(NodeView, Form):
form_fields = FormFields(
schema.TextLine(__name__='title', title=_(u'Title')),
schema.Text(__name__='body', title=_(u'Body Text')),
schema.Text(__name__='data', title=_(u'Body Text')),
schema.TextLine(__name__='linkUrl', title=_(u'Link'), required=False),
)
@ -48,8 +61,10 @@ class CreateObjectForm(NodeView, Form):
def __init__(self, context, request):
super(CreateObjectForm, self).__init__(context, request)
def setUp(self):
self.setUpWidgets()
self.widgets['body'].height = 3
self.widgets['data'].height = 3
def __call__(self):
return innerHtml(self)
@ -57,22 +72,48 @@ class CreateObjectForm(NodeView, Form):
class CreateObject(FormController):
@Lazy
def loopsRoot(self):
return self.view.loopsRoot
def update(self):
prefix = 'form.'
conceptPrefix = 'concept.'
form = self.request.form
print 'updating...'
# determine name
# create object, assign basic concepts (type, ...)
obj = Resource()
container = self.loopsRoot.getResourceManager()
title = form.get('form.title')
if not title:
raise BadRequest('Title field is empty')
name = INameChooser(container).chooseName(title, obj)
container[name] = obj
obj.resourceType = self.loopsRoot.getConceptManager()['note']
adapter = IType(obj).typeInterface(obj)
for k in form.keys():
if k.startswith(prefix):
fn = k[len(prefix):]
if fn in ('action',):
continue
value = form[k]
if fn.startswith('concept.search.'):
self.assignConcepts(fn, value)
if fn.startswith(conceptPrefix):
self.assignConcepts(obj, fn[len(conceptPrefix):], value)
else:
pass
#setattr(obj, fn, value)
print fn, value
setattr(adapter, fn, value)
notify(ObjectCreatedEvent(obj))
notify(ObjectModifiedEvent(obj))
return True
def assignConcepts(self, fieldName, value):
pass
def assignConcepts(self, obj, fieldName, value):
if fieldName == 'search.text_selected':
concept = util.getObjectForUid(value)
obj.assignConcept(concept)
class ResourceNameChooser(NameChooser):
adapts(IResourceManager)
def chooseName(self, title, obj):
name = title.replace(' ', '_').lower()
name = super(ResourceNameChooser, self).chooseName(name, obj)
return name

View file

@ -1,6 +1,6 @@
<metal:block define-macro="create">
<div>
<form method="get">
<div tal:define="dummy view/setUp">
<form method="post">
<input type="hidden" name="form.action" value="create"
tal:attributes="value view/form_action" />
<table cellpadding="3" class="form">
@ -10,6 +10,7 @@
i18n:translate="">Create Information Object</span>
</th>
</tr>
<tr tal:repeat="widget view/widgets">
<td class="label"
tal:define="hint widget/hint">
@ -30,6 +31,7 @@
</div>
</td>
</tr>
<tr>
<td colspan="4" class="headline">Assign Concept(s)</td>
</tr>

View file

@ -26,12 +26,12 @@ from zope import schema, component
from zope.interface import Interface, Attribute, implements
from zope.app import traversing
from zope.app.catalog.interfaces import ICatalog
from zope.app.intid.interfaces import IIntIds
from zope.cachedescriptors.property import Lazy
from loops.interfaces import IConcept
from loops.common import AdapterBase
from loops.type import TypeInterfaceSourceList
from loops import util
from loops.util import _
@ -82,8 +82,7 @@ class BaseQuery(object):
if not uid:
queue = list(self.queryConcepts(title=title, type=type))
else:
intIds = component.getUtility(IIntIds)
queue = [intIds.getObject(int(uid))]
queue = [util.getObjectForUid(uid)]
concepts = []
while queue:
c = queue.pop(0)

View file

@ -119,6 +119,7 @@ purposes fairly primitive) catalog and a resource we can search for:
... implements(ICatalog)
... def searchResults(self, **criteria):
... name = criteria.get('loops_title')
... if name.endswith('*'): name = name[:-1]
... type = criteria.get('loops_type', ('resource',))
... if name:
... if 'concept' in type[0]:
@ -156,10 +157,10 @@ Search via related concepts
We first have to prepare some test concepts (topics); we also assign our test
resource (rplone) from above to one of the topics:
>>> czope = concepts['zope'] = Concept('Zope')
>>> czope2 = concepts['zope2'] = Concept('Zope 2')
>>> czope3 = concepts['zope3'] = Concept('Zope 3')
>>> cplone = concepts['plone'] = Concept('Plone')
>>> czope = concepts['zope'] = Concept(u'Zope')
>>> czope2 = concepts['zope2'] = Concept(u'Zope 2')
>>> czope3 = concepts['zope3'] = Concept(u'Zope 3')
>>> cplone = concepts['plone'] = Concept(u'Plone')
>>> for c in (czope, czope2, czope3, cplone):
... c.conceptType = topic
>>> czope.assignChild(czope2)
@ -193,11 +194,11 @@ To support easy entry of concepts to search for we can preselect the available
concepts (optionally restricted to a certain type) by entering text parts
of the concepts' titles:
>>> form = {'searchType': 'loops:concept:topic', 'searchString': u'zo'}
>>> form = {'searchType': 'loops:concept:topic', 'searchString': u'zope'}
>>> request = TestRequest(form=form)
>>> view = Search(page, request)
>>> view.listConcepts()
'[]'
"[['Zope', '23']]"
TODO - more to come...

14
util.py
View file

@ -22,6 +22,8 @@ Utility functions.
$Id$
"""
from zope import component
from zope.app.intid.interfaces import IIntIds
from zope.interface import directlyProvides, directlyProvidedBy
from zope.i18nmessageid import MessageFactory
from zope.schema import vocabulary
@ -53,3 +55,15 @@ def nl2br(text):
return '<br />\n'.join(x.replace('\r', '') for x in text.split('\n'))
else: # gracefully handle Mac line endings
return '<br />\n'.join(text.split('\r'))
def getObjectForUid(uid):
if uid == '*': # wild card
return '*'
intIds = component.getUtility(IIntIds)
return intIds.getObject(int(uid))
def getUidForObject(obj):
if obj == '*': # wild card
return '*'
intIds = component.getUtility(IIntIds)
return intIds.queryId(obj)