Developer Snippet Diary

Replace category-based dynamic menu items with custom post type posts in WordPress nav menu

<?php
/* add code in function.php 
	add CSS Classes (optional) >> class = articles-menu inside menu 
add_action('init', 'my_register_category_for_article', 20);
	 that's it, all categories, of custom post type articles will be added in this dropdown
*/


add_action('wp_enqueue_scripts', function() {
    wp_enqueue_style(
        'child-style',
        get_stylesheet_uri(), // loads style.css
        array(),
        filemtime(get_stylesheet_directory() . '/style.css') // cache busting
    );
});



function my_article_menu_terms() {
    global $wpdb;

    return $wpdb->get_results(
        $wpdb->prepare(
            "
            SELECT DISTINCT t.term_id, t.name
            FROM {$wpdb->terms} t
            INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id
            INNER JOIN {$wpdb->term_relationships} tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
            INNER JOIN {$wpdb->posts} p ON tr.object_id = p.ID
            WHERE tt.taxonomy = %s
              AND p.post_type = %s
              AND p.post_status = %s
            ORDER BY t.name ASC
            ",
            'category',
            'article',
            'publish'
        )
    );
}

add_filter('wp_nav_menu_objects', function ($items, $args) {
    $terms = my_article_menu_terms();

    if (empty($terms)) {
        return $items;
    }

    $parent_index = null;

    foreach ($items as $i => $item) {
        $classes = is_array($item->classes) ? $item->classes : array();

        if (in_array('articles-menu', $classes, true)) {
            $parent_index = $i;
            break;
        }
    }

    if ($parent_index === null) {
        return $items;
    }

    $parent = $items[$parent_index];
    $next_id = 100000;

    foreach ($items as $item) {
        $next_id = max($next_id, (int) $item->ID + 1);
    }

    $children = array();

    foreach ($terms as $term) {
        $url = get_term_link((int) $term->term_id, 'category');

        if (is_wp_error($url)) {
            continue;
        }

        $child = new stdClass();
        $child->ID = $next_id++;
        $child->db_id = $child->ID;
        $child->menu_item_parent = $parent->ID;
        $child->object_id = (int) $term->term_id;
        $child->object = 'category';
        $child->type = 'taxonomy';
        $child->type_label = 'Category';
        $child->title = $term->name;
        $child->url = $url;
        $child->target = '';
        $child->attr_title = '';
        $child->description = '';
        $child->classes = array('menu-item', 'menu-item-type-taxonomy', 'menu-item-object-category','articles_sub_menu');
        $child->xfn = '';
        $child->status = 'publish';
        $child->current = is_category((int) $term->term_id);

        $children[] = $child;
    }

    array_splice($items, $parent_index + 1, 0, $children);

    return $items;
}, 10, 2);
Posted by: R GONDAL
Email: rizikmw@gmail.com