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 :
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 :
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 :
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 :
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 :
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 :
Vous l'aviez surement deviné, il s'agit d'un système de recherche pour des recettes de cuisine !
Sources Webs:
- Theme views exposed filters (search filter) fields
- Views module: theming exposed filters
- Theming Exposed Filters Forms
- Drupal Views2 Exposed Form how to change
- (Displaying Views' exposed filters in a block)
- http://www.delicious.com/gazwal.com/exposed_filter
- Modules :
- Mots-clés :
- 9661 lectures

Commentaires :
Merci pour l'astuce,
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
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
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
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
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
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 !!
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