Dans certains cas les clients demandent de ne pas inclure certains dossiers ou répertoires des résultats de recherche, ceci aussi bien pour les recherches effectuées depuis le portlet de recherche (live search) que depuis le formulaire de recherche avancées. Voici les solutions que j’ai trouvé en fouillant un peu les forums de Plone.

Le cas d’utilisation auquel j’ai été confronté :

  • L’ensemble des pages de l’ancien site ont été importées dans un dossiers “/archives”.
  • Ces documents d’archives doivent rester en statut “publié” pour permettre aux visiteurs provenant des moteurs de recherche de ne pas tomber sur des erreurs 404.
  • L’utilisation du moteur de recherche ne doit pas retourner des documents provenant de “/archives”.

Scripts réalisant les recherches dans Plone 3 :

  • Lors de l’affichage de la page de résultats d’une recherche: CMFPlone/skins/plone_scripts/queryCatalog.py
  • Résultats instantanés du “live search”: Products/CMFPlone/skins/plone_scripts/livesearch_reply.py ou Products/NuPlone/skins/nuplone_templates/livesearch_reply.py

Solution 1 : Utiliser le produit Products.AdvancedQuery

En considérant que le path absolu du répertoire contenant les archives est “/plone/archives”, on peut remplacer la recherche classique (dans queryCatalog.py et livesearch_reply.py):

results = catalog(**query)

par une requête AdvancedQuery excluant “/plone/archives”:

from Products.AdvancedQuery import Generic
advanced_query = catalog.makeAdvancedQuery(query) & ~ Generic('path','/plone/archives')
results = catalog.evalAdvancedQuery(advanced_query)

Inconvénient de cette solution : ça ne fonctionne pas si vous utilisez collective.solr comme moteur d’indexation.

Solution 2 : Utiliser une propriété “search_me” associée à un indexe du portal_catalog

  • Créer la propriété “search_me” (type booléen) à la racine du site Plone et lui donner la valeur “True”.
  • Créer la propriété “search_me” (type booléen) sur le répertoire “archives” et lui donner la valeur “False”.
  • Créer l’indexe “search_me” (type field) dans le portal_catalog et réindexer le contenu du site.
  • Modifier queryCatalog.py et livesearch_reply.py pour étendre les recherches effectuées avec le critère “search_me=True”.

Solution 3 : Filter manuellement les résultats de recherche

Dans queryCatalog.py et livesearch_reply.py, une fois la recherche effectée, filtrer manuellement en bouclant sur la liste de résultats.

exclude_url = 'http://monsite.com/archives'
filtered_results = []
for el in results:
    if not el.getURL().startswith(exclude_url):
        filtered_results.append(el)

Inconvénient de cette solution : cela impacte les performances lorsque le nombre d’éléments retournés par la recherche est important.