quicksearch improvements; make search process in relation widget more flexible

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3250 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-02-25 17:42:23 +00:00
parent 9248fa988f
commit ec7dd9391d
12 changed files with 88 additions and 49 deletions

View file

@ -24,7 +24,9 @@
<div metal:use-macro="views/node_macros/object_actions" />
</tal:actions>
<h1 tal:attributes="ondblclick item/openEditWindow">
<a name="top"
<a name="top" />
<a tal:omit-tag="python: level > 1"
tal:attributes="href request/URL"
tal:content="item/title">Title</a>
</h1>
<p tal:define="description description|item/renderedDescription"

View file

@ -298,8 +298,9 @@ div.menu-1, div.menu-2 {
}
.listing .object-actions {
float: none;
padding: 0;
text-align: left;
text-align: center;
}
.icon-action {

View file

@ -1,4 +1,4 @@
<tal:show i18n:domain="zope">
<tal:show i18n:domain="loops">
<html metal:use-macro="context/@@skin_macros/page">
<head></head>
<body>

View file

@ -105,9 +105,10 @@ class NodeView(BaseView):
cm.register('top_actions', 'top_actions', name='multi_actions',
subMacros=[i18n_macros.macros['language_switch']])
if self.globalOptions('expert.quicksearch'):
from loops.expert.browser.search import search_macros
from loops.expert.browser.search import searchMacrosTemplate
cm.register('top_actions', 'top_quicksearch', name='multi_actions',
subMacros=[search_macros.macros['quicksearch']], priority=20)
subMacros=[searchMacrosTemplate.macros['quicksearch']],
priority=20)
cm.register('portlet_left', 'navigation', title='Navigation',
subMacro=node_macros.macros['menu'])
if canWrite(self.context, 'title') or (

View file

@ -6,7 +6,9 @@
<tal:actions condition="view/showObjectActions">
<div metal:use-macro="views/node_macros/object_actions" />
</tal:actions>
<h1 tal:content="item/title">Title</h1>
<h1><a tal:omit-tag="python: level > 1"
tal:attributes="href request/URL"
tal:content="item/title">Title</a></h1>
<p tal:define="description description|item/description"
tal:condition="description">
<i tal:content="description">Description</i></p>

View file

@ -13,11 +13,18 @@
</div>
<div metal:define-macro="quicksearch_view" id="search.results"
tal:define="item nocall:view">
<h1 i18n:translate="">Search results</h1><br />
<metal:results use-macro="item/search_macros/results" />
</div>
<div metal:define-macro="search_results" id="search.results"
tal:define="item nocall:view">
<fieldset class="box">
<h2 i18n:translate="">Search results</h2>
<metal:results define-macro="results">
<h2 i18n:translate="">Search results</h2>
<table class="listing" summary="Search results"
i18n:attributes="summary">
<thead>
@ -36,11 +43,11 @@
<tbody>
<tal:items tal:repeat="row item/results">
<tal:item define="class python: repeat['row'].odd() and 'even' or 'odd';
description row/description">
description row/description;
targetUrl python:view.getUrlForTarget(row)">
<tr tal:attributes="class class">
<td>
<a tal:attributes="href
string:${view/url}/.target${row/uniqueId}?version=this;
<a tal:attributes="href string:$targetUrl?version=this;
title description">
<img tal:define="icon row/icon"
tal:condition="icon"
@ -55,7 +62,8 @@
<a href="#"
tal:content="versionId"
tal:omit-tag="python: versionId and versionId=='1.1'"
tal:attributes="href string:${view/url}/.target${row/uniqueId}?loops.viewName=listversions">1.1</a>
tal:attributes="href
string:$targetUrl?loops.viewName=listversions">1.1</a>
</td>
</tal:version>
<td class="nowrap number">

View file

@ -34,15 +34,19 @@ from loops import util
from loops.util import _
search_macros = ViewPageTemplateFile('search.pt')
searchMacrosTemplate = ViewPageTemplateFile('search.pt')
class SearchResults(NodeView):
""" Provides results listing """
@Lazy
def search_macros(self):
return searchMacrosTemplate.macros
@Lazy
def macro(self):
return search_macros.macros['search_results']
return self.search_macros['quicksearch_view']
@Lazy
def item(self):
@ -52,7 +56,7 @@ class SearchResults(NodeView):
def results(self):
form = self.request.form
text = form.get('search.text')
type = self.globalOptions('expert.quicksearch')[0]
type = self.globalOptions('expert.quicksearch')
result = FullQuery(self).query(text=text, type=type,
useTitle=True, useFull=True,)
return self.viewIterator(result)

View file

@ -124,31 +124,34 @@ class FullQuery(BaseQuery):
return ScoredSet(result, scores)
if text or type != 'loops:*': # TODO: this may be highly inefficient!
cat = self.catalog
if type.endswith('*'):
start = type[:-1]
end = start + '\x7f'
else:
start = end = type
criteria = {'loops_type': (start, end),}
if useFull and text:
criteria['loops_text'] = text
r1 = cat.apply(criteria) #r1 = set(cat.searchResults(**criteria))
else:
r1 = IFBucket() #r1 = set()
if useTitle and text:
if 'loops_text' in criteria:
del criteria['loops_text']
criteria['loops_title'] = text
r2 = cat.apply(criteria) #r2 = set(cat.searchResults(**criteria))
else:
r2 = IFBucket() #r2 = set()
if not r1 and not r2:
r1 = cat.apply(criteria) # search only for type
x, uids = weightedUnion(r1, r2) #result = r1.union(r2)
for r, score in uids.items():
obj = intids.getObject(r)
result.add(obj)
scores[obj] = score
if isinstance(type, basestring):
type = [type]
for tp in type:
if tp.endswith('*'):
start = tp[:-1]
end = start + '\x7f'
else:
start = end = tp
criteria = {'loops_type': (start, end),}
if useFull and text:
criteria['loops_text'] = text
r1 = cat.apply(criteria) #r1 = set(cat.searchResults(**criteria))
else:
r1 = IFBucket() #r1 = set()
if useTitle and text:
if 'loops_text' in criteria:
del criteria['loops_text']
criteria['loops_title'] = text
r2 = cat.apply(criteria) #r2 = set(cat.searchResults(**criteria))
else:
r2 = IFBucket() #r2 = set()
if not r1 and not r2:
r1 = cat.apply(criteria) # search only for type
x, uids = weightedUnion(r1, r2) #result = r1.union(r2)
for r, score in uids.items():
obj = intids.getObject(r)
result.add(obj)
scores[obj] = score
if rc is not None:
if result:
result = result.intersection(rc)

View file

@ -201,8 +201,10 @@ class BaseWorkItemsView(object):
def baseCriteria(self):
result = {}
form = self.request.form
tsFrom = parseDate(form.get('wi_from') or self.options.wi_from)
tsTo = parseDate(form.get('wi_to') or self.options.wi_to)
tsFrom = parseDate(form.get('wi_from') or
self.options.wi_from or self.typeOptions.wi_from)
tsTo = parseDate(form.get('wi_to') or
self.options.wi_to or self.typeOptions.wi_to)
if tsTo:
tsTo += 3600 * 24 - 1 # include full end date
if tsFrom or tsTo:

View file

@ -44,6 +44,10 @@ relation_macros = ViewPageTemplateFile('relation_macros.pt')
class BaseRelationFieldInstance(object):
@Lazy
def selection_view(self):
return getattr(self.context, 'selection_view', 'listConceptsForComboBox.js')
@Lazy
def typesParams(self):
result = []

View file

@ -7,7 +7,7 @@
tal:define="fieldInstance field/getFieldInstance;
types fieldInstance/typesParams">
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
tal:attributes="url string:listConceptsForComboBox.js$types;
tal:attributes="url string:${fieldInstance/selection_view}$types;
jsId string:${name}_search_store" >
</div>
<div tal:attributes="id string:${name}_values">
@ -38,7 +38,7 @@
tal:define="fieldInstance field/getFieldInstance;
types fieldInstance/typesParams">
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
tal:attributes="url string:listConceptsForComboBox.js$types;
tal:attributes="url string:${fieldInstance/selection_view}$types;
jsId string:${name}_search_store" >
</div>
<div tal:define="obj data/?name"

View file

@ -35,7 +35,7 @@ from cybertools.relation.interfaces import IRelationRegistry
from cybertools.typology.interfaces import ITypeManager
from loops.browser.common import BaseView
from loops.browser.node import NodeView
from loops.common import adapted
from loops.common import adapted, AdapterBase
from loops.expert.concept import ConceptQuery, FullQuery
from loops import util
from loops.util import _
@ -108,18 +108,19 @@ class Search(BaseView):
if not isinstance(types, (list, tuple)):
types = [types]
for type in types:
result = ConceptQuery(self).query(title=title or None, type=type,
exclude=('system',))
result = self.executeQuery(title=title or None, type=type,
exclude=('system',))
for o in result:
if o.getLoopsRoot() == self.loopsRoot:
name = adapted(o, self.languageInfo).title
adObj = adapted(o, self.languageInfo)
name = self.getRowName(adObj)
if title and title.endswith('*'):
title = title[:-1]
sort = ((title and name.startswith(title) and '0' or '1')
+ name.lower())
if o.conceptType is None:
raise ValueError('Concept Type missing for %r.' % name)
data.append({'label': '%s (%s)' % (name, o.conceptType.title),
data.append({'label': self.getRowLabel(adObj, name),
'name': name,
'id': util.getUidForObject(o),
'sort': sort})
@ -127,13 +128,24 @@ class Search(BaseView):
if not title:
data.insert(0, {'label': '', 'name': '', 'id': ''})
json = []
for item in data:
for item in data[:20]:
json.append("{label: '%s', name: '%s', id: '%s'}" %
(item['label'], item['name'], item['id']))
json = "{identifier: 'id', items: [%s]}" % ', '.join(json)
#print '***', json
return json
def executeQuery(self, **kw):
return ConceptQuery(self).query(**kw)
def getRowName(self, obj):
return obj.title
def getRowLabel(self, obj, name):
if isinstance(obj, AdapterBase):
obj = obj.context
return '%s (%s)' % (name, obj.conceptType.title)
def submitReplacing(self, targetId, formId, view):
self.registerDojo()
return 'submitReplacing("%s", "%s", "%s"); return false;' % (