Updated advanced search engine to search over tags, themes and collections
authorThierry Florac <thierry.florac@onf.fr>
Tue, 28 Aug 2018 17:24:59 +0200
changeset 899 69b028b6eecb
parent 898 2d346aeb66d6
child 900 219bf66b812c
Updated advanced search engine to search over tags, themes and collections
src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.mo
src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po
src/pyams_content/root/zmi/search.py
src/pyams_content/root/zmi/templates/advanced-search.pt
src/pyams_content/shared/common/zmi/search.py
src/pyams_content/shared/common/zmi/templates/advanced-search.pt
Binary file src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.mo has changed
--- a/src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po	Tue Aug 28 16:19:33 2018 +0200
+++ b/src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po	Tue Aug 28 17:24:59 2018 +0200
@@ -4953,7 +4953,7 @@
 
 #: src/pyams_content/features/checker/zmi/__init__.py:82
 msgid "No checker available. This content is clean!"
-msgstr "Pas de vérificateur disponible. Ce contenu est propre !"
+msgstr "Pas de vérificateur disponible pour ce contenu."
 
 #: src/pyams_content/features/checker/zmi/__init__.py:78
 #, python-format
--- a/src/pyams_content/root/zmi/search.py	Tue Aug 28 16:19:33 2018 +0200
+++ b/src/pyams_content/root/zmi/search.py	Tue Aug 28 17:24:59 2018 +0200
@@ -17,8 +17,10 @@
 
 # import interfaces
 from hypatia.interfaces import ICatalog
+from pyams_content.component.theme.interfaces import ITagsManager
 from pyams_content.profile.interfaces import IAdminProfile
 from pyams_content.root import ISiteRoot
+from pyams_content.shared.common.interfaces import CONTENT_TYPES_VOCABULARY
 from pyams_content.shared.common.interfaces.zmi import ISiteRootDashboardTable
 from pyams_content.skin.zmi.interfaces import IAllContentsMenu
 from pyams_form.search import ISearchFields, SearchForm, SearchView, SearchResultsView
@@ -45,6 +47,8 @@
 from pyams_skin.table import BaseTable
 from pyams_skin.viewlet.menu import MenuItem
 from pyams_template.template import template_config
+from pyams_thesaurus.schema import ThesaurusTermsListField
+from pyams_thesaurus.zmi.widget import ThesaurusTermsTreeFieldWidget
 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
 from pyams_utils.list import unique
 from pyams_utils.registry import get_utility
@@ -154,7 +158,7 @@
     """Site root advanced search fields"""
 
     content_type = List(title=_("Content types"),
-                        value_type=Choice(vocabulary='PyAMS content types'),
+                        value_type=Choice(vocabulary=CONTENT_TYPES_VOCABULARY),
                         required=False)
 
     owner = Principal(title=_("Owner"),
@@ -172,6 +176,9 @@
     modified_before = Datetime(title=_("Modified before..."),
                                required=False)
 
+    tags = ThesaurusTermsListField(title=_("Tags"),
+                                   required=False)
+
 
 @template_config(template='templates/advanced-search.pt', layer=IPyAMSLayer)
 @implementer(IInnerPage)
@@ -186,8 +193,17 @@
         apply_skin(self.request, 'PyAMS admin skin')
 
     fields = field.Fields(ISiteRootAdvancedSearchFields)
+    fields['tags'].widgetFactory = ThesaurusTermsTreeFieldWidget
     ajax_handler = 'advanced-search-results.html'
 
+    def updateWidgets(self, prefix=None):
+        super(SiteRootAdvancedSearchForm, self).updateWidgets(prefix)
+        if 'tags' in self.widgets:
+            widget = self.widgets['tags']
+            manager = ITagsManager(self.request.root)
+            widget.thesaurus_name = manager.thesaurus_name
+            widget.extract_name = manager.extract_name
+
 
 @adapter_config(context=(ISiteRoot, IPyAMSLayer, SiteRootAdvancedSearchForm), provides=IContentSearch)
 class SiteRootAdvancedSearchFormSearchAdapter(ContextRequestViewAdapter):
@@ -228,6 +244,9 @@
             params &= Ge(catalog['modified_date'], data['modified_after'])
         if data.get('modified_before'):
             params &= Le(catalog['modified_date'], data['modified_before'])
+        if data.get('tags'):
+            tags = [intids.register(term) for term in data['tags']]
+            params &= Any(catalog['tags'], tags)
         return unique(map(lambda x: IWorkflowVersions(x).get_last_versions()[0],
                           CatalogResultSet(CatalogQuery(catalog).query(params,
                                                                        sort_index='modified_date',
--- a/src/pyams_content/root/zmi/templates/advanced-search.pt	Tue Aug 28 16:19:33 2018 +0200
+++ b/src/pyams_content/root/zmi/templates/advanced-search.pt	Tue Aug 28 17:24:59 2018 +0200
@@ -102,8 +102,10 @@
 										</div>
 									</div>
 								</tal:var>
+							</div>
+							<div class="form-group">
 								<tal:var define="widget view.widgets['content_type']">
-									<label class="control-label col-md-2">
+									<label class="control-label col-md-3">
 										<span>
 											<tal:var content="widget.label" />
 											<i class="fa fa-question-circle hint" title="Input hint"
@@ -113,7 +115,7 @@
 															   data-ams-hint-html '<' in description;"></i>
 										</span>
 									</label>
-									<div class="col-md-3">
+									<div class="col-md-4">
 										<div class="input"
 											 tal:attributes="class widget.widget_css_class | default;
 															 data-ams-data tales:object_data(widget);
@@ -175,6 +177,13 @@
 									</div>
 								</div>
 							</div>
+							<fieldset tal:condition="'tags' in view.widgets">
+								<legend class="switcher" i18n:translate="">Tags</legend>
+								<div class="input"
+									 tal:define="widget view.widgets['tags']">
+									<input tal:replace="structure widget.render()" />
+								</div>
+							</fieldset>
 						</fieldset>
 					</tal:loop>
 					<div class="widgets-suffix"
--- a/src/pyams_content/shared/common/zmi/search.py	Tue Aug 28 16:19:33 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/search.py	Tue Aug 28 17:24:59 2018 +0200
@@ -17,6 +17,8 @@
 
 # import interfaces
 from hypatia.interfaces import ICatalog
+from pyams_content.component.theme.interfaces import ITagsManager, IThemesManagerTarget, IThemesManager, \
+    ICollectionsManagerTarget, ICollectionsManager
 from pyams_content.profile.interfaces import IAdminProfile
 from pyams_content.shared.common.interfaces import IBaseSharedTool
 from pyams_content.shared.common.interfaces.zmi import ISharedToolDashboardTable
@@ -46,6 +48,8 @@
 from pyams_skin.table import BaseTable
 from pyams_skin.viewlet.menu import MenuItem
 from pyams_template.template import template_config
+from pyams_thesaurus.schema import ThesaurusTermsListField
+from pyams_thesaurus.zmi.widget import ThesaurusTermsTreeFieldWidget
 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
 from pyams_utils.list import unique
 from pyams_utils.registry import get_utility
@@ -182,6 +186,15 @@
     modified_before = Datetime(title=_("Modified before..."),
                                required=False)
 
+    tags = ThesaurusTermsListField(title=_("Tags"),
+                                   required=False)
+
+    themes = ThesaurusTermsListField(title=_("Themes"),
+                                     required=False)
+
+    collections = ThesaurusTermsListField(title=_("Collections"),
+                                          required=False)
+
 
 @template_config(template='templates/advanced-search.pt', layer=IPyAMSLayer)
 @implementer(IInnerPage)
@@ -202,8 +215,35 @@
         workflow = IWorkflow(self.context)
         fields = field.Fields(ISharedToolAdvancedSearchFields)
         fields['status'].vocabulary = workflow.states
+        fields['tags'].widgetFactory = ThesaurusTermsTreeFieldWidget
+        if IThemesManagerTarget.providedBy(self.context):
+            fields['themes'].widgetFactory = ThesaurusTermsTreeFieldWidget
+        else:
+            fields = fields.omit('themes')
+        if ICollectionsManagerTarget.providedBy(self.context):
+            fields['collections'].widgetFactory = ThesaurusTermsTreeFieldWidget
+        else:
+            fields = fields.omit('collections')
         return fields
 
+    def updateWidgets(self, prefix=None):
+        super(SharedToolAdvancedSearchForm, self).updateWidgets(prefix)
+        if 'tags' in self.widgets:
+            widget = self.widgets['tags']
+            manager = ITagsManager(self.request.root)
+            widget.thesaurus_name = manager.thesaurus_name
+            widget.extract_name = manager.extract_name
+        if 'themes' in self.widgets:
+            widget = self.widgets['themes']
+            manager = IThemesManager(self.context)
+            widget.thesaurus_name = manager.thesaurus_name
+            widget.extract_name = manager.extract_name
+        if 'collections' in self.widgets:
+            widget = self.widgets['collections']
+            manager = ICollectionsManager(self.context)
+            widget.thesaurus_name = manager.thesaurus_name
+            widget.extract_name = manager.extract_name
+
 
 @adapter_config(context=(IBaseSharedTool, IPyAMSLayer, SharedToolAdvancedSearchForm), provides=IContentSearch)
 class SharedToolAdvancedSearchFormSearchAdapter(ContextRequestViewAdapter):
@@ -243,6 +283,15 @@
             params &= Ge(catalog['modified_date'], data['modified_after'])
         if data.get('modified_before'):
             params &= Le(catalog['modified_date'], data['modified_before'])
+        if data.get('tags'):
+            tags = [intids.register(term) for term in data['tags']]
+            params &= Any(catalog['tags'], tags)
+        if data.get('themes'):
+            tags = [intids.register(term) for term in data['themes']]
+            params &= Any(catalog['themes'], tags)
+        if data.get('collections'):
+            tags = [intids.register(term) for term in data['collections']]
+            params &= Any(catalog['collections'], tags)
         if data.get('status'):
             return unique(map(lambda x: sorted(IWorkflowVersions(x).get_versions(data['status']),
                                                key=lambda y: IZopeDublinCore(y).modified)[0],
--- a/src/pyams_content/shared/common/zmi/templates/advanced-search.pt	Tue Aug 28 16:19:33 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/templates/advanced-search.pt	Tue Aug 28 17:24:59 2018 +0200
@@ -102,8 +102,10 @@
 										</div>
 									</div>
 								</tal:var>
+							</div>
+							<div class="form-group">
 								<tal:var define="widget view.widgets['status']">
-									<label class="control-label col-md-1">
+									<label class="control-label col-md-3">
 										<span>
 											<tal:var content="widget.label" />
 											<i class="fa fa-question-circle hint" title="Input hint"
@@ -175,6 +177,16 @@
 									</div>
 								</div>
 							</div>
+							<tal:loop repeat="fieldname ('tags', 'themes', 'collections')">
+								<fieldset tal:condition="fieldname in view.widgets">
+									<tal:var define="widget view.widgets[fieldname]">
+										<legend class="switcher">${widget.label}</legend>
+										<div class="input">
+											<input tal:replace="structure widget.render()" />
+										</div>
+									</tal:var>
+								</fieldset>
+							</tal:loop>
 						</fieldset>
 					</tal:loop>
 					<div class="widgets-suffix"