more on entry forms; concept search combo box now provides UID
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1355 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
cb194f0f24
commit
2743e01d78
7 changed files with 64 additions and 21 deletions
|
@ -4,10 +4,14 @@
|
||||||
<head></head>
|
<head></head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
||||||
<metal:body fill-slot="body"
|
<metal:body fill-slot="body"
|
||||||
tal:define="item nocall:view">
|
tal:define="item nocall:view">
|
||||||
<metal:block use-macro="views/resource_macros/render" />
|
<h1 tal:content="item/title">Title</h1>
|
||||||
|
<div class="content-1" id="1.body"
|
||||||
|
tal:content="structure item/render">
|
||||||
|
The body
|
||||||
|
</div>
|
||||||
</metal:body>
|
</metal:body>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
"""
|
"""
|
||||||
View class for Node objects.
|
Classes for form presentation and processing.
|
||||||
|
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
@ -58,4 +58,21 @@ class CreateObjectForm(NodeView, Form):
|
||||||
class CreateObject(FormController):
|
class CreateObject(FormController):
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
prefix = 'form.'
|
||||||
|
form = self.request.form
|
||||||
print 'updating...'
|
print 'updating...'
|
||||||
|
# determine name
|
||||||
|
# create object, assign basic concepts (type, ...)
|
||||||
|
for k in form.keys():
|
||||||
|
if k.startswith(prefix):
|
||||||
|
fn = k[len(prefix):]
|
||||||
|
value = form[k]
|
||||||
|
if fn.startswith('concept.search.'):
|
||||||
|
self.assignConcepts(fn, value)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
#setattr(obj, fn, value)
|
||||||
|
print fn, value
|
||||||
|
|
||||||
|
def assignConcepts(self, fieldName, value):
|
||||||
|
pass
|
||||||
|
|
|
@ -46,7 +46,8 @@
|
||||||
</metal:editicons>
|
</metal:editicons>
|
||||||
</tal:ignore>
|
</tal:ignore>
|
||||||
<div class="content-1 subcolumn" id="1.body"
|
<div class="content-1 subcolumn" id="1.body"
|
||||||
tal:define="item nocall:target"
|
tal:define="node nocall:item;
|
||||||
|
item nocall:target"
|
||||||
tal:attributes="class string:content-$level;
|
tal:attributes="class string:content-$level;
|
||||||
id id;
|
id id;
|
||||||
ondblclick python: target.openEditWindow('configure.html')">
|
ondblclick python: target.openEditWindow('configure.html')">
|
||||||
|
@ -205,7 +206,7 @@
|
||||||
<metal:actions define-macro="actions">
|
<metal:actions define-macro="actions">
|
||||||
<div class="menu-2"
|
<div class="menu-2"
|
||||||
tal:define="dummy view/registerDojo">
|
tal:define="dummy view/registerDojo">
|
||||||
<a href="#"
|
<a href="javascript:createObjectDialog()"
|
||||||
onclick="createObjectDialog(); return false;">
|
onclick="createObjectDialog(); return false;">
|
||||||
Create Resource...
|
Create Resource...
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<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;
|
||||||
item nocall:view;">
|
item nocall:node|nocall:view;">
|
||||||
<div metal:use-macro="views/node_macros/editicons" />
|
<div metal:use-macro="views/node_macros/editicons" />
|
||||||
</tal:edit>
|
</tal:edit>
|
||||||
<div class="content-1" id="1.body"
|
<div class="content-1" id="1.body"
|
||||||
|
|
18
query.py
18
query.py
|
@ -25,8 +25,9 @@ $Id$
|
||||||
from zope import schema, component
|
from zope import schema, component
|
||||||
from zope.interface import Interface, Attribute, implements
|
from zope.interface import Interface, Attribute, implements
|
||||||
from zope.app import traversing
|
from zope.app import traversing
|
||||||
from zope.cachedescriptors.property import Lazy
|
|
||||||
from zope.app.catalog.interfaces import ICatalog
|
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.interfaces import IConcept
|
||||||
from loops.common import AdapterBase
|
from loops.common import AdapterBase
|
||||||
|
@ -72,13 +73,17 @@ class BaseQuery(object):
|
||||||
result = set(r for r in result if r.getLoopsRoot() == self.loopsRoot)
|
result = set(r for r in result if r.getLoopsRoot() == self.loopsRoot)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def queryConceptsWithChildren(self, title=None, type=None):
|
def queryConceptsWithChildren(self, title=None, type=None, uid=None):
|
||||||
if title: # there are a few characters that the index doesn't like
|
if title: # there are a few characters that the index doesn't like
|
||||||
title = title.replace('(', ' ').replace(')', ' ')
|
title = title.replace('(', ' ').replace(')', ' ')
|
||||||
if not title and (type is None or '*' in type):
|
if not title and not uid and (type is None or '*' in type):
|
||||||
return None
|
return None
|
||||||
result = set()
|
result = set()
|
||||||
queue = list(self.queryConcepts(title=title, type=type))
|
if not uid:
|
||||||
|
queue = list(self.queryConcepts(title=title, type=type))
|
||||||
|
else:
|
||||||
|
intIds = component.getUtility(IIntIds)
|
||||||
|
queue = [intIds.getObject(int(uid))]
|
||||||
concepts = []
|
concepts = []
|
||||||
while queue:
|
while queue:
|
||||||
c = queue.pop(0)
|
c = queue.pop(0)
|
||||||
|
@ -96,9 +101,10 @@ class BaseQuery(object):
|
||||||
class FullQuery(BaseQuery):
|
class FullQuery(BaseQuery):
|
||||||
|
|
||||||
def query(self, text=None, type=None, useTitle=True, useFull=False,
|
def query(self, text=None, type=None, useTitle=True, useFull=False,
|
||||||
conceptTitle=None, conceptType=None):
|
conceptTitle=None, conceptUid=None, conceptType=None):
|
||||||
result = set()
|
result = set()
|
||||||
rc = self.queryConceptsWithChildren(title=conceptTitle, type=conceptType)
|
rc = self.queryConceptsWithChildren(title=conceptTitle, uid=conceptUid,
|
||||||
|
type=conceptType)
|
||||||
if not rc and not text and '*' in type: # there should be some sort of selection...
|
if not rc and not text and '*' in type: # there should be some sort of selection...
|
||||||
return result
|
return result
|
||||||
if text or type != 'loops:*': # TODO: this may be highly inefficient!
|
if text or type != 'loops:*': # TODO: this may be highly inefficient!
|
||||||
|
|
|
@ -17,10 +17,11 @@ and setup a simple loops site with a concept manager and some concepts
|
||||||
(with all the type machinery, what in real life is done via standard
|
(with all the type machinery, what in real life is done via standard
|
||||||
ZCML setup):
|
ZCML setup):
|
||||||
|
|
||||||
>>> from cybertools.relation.interfaces import IRelationRegistry
|
|
||||||
>>> from cybertools.relation.registry import DummyRelationRegistry
|
>>> from cybertools.relation.registry import DummyRelationRegistry
|
||||||
|
>>> from cybertools.relation.tests import IntIdsStub
|
||||||
>>> relations = DummyRelationRegistry()
|
>>> relations = DummyRelationRegistry()
|
||||||
>>> component.provideUtility(relations, IRelationRegistry)
|
>>> component.provideUtility(relations)
|
||||||
|
>>> component.provideUtility(IntIdsStub())
|
||||||
|
|
||||||
>>> from loops.type import ConceptType, TypeConcept
|
>>> from loops.type import ConceptType, TypeConcept
|
||||||
>>> from loops.interfaces import ITypeConcept
|
>>> from loops.interfaces import ITypeConcept
|
||||||
|
@ -170,7 +171,7 @@ Now we can fill our search form and execute the query; note that all concepts
|
||||||
found are listed, plus all their children and all resources associated
|
found are listed, plus all their children and all resources associated
|
||||||
with them:
|
with them:
|
||||||
|
|
||||||
>>> form = {'search.3.type': 'loops:concept:topic', 'search.3.text_selected': u'zope'}
|
>>> form = {'search.3.type': 'loops:concept:topic', 'search.3.text': u'zope'}
|
||||||
>>> request = TestRequest(form=form)
|
>>> request = TestRequest(form=form)
|
||||||
>>> resultsView = SearchResults(page, request)
|
>>> resultsView = SearchResults(page, request)
|
||||||
>>> results = list(resultsView.results)
|
>>> results = list(resultsView.results)
|
||||||
|
@ -179,7 +180,7 @@ with them:
|
||||||
>>> results[0].context.__name__
|
>>> results[0].context.__name__
|
||||||
u'plone'
|
u'plone'
|
||||||
|
|
||||||
>>> form = {'search.3.type': 'loops:concept:topic', 'search.3.text_selected': u'zope3'}
|
>>> form = {'search.3.type': 'loops:concept:topic', 'search.3.text': u'zope3'}
|
||||||
>>> request = TestRequest(form=form)
|
>>> request = TestRequest(form=form)
|
||||||
>>> resultsView = SearchResults(page, request)
|
>>> resultsView = SearchResults(page, request)
|
||||||
>>> results = list(resultsView.results)
|
>>> results = list(resultsView.results)
|
||||||
|
@ -192,6 +193,12 @@ 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
|
concepts (optionally restricted to a certain type) by entering text parts
|
||||||
of the concepts' titles:
|
of the concepts' titles:
|
||||||
|
|
||||||
TODO...
|
>>> form = {'searchType': 'loops:concept:topic', 'searchString': u'zo'}
|
||||||
|
>>> request = TestRequest(form=form)
|
||||||
|
>>> view = Search(page, request)
|
||||||
|
>>> view.listConcepts()
|
||||||
|
'[]'
|
||||||
|
|
||||||
|
TODO - more to come...
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ from zope.formlib.namedtemplate import NamedTemplate, NamedTemplateImplementatio
|
||||||
from zope.i18nmessageid import MessageFactory
|
from zope.i18nmessageid import MessageFactory
|
||||||
|
|
||||||
from cybertools.ajax import innerHtml
|
from cybertools.ajax import innerHtml
|
||||||
|
from cybertools.relation.interfaces import IRelationRegistry
|
||||||
from cybertools.typology.interfaces import ITypeManager
|
from cybertools.typology.interfaces import ITypeManager
|
||||||
from loops.browser.common import BaseView
|
from loops.browser.common import BaseView
|
||||||
from loops.query import ConceptQuery, FullQuery
|
from loops.query import ConceptQuery, FullQuery
|
||||||
|
@ -77,9 +78,14 @@ class Search(BaseView):
|
||||||
title = request.get('searchString', '').replace('(', ' ').replace(')', ' ')
|
title = request.get('searchString', '').replace('(', ' ').replace(')', ' ')
|
||||||
type = request.get('searchType') or 'loops:concept:*'
|
type = request.get('searchType') or 'loops:concept:*'
|
||||||
result = ConceptQuery(self).query(title=title, type=type)
|
result = ConceptQuery(self).query(title=title, type=type)
|
||||||
|
registry = component.getUtility(IRelationRegistry)
|
||||||
# simple way to provide JSON format:
|
# simple way to provide JSON format:
|
||||||
return str(sorted([[`o.title`[2:-1], `traversing.api.getName(o)`[2:-1]]
|
return str(sorted([[`o.title`[2:-1],
|
||||||
for o in result])).replace('\\\\x', '\\x')
|
`registry.getUniqueIdForObject(o)`]
|
||||||
|
for o in result
|
||||||
|
if o.getLoopsRoot() == self.loopsRoot])).replace('\\\\x', '\\x')
|
||||||
|
#return str(sorted([[`o.title`[2:-1], `traversing.api.getName(o)`[2:-1]]
|
||||||
|
# for o in result])).replace('\\\\x', '\\x')
|
||||||
|
|
||||||
def submitReplacing(self, targetId, formId, view):
|
def submitReplacing(self, targetId, formId, view):
|
||||||
self.registerDojo()
|
self.registerDojo()
|
||||||
|
@ -106,10 +112,12 @@ class SearchResults(BaseView):
|
||||||
useTitle = request.get('search.2.title')
|
useTitle = request.get('search.2.title')
|
||||||
useFull = request.get('search.2.full')
|
useFull = request.get('search.2.full')
|
||||||
conceptType = request.get('search.3.type', 'loops:concept:*')
|
conceptType = request.get('search.3.type', 'loops:concept:*')
|
||||||
conceptTitle = request.get('search.3.text_selected')
|
conceptTitle = request.get('search.3.text')
|
||||||
|
conceptUid = request.get('search.3.text_selected')
|
||||||
result = FullQuery(self).query(text=text, type=type,
|
result = FullQuery(self).query(text=text, type=type,
|
||||||
useTitle=useTitle, useFull=useFull,
|
useTitle=useTitle, useFull=useFull,
|
||||||
conceptTitle=conceptTitle, conceptType= conceptType)
|
conceptTitle=conceptTitle, conceptUid=conceptUid,
|
||||||
|
conceptType= conceptType)
|
||||||
result = sorted(result, key=lambda x: x.title.lower())
|
result = sorted(result, key=lambda x: x.title.lower())
|
||||||
return self.viewIterator(result)
|
return self.viewIterator(result)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue