web-dev-qa-db-fra.com

Supprimer la classe dans le filtre nav_menu_link_attibutes

J'ai le code suivant dans le fichier functions.php de mon thème enfant:

function add_menu_atts( $atts, $item, $args ) {
    if ( $class_key = array_search( 'search-class', $item->classes ) !== FALSE ) {
        $atts['data-something'] = 'something';
        $atts['class'] = 'something-class';
        //the following line is the one relevant to this question
        unset($item->classes[$class_key]);
    }
    return $atts;
}
add_filter( 'nav_menu_link_attributes', 'add_menu_atts', 10, 3 );

Après avoir utilisé la classe search-class pour localiser l'élément, je souhaite le supprimer de l'élément. Cependant, mon appel à unset($item->classes[$class_key]); ne fonctionne pas.

Je ne comprends pas exactement ce qu'est l'objet $item et c'est probablement le problème. Lorsque j'appelle get_class() sur $item, je reçois WP_Post, mais WP_Post n'a pas de propriété classes. Alors, comment $item->classes renvoie-t-il un tableau de classes?

(Je suis nouveau sur PHP et WordPress)

Puis-je supprimer la classe search-class du tableau de classes de l'objet $item dans ma méthode?

1
theyuv

Regardons d'abord cette partie:

Je ne comprends pas exactement ce qu'est l'objet $item et c'est probablement le problème. Lorsque j'appelle get_class() sur $item, je reçois WP_Post, mais WP_Post ne possède pas de propriété de classes. Alors, comment $item->classes renvoie-t-il un tableau de classes?

Quelques notes concernant la structure des menus dans WordPress:

  • Chaque menu de navigation est enregistré en tant que terme dans la taxonomie nav_menu.

  • Ensuite, lorsque nous ajoutons des éléments à ce menu, nous créons de nouveaux objets de publication du type nav_menu_item.

  • L'arborescence de chaque menu n'est pas stockée dans le champ post_parent de la publication nav_menu_item, comme prévu. Nous le trouvons en fait dans la table de méta de publication où il est stocké sous la clé de méta _menu_item_menu_item_parent, pour chaque publication de nav_menu_item.

  • L'objet de données d'élément de menu $item est un objet WP_Post décoré, c'est-à-dire avec des attributs supplémentaires ajoutés à l'aide de la fonction wp_setup_nav_menu_item() :

    /**
     * Decorates a menu item object with the shared navigation menu item properties.
     *
     * Properties:
     * - ID:               The term_id if the menu item represents a taxonomy term. 
     * - attr_title:       The title attribute of the link element for this menu item.
     * - classes:          The array of class attribute values for the link element of this menu item.
     * - db_id:            The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
     * - description:      The description of this menu item.
     * - menu_item_parent: The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise.
     * - object:           The type of object originally represented, such as "category," "post", or "attachment."
     * - object_id:        The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
     * - post_parent:      The DB ID of the original object's parent object, if any (0 otherwise).
     * - post_title:       A "no title" label if menu item represents a post that lacks a title.
     * - target:           The target attribute of the link element for this menu item.
     * - title:            The title of this menu item.
     * - type:             The family of objects originally represented, such as "post_type" or "taxonomy."
     * - type_label:       The singular label used to describe this type of menu item.
     * - url:              The URL to which this menu item points.
     * - xfn:              The XFN relationship expressed in the link of this menu item.
     * - _invalid:         Whether the menu item represents an object that no longer exists.
    

Alors regardons cette partie:

Après avoir utilisé la classe search-class pour localiser l'élément, je souhaite le supprimer de l'élément. Cependant, mon appel à unset($item->classes[$class_key]); ne fonctionne pas.

Il est trop tard pour supprimer des classes de l'objet $item, dans le filtre nav_menu_link_attributes, afin de supprimer des classes des éléments de menu (balises li).

Nous pouvons par exemple utilisez le filtre nav_menu_css_class pour modifier ces classes.

Il est également probablement préférable d'utiliser un tel filtre plutôt que de modifier l'objet de données directement, car d'autres plugins pourraient dépendre de l'objet de données brut.

Voici un exemple comment supprimer la classe search-class:

add_filter( 'nav_menu_css_class', function( $classes, $item, $args, $depth )
{
    return array_filter(
        (array) $classes, 
        function( $val ) { return 'search-class' !== $val; } 
    ); 

}, 10, 4 );

Ensuite, nous pouvons utiliser le filtre nav_menu_link_attributesfilter pour ajouter un attribut de données et ajouter une classe à la balise d'ancrage:

add_filter( 'nav_menu_link_attributes', function( $atts, $item, $args )
{
    // Nothing to do
    if( 
           ! isset( $item->classes ) 
        || ! in_array( 'klasi1', $item->classes, true ) 
        || ! isset( $atts['class'] ) 
    )
        return $atts;

    // Add data attribute to anchor tag
    $atts['data-something'] = 'something';

    // Append an anchor class
    $classes = explode( ' ', $atts['class'] );
    $classes[] = 'something-class';
    $atts['class'] = join( ' ', array_filter( $classes ) );

    return $atts;
}, 10, 3 );

Nous pourrions également vouloir limiter les filtres ci-dessus à un menu donné, en vérifiant si $args->theme_location est 'primary' ou $args->menu->slug est 'somemenuslug'.

0
birgire