Skip Navigation
May 23, 2022

WPML CMS Navigation add-on plugin allows you to create beautiful navigation menus with your own HTML for menu items.

Let’s start with an example. Supposing you want to add icons and a short description to the top navigation menus like in the following image.

Items in drop down menus have icons and description
Items in drop-down menus have icons and description

What we will do is add custom fields to each of the pages, which will hold the icons and the description text. Then, we’ll hook to the menu function and tell it to use these fields in the menu items.

Step 1) Add the Custom Fields to the pages

In order for each page to get its own unique icon and description, we’ll use custom fields.

Icon and Description custom fields added to a page
Icon and Description custom fields added to a page

Step 2) Build the theme function that will produce the menu items

We need to create a function that will generate the HTML for the menu items. By default, each item in the menu gets the page title. This function will allow us to place arbitrary HTML inside menu items.

WPML will still build the entire menu, including the drop-down effect, sections and everything else. This function lets us control the contents of each item.

Here is my function:

function text_for_menu($page_id, $menu_level){
  $ret = '';
  $icon = get_post_meta($page_id,'icon',true);
  $description = get_post_meta($page_id,'Description',true);
    if ($icon) $ret .= '<img width="24" height="24" style="vertical-align: middle; margin:0 5px 0 5px;" src="'.$icon.'" alt="icon" />';
    $ret .= get_the_title($page_id);
    $ret .= '<br /><span>'.$description.'</span>';
  } else {
    if ($icon) $ret .= '<img width="16" height="16" style="vertical-align: middle; margin:0 5px 0 0;" src="'.$icon.'" alt="icon" />';
    $ret .= get_the_title($page_id);
  return $ret;

What it does:

  1. Get the contents of the custom fields called “icon” and “Description”: get_post_meta($page_id,’icon’,true);
  2. Check which menu level the item belongs to. Top menu items are “0” and the drop-down items are “1”.
  3. For the top menu items, it adds a 24×24 pixels icon, then the page title, and then the description.
  4. For drop-down menu items, it adds a 16×16 pixels icon and then the page title.

Step 3) Hook that function to WPML

Last, we tell WPML to use this function in order to create the menu items. We do this by adding the following line to the functions.php file:

add_filter('icl_nav_page_html', 'text_for_menu', 1, 2);

What this does is instruct WordPress to add a function called text_for_menu to WPML’s icl_nav_page_html. It’s a standard WP filter, so you can call it several times and add more and more fields.