summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrédéric Péters <fpeters@entrouvert.com>2018-08-09 08:31:20 (GMT)
committerFrédéric Péters <fpeters@entrouvert.com>2018-08-31 14:01:16 (GMT)
commit1b6a015539102687b61e3b22727cd1739f94a5a8 (patch)
treecceda326cf76ea0155820254503be58547da8de0
parent90a11b1328f4e73c0a63ccf194e9ebaac4038c5b (diff)
downloadcombo-1b6a015539102687b61e3b22727cd1739f94a5a8.zip
combo-1b6a015539102687b61e3b22727cd1739f94a5a8.tar.gz
combo-1b6a015539102687b61e3b22727cd1739f94a5a8.tar.bz2
search: add possibility to specify templates for hits (#25614)
-rw-r--r--combo/apps/search/README13
-rw-r--r--combo/apps/search/models.py12
-rw-r--r--tests/test_search.py31
3 files changed, 56 insertions, 0 deletions
diff --git a/combo/apps/search/README b/combo/apps/search/README
index 5ef850c..137f4bd 100644
--- a/combo/apps/search/README
+++ b/combo/apps/search/README
@@ -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}}',
+ },
+ }
diff --git a/combo/apps/search/models.py b/combo/apps/search/models.py
index 97a241c..cac995a 100644
--- a/combo/apps/search/models.py
+++ b/combo/apps/search/models.py
@@ -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)
diff --git a/tests/test_search.py b/tests/test_search.py
index 276f564..909cb5a 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -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')