Skip to Content

Views theming : mettre en forme les filtres exposés d'une View

Un tuto écrit plein de code PHP pour vous montrer comment améliorer la mise en forme des filtres exposés d'une View, surtout lorsqu'il y en a beaucoup ...

La situation

Exposer à l'internaute des filtres d'une Views, c'est pratique mais difficile à mettre en forme, surtout lorsque les filtres sont nombreux et de nature diverses (checkbox, select, ...), voilà à quoi on peut arriver par défaut :

views-expo-filter-w250

C'est d'autant plus le bordel que les filtres sont placés à l'intérieur d'un formulaire en float CSS via les CSS du module Views. De plus, il n'y a pas de class et d'ID pour différencier les filtres :

views-expo-filter-02

Pas facile dans l'état actuel de mettre en forme ces .views-exposed-widget sans class et ID CSS, surtout lorsqu'il faut arriver au résultat suivant d'une maquette PSD :

views-expo-filter-03-w250

Le template de Views

Le module views utilise un template générique pour afficher les filtres, vous le trouverez dans le module ici : /views/theme/views-exposed-form.tpl.php
Faites une copie de ce dernier et placez-le dans votre thème, videz le cache du registre (theme registry). Notez que ce template n'apparaît pas dans la section "Thème: Informations" dans l'admin de la View, tentez malgré tout un scan via le bouton "Rescan template files"

Ce template s'applique pour toutes les views de votre site, on va donc le renommer pour cibler note view spécifique de cette façon : views-exposed-form--NomDeLaView--DisplayID.tpl.php
Dans mon cas, ma view s'appelle recherche et l'ID de l'affichage (qui est une page) est page_3; je renomme donc en views-exposed-form--recherche--page-3.tpl.php

Pour trouver l'ID de l'affichage (display ID), il suffit de survoler les affichages (display) à gauche et de noter l'url qui apparaît dans votre navigateur, en bas dans mon cas :

views-expo-filter-04-w250

Si vous avez un doute, observez les nommages dans la section "Thème: Informations", et pour aller plus loin : Views' template files

Le contenu du template views-exposed-form.tpl.php :

<?php
// $Id: views-exposed-form.tpl.php,v 1.4.4.1 2009/11/18 20:37:58 merlinofchaos Exp $
/**
 * @file views-exposed-form.tpl.php
 *
 * This template handles the layout of the views exposed filter form.
 *
 * Variables available:
 * - $widgets: An array of exposed form widgets. Each widget contains:
 * - $widget->label: The visible label to print. May be optional.
 * - $widget->operator: The operator for the widget. May be optional.
 * - $widget->widget: The widget itself.
 * - $button: The submit button for the form.
 *
 * @ingroup views_templates
 */
?>
<?php if (!empty($q)): ?>
  <?php
    // This ensures that, if clean URLs are off, the 'q' is added first so that
    // it shows up first in the URL.
    print $q;
  ?>
<?php endif; ?>
<div class="views-exposed-form">
  <div class="views-exposed-widgets clear-block">
    <?php foreach($widgets as $id => $widget): ?>
      <div class="views-exposed-widget">
        <?php if (!empty($widget->label)): ?>
          <label for="<?php print $widget->id; ?>">
            <?php print $widget->label; ?>
          </label>
        <?php endif; ?>
        <?php if (!empty($widget->operator)): ?>
          <div class="views-operator">
            <?php print $widget->operator; ?>
          </div>
        <?php endif; ?>
        <div class="views-widget">
          <?php print $widget->widget; ?>
        </div>
      </div>
    <?php endforeach; ?>
    <div class="views-exposed-widget">
      <?php print $button ?>
    </div>
  </div>
</div>

Explorer les $variables avec dpm()

Une des solutions serait de créer une fonction pour générer un ID unique au niveau de la DIV .views-exposed-widgets, cependant, cela va pas me permettre de placer les filtres de façon ciblée pour matcher ma maquette PSD. Il faut que je puisse les placer dans 4 colonnes distinctes via un squelette HTML.

Le template de views opère une boucle foreach sur la variable $widgets, nous allons explorer ce que contient cette variable php.

