Dynamically modify WordPress menus

Part 1. Introduction

Overview

This is the first article in a series that shows how you can dynamically change a WordPress menu, depending on runtime data. This allows you for instance to tailor the menu to the user, e.g. by selectively displaying items depending on whether the user is logged in, or any other criteria.

Another example where this would be useful is if you wanted the menu of an online store to only display product categories that are relevant for the current season, e.g. hide Christmas products in the spring and summer.

Simple example: Change one menu item

We’ll start with a very simple example.

Let’s say you have an e-commerce website that sells widgets and the menu has a “Widgets” button that leads to the catalog of widgets that are for sale.

Now let’s say that beside the title “Widgets” you wanted to display the number of widgets currently in stock. That number is constantly changing, every time you make a sale, so you cannot hardcode it in your menu. Instead you have to retrieve it from your e-commerce system every time a user accesses your website.

Modifying a WordPress menu at runtime

The easiest way to achieve this goal is to insert some code into the WordPress process that displays menus. WordPress provides a number of “hooks” that allow you to do that. We’ll use the wp_nav_menu_objects filter.

Add the following code in the theme’s functions.php file, or in a plugin.

add_filter( 'wp_nav_menu_objects', 'nav_menu_filter', 10, 2 );

function nav_menu_filter( $menu_items, $args )  {
	// Call a function to determine the stock
	$count = query_stock(); 
	// Loop through all the menu items and add the stock count to the Widgets entry
	foreach ($menu_items as $menu_item) {
		if ($menu_item->title == 'Widgets') {
			$menu_item->title .= " ($count in stock)";
		}
	}                                                 
	return $menu_items;
}

function query_stock() {
	// Replace this with an actual stock query routine
	return rand(100, 1000);
}

The filter function receives two arguments: the list of menu items in Object format, and the arguments that were passed to the function that the theme called to generate the menu. We only concern ourselves with the menu items for now.

The code loops through the menu and when it finds the “Widgets” item, it appends the number of widgets in stock to the label.

And that’s all there is to it. In my next article, I will show a more complex example.

Leave a Reply

Your email address will not be published.