Many sites (and themes) need a custom language switcher, which will blend into the overall design. This tutorial explains how to design custom language switchers, using only HTML templates and without writing PHP.

Introduction to Twig templates for language switchers

Twig is a templating engine, which allows you to design with HTML and pseudo code.

For example, this is a Twig template:

What this template does is:

  1. Open the container DIV and UL tags for the language switcher.
  2. Iterate through the different languages.
  3. Output a list item (LI) for each language.
  4. Inside the list item, output a link to the language.
  5. If the language has a flag, output it.
  6. Output the language name.
  7. Close all the nested tags.

Looks simple? Let’s see how you can create such templates for your own language switchers.

Adding a language switcher template to your theme

WPML allows you to add a directory with language switcher templates to the theme. If you are building a theme to sell, you can include these templates with your theme, for everyone to use. If you are customizing a theme, you should create these custom language switcher templates in a child theme, so that your edits are not lost on every theme update.

The language switcher template needs to go into the following folder structure:

my-theme/wpml/templates/language-switchers/my-template

Structure of directories for your language switcher files

Structure of directories for your language switcher files

This means that you should create a folder called “wpml” inside the root of your theme (or child theme). In it, create the templates/language-switchers folders. Inside the language-switchers directory, you can create subdirectories for the different templates that you create (in our example “my-template”).

Inside the template directory (“my-template”), you need to have the following files, with the following names:

  • template.twig file (required)
  • config.json file (required)
  • CSS files (optional)
  • JS files (optional)
  • flag directory (optional)

Designing the template.twig file

The template.twig file is the actual template you are designing. It uses the Twig syntax. In the template, you can use these variables:

current_language_code (string)
css_classes           (string)
languages             (array)
code          (string)
url           (string)
flag_url      (string)
flag_title   (string)
native_name   (string)
display_name  (string)
is_current    (bool)
css_classes   (string)

Setting options in the config.json file

Every language switcher must have a file called config.json, which gives WPML information about the switcher.

Here are the fields for that file:

  • name (required): The name of the template. No need to prefix it, WPML will do this with the theme or plugin name. This is the only required field.
  • version (optional): The version of your template. This is recommended as it will force refreshing stylesheets and javascript resources.
  • css (optional): By default it will scan and enqueue all existing CSS files in the template directory. However, you can pass a JSON array of CSS files inside the template directory. Example: “css”: [“style.css”, “responsive.css”] .
  • js (optional): By default it will scan and enqueue all existing JS files in the template directory. However, you can pass a JSON array of JS files inside the template directory.
    Example: “js”: [“script.js”, “click-script.js”] . Note that the script should be written in pure Javascript except if the theme or plugin includes some other library by itself.
  • flags_dir (optional): By default it will scan for an existing “flags” directory inside the template folder or the specified one, if it is defined.
  • flag_extension (optional): The file extension for the flag files (png, svg, jpg, gif).
  • for (optional): By default, the template will be available for all site locations (“menus”, “sidebars”, “footer”, “post_translations”, “shortcode_actions”). However, you can specify one or more of these locations in a JSON array.
    Example: “for”: [“sidebars”, “post_translations”] .
  • settings (optional): You can override user settings in the admin UI by forcing some settings. Simply pass a JSON object with the required value (0 or 1) for display_flags , display_names_in_native_lang , display_names_in_current_lang , or display_link_for_current_lang.
    Example: “settings”: {“display_link_for_current_lang”: 1} .

Here is the most basic example of a config.json file:

{
"name":           "My custom switcher",
}

And here is a more complete example, with additional (optional) fields:

{
"name":           "Vertical List",
"version":         "1.0",
"css":            ["style.css"],
"js":             ["script.js"],
"flags_dir":      "super-flags",
"flag_extension": "png",
"for":            ["sidebars", "shortcode_actions"],
"settings":       {"display_link_for_current_lang": 1}
}

Adding a language switcher template to your uploads folder

