How to have language-dynamic menus with Polylang

Here's a simple guide on how to avoid this issue and make your templates fully language-dynamic.

As I've said before in my previous Oxygen Builder Polylang Strings tutorial, when creating multilingual sites, Polylang is my plugin of choice.

The ability to use translation strings for static text in templates saves a lot of headaches when using Oxygen Builder, as it means not needing to maintain multiple language-specific versions of every template. However, one of the things that won't be dynamic is the site's navigation menus, assuming you are using the Oxygen Menu or Pro Menu elements.

Step 0: Install Polylang and add at least two languages

Simple enough, right?

Step 1: Create Menus

The important thing here is to have a consistent naming structure for your menus. Let's assume that your site needs three:

  • Main Menu
  • Footer Menu 1
  • Footer Menu 2

Create the three menus, and append the name of each menu with the language code that you've set up for your language in Polylang.

How to have language-dynamic menus with Polylang 1

For example, a site running English (en) and French (fr) would have six menus, named as follows:

  • Main Menu EN
  • Footer Menu 1 EN
  • Footer Menu 2 EN
  • Main Menu FR
  • Footer Menu 1 FR
  • Footer Menu 2 FR

In my demonstration, I'm just using two; 'Test Menu EN' and 'Test Menu FR':

How to have language-dynamic menus with Polylang 2

Step 2: Add menus to the site using a plugin

Download, install, and activate the free Translatable Menu for Polylang plugin. Then you can use the [translatable-menu] shortcode to display your menu, or if you're an Oxygen Builder user lucky enough to have an OxyExtras license, you can use the Slide Menu element to display your menu.

Menu Shortcode

The [translatable-menu] shortcode takes the following attributes:

  • menu-slug (required) - the slug of the menu you want to display, without the language code included. For example 'Test Menu EN' would be 'test-menu'
  • menu-class (optional) - any additional class names you want to add to the menu <ul>, for extra styling

Full shortcode example:

[translatable-menu menu-slug="test-menu" menu-class="main-menu menu-123"]

More CSS will need to be added to customise the menu's appearance. Every menu added with the shortcode will have the class 'sw-shortcode-menu' on the <ul>, plus any other class you specified. For example, you could style it like so:

ul.sw-shortcode-menu {
    list-style-type: none;
    padding: 0;
    margin: 0;
}

ul.sw-shortcode-menu > li {
    font-size: 0.9em;
}

ul.sw-shortcode-menu > li > a {
    color: green;
}

OxyExtras Slide Menu

  1. Add a new 'Slide Menu' element
  2. Click Menu Source > Dynamic
  3. Under WP Menu, click Data > PHP Function Return Value
  4. Enter sw_menu_name under 'Function Name' and your menu slug (e.g. test-menu) under 'Function Arguments'
  5. Click 'Insert' and then 'Apply Params'
  6. Your menu will show and you can customise it using the controls OxyExtras provides

Rather not install the plugin? The above steps will also work if you add this to a code snippet:

<?php
function sw_menu_name($menu_slug) {
	if(function_exists('pll_current_language')) {
		$menu_name = $menu_slug . '-' . pll_current_language('slug');
		return $menu_name;
	} else {
		return false;
	}
}
?>

Step 2 (Alternative): Code it yourself

If you'd rather get involved in the PHP side of things, you can drop this into a code block and take it from there:

<?php
if( function_exists('pll_current_language') ) {
    $lang_slug = pll_current_language('slug');
} else {
    $lang_slug = '';
}
  
$menu_name = $a['menu-slug'] . '-' . $lang_slug;
$menu_class = 'whatever-class-you-like'; // customise this

wp_nav_menu( 
    array( 
      'menu' => $menu_name,
      'menu_class' => $menu_class,
    ),
);
?>

Sum Up

Hope that helps - as always thanks for reading, and feel free to check out my plugins and other tutorials. If you're looking for any custom development, or just want to say hi, ping me a message on alex (at) smoothwebsites.net.

crossmenu linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram