WPML
apply_filters( 'wpml_active_languages', mixed $empty_value, array|string $args )
Type
filter
WPML Version
3.2

Description

Filters the list of the languages enabled (active) for a site. This filter is usually used to create custom language switchers.

This filter can only work when the global $wp_query object has been instantiated. This means that it should be called after the wp action happens.

WPML returns a site’s active (enabled) languages as an array, with information about each language. The example below comes from a WPML 5.0 site. Its default language is English (United States), German is served at /de-de/, and Arabic is served at /ar/:

Array
(
 [en-us] => Array
  (
   [id] => 1
   [active] => 1
   [default_locale] => en_US
   [native_name] => English (United States)
   [missing] => 0
   [translated_name] => English (United States)
   [language_code] => en-us
   [country] => US
   [display_code] => en-us
   [country_flag_url] => https://example.com/wp-content/plugins/sitepress-multilingual-cms/res/flags/country/us.svg
   [url] => https://example.com/about
  )

 [de] => Array
  (
   [id] => 3
   [active] => 0
   [default_locale] => de_DE
   [native_name] => Deutsch
   [missing] => 0
   [translated_name] => German
   [language_code] => de
   [country] => DE
   [display_code] => de-de
   [country_flag_url] => https://example.com/wp-content/plugins/sitepress-multilingual-cms/res/flags/country/de.svg
   [url] => https://example.com/de-de/ueber-uns
  )

 [ar] => Array
  (
   [id] => 30
   [active] => 0
   [default_locale] => ar
   [native_name] => العربية
   [missing] => 0
   [translated_name] => Arabic
   [language_code] => ar
   [country] => 
   [display_code] => ar
   [country_flag_url] => https://example.com/wp-content/plugins/sitepress-multilingual-cms/res/flags/language/ar.svg
   [url] => https://example.com/ar/about
  )
)
Read the address of a language from url. Never build it from language_code. German above has the code de and the address /de-de/. WPML qualifies the URL code when you add two countries of one language in the same step, the site owner can also edit it, and in domain mode the address is the domain the owner typed.

The keys in WPML 5.0

  • language_code is the stored code. A language that carries a country has the country in the code, for example en-us or de-at. German, Spanish, French, Italian and Dutch keep the plain code for their home country (de, es, fr, it, nl). Portuguese and Chinese always carry a country. Arabic and other single-country languages carry none. A language keeps the code it was created with, so an upgraded site can use en where a new site uses en-us.
  • country is the country code of the language. It is empty for a language with no country.
  • display_code is the code WPML uses in URLs. It differs from language_code when WPML qualifies the code, or when the site owner edits it. To read the same map in your own code, use the wpml_language_codes_map filter.
  • country_flag_url is the URL of the flag. It is an empty string when the site shows the language code instead of a flag, so test the value before you print it. WPML’s own flags are res/flags/country/<country>.svg for a language with a country, and res/flags/language/<code>.svg for a language without one. A custom flag comes from the uploads folder. Never build the path yourself: res/flags/sv.svg is the flag of Sweden, and res/flags/country/sv.svg is the flag of El Salvador.

On a site that has not finished WPML’s upgrade, country can be NULL and display_code can be absent. Use isset() before you read them.

The wpml_active_languages filter provides a way to do things like reorder the language array. Or something more complex, like redirecting missing languages to a custom url.

Arguments

$empty_value
(mixed) (Required) This is normally the value the filter will be modifying. We are not filtering anything here so set this to NULL. This for the filter function to actually receive the full argument list
$args
(array|string) (Optional) Arguments to filter the language output
  • skip_missing(bool) How to treat languages with no translations. 1 to skip language or 0 to link to home of language for missing translations.
  • link_empty_to(string) Works in conjunction with skip_missing = 0 and allows using custom links for the languages that do not have translations for the current element. {%lang} can be used as placeholder for the language code. Empty by default.
  • orderby(string) Accepts id|code|name Defaults to custom. The custom order can be defined in the WordPress admin under WPML » Settings » Language Switchers » Language switcher options
  • order(string) Accepts asc|desc

Example usage

Remember to escape any output. See the page about data sanitization/escaping to learn more about best practices.

The filter’s arguments can be passed to it as a string as shown in the first example below. They can also be passed as an array as you can see in the second example further down.

In the example below we display a flag only language switcher. However, there is a small difference to the flag-only language switcher you can configure from your “WPML language settings” in the admin backend.

The difference here is that the current language will not be wrapped inside an anchor. Only the page’s alternative languages will have a link. Have a look.

Example
function my_flag_only_language_switcher() {
    $languages = apply_filters( 'wpml_active_languages', NULL, 'orderby=id&order=desc' );

    if ( !empty( $languages ) ) {
        foreach( $languages as $l ) {
            if ( !$l['active'] ) echo ' <a href="' . esc_url( $l['url'] ) . '">';
            if ( '' !== $l['country_flag_url'] ) {
                echo '<img src="' . esc_url( $l['country_flag_url'] ) . '" height="12" alt="' . esc_attr( $l['language_code'] ) . '" width="18" />';
            } else {
                echo esc_html( $l['language_code'] );
            }
            if ( !$l['active'] ) echo '</a> ';
        }
    }
}

In the next example you see below, we redirect missing languages to a custom page where we display a contact form for people to notify the site admin of untranslated content.
We also capitalize the language name of the active language i.e. the language we are currently viewing, using PHP’s strtoupper function.
A second example
function my_custom_language_switcher() {
    $languages = apply_filters( 'wpml_active_languages', NULL, array( 'skip_missing' => 0, 'link_empty_to' => 'http://domain.com/missing-translation-contact-form' ) );

    if( !empty( $languages ) ) {
        foreach( $languages as $language ){
			$native_name = $language['active'] ? strtoupper( $language['native_name'] ) : $language['native_name'];

            if( !$language['active'] ) echo '<a href="' . esc_url( $language['url'] ) . '">';
            echo esc_html( $native_name ) . ' ';
            if( !$language['active'] ) echo '</a>';
        }
    }
}

wpml_decode_custom_field, wpml_footer_language_selector, wpml_add_language_form_field, wpml_ls_exclude_in_menu, wpml_is_rtl, wpml_alternate_hreflang, wpml_head_langs, wpml_must_translate_canonical_url, wpml_browser_redirect_language_params, wpml_encode_custom_field

All 30 Site-Wide Language Information hooks