By placing your custom language switcher into the WordPress uploads folder, you can ensure that your templates will not be erased or overwritten when you update your theme or plugin.

All you need to do is place your custom language switcher templates into the ../wp-content/uploads/wpml/templates/language-switchers folder. This folder is automatically scanned for language switcher templates by WPML.

Adding a language switcher template to your plugin

For themes, WPML automatically scans a specific folder to find template files, but for plugins, you need to manually define where to scan. This can be done using the wpml_ls_directories_to_scan hook.

The following code should be used in the main plugin’s file.

function myplugin_wpml_ls_dirs_to_scan( $dirs ) {
    $folder_name = basename( dirname( __FILE__ ) );
    $dirs[]      = trailingslashit( WP_PLUGIN_DIR ) . $folder_name . '/templates/';
    return $dirs;
}
add_filter( 'wpml_ls_directories_to_scan', 'myplugin_wpml_ls_dirs_to_scan' );

The templates folder should have one or more sub-folders in it (e.g. ../templates/my-dropdown/ ).

The language switcher template needs to go into the following folder structure:
../my-plugin/templates/my-template

Language switcher examples

Let’s say that you want to create a custom language, to appear in the menu, like this one:

Custom language switcher with ISO codes

Custom language switcher with ISO codes

The menu will contain only the ISO code for each language (in uppercase style).

  1. Create a new template folder in our theme: mytheme/wpml/templates/language-switchers/menu-iso-codes/
  1. In this folder, add a config.json file with the content below:
{
"name" : "ISO codes for menus",
"for": ["menus"]
}

Basically, you define the name of the template (which will be listed in the available choices) and in which context this template will be available (only for menus).

  1. Now, add the template.twig file with the content below:

[ code|upper ]

As it’s a menu template, you just need to render the content of the menu item element. Here we display the language code after it is processed by the twig upper filter (see documentation here http://twig.sensiolabs.org/doc/filters/upper.html).

Note: It is still possible to change the display options (flag, native language, …) in the WordPress administration interface but it will not have any effect on the front-end because our custom template does not handle it. To avoid confusion for the user, we can force those settings to be disabled. Here is an enhanced config.json file:

{
"name" : "ISO codes for menus",
"for": ["menus"],
"settings": {
   "display_flags": 0,
   "display_names_in_native_lang": 0,
   "display_names_in_current_lang": 0
 }
}

And here is how this will be output in the administration user interface:

Custom Language Switcher On The Backend

Custom Language Switcher On The Backend

Get the source: You can find the files for this example on our dedicated GitHub page.

Horizontal list language switcher

You would like to display a minimalist horizontal language switcher with only flags and the language name as the link title. Moreover, you will use your own collection of SVG flags.

Horizontal language switcher with flags only

Horizontal language switcher with flags only

  1. Create your custom template folder in mytheme/wpml/templates/language-switchers/custom-flags-with-titles/
  1. Import your collection of flags in the folder mytheme/wpml/templates/language-switchers/custom-flags-with-titles/flags/.

(source https://github.com/lipis/flag-icon-css)

Note: The flag collection must include one file for each language code, like this: “en.svg”, “fr.svg”, “es.svg”, “pt-pt.svg”, …

  1. Create a config.json file like the following:
{
"name": "Custom flags with titles",
"for": ["sidebars"],
"flag_extension": "svg",
"settings": {
  "display_flags": 1,
  "display_names_in_native_lang": 1,
  "display_names_in_current_lang": 1
 }
}

You just define the file extension for the flags (“svg”), but there is no need to define the flag folder since we are using the default folder name (“flags”).

  1. Create a template.twig file like like the following:

  1. In order to have some CSS styles, you also need to create a style.css file like the following:
.custom-flags-with-titles li {
  list-style: none;
  float: left;
  margin: 0 3px;
}

.item-custom-flags-with-titles img {
  max-width: 32px;
  height: auto;
}

Get the source: You can find the files for this example on our dedicated GitHub page.