A frequent issue is a menu which is correct when directly accessing the page but doesn』t switch when clicking on the language switcher. More and more themes are loading the content in Ajax and thus don』t reload the menu and content common to every pages (ex footer, widgets). This Ajax feature is obviously not compatible with multilingual websites. Try disabling the Ajax feature in your theme options or contact the theme support if you don』t find such option.
Author 诗语
REST API
The feature is available only in Polylang Pro.
The 『lang』 argument
It is possible to get posts or terms in only one language. For example:
1GET /wp/v2/posts?lang=fr
lists all posts in French, while
1GET /wp/v2/posts
lists all posts in all languages.
The 『lang』 argument works for requests related to the posts and terms, whatever the post type or taxonomy.
The language and translations in responses
When querying posts or terms, two new fields are added to the response.
『lang』: contains the language code (generally 2 letter ISO code) of the queried post or term.
『translations』: contains an array with the language codes as keys and the id of the translated posts or terms as values. The array always includes the queried post or term itself.
Assign the language and translations
It is not only possible to get the language and translations of posts and terms but it is also possible to assign them. For example:
1POST /wp/v2/posts/3376?lang=fr&translations[en]=3374
will assign the French language to the post 3376 and link it to the post 3374 as its English translation. Note that you must first make sure that the post 3374 is in English.
Get the languages
Apart from extending the WP API, it is possible to get the languages with an additional endpoint:
1GET /pll/v1/languages
The response will include several properties such as:
name: native language name
slug: language code (generally 2 letter ISO code)
locale: WordPress locale
flag_url: the url of the flag associated to the language
home_url: the url of the home page in that language
page_on_front: if relevant, the id of the static front page in that language
page_for_posts: if relevant, the id of the page for posts in that language
The list above is not exhaustive as the response includes several other internal properties.
Function reference
IMPORTANT: when using one or more of these function, you *must* check for its existence before using it, otherwise your site will badly break with a fatal error at next Polylang update (as WordPress deletes the plugin when updating it).
pll_the_languages
Displays a language switcher.
Usage:
1pll_the_languages( $args );
$args is an optional array parameter. Options are:
『dropdown』 => displays a list if set to 0, a dropdown list if set to 1 (default: 0)
『show_names』 => displays language names if set to 1 (default: 1)
『display_names_as』 => either 『name』 or 『slug』 (default: 『name』)
『show_flags』 => displays flags if set to 1 (default: 0)
『hide_if_empty』 => hides languages with no posts (or pages) if set to 1 (default: 1)
『force_home』 => forces link to homepage if set to 1 (default: 0)
『echo』 => echoes if set to 1, returns a string if set to 0 (default: 1)
『hide_if_no_translation』 => hides the language if no translation exists if set to 1 (default: 0)
『hide_current』=> hides the current language if set to 1 (default: 0)
『post_id』 => if set, displays links to translations of the post (or page) defined by post_id (default: null)
『raw』 => use this to create your own custom language switcher (default:0)
Important: You have to output yourself the ul tags if you don』t use the dropdown option.
Examples:
123456789101112
- 1,'show_names' => 0 ) ); ?>
1 ) ); ?>
If the options are not enough, you can build your own custom language switcher using the 『raw』 argument:
1$translations = pll_the_languages( array( 'raw' => 1 ) );
The function will return an array of arrays, one array per language with the following entries:
[id] => language id
[slug] => language code used in urls
[name] => language name
[url] => url of the translation
[flag] => url of the flag
[current_lang] => true if this is the current language, false otherwise
[no_translation] => true if there is no available translation, false otherwise
The function is meant to display a language switcher. So it is not availaible on backend. If you need a function to get information about available languages, you should use pll_languages_list() instead.
pll_current_language
Returns the current language
Usage:
1pll_current_language( $value );
『$value』 => (optional) either 『name』 or 『locale』 or 『slug』, defaults to 『slug』
returns either the full name, or the WordPress locale (just as the WordPress core function 『get_locale』 or the slug ( 2-letters code) of the current language.
pll_default_language
Returns the default language
Usage:
1pll_default_language( $value );
『$value』 => (optional) either 『name』 or 『locale』 or 『slug』, defaults to 『slug』
returns either the full name, or the WordPress locale (just as the WordPress core function 『get_locale』 or the slug ( 2-letters code) of the current language.
pll_get_post
Returns the post (or page) translation
Usage:
1pll_get_post( $post_id, $slug );
『$post_id』 => (required) id of the post you want the translation
『$slug』 => (optional) 2-letters code of the language, defaults to current language
returns the id of the translated post or page as integer.
pll_get_term
Returns the category (or post tag) translation
Usage:
1pll_get_term( $term_id, $slug );
『$term_id』 => (required) id of the term you want the translation
『$slug』 => (optional) 2-letters code of the language, defaults to current language
returns the id of the translated term as integer.
pll_home_url
Returns the home page url
Usage:
1pll_home_url( $slug );
『$slug』 => 2-letters code of the language. The parameter is optional and defaults to the current language if the function is called on frontend.
returns the url of the homepage in the requested language, as a string.
pll_register_string
Allows plugins to add their own strings in the 「strings translation」 panel. The function must be called on admin side (the functions.php file is OK for themes). It is possible to register empty strings (for example when they come from options) but they won』t appear in the list table.
Usage:
1pll_register_string( $name, $string, $group, $multiline );
『$name』 => (required) name provided for sorting convenience (ex: 『myplugin』)
『$string』 => (required) the string to translate
『$group』 => (optional) the group in which the string is registered, defaults to 『polylang』
『$multiline』 => (optional) if set to true, the translation text field will be multiline, defaults to false
pll__
translates a string previously registered with pll_register_string
Usage:
1pll__( $string );
The unique parameter is required:
『$string』 => the string to translate
returns the translated string.
pll_e
Echoes a translated string previously registered with pll_register_string
Usage:
1pll_e( $string );
The unique parameter is required:
『$string』 => the string to translate
pll_translate_string
Translates a string previously registered with pll_register_string in a given language. Unlike 『pll__()』 and 『pll_e()』 which allow to get the translation only in the current language (as do the WordPress localization functions 『__()』 and 『_e()』), this function allows to get the translation in any language.
Usage:
1pll_translate_string( $string, $lang );
『$string』 => the string to translate
『$lang』 => the language code of the desired translation
returns the translated string.
pll_is_translated_post_type
Returns true if Polylang manages languages and translations for this post type, false otherwise
Usage:
1pll_is_translated_post_type( $post_type );
The unique parameter is required:
『$post_type』 => the post type to check
pll_is_translated_taxonomy
Returns true if Polylang manages languages and translations for this taxonomy, false otherwise
Usage:
1pll_is_translated_taxonomy( $tax );
The unique parameter is required:
『$tax』 => the taxonomy to check
pll_languages_list
Returns the list of languages
Usage:
1pll_languages_list( $args );
$args is an optional array parameter. Options are:
『hide_empty』 => hides languages with no posts if set to 1 (default: 0)
『fields』 => returns only that field if set. Possible values are 『slug』, 『locale』, 『name』, defaults to 『slug』
pll_get_post_language
gets the language of a post or page (or custom post type post)
Usage:
1pll_get_post_language( $post_id, $field );
『$post_id』 => (required) id of the post for which you want to get the language
『$field』 => (optional) either 『name』 or 『locale』 or 『slug』, defaults to 『slug』
returns either the full name, or the WordPress locale or the slug ( 2-letters code) of the post.
pll_get_term_language
gets the language of a category or post tag (or custom taxonomy term)
Usage:
1pll_get_term_language( $term_id, $field );
『$term_id』 => (required) id of the term for which you want to get the language
『$field』 => (optional) either 『name』 or 『locale』 or 『slug』, defaults to 『slug』
returns either the full name, or the WordPress locale or the slug ( 2-letters code) of the term.
pll_set_post_language
Sets the language of a post or page (or custom post type post)
Usage:
1pll_set_post_language($post_id, $lang);
『$post_id』 => (required) id of the post for which you want to set the language
『$lang』 => (required) language code
pll_set_term_language
Sets the language of a category or post tag (or custom taxonomy term)
Usage:
1pll_set_term_language( $term_id, $lang );
『$term_id』 => (required) id of the term for which you want to set the language
『$lang』 => (required) language code
pll_get_post_translations
Returns an associative array of translations with language code as key and translation post_id as value
Usage:
1pll_get_post_translations( $post_id );
『$post_id』 => (required) id of the post for which you want to get the translations
pll_get_term_translations
Returns an associative array of translations with language code as key and translation term_id as value
Usage:
1pll_get_term_translations( $term_id );
『$term_id』 => (required) id of the term for which you want to get the translations
pll_save_post_translations
Defines which posts are translations of each other
Usage:
1pll_save_post_translations( $arr );
『$arr』 => (required) associative array of translations with language code as key and post id as value
pll_save_term_translations
Defines which terms are translations of each other
Usage:
1pll_save_term_translations( $arr );
『$arr』 => (required) associative array of translations with language code as key and term id as value
pll_count_posts
Counts posts in a defined language
Usage:
1pll_count_posts( $lang, $args );
『$lang』 => (required) language code
『$args』 => (optional) allows to restrict the count to a certain class of post archive. Accepted keys are 『post_type』, 『m,』 『year』, 『monthnum』, 『day』, 『author』, 『author_name』, 『post_format』
My menus disappeared when switching to another theme
The menu theme locations are theme dependant and are not kept when you switch to another theme. You must reassign them.
Is it possible to use a static front page?
Yes. You have to create one page per language. Set translations as usual and then go to the WordPress 『Reading settings』 panel. Check 『Front page displays a static page』 and choose one of the page you have just created. The language doesn』t matter. You can do the same for the posts page.
Then, if you want that the url looks like http://www.yoursite.com/en/ instead of http://www.yoursite.com/startpage/, go to Settings > Languages > Settings and check the option 「The front page url contains the language code instead of the page name or page id」 in the URL modifications section.
Filter reference
pll_copy_post_metas
Allows plugins to copy custom fields when a new post (or page) translation is created or synchronizing them. Filter arguments:
$metas => an array of post metas
$sync => false when copying custom fields to a new translation, true when synchronizing translations
$from => Id of the post from which we copy informations
$to => Id of the post to which we paste informations
$lang => Language slug
Example:
12345add_filter( 'pll_copy_post_metas', 'copy_post_metas' ); function copy_post_metas( $metas ) { return array_merge( $metas, array( 'my_post_meta' ) );}
pll_translate_post_meta
Allows plugins to modify custom fields when it is copied from one post to a translation. This is typically used in combination with `pll_copy_post_metas』 to translate the custom field. Filter arguments:
$value => Meta value
$key => Meta key
$lang => Language slug of the target post
$from => Id of the post from which we copy informations
$to => Id of the post to which we paste informations
Example:
12345678add_filter( 'pll_translate_post_meta', 'translate_post_meta', 10, 3 ); function translate_post_meta( $value, $key, $lang ) { if ( '_thumbnail_id' === $key ) { $value = pll_get_post( $value, $lang ); } return $value;}
pll_copy_term_metas
Allows plugins to copy term metas when a new term translation is created or synchronizing them. The usage is similar to the filter 『pll_copy_post_metas』.
pll_translate_term_meta
Allows plugins to modify term metas when it is copied from one term to a translation. This is typically used to translate the term meta. The usage is similar to the filter 『pll_translate_post_meta』.
pll_copy_taxonomies
Allows plugins to copy taxonomy terms when a new post (or page) translation is created or synchronize them. Filter arguments:
$taxonomies => list of taxonomy names
$sync => true if it is synchronization, false if it is a copy
$from => Id of the post from which we copy informations
$to => Id of the post to which we paste informations
$lang => Language slug
Example:
123456add_filter( 'pll_copy_taxonomies', 'copy_tax', 10, 2 ); function copy_tax( $taxonomies, $sync ) { $taxonomies[] = 'my_custom_tax'; return $taxonomies;}
pll_translation_url
Allows plugins to modify (or create) the translation url. This is thus a more generic filter than 『pll_the_languages_link』 described below. Filter arguments:
$url => the translation URL to modify (set to null if there is no translation available)
$slug => the 2-letters language iso-code of the translation
pll_the_language_link
Allows plugins to modify the translation link outputed by the language switcher (valid for the widget, the nav menus and the function pll_the_languages). Filter arguments:
$url => the translation URL to modify (set to null if there is no translation available)
$slug => the 2-letters language iso-code of the translation
$locale => the WordPress locale for the language of the translation
Example (to link to the posts list in the right language when there is no translation available):
12345add_filter( 'pll_the_language_link', 'my_link', 10, 2 ); function my_link( $url, $slug ) { return $url === null ? home_url( '?lang=' . $slug ) : $url;}
pll_flag_title
Allows plugins to modify the title attribute of the flag in the language switcher (defaults to language name). Filter arguments:
$title => the title attribute
$slug => the 2-letters language iso-code of the translation
$locale => the WordPress locale for the language of the translation
Example:
123456789101112131415add_filter( 'pll_flag_title', 'my_flag_title', 10, 2 ); function my_flag_title( $title, $slug ) { switch( $slug ) { case 'en': return 'The blog in ' . $title; break; case 'fr': return 'Le blog en ' . $title; break; default: return $title; break; }}
pll_the_languages
Allows plugins to modify the whole output of the language switcher. Filter arguments:
$output => the output of the language filter
$args => the arguments of the function pll_the_languages
Example (to add a link to the flag file in the title attribute of the dropdown list which maybe useful used together with a script adding a picture in the dropdown):
12345678910111213add_filter( 'pll_the_languages', 'my_dropdown', 10, 2 ); function my_dropdown( $output, $args ) { if ( ! $args['dropdown'] ) { return $output; } foreach ( array( 'en_US', 'fr_FR', 'de_DE' ) as $lang ) { $file = POLYLANG_DIR . 」/flags/$lang.png」; $value = reset( explode( '_', get_locale() ) ); $output = str_replace( 「value='$value'」, 「value='$lang' title='$file'」, $output ); } return $output;}
pll_the_languages_args
Allows plugins to filter the arguments passed to the function pll_the_languages used to display a language switcher. Filter arguments:
$args => the arguments of the function pll_the_languages
Example (to display the language code instead of the language native name in the language switcher):
123456add_filter( 'pll_the_languages_args', 'my_language_switcher_args' ); function my_language_switcher_args( $args ) { $args['display_names_as'] = 'slug'; return $args;}
pll_get_post_types
Allows plugins to modify the list of post types which will be filtered by language. The default are custom post types which have the parameter 『public』 set to true. The filter must be added soon in the WordPress loading process: in a function hooked to 『plugins_loaded』 or directly in functions.php for themes. Filter arguments:
$post_types => the array of post type names
$is_settings => true when displaying the list of custom post types in Polylang settings (avoid the user to modify the decision made by the plugin author for a post type)
Example:
123456789101112add_filter( 'pll_get_post_types', 'add_cpt_to_pll', 10, 2 ); function add_cpt_to_pll( $post_types, $is_settings ) { if ( $is_settings ) { // hides 'my_cpt' from the list of custom post types in Polylang settings unset( $post_types['my_cpt'] ); } else { // enables language and translation management for 'my_cpt' $post_types['my_cpt'] = 'my_cpt'; } return $post_types;}
pll_get_taxonomies
Allows plugins to modify the list of taxonomies which will be filtered by language. The default are taxonomies which have the parameter 『public』 set to true (which include categories and post tags). The filter must be added soon in the WordPress loading process: in a function hooked to 『plugins_loaded』 or directly in functions.php for themes. Filter arguments:
$taxonomies => the array of taxonomy names
$is_settings => true when displaying the list of custom taxonomies in Polylang settings (avoid the user to modify the decision made by the plugin author for a taxonomy)
Example:
12345678910add_filter( 'pll_get_taxonomies', 'add_tax_to_pll', 10, 2 ); function add_tax_to_pll( $taxonomies, $is_settings ) { if ( $is_settings ) { unset( $taxonomies['my_tax'] ); } else { $taxonomies['my_tax'] = 'my_tax'; } return $taxonomies;}
pll_rewrite_rules
Allows plugins to inform Polylang of a new rewrite rules filter to use (allowing this rules to be filtered by language. Filter arguments:
$rules => the array rewrite rules to filter
Example:
123456789101112// create rewrite rules with a filter 'something_rewrite_rules'add_filter( 'generate_rewrite_rules', 'my_rules' ); function my_rules( $wp_rewrite ) { $rules[] = ... $rules = apply_filters( 'my_own_rewrite_rules', $rules ); $wp_rewrite->rules = array_merge( $rules, $wp_rewrite->rules );}// add the filter (without '_rewrite_rules') to the Polylang listadd_filter( 'pll_rewrite_rules', function( $rules ) { return array_merge( $rules, array( "my_own" ) ); } );
pll_preferred_language
Allows plugins to modify the visitor preferred language (normally set first by cookie if this is not the first visit, then by the browser preferences). If no preferred language has been found or set by this filter, Polylang fallbacks to the default language. Filter arguments:
$slug => language code or false if no preferred language has been found
Example:
123456// fallback language is English whatever the default languageadd_filter( 'pll_preferred_language', 'my_language_fallback' ); function my_language_fallback( $slug ) { return $slug === false ? 'en' : $slug;}
pll_get_flag
Allows plugins to modify the html output of flags (the images). Filter arguments:
$flag => html output of one flag
$slug => language code
Example:
123456// displays language code instead of flags on admin sideadd_filter( 'pll_get_flag', 'no_flag_on_admin' ); function no_flag_on_admin( $flag ) { return is_admin() ? '' : $flag;}
pll_redirect_home
When a visitor reaches the home, Polylang redirects to the home in the correct language. This filter allows plugins to modify the redirected url or prevent this redirection. Filter arguments:
$redirect => the redirected url. If set to false, there will be no redirection.
Example:
12// prevents home redirectionadd_filter( 'pll_redirect_home', '__return_false' );
Note: You must add this filter in a custom plugin as it is generally applied before the theme is loaded.
pll_sanitize_string_translation
Allows to sanitize strings registered with pll_register_string. Filter arguments:
$string => the translated string to sanitize
$name => string name
$group => the group in which the string is registered
pll_cookie_expiration
Allows to modify the cookie duration. Filter arguments:
$duration => the cookie duration in seconds. Defaults to one year
Note: You must add this filter in a custom plugin as it is generally applied before the theme is loaded.
pll_rel_hreflang_attributes
Allows to modify hreflang attributes displayed in the html head on frontend. Filter arguments:
$hreflangs => Array of urls with language codes as keys and links as values
pll_custom_flag
Allows to modify a flag url and size. Filter arguments:
$flag => An array of information with 『url』,』src』, height』, 『width』 keys. The url is mandatory. The 3 other parameters are optional. The 『height』 and 『width』 parameters are especially useful for SVG flags.
$code => Flag code
Notes:
The filter needs to be added in a plugin or mu-plugin before the action 『plugins_loaded』 has been fired. It can』t work in the functions.php of a theme.
The filter acts only on flags displayed on frontend. The flags used in the backend are kept unchanged.
After you have changed the code in the filter, go to Languages > Settings. Click on the 「URL modifications」 settings and then on Save Changes, to reset the transient storing the languages.
Example:
12345678add_filter( 'pll_custom_flag', 'pll_custom_flag', 10, 2 ); function pll_custom_flag( $flag, $code ) { $flag['url'] = "http://mysite.com/wordpress/wp-content/polylang/{$code}.svg"; $flag['width'] = 32; $flag['height'] = 22; return $flag;}
pll_flag
This filter works the same as 『pll_custom_flag』 except that it acts both on frontend and backend.
pll_pre_current_user_can_synchronize_post
Used to decide if a synchronizations capability check should take place when a user doesn』t have the right to edit one of the translated posts. Filter arguments:
$check => null to enable the capability check, true to allow the synchronization, false to disallow the synchronization. Defaults to true.
$post_id => Id of the synchronization source post.
Example:
1add_filter( 'pll_pre_current_user_can_synchronize_post', '__return_null' );
I can』t add the language switcher in the menus
In Appearance >Menus, go to screen options on top right of your screen and check the 「Language switcher」 checkbox. You then should have a new metabox which allows you to add a language switcher the same way you add other menu items.
Due to WordPress limitations, it is currently not possible to add the language switcher from the Customizer Menus.
Is Polylang compatible with multisite?
Yes it is. Polylang is fully tested in a multisite environment, activated at site level.
It should also work when network activated but is not so well tested in this configuration. In most cases, it shouldn』t be useful to network activate Polylang.