Je veux faire une liste de catégories de ce site: https://premium.wpmudev.org/blog/
Alors je crée ce code:
<select class="select">
<?php
$args = array(
'orderby' => 'name',
'order' => 'ASC'
);
$categories = get_categories($args);
foreach ($categories as $cat) {
echo '<option value="'.esc_url( get_category_link( $cat->term_id ) ).'" '.selected( esc_url( get_category_link( $cat->term_id ) ) ).'>'.$cat->name.'</option>';
}
?>
</select>
Le code fonctionne et me redirige vers le lien de catégorie que j'ai sélectionné, mais le problème est qu'après avoir redirigé vers la catégorie, l'option de catégorie dans la liste de sélection des catégories n'est pas remplacée par la catégorie actuelle.
Le problème est ici: selected( esc_url( get_category_link( $cat->term_id ) )
mais je ne peux pas le résoudre.
Le problème est de savoir comment vous avez utilisé selected()
. Cette fonction génère selected="selected"
si le premier argument correspond au deuxième argument.
Donc, ce que vous faites est de marquer l'option comme étant sélectionnée si:
(string) 'https://premium.wpmudev.org/blog/category/news-community/' === (string) true
Dans la mesure où les valeurs sont converties en chaînes et comparées à ===
, elles ne seront jamais vraies, même si l'URL est identique à la catégorie affichée. Voir la fonction utilisée sous le capot pour cela.
Vous devez donc transmettre des valeurs à cette fonction qui peut vérifier si l’option actuelle est identique à la catégorie actuellement affichée. En réalité, vous n'avez pas besoin d'utiliser l'attribut value
réel pour pouvoir effectuer la comparaison. Étant donné que chaque option est représentant une catégorie, vous pouvez simplement comparer l'ID de cette option et l'ID de la catégorie en cours d'affichage.
Nous pouvons donc utiliser $cat->term_id
pour l'identifiant de l'option en cours et get_queried_object_id()
pour obtenir l'identifiant de la catégorie en cours de visualisation. Toutefois, un inconvénient important est que get_queried_object_id()
renverra également l'ID de publication si vous affichez une publication. Etant donné que les publications et les termes sont stockés séparément, vous pouvez obtenir une correspondance même si vous ne visualisez aucune catégorie. Donc, vous devriez vérifier que vous visualisez même une catégorie avant d'utiliser get_queried_object_id()
.
Appliquez tout cela et votre code devrait ressembler à quelque chose comme:
$categories = get_categories( array(
'orderby' => 'name',
'order' => 'ASC'
) );
$current_category = is_category() ? get_queried_object_id() : false;
foreach ( $categories as $category ) {
printf(
'<option value="%s" %s>%s</option>',
esc_url( get_category_link( $category ) ),
selected( $category->term_id, $current_category, false ),
esc_html( $category->name )
);
}
Cette ligne obtient l'ID de la catégorie actuelle, à condition que nous affichions même une catégorie:
$current_category = is_category() ? get_queried_object_id() : false;
Ensuite, cette ligne correspond au fonctionnement de la fonction selected()
:
selected( $category->term_id, $current_category, false ),
Notez que je compare l'ID de la catégorie dans la boucle foreach
à la catégorie affichée, telle que définie ci-dessus. Notez également que le dernier argument est false
. Nous voulons seulement retourner le texte de l'attribut parce que nous faisons déjà écho.
Il y a aussi quelques changements stylistiques que j'ai apportés que vous n'avez pas besoin d'utiliser, mais je pense que je devrais expliquer:
$category
au lieu de $cat
. Je n'aime pas les abréviations dans le code. Tu peux faire ce que tu veux.printf()
au lieu de concaténer une chaîne. La concaténation d'une balise <option>
avec toutes ces valeurs peut entraîner une très longue ligne de code. Utiliser printf()
le rend plus compact et lisible (à mon avis).esc_html()
. Ceci afin que le nom de la catégorie ne puisse pas casser le code HTML de la balise d'option que nous créons.