Problématique

WordPress est depuis sa version 3 un véritable CMS et non plus un simple moteur de blogs. Cette version a apporté un gestionnaire de menus et les contenus personnalisés.

Les sites de mes clients réalisés sous WordPress sont composés généralement soit d’un site, soit d’un site plus un blog.

Dans ce second cas, si le nombre de pages du site et le nombre de billets du blog sont importants, un moteur de recherche est tout à fait justifié.

J’ai été confronté à un problème en voulant dans le site proposer une recherche sur l’ensemble du contenu, et dans le blog, limiter la recherche aux billets.

Le moteur de recherche du site

Le moteur de recherche du blog

Les 2 sections (site et blog) ont une identité visuelle distincte et chacune dispose donc de son moteur de recherche.

Solution

Le principe est de filtrer la recherche aux billets mais uniquement lorsque l’on utilise le moteur de recherche du blog.

L’idée est d’ajouter un champ hidden au formulaire de recherche du blog pour identifier l’origine de la recherche.

Dans mon cas, la zone de recherche du blog étant un widget, j’utilise jQuery pour injecter le champ hidden dans le fomulaire. Peu importe la technique employée.

[php]<script type="text/javascript">// <![CDATA[
jQuery(function($){
$(‘.widget_search div’).prepend(‘<input name="origine" value="blog" type="hidden" />’);
});
// ]]></script>[/php]

J’ajoute ensuite ce bout de code dans function.php pour filtrer la recherche.

[php]function filtre_recherche( $query ) {
if ( $_GET["origine"]=="blog" && $query->is_search && !is_admin() ) {
$query->set( ‘post_type’, ‘post’ );
}
return $query;
}
add_filter( ‘pre_get_posts’, ‘filtre_recherche’ );[/php]

On vérifie que l’on arrive bien du blog, qu’il s’agit bien d’une requête de recherche et que nous ne sommes pas dans l’admin (pour ne pas appliquer le filtre dans le back-office).

Reste ensuite a gérer l’apparence de la page de résultats des recherches. J’utilise simplement la page search.php prévue à cet effet, mais je conditionne sur mon champ hidden le chargement d’un header et d’une sidebar spécifiques au blog.

[php]get_header($_GET["origine"]=="blog"?"blog":"");

get_sidebar($_GET["origine"]=="blog"?"blog":"");[/php]

Ainsi les résultats d’une recherche sur le site s’affichent bien dans l’interface du site et ceux d’une recherche dans le blog dans l’interface du blog.