Adding custom menu items to your menu

Sometimes you'd like to add things to your menu that you usually cannot find in the menus page. Something more than just links, or you'd like to have customized menu item that behaves differently when you're logged in or not. I'm going to show you two examples of using the 'wp_nav_menu_items' filter: one is adding custom My Account menu item for WooCommerce, and the other example will show you how to add a dropdown widget to your menu.

As you may have noticed I usually get inspired to write when I had some interesting project to do on my job. I found that those are the cases when I learn something new and I think that it’s good to share that with you (sharing is caring : ) ). Today’s example is something I have actually done many months ago, but it totally slipped my mind. Customizing menu items so that we can use pages and functionality from WooCommerce (in this particular example).

WordPress menu can be customized using the menu walker, but it can also be manipulated by adding your own menu items using
wp_nav_menu_items filter hook. This filter allows us to add our own menu items to an already existing menu items.

Filters overview

WordPress filters are a great way to modify already existing data. WordPress has a lot of built in filter hooks that you can modify. Likewise you can create your own filter hook in the plugin you’re building, so that users can modify the data later on. For instance, let’s say you have a function that returns an array of values that you’d like to extend at some later point. In that case you’d want to create a function with your array, and check if the filter that will modify it exists, and then apply it to your array if it does:

1

2

3

4

5

6

7

8

9

10

11

12

13

functionmy_custom_array(){

$my_array=array(

'name'=>'Denis',

'age'=>28,

'title'=>'web developer',

);

if(has_filter('add_additional_data')){

$my_array=apply_filters('add_additional_data',$my_array);

}

return$my_array;

}

Now since we’ve added a check for a filter that will add additional data, we can modify our array in an easy way

1

2

3

4

5

6

7

add_filter('add_additional_data','new_data');

functionnew_data($my_array){

$my_array['description']='A totally cool guy';

return$my_array;

}

That way we can modify the data when we see fit. You can read more about it here. We are going to take advantage of the built in
wp_nav_menu_items filter hook and add our own items.

Adding the new item

First example that I’ll show you is adding a ‘Log In’ menu item when you’re logged out, that will then turn to ‘My Account’ menu item drop down with WooCommerce endpoints when you’re logged in. You may be thinking: Why would you add the endpoints that way? They are already in the menu page. That’s completely true, but on the project I am currently working on, we thought that it would be a better user experience to have a login button, that will turn to my account menu item upon login. It is following the rationale of: if you don’t use it, don’t show it. And if you think about it – why would a person who isn’t logged in, and is not a member of whatever your site is (a custom shop, a digital agency, affiliate program, forum community, etc.), see the pages he or she isn’t going to use? Makes no sense to show it to them.

In my case just adding all the endpoints wasn’t going to cut it. Plus we added some additional custom menu items. So in your
functions.php (or some file where you put your custom php additionals), add this code

First we check if we even have WooCommerce installed and activated. No point in adding a menu item that depends on WooCommerce if you cannot access the pages (my account endpoints). Next is the function that will actually add the menu item. We want to add our custom menu item only in the header menu, so we can check that the menu location is correct. In the case of Twentysixteen theme, the menu location for the header menu is called ‘primary’. In some cases this is ‘header-menu’ or something similar. If you are wondering what are the menu locations in your theme, just search for the register_nav_menus() function.

Next we want to cover two cases – when user is logged in, and when user is logged out. If user is logged out, show the ‘Log In’ menu item, and if her/she isn’t then show the ‘My account’ menu with dropdowns that you can customize. To get our desired endpoints, we’re using the wc_get_endpoint_url function that comes with WooCommerce – you need to specify the endpoint slug you want to get, and you must specify the permalink of My Account page, otherwise the link to your endpoint won’t work correctly (it will work correctly only if you’re on the my account page already).

After that it’s just building the html of your menu item, and you’re set.

Menu item when you’re logged in

Menu item when you’re logged out

Shopping cart in the menu

In the next example we’re going to add a cart drop down to our menu. First we need to add our menu item using the
wp_nav_menu_items filter hook. You can add it right after our filter with
add_loginout_link function

The function is very similar to the previous one with the endpoints. But there is a catch – to actually output the widget, we’ll need to store it in the output buffer. That’s why we define a new function:

This function will output the widget in the output buffer and return the contents of it. Adding some styling so that our dropdown looks pretty

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

/* Menu cart widget */

#shop_link_dropdown_cart{

position:relative;

}

#shop_link_dropdown_cart .cart-contents{

display:inline-block;

padding-top:14px;

padding-left:12px;

padding-bottom:3px;

}

#shop_link_dropdown_cart .cart-contents .span_ci_icon-shopping-cart{

position:relative;

top:0;

font-size:24px;

color:#fff;

display:block;

}

#shop_link_dropdown_cart .cart_dropdown_widget{

position:absolute;

top:42px;

right:0;

background:#fff;

width:350px;

border:1pxsolid#d1d1d1;

padding:0;

text-decoration:none;

list-style:none;

opacity:0;

visibility:hidden;

-webkit-transition:all200msease-in;

transition:all200msease-in;

z-index:10;

}

.woocommerce-cart #shop_link_dropdown_cart .cart_dropdown_widget{

display:none;

}

#shop_link_dropdown_cart:hover .cart_dropdown_widget{

opacity:1;

visibility:visible;

}

#shop_link_dropdown_cart .cart_dropdown_widget:after{

content:"";

position:absolute;

top:-10px;

left:0;

width:100%;

height:10px;

}

#shop_link_dropdown_cart .widget_shopping_cart{

margin:0;

padding:20px;

border:0;

}

#shop_link_dropdown_cart .product_list_widget {

position:static;

border:0;

}

#shop_link_dropdown_cart .product_list_widget:before,

#shop_link_dropdown_cart .product_list_widget:after {

display:none;

}

#shop_link_dropdown_cart .product_list_widget li{

border:0;

padding-bottom:25px;

}

#shop_link_dropdown_cart .product_list_widget li.empty{

padding-bottom:0;

}

#shop_link_dropdown_cart .product_list_widget .remove{

background:none;

color:red!important;

}

#shop_link_dropdown_cart .product_list_widget li a:not(.remove){

padding-top:12px;

padding-left:25px;

width:auto;

}

#shop_link_dropdown_cart .product_list_widget li a:not(.remove) img {

width:100px;

margin:0;

}

#shop_link_dropdown_cart .product_list_widget li .quantity{

padding-left:27px;

}

#shop_link_dropdown_cart .total{

border-top:1pxsolid#d1d1d1;

}

We have our cart in the menu that will be shown when you hover on the little shop cart icon. Note that the icon font is included in the theme, if you have other icon font loaded, change the class of it accordingly.

Conclusion

That’s it, a simple way to add additional and custom ‘stuff’ to your menu items. In the same way you could add other widgets, or content in your menu. Notice that you are appending your new menu item to the end of the existing menu items, so you’ll be adding your link to the end of the menu you’ve created in the WordPress admin area.

I hope you find this tutorial useful. If you have any questions about this method of adding custom menu items to your theme, feel free to leave a comment below. Happy coding.