Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
448 views
in Technique[技术] by (71.8m points)

php - Sort WooCommerce product category sub menu items by name ASC in Wordpress menu

I am adding in my main WordPress menu to WooCommerce product category menu items, the children subcategory terms as submenu items with the following code and it works.

enter image description here

The code:

add_filter("wp_get_nav_menu_items", function ($items, $menu, $args) {

    // don't add child categories in administration of menus
    if (is_admin()) {
        return $items;
    }
    foreach ($items as $index => $i) {

        if ("product_cat" !== $i->object) {
            continue;
        }
        $term_children = get_term_children($i->object_id, "product_cat");
        // add child categories
        foreach ($term_children as $index2 => $child_id) {
            $child = get_term($child_id);
            $url = get_term_link($child);
            $e = new stdClass();
            $e->title = $child->name;
            $e->url = $url;
            $e->menu_order = 500 * ($index + 1) + $index2;
            $e->post_type = "nav_menu_item";
            $e->post_status = "published";
            $e->post_parent = $i->ID;
            $e->menu_item_parent = $i->ID;
            $e->type = "custom";
            $e->object = "custom";
            $e->description = "";
            $e->object_id = 0;
            $e->db_id = 0;
            $e->ID = 0;
            $e->position = 0;
            $e->classes = array();
            $items[] = $e;
        }
    }

    return $items;

}, 10, 3); 

But I would like to sort that submenu items alphabetically in Ascending order and I didn't find a way to do it yet. How can I sort that submenu items by name (alphabetically) in Ascending order?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

An additional foreach loop is required, to sort category sub menu items by name. Also there was some little oversights in your code (to avoid some errors). To finish you should always name your hooked functions for many different reasons.

The revisited code:

add_filter( 'wp_get_nav_menu_items', 'custom_submenu_product_categories', 10, 3 );
function custom_submenu_product_categories( $items, $menu, $args ) {
    // don't add child categories in administration of menus
    if (is_admin()) {
        return $items;
    }

    $taxonomy = 'product_cat';

    foreach ($items as $index => $post) {

        if ( $taxonomy !== $post->object ) {
            continue;
        }

        $children_terms_ids = get_term_children( $post->object_id, $taxonomy );
        $unsorted_terms     = array(); // Initializing

        // Loop through children terms to prepare them to be sorted by name
        foreach ( $children_terms_ids as $child_id ) {
            $child_term = get_term( $child_id, $taxonomy );

            $unsorted_terms[$child_term->name] = $child_term; // Set each term in an array for sorting
        }

        ksort($unsorted_terms); // Sort menu sub-items by term name ASC

        $index2 = 0; // Initializing

        // Loop through sorted child terms to set them as sorted sub menu items
        foreach ( $unsorted_terms as $child_term_name => $child_term ) {
            $item = new stdClass();

            $item->title            = $child_term_name;
            $item->url              = get_term_link( $child_term, $taxonomy );
            $item->menu_order       = 500 * ($index + 1) + $index2;
            $item->post_type        = 'nav_menu_item';
            $item->post_status      = 'published';
            $item->post_parent      = $post->ID;
            $item->menu_item_parent = $post->ID;
            $item->type             = 'custom';
            $item->object           = 'custom';
            $item->description      = '';
            $item->object_id        = 0;
            $item->db_id            = 0;
            $item->ID               = 0;
            $item->position         = 0;
            $item->classes          = array();
            $item->target           = ''; // <= Missing - Mandatory to avoid an error
            $item->xfn              = ''; // <= Missing - Mandatory to avoid an error

            $items[] = $item;
            $index2++;
        }
    }
    return $items;
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...