diff --git a/combo/apps/search/__init__.py b/combo/apps/search/__init__.py
index e551722d..2a641214 100644
--- a/combo/apps/search/__init__.py
+++ b/combo/apps/search/__init__.py
@@ -17,6 +17,9 @@
import django.apps
from django.utils.translation import ugettext_lazy as _
+from .engines import engines
+
+
class AppConfig(django.apps.AppConfig):
name = 'combo.apps.search'
verbose_name = _('Search')
diff --git a/combo/apps/search/engines.py b/combo/apps/search/engines.py
new file mode 100644
index 00000000..282b5fbe
--- /dev/null
+++ b/combo/apps/search/engines.py
@@ -0,0 +1,35 @@
+# combo - content management system
+# Copyright (C) 2014-2018 Entr'ouvert
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+from django.conf import settings
+
+
+class Engines(object):
+ """Singleton object that serves as a registry of classes providing search
+ engines."""
+
+ def __init__(self):
+ self.engines = {}
+
+ def register(self, key, **options):
+ self.engines[key] = options
+
+ def get(self, key):
+ if key in settings.COMBO_SEARCH_SERVICES:
+ return settings.COMBO_SEARCH_SERVICES[key]
+ return self.engines.get(key)
+
+engines = Engines() # singleton object
diff --git a/combo/apps/search/models.py b/combo/apps/search/models.py
index 28af4c4e..088422b4 100644
--- a/combo/apps/search/models.py
+++ b/combo/apps/search/models.py
@@ -29,6 +29,8 @@ from combo.data.models import CellBase
from combo.data.library import register_cell_class
from combo.utils import get_templated_url
+from . import engines
+
@register_cell_class
class SearchCell(CellBase):
@@ -55,10 +57,7 @@ class SearchCell(CellBase):
def search_services(self):
services = []
for service_slug in self._search_services.get('data') or []:
- if service_slug == '_text':
- service = {'url': reverse('api-search') + '?q=%(q)s', 'label': _('Page Contents')}
- else:
- service = settings.COMBO_SEARCH_SERVICES.get(service_slug)
+ service = engines.get(service_slug)
if service and service.get('url'):
service['slug'] = service_slug
services.append(service)
diff --git a/combo/data/apps.py b/combo/data/apps.py
index f6ab3cd4..52b1dd96 100644
--- a/combo/data/apps.py
+++ b/combo/data/apps.py
@@ -15,7 +15,18 @@
# along with this program. If not, see .
from django.apps import AppConfig
+from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext_lazy as _
+
class DataConfig(AppConfig):
name = 'combo.data'
verbose_name = 'data'
+
+ def ready(self):
+ # register built-in search engine for page contents
+ from combo.apps.search import engines
+ engines.register('_text',
+ url=reverse('api-search') + '?q=%(q)s',
+ label=_('Page Contents')
+ )
diff --git a/tests/test_search.py b/tests/test_search.py
index f08d8b1b..8eed48ca 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -40,7 +40,7 @@ class SearchServices(object):
settings.COMBO_SEARCH_SERVICES = self.search_services
def __exit__(self, *args, **kwargs):
- delattr(settings, 'COMBO_SEARCH_SERVICES')
+ settings.COMBO_SEARCH_SERVICES = {}
def test_search_cell(app):
with SearchServices(SEARCH_SERVICES):