Pour ce faire, installez et activez le module Devel.
Ensuite, on va placer un dpm($widgets) dans notre template, que je simplifie comme ceci :

<?php if (!empty($q)): ?>
  <?php
    // This ensures that, if clean URLs are off, the 'q' is added first so that
    // it shows up first in the URL.
    print $q;
  ?>
<?php endif; ?>
    <div class="views-exposed-form">
      <?php dpm($widgets); ?>
      <div class="views-exposed-widgets clear-block views-exposed-widget">
        <?php print $button ?>
      </div>
    </div>

N'oubliez pas de vider à chaque modification le cache du registre (...)

Vous devriez arriver à quelquechose comme cela :

views-expo-filter-05

J'ai dans mon cas 7 filtres qui sont stockés dans le tableau PHP (array) $widgets. Chaque filtre étant un Objet PHP. Je passe les explications techniques PHP (...) mais on va pouvoir afficher chaque filtre/widget de la mannière suivante :

<?php print $widgets['filter-title']->widget; ?>
<?php print $widgets['filter-date_filter']->widget; ?>
<?php print $widgets['filter-date_filter_1']->widget; ?>
<?php print $widgets['filter-tid_3']->widget; ?>
<?php print $widgets['filter-tid_4']->widget; ?>
<?php print $widgets['filter-tid_5']->widget; ?>
<?php print $widgets['filter-tid']->widget; ?>

Le résultat

En explorant et en choisissant les variables PHP dont j'ai besoin, je vais pouvoir répartir les filtres dans diverses colonnes avec des DIV.
Au final, voici à titre indicatif, mon views-exposed-form--recherche--page-3.tpl.php :

<?php
// $Id: views-exposed-form.tpl.php,v 1.4.4.1 2009/11/18 20:37:58 merlinofchaos Exp $
/**
 * @file views-exposed-form.tpl.php
 *
 * This template handles the layout of the views exposed filter form.
 *
 * Variables available:
 * - $widgets: An array of exposed form widgets. Each widget contains:
 * - $widget->label: The visible label to print. May be optional.
 * - $widget->operator: The operator for the widget. May be optional.
 * - $widget->widget: The widget itself.
 * - $button: The submit button for the form.
 *
 * @ingroup views_templates
 */
?>
<?php if (!empty($q)): ?>
  <?php
    // This ensures that, if clean URLs are off, the 'q' is added first so that
    // it shows up first in the URL.
    print $q;
  ?>
<?php endif; ?>

<?php// dpm($widgets); ?>


    <div class="ra-weapper clearfix">
      <div class="racol racol01">
        <div class="filter-block">
          <h3 class="filter-title">
            Titre
          </h3>
          <?php print $widgets['filter-title']->widget; ?>
        </div>
        <div class="filter-block">
          <h3 class="filter-title">
            PubliÈ aprËs le
          </h3>
          <?php print $widgets['filter-date_filter']->widget; ?>
        </div>
        <div class="filter-block">
          <h3 class="filter-title">
            PubliÈ avant le
          </h3>
          <?php print $widgets['filter-date_filter_1']->widget; ?>
        </div>
      </div><!-- /racol -->
      <div class="racol racol02">
        <div class="filter-block">
          <h3 class="filter-title">
            Saison
          </h3>
          <?php print $widgets['filter-tid_3']->widget; ?>
        </div>
        <div class="filter-block">
          <h3 class="filter-title">
            Quoi ?
          </h3>
          <?php print $widgets['filter-tid_4']->widget; ?>
        </div>
      </div><!-- /racol -->
      <div class="racol racol03 filter-block">
        <h3 class="filter-title">
          Miam !
        </h3>
        <?php print $widgets['filter-tid_5']->widget; ?>
      </div><!-- /racol -->
      <div class="racol racol04 last filter-block">
        <h3 class="filter-title">
          Auteurs
        </h3>
        <?php print $widgets['filter-tid']->widget; ?>
      </div><!-- /racol -->
    
    
    <div class="rabutton clearboth"><?php print $button ?></div>
    
    </div><!-- /ra-weapper clearfix -->

Et le résultat côté frontend, après un peu de CSS :

views-expo-filter-06-w250

Vous l'aviez surement deviné, il s'agit d'un système de recherche pour des recettes de cuisine !

Sources Webs:

3.75
Average: 3.8 (4 votes)
Your rating: Aucun

Commentaires :

Merci pour l'astuce,

Portrait de selinav

Merci pour l'astuce, existe-t-il une possibilité de modifier les valeurs issues des widgets?

Par exemple, j'affiche un champ exposé taxonomie mais il y a un bug avec views et la traduction des taxonomies, les termes ne sont pas traduits, donc j'aurais voulu mettre une fonction de traduction au moment où il récupère les termes.

tout est possible si on

Portrait de robin

tout est possible si on connais le PHP, là, j'ai pas d'exemple sous la main. Cela dit, la bonne méthode est d'aller traduire les strings concernées en français, il y a au besoin pas mal de module pour aider à les trouver, ex : http://drupal.org/project/l10n_client ou http://drupal.org/project/stringoverrides

Filtres exposés d'une view en checkbox

Portrait de Laila

Merci pour l'astuce, pourriez-vous m'expliquer svp une chose...

Je veux afficher les filtres exposés d'une vue en checkboxes, juque là ca va j'ai pu le faire mais le problème c'est que avec ces checkboxes la valeur est envoyées par URL sous la forme: nom_de_mon_filtre [valeur_de_ce_filtre] = valeur_de_ce_filtre

Alors que normalement, les filtres exposés en select sont envoyés par URL sous la forme: nom_de_mon_filtre = valeur_de_ce_filtre et du coup la vue n'affiche plus de résultats quand je check un checkbox

Si vous avez une solution je suis preneuse...

Merci d'avance pour votre réponse

bonjour, à priori, pas de

Portrait de robin

bonjour, à priori, pas de souci de mon côté avec les checkbox. J'avais activé l'utilisation AJAX pour ma view, afin que le résultat de recherche s'affiche directement sans recharger la page. Les urls des views dans mon exemple sont du style /recherche/recettes , recherche/articles ; etc ... normalement, tu ne devrait pas avoir de problèmes, ta view doit avoir un "dis-fonctionnement" (???) ++ bon courage

Filtre cases à cocher

Portrait de Paps

Bonjour Robin

Ca fait longtemps que je regarde tes tutos vidéos qui m'ont appris pas mal de choses sur Drupal (merci encore) mais là j'avoue j'ai un soucis sur celui-ci : Comment tu fais pour afficher, dès le départ, des cases à cocher (sans modifier la page ni le css) ??? Est-ce dépendant du type de champ cck que l'on veut exposer ou pas du tout ?
Par exemple si je veux exposer plusieurs types de contenu, par défaut il me créé un liste de sélection mais pas de cases à cocher ! Y a-t-il une manip à faire en amont ? Autre exemple si j'expose un champ qui, à la base, est une liste de sélection, j'ai juste un champ texte où je dois dire si c'est "égal", "contient", "sensible à la casse"...

Bref c'est la panade... j'ai pas dû tout bien faire, ce qui dommage car c'est fort pratique ce système.

Si tu peux m'éclairer j'en serai d'autant plus ravi

Merci encore pour tes tutos

Paps

J'y suis presque ! Au lieu de

Portrait de Paps

J'y suis presque !

Au lieu de sélectionner mon champ cck normal j'ai cocher celui où est écrit "Valeurs autorisées" et là je peux avoir une liste de sélection MAIS je n'ai tjrs pas mes cases à cocher ?!

Donc je continu mes recherches en espérant que tu puisses m'aider d'ici là

Paps

Cases à cocher résolu !!

Portrait de Paps

Dernière publi pour ce post

J'ai trouvé en installant le module "better_exposed_filter"
Ca marche nickel :)

@ bientôt

Paps

Poster un nouveau commentaire

Le contenu de ce champ ne sera pas montré publiquement. Si vous avez un compte gravatar, l'utilisez pour afficher votre avatar.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.

Plus d'informations sur les options de formatage

By submitting this form, you accept the Mollom privacy policy.