search: add possibility to specify templates for hits (#25614)
This commit is contained in:
parent
90a11b1328
commit
1b6a015539
|
@ -29,3 +29,16 @@ which is sent to template 'combo/search-cell-results.html'
|
|||
If the cell slug is "foo" and a variable named "foo" exists in the
|
||||
query_string, it is added to the global page context, so it can be
|
||||
used, for example, by a JsonCell.
|
||||
|
||||
|
||||
It is also possible to extend the search service definition with custom
|
||||
templates for hit URLs and labels:
|
||||
|
||||
COMBO_SEARCH_SERVICES = {
|
||||
'user': {
|
||||
'label': 'Search a user',
|
||||
'url': 'https://.../api/user/?q=%(q)s',
|
||||
'hit_url_template': '/fiche-usager/{{user_name_identifier_0}}/',
|
||||
'hit_label_template': '{{first_name}} {{last_name}}',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ from django.http import HttpResponse
|
|||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.http import quote
|
||||
from django.template import Context, Template
|
||||
|
||||
from jsonfield import JSONField
|
||||
|
||||
|
@ -140,4 +141,15 @@ class SearchCell(CellBase):
|
|||
kwargs['cache_duration'] = service.get('cache_duration', 0)
|
||||
kwargs['remote_service'] = 'auto' if service.get('signature') else None
|
||||
results = requests.get(url, **kwargs).json()
|
||||
hit_templates = {}
|
||||
if service.get('hit_url_template'):
|
||||
hit_templates['url'] = Template(service['hit_url_template'])
|
||||
if service.get('hit_label_template'):
|
||||
hit_templates['text'] = Template(service['hit_label_template'])
|
||||
if service.get('hit_description_template'):
|
||||
hit_templates['description'] = Template(service['hit_description_template'])
|
||||
if hit_templates:
|
||||
for hit in results.get('data') or []:
|
||||
for k, v in hit_templates.items():
|
||||
hit[k] = v.render(Context(hit))
|
||||
return render_response(service, results)
|
||||
|
|
|
@ -138,6 +138,37 @@ def test_search_global_context(app):
|
|||
resp = app.get(url)
|
||||
assert requests_get.call_args[0][0] == 'http://www.example.net/search/foo/'
|
||||
|
||||
def test_search_custom_templates(app):
|
||||
services = {
|
||||
'search2': {
|
||||
'label': 'Search 2',
|
||||
'url': 'http://www.example.net/search/?q=%(q)s',
|
||||
'hit_url_template': 'http://example.net/{{id}}/',
|
||||
'hit_label_template': '{{a}} {{b}}',
|
||||
'hit_description_template': 'description {{a}}',
|
||||
}
|
||||
}
|
||||
with SearchServices(services):
|
||||
page = Page(title='Search', slug='search_page', template_name='standard')
|
||||
page.save()
|
||||
|
||||
cell = SearchCell(page=page, placeholder='content', order=0)
|
||||
cell._search_services = {'data': ['search2']}
|
||||
cell.save()
|
||||
|
||||
with mock.patch('combo.apps.search.models.requests.get') as requests_get:
|
||||
response = {
|
||||
'err': 0,
|
||||
'data': [{'id': '123', 'a': 'A', 'b': 'B'}],
|
||||
}
|
||||
mock_json = mock.Mock()
|
||||
mock_json.json.return_value = response
|
||||
requests_get.return_value = mock_json
|
||||
|
||||
resp = app.get('/ajax/search/%s/search2/?q=foo' % cell.pk, status=200)
|
||||
assert resp.text.count('<li>') == 1
|
||||
assert '<li><a href="http://example.net/123/">A B</a>' in resp.text
|
||||
assert '<div>description A</div>' in resp.text
|
||||
|
||||
def test_search_cell_visibility(app):
|
||||
page = Page(title='example page', slug='example-page')
|
||||
|
|
Loading…
Reference in New Issue