Déception
Aujourd’hui, j’ai décidé de faire un peu de doc sur WordPress ! Ça fait un p’tit moment que je n’avais pas fait de tuto dessus et j’ai justement été confronté à un problème, donc ça tombe super bien.
Je te passe les détails, mais en gros, j’utilise un plugin qui propose d’afficher un formulaire de recherche via un shortcode. Et mon boulot était justement d’intégrer ce fameux formulaire de recherche à un menu. Là, je me suis dis cool, je vais simplement ajouter le shortcode dans le label du menu et ça fera l’affaire. A mon grand étonnement, je me suis rendu compte que WordPress ne rend pas les shortcodes qui sont ajoutés dans les menus.
Texas ranger
Alors je ne sais pas si tu sais, mais le rendu HTML d’un menu WordPress est réalisé par ce qu’on appelle un « Walker ». C’est une classe de WordPress qui peut être surchargée quand on veut générer des sorties de code HTML très spécifiques. Mais trêve de bavardage, moi j’ai envie de savoir pourquoi le shortcode ne fonctionne pas !
Dans la doc en ligne de WordPress sur le Walker, plus précésement dans le fichier class-walker-nav-menu.php, c’est la méthode start_el de la classe Walker_Nav_Menu qui est utilisée, en voici une partie
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . $title . $args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
/**/
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
Sans chercher bien loin, je peux voir qu’il n’y a tout simplement pas de do_shortcode() executé sur le contenu texte. Heureusement, le truc super cool, c’est que l’équipe WordPress a pensé à ajouter un filtre, et grâce à lui on va pouvoir faire notre do_shortcode() manuellement.
Do_shortcode()
Du coup, je récupère le nom du filtre et je claque ce petit morceau de code tout mignon dans mon fichier functions.php, ce qui va tout simplement exécuter un do_shortcode() sur le lien, et PAF ça fait des Chocapics.
add_filter( 'walker_nav_menu_start_el', 'gol_walker_nav_menu_start_el', 10, 4);
function gol_walker_nav_menu_start_el( $item_output, $item, $depth, $args ){
return do_shortcode($item_output);
}
A+
Bon voilà j’ai réussi, tout fonctionne correctement ou presque. En fait, le contenu du shortcode est encapsulé dans une balise A et ce n’est pas forcement le top, car dès que je vais cliquer sur un élément de formulaire, il va y avoir un déclenchement de lien dont je n’ai pas forcément envie.
Pour résoudre le problème, j’utilise une expression régulière qui va vérifier s’il y a juste un shortcode. Si c’est le cas il va alors le retourner sans le lien.>
add_filter( 'walker_nav_menu_start_el', 'gol_walker_nav_menu_start_el', 10, 4);
function gol_walker_nav_menu_start_el( $item_output, $item, $depth, $args ){
//permet uniquement de matcher sur <a...>[ton_shortcode_de_ouff]</a>
preg_match_all('/<a.+>(\[.+\])<\/a>/i', $item_output, $matches);
if( !empty($matches[1][0]) ){
$item_output = $matches[1][0];
}
return do_shortcode($item_output);
}
01/02/2018
Yann Vangampelaere - nouslesdevs -