Add Nav/Menu block compatibility with JC Submenu plugin

Over the years we have used many different ways to dynamically generate menu items.

A few years ago we found JC Submenu, which, despite it’s age and lack of recent updates has always worked very well and has been stable across WordPress versions and themes.

We have tested this with Cwicly’s Nav block and it does not work, the menu items are not shown in the Cwicly Nav.

Please add compatibility for this, as it is extremely useful and we have multiple sites that rely on this.

Update: It seems JC Submenu is using a different way of filtering the menu items than Cwicly, I may be able to patch it, I will post an update when things are clearer.

Thank you!

Example of one usage for dynamically adding all non-empty custom taxonomy terms as children of a post archive menu item.

1 Like

Thanks for mentioning this tool, I always do this with filters.

No problem, I’m wondering whether you have this working with the Cwicly Nav block or another means of displaying them.

Well, I’ve actually not tested with Cwicly yet, it was another page builder :wink:

Ahh, ok, understood. In that case, it seems we both will benefit from this being added.

While I will take a look at this later, I find it important not to imply you cannot filter Cwicly Nav Menu block items, or that they do not pass through the native paths.

We use the native wp_get_nav_menu_items() function to retrieve the items, which itself allows you to filter all items through wp_get_nav_menu_items.

Cheers,

Hi @Louis,

I meant no negative implication, I hadn’t looked at the Cwicly Nav block code and so I didn’t know yet the difference between how Cwicly renders the menu items dynamically and how legacy themes did it. I was more implying that there may be something obscure, old or deprecated that is required that Cwicly hasn’t implemented, due to the age of the other plugin.

My only frame of reference was the Cwicly Menu block, which at the time I looked at it didn’t apply certain filters. You can blame my ignorance on the rapid speed with which Cwicly has developed in a short space of time.

I know you put a lot of work and features into the Nav block, which is why I was surprised JC Submenu didn’t work. The incompatibility may be within that plugin for all I know, the most important thing is we all want to find a working solution to this common use case.

JC Submenu essentially has two ways it can work:

	/**
	 * Set which type of attachment is used
	 * @return void
	 */
	public function init(){

		$this->public_walker = apply_filters('jcs/enable_public_walker', true );

		if(!$this->public_walker){
			add_filter( 'wp_nav_menu_objects', array( $this, 'populate_menu_items' ));
		}else{
			add_filter( 'wp_nav_menu_args', array( $this, 'attach_menu_walker' ));
		}
	}

	/**
	 * Attach custom nav walker
	 *
	 * Hook into theme menu, attach custom walker
	 * 
	 * @param  array $args 
	 * @return array       
	 */
	function attach_menu_walker($args){
		if(empty($args['walker'])){
			$args['walker'] = new JC_Submenu_Nav_Walker();
		}
		return $args;
	}

	/**
	 * Add menu items without using a custom walker
	 * 
	 * @param  array  $menu_items
	 * @return array new menu items
	 */
	function populate_menu_items($menu_items = array()){

		$walker = new JC_Submenu_Nav_Walker();
		$menu_items = $walker->attach_elements($menu_items);
		$menu_items = $walker->_process_menu($menu_items);

		return $menu_items;
	}

It is not directly using wp_get_nav_menu_items so this may be part of the problem.

Before looking at the code my initial instinct was to test setting enable_public_walker to false as that was needed with certain themes in the past, but this had no effect.

I will look into this in more depth, if you have any suggestions for a “quick fix” or workaround, let me know.

Good news! I was successfully able to patch the plugin using wp_get_nav_menu_items. I will continue to test it and as long as there are no adverse side-effects I will share it.

@Louis, no action required from the Cwicly side, as usual there is always a way to make it happen.

One side-effect of using wp_get_nav_menu_items is that this also effects the Appearance > Menus editor.

Every time you load the menu it adds the dynamically generated menu items to the actual menu in the back end also. So I will have to make some further modifications to cover that scenario.

Hello @StrangeTech,

Thanks for looking into this,
I didn’t mean my previous post to be harsh in any way, so my apologies if it seemed so.

We use wp_get_nav_menu_items for the Menu and Nav block, and a code snippet was added on our docs quite some time ago to helps users who wanted to filter it directly: https://docs.cwicly.com/miscellaneous/code-snippets#add-menu-item-to-cwicly-menu

Glad to hear that JC Submenu seems to work with wp_get_nav_menu_items, thanks for sharing. This is maybe something we can include within Cwicly to make it compatible with JC Submenu.

You might want to use:

if (is_admin()) { return $items; }

Not at all, I didn’t want my post to even remotely not accurately represent Cwicly’s features or capabilities, there is enough confusion on the internet as it is, important to keep things as clear as possible.

Yes, thanks, we already added something very similar using the opposite condition, which works very well:

	function populate_menu_items($menu_items = array()){
		
		if (!is_admin()) { 
			[ ... DO JC SUBMENU PROCESSING HERE ...]
		}

		return $menu_items;
	}

So, barring any other issues, the plugin is now fully compatible with Cwicly’s Nav block.

Hi,

Out of curiosity, I tested my custom code to dynamically edit WP menu, and there’s no issue at all with Cwicly.

For instance, to add events to a dropdown:

add_filter( 'wp_get_nav_menu_items', function( $items, $menu, $args ) {
	
	if ( is_admin() )
		return $items;
	
	$new_items = []; 
	$menu_order = count($items);

	foreach ( $items as $item ) {
		if ( in_array( 'events-dropdown', $item->classes ) ) {
			foreach( get_posts( 'post_type=event&parent=0&orderby=menu_order&order=ASC&numberposts=5' ) as $post ) {
						$post->menu_item_parent = $item->ID;
						$post->post_type = 'nav_menu_item';
						$post->object = 'custom';
						$post->type = 'custom';
						$post->menu_order = ++$menu_order;
						$post->title = $post->post_title;
						$post->url = get_permalink( $post->ID );
						array_push( $new_items, $post );
			}
		}
	}

	return array_merge( $items, $new_items );

}, 10, 3 );

So I guess a plugin might not be required for this.

Not required but useful if you want to quickly add these via a UI or enable your client to add them via a UI.

Our goal is always to make code as reusable and easy to maintain and utilise as possible. Having snippets is great as long as they are easy to configure.

In our workflow, the plugin is simply a nice way to quickly add submenu items dynamically. It may not be ideal for all use cases, especially a complex nested dynamic structure, but for ease of use and speed when developing it is an excellent resource, so it was well worth the upfront effort to make it compatible.

Once we have used/tested it for a bit longer we will make it available for anyone that wants to use it with Cwicly.