wp/wp-includes/l10n.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     1 <?php
     1 <?php
     2 /**
     2 /**
     3  * WordPress Translation API
     3  * Core Translation API
     4  *
     4  *
     5  * @package WordPress
     5  * @package WordPress
     6  * @subpackage i18n
     6  * @subpackage i18n
     7  */
     7  * @since 1.2.0
     8 
     8  */
     9 /**
     9 
    10  * Get the current locale.
    10 /**
    11  *
    11  * Retrieves the current locale.
    12  * If the locale is set, then it will filter the locale in the 'locale' filter
    12  *
    13  * hook and return the value.
    13  * If the locale is set, then it will filter the locale in the {@see 'locale'}
       
    14  * filter hook and return the value.
    14  *
    15  *
    15  * If the locale is not set already, then the WPLANG constant is used if it is
    16  * If the locale is not set already, then the WPLANG constant is used if it is
    16  * defined. Then it is filtered through the 'locale' filter hook and the value
    17  * defined. Then it is filtered through the {@see 'locale'} filter hook and
    17  * for the locale global set and the locale is returned.
    18  * the value for the locale global set and the locale is returned.
    18  *
    19  *
    19  * The process to get the locale should only be done once, but the locale will
    20  * The process to get the locale should only be done once, but the locale will
    20  * always be filtered using the 'locale' hook.
    21  * always be filtered using the {@see 'locale'} hook.
    21  *
    22  *
    22  * @since 1.5.0
    23  * @since 1.5.0
    23  *
    24  *
    24  * @return string The locale of the blog or from the 'locale' hook.
    25  * @global string $locale
       
    26  * @global string $wp_local_package
       
    27  *
       
    28  * @return string The locale of the blog or from the {@see 'locale'} hook.
    25  */
    29  */
    26 function get_locale() {
    30 function get_locale() {
    27 	global $locale, $wp_local_package;
    31 	global $locale, $wp_local_package;
    28 
    32 
    29 	if ( isset( $locale ) ) {
    33 	if ( isset( $locale ) ) {
    30 		/**
    34 		/**
    31 		 * Filter WordPress install's locale ID.
    35 		 * Filters the locale ID of the WordPress installation.
    32 		 *
    36 		 *
    33 		 * @since 1.5.0
    37 		 * @since 1.5.0
    34 		 *
    38 		 *
    35 		 * @param string $locale The locale ID.
    39 		 * @param string $locale The locale ID.
    36 		 */
    40 		 */
    47 	}
    51 	}
    48 
    52 
    49 	// If multisite, check options.
    53 	// If multisite, check options.
    50 	if ( is_multisite() ) {
    54 	if ( is_multisite() ) {
    51 		// Don't check blog option when installing.
    55 		// Don't check blog option when installing.
    52 		if ( defined( 'WP_INSTALLING' ) || ( false === $ms_locale = get_option( 'WPLANG' ) ) ) {
    56 		if ( wp_installing() || ( false === $ms_locale = get_option( 'WPLANG' ) ) ) {
    53 			$ms_locale = get_site_option( 'WPLANG' );
    57 			$ms_locale = get_site_option( 'WPLANG' );
    54 		}
    58 		}
    55 
    59 
    56 		if ( $ms_locale !== false ) {
    60 		if ( $ms_locale !== false ) {
    57 			$locale = $ms_locale;
    61 			$locale = $ms_locale;
    70 	/** This filter is documented in wp-includes/l10n.php */
    74 	/** This filter is documented in wp-includes/l10n.php */
    71 	return apply_filters( 'locale', $locale );
    75 	return apply_filters( 'locale', $locale );
    72 }
    76 }
    73 
    77 
    74 /**
    78 /**
       
    79  * Retrieves the locale of a user.
       
    80  *
       
    81  * If the user has a locale set to a non-empty string then it will be
       
    82  * returned. Otherwise it returns the locale of get_locale().
       
    83  *
       
    84  * @since 4.7.0
       
    85  *
       
    86  * @param int|WP_User $user_id User's ID or a WP_User object. Defaults to current user.
       
    87  * @return string The locale of the user.
       
    88  */
       
    89 function get_user_locale( $user_id = 0 ) {
       
    90 	$user = false;
       
    91 	if ( 0 === $user_id && function_exists( 'wp_get_current_user' ) ) {
       
    92 		$user = wp_get_current_user();
       
    93 	} elseif ( $user_id instanceof WP_User ) {
       
    94 		$user = $user_id;
       
    95 	} elseif ( $user_id && is_numeric( $user_id ) ) {
       
    96 		$user = get_user_by( 'id', $user_id );
       
    97 	}
       
    98 
       
    99 	if ( ! $user ) {
       
   100 		return get_locale();
       
   101 	}
       
   102 
       
   103 	$locale = $user->locale;
       
   104 	return $locale ? $locale : get_locale();
       
   105 }
       
   106 
       
   107 /**
    75  * Retrieve the translation of $text.
   108  * Retrieve the translation of $text.
    76  *
   109  *
    77  * If there is no translation, or the text domain isn't loaded, the original text is returned.
   110  * If there is no translation, or the text domain isn't loaded, the original text is returned.
    78  *
   111  *
    79  * *Note:* Don't use {@see translate()} directly, use `{@see __()} or related functions.
   112  * *Note:* Don't use translate() directly, use __() or related functions.
    80  *
   113  *
    81  * @since 2.2.0
   114  * @since 2.2.0
    82  *
   115  *
    83  * @param string $text   Text to translate.
   116  * @param string $text   Text to translate.
    84  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   117  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   118  *                       Default 'default'.
    85  * @return string Translated text
   119  * @return string Translated text
    86  */
   120  */
    87 function translate( $text, $domain = 'default' ) {
   121 function translate( $text, $domain = 'default' ) {
    88 	$translations = get_translations_for_domain( $domain );
   122 	$translations = get_translations_for_domain( $domain );
    89 	$translations = $translations->translate( $text );
   123 	$translation  = $translations->translate( $text );
    90 
   124 
    91 	/**
   125 	/**
    92 	 * Filter text with its translation.
   126 	 * Filters text with its translation.
    93 	 *
   127 	 *
    94 	 * @since 2.0.11
   128 	 * @since 2.0.11
    95 	 *
   129 	 *
    96 	 * @param string $translations Translated text.
   130 	 * @param string $translation  Translated text.
    97 	 * @param string $text         Text to translate.
   131 	 * @param string $text         Text to translate.
    98 	 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
   132 	 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
    99 	 */
   133 	 */
   100 	return apply_filters( 'gettext', $translations, $text, $domain );
   134 	return apply_filters( 'gettext', $translation, $text, $domain );
   101 }
   135 }
   102 
   136 
   103 /**
   137 /**
   104  * Remove last item on a pipe-delimited string.
   138  * Remove last item on a pipe-delimited string.
   105  *
   139  *
   111  * @param string $string A pipe-delimited string.
   145  * @param string $string A pipe-delimited string.
   112  * @return string Either $string or everything before the last pipe.
   146  * @return string Either $string or everything before the last pipe.
   113  */
   147  */
   114 function before_last_bar( $string ) {
   148 function before_last_bar( $string ) {
   115 	$last_bar = strrpos( $string, '|' );
   149 	$last_bar = strrpos( $string, '|' );
   116 	if ( false == $last_bar )
   150 	if ( false === $last_bar ) {
   117 		return $string;
   151 		return $string;
   118 	else
   152 	} else {
   119 		return substr( $string, 0, $last_bar );
   153 		return substr( $string, 0, $last_bar );
       
   154 	}
   120 }
   155 }
   121 
   156 
   122 /**
   157 /**
   123  * Retrieve the translation of $text in the context defined in $context.
   158  * Retrieve the translation of $text in the context defined in $context.
   124  *
   159  *
   125  * If there is no translation, or the text domain isn't loaded the original
   160  * If there is no translation, or the text domain isn't loaded the original
   126  * text is returned.
   161  * text is returned.
       
   162  *
       
   163  * *Note:* Don't use translate_with_gettext_context() directly, use _x() or related functions.
   127  *
   164  *
   128  * @since 2.8.0
   165  * @since 2.8.0
   129  *
   166  *
   130  * @param string $text    Text to translate.
   167  * @param string $text    Text to translate.
   131  * @param string $context Context information for the translators.
   168  * @param string $context Context information for the translators.
   132  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
   169  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   170  *                        Default 'default'.
   133  * @return string Translated text on success, original text on failure.
   171  * @return string Translated text on success, original text on failure.
   134  */
   172  */
   135 function translate_with_gettext_context( $text, $context, $domain = 'default' ) {
   173 function translate_with_gettext_context( $text, $context, $domain = 'default' ) {
   136 	$translations = get_translations_for_domain( $domain );
   174 	$translations = get_translations_for_domain( $domain );
   137 	$translations = $translations->translate( $text, $context );
   175 	$translation  = $translations->translate( $text, $context );
   138 	/**
   176 	/**
   139 	 * Filter text with its translation based on context information.
   177 	 * Filters text with its translation based on context information.
   140 	 *
   178 	 *
   141 	 * @since 2.8.0
   179 	 * @since 2.8.0
   142 	 *
   180 	 *
   143 	 * @param string $translations Translated text.
   181 	 * @param string $translation  Translated text.
   144 	 * @param string $text         Text to translate.
   182 	 * @param string $text         Text to translate.
   145 	 * @param string $context      Context information for the translators.
   183 	 * @param string $context      Context information for the translators.
   146 	 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
   184 	 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
   147 	 */
   185 	 */
   148 	return apply_filters( 'gettext_with_context', $translations, $text, $context, $domain );
   186 	return apply_filters( 'gettext_with_context', $translation, $text, $context, $domain );
   149 }
   187 }
   150 
   188 
   151 /**
   189 /**
   152  * Retrieve the translation of $text. If there is no translation,
   190  * Retrieve the translation of $text.
   153  * or the text domain isn't loaded, the original text is returned.
   191  *
       
   192  * If there is no translation, or the text domain isn't loaded, the original text is returned.
   154  *
   193  *
   155  * @since 2.1.0
   194  * @since 2.1.0
   156  *
   195  *
   157  * @param string $text   Text to translate.
   196  * @param string $text   Text to translate.
   158  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   197  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   198  *                       Default 'default'.
   159  * @return string Translated text.
   199  * @return string Translated text.
   160  */
   200  */
   161 function __( $text, $domain = 'default' ) {
   201 function __( $text, $domain = 'default' ) {
   162 	return translate( $text, $domain );
   202 	return translate( $text, $domain );
   163 }
   203 }
   169  *
   209  *
   170  * @since 2.8.0
   210  * @since 2.8.0
   171  *
   211  *
   172  * @param string $text   Text to translate.
   212  * @param string $text   Text to translate.
   173  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   213  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   214  *                       Default 'default'.
   174  * @return string Translated text on success, original text on failure.
   215  * @return string Translated text on success, original text on failure.
   175  */
   216  */
   176 function esc_attr__( $text, $domain = 'default' ) {
   217 function esc_attr__( $text, $domain = 'default' ) {
   177 	return esc_attr( translate( $text, $domain ) );
   218 	return esc_attr( translate( $text, $domain ) );
   178 }
   219 }
   179 
   220 
   180 /**
   221 /**
   181  * Retrieve the translation of $text and escapes it for safe use in HTML output.
   222  * Retrieve the translation of $text and escapes it for safe use in HTML output.
   182  *
   223  *
   183  * If there is no translation, or the text domain isn't loaded, the original text is returned.
   224  * If there is no translation, or the text domain isn't loaded, the original text
       
   225  * is escaped and returned..
   184  *
   226  *
   185  * @since 2.8.0
   227  * @since 2.8.0
   186  *
   228  *
   187  * @param string $text   Text to translate.
   229  * @param string $text   Text to translate.
   188  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   230  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   231  *                       Default 'default'.
   189  * @return string Translated text
   232  * @return string Translated text
   190  */
   233  */
   191 function esc_html__( $text, $domain = 'default' ) {
   234 function esc_html__( $text, $domain = 'default' ) {
   192 	return esc_html( translate( $text, $domain ) );
   235 	return esc_html( translate( $text, $domain ) );
   193 }
   236 }
   197  *
   240  *
   198  * @since 1.2.0
   241  * @since 1.2.0
   199  *
   242  *
   200  * @param string $text   Text to translate.
   243  * @param string $text   Text to translate.
   201  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   244  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   245  *                       Default 'default'.
   202  */
   246  */
   203 function _e( $text, $domain = 'default' ) {
   247 function _e( $text, $domain = 'default' ) {
   204 	echo translate( $text, $domain );
   248 	echo translate( $text, $domain );
   205 }
   249 }
   206 
   250 
   209  *
   253  *
   210  * @since 2.8.0
   254  * @since 2.8.0
   211  *
   255  *
   212  * @param string $text   Text to translate.
   256  * @param string $text   Text to translate.
   213  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   257  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   258  *                       Default 'default'.
   214  */
   259  */
   215 function esc_attr_e( $text, $domain = 'default' ) {
   260 function esc_attr_e( $text, $domain = 'default' ) {
   216 	echo esc_attr( translate( $text, $domain ) );
   261 	echo esc_attr( translate( $text, $domain ) );
   217 }
   262 }
   218 
   263 
   221  *
   266  *
   222  * @since 2.8.0
   267  * @since 2.8.0
   223  *
   268  *
   224  * @param string $text   Text to translate.
   269  * @param string $text   Text to translate.
   225  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   270  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   271  *                       Default 'default'.
   226  */
   272  */
   227 function esc_html_e( $text, $domain = 'default' ) {
   273 function esc_html_e( $text, $domain = 'default' ) {
   228 	echo esc_html( translate( $text, $domain ) );
   274 	echo esc_html( translate( $text, $domain ) );
   229 }
   275 }
   230 
   276 
   240  * @since 2.8.0
   286  * @since 2.8.0
   241  *
   287  *
   242  * @param string $text    Text to translate.
   288  * @param string $text    Text to translate.
   243  * @param string $context Context information for the translators.
   289  * @param string $context Context information for the translators.
   244  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
   290  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   291  *                        Default 'default'.
   245  * @return string Translated context string without pipe.
   292  * @return string Translated context string without pipe.
   246  */
   293  */
   247 function _x( $text, $context, $domain = 'default' ) {
   294 function _x( $text, $context, $domain = 'default' ) {
   248 	return translate_with_gettext_context( $text, $context, $domain );
   295 	return translate_with_gettext_context( $text, $context, $domain );
   249 }
   296 }
   254  * @since 3.0.0
   301  * @since 3.0.0
   255  *
   302  *
   256  * @param string $text    Text to translate.
   303  * @param string $text    Text to translate.
   257  * @param string $context Context information for the translators.
   304  * @param string $context Context information for the translators.
   258  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
   305  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   306  *                        Default 'default'.
   259  * @return string Translated context string without pipe.
   307  * @return string Translated context string without pipe.
   260  */
   308  */
   261 function _ex( $text, $context, $domain = 'default' ) {
   309 function _ex( $text, $context, $domain = 'default' ) {
   262 	echo _x( $text, $context, $domain );
   310 	echo _x( $text, $context, $domain );
   263 }
   311 }
   268  * @since 2.8.0
   316  * @since 2.8.0
   269  *
   317  *
   270  * @param string $text    Text to translate.
   318  * @param string $text    Text to translate.
   271  * @param string $context Context information for the translators.
   319  * @param string $context Context information for the translators.
   272  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
   320  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   321  *                        Default 'default'.
   273  * @return string Translated text
   322  * @return string Translated text
   274  */
   323  */
   275 function esc_attr_x( $text, $context, $domain = 'default' ) {
   324 function esc_attr_x( $text, $context, $domain = 'default' ) {
   276 	return esc_attr( translate_with_gettext_context( $text, $context, $domain ) );
   325 	return esc_attr( translate_with_gettext_context( $text, $context, $domain ) );
   277 }
   326 }
   282  * @since 2.9.0
   331  * @since 2.9.0
   283  *
   332  *
   284  * @param string $text    Text to translate.
   333  * @param string $text    Text to translate.
   285  * @param string $context Context information for the translators.
   334  * @param string $context Context information for the translators.
   286  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
   335  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   336  *                        Default 'default'.
   287  * @return string Translated text.
   337  * @return string Translated text.
   288  */
   338  */
   289 function esc_html_x( $text, $context, $domain = 'default' ) {
   339 function esc_html_x( $text, $context, $domain = 'default' ) {
   290 	return esc_html( translate_with_gettext_context( $text, $context, $domain ) );
   340 	return esc_html( translate_with_gettext_context( $text, $context, $domain ) );
   291 }
   341 }
   292 
   342 
   293 /**
   343 /**
   294  * Retrieve the plural or single form based on the supplied amount.
   344  * Translates and retrieves the singular or plural form based on the supplied number.
   295  *
   345  *
   296  * If the text domain is not set in the $l10n list, then a comparison will be made
   346  * Used when you want to use the appropriate form of a string based on whether a
   297  * and either $plural or $single parameters returned.
   347  * number is singular or plural.
   298  *
   348  *
   299  * If the text domain does exist, then the parameters $single, $plural, and $number
   349  * Example:
   300  * will first be passed to the text domain's ngettext method. Then it will be passed
   350  *
   301  * to the 'ngettext' filter hook along with the same parameters. The expected
   351  *     printf( _n( '%s person', '%s people', $count, 'text-domain' ), number_format_i18n( $count ) );
   302  * type will be a string.
       
   303  *
   352  *
   304  * @since 2.8.0
   353  * @since 2.8.0
   305  *
   354  *
   306  * @param string $single The text that will be used if $number is 1.
   355  * @param string $single The text to be used if the number is singular.
   307  * @param string $plural The text that will be used if $number is not 1.
   356  * @param string $plural The text to be used if the number is plural.
   308  * @param int    $number The number to compare against to use either $single or $plural.
   357  * @param int    $number The number to compare against to use either the singular or plural form.
   309  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   358  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
   310  * @return string Either $single or $plural translated text.
   359  *                       Default 'default'.
       
   360  * @return string The translated singular or plural form.
   311  */
   361  */
   312 function _n( $single, $plural, $number, $domain = 'default' ) {
   362 function _n( $single, $plural, $number, $domain = 'default' ) {
   313 	$translations = get_translations_for_domain( $domain );
   363 	$translations = get_translations_for_domain( $domain );
   314 	$translation = $translations->translate_plural( $single, $plural, $number );
   364 	$translation  = $translations->translate_plural( $single, $plural, $number );
       
   365 
   315 	/**
   366 	/**
   316 	 * Filter text with its translation when plural option is available.
   367 	 * Filters the singular or plural form of a string.
   317 	 *
   368 	 *
   318 	 * @since 2.2.0
   369 	 * @since 2.2.0
   319 	 *
   370 	 *
   320 	 * @param string $translation Translated text.
   371 	 * @param string $translation Translated text.
   321 	 * @param string $single      The text that will be used if $number is 1.
   372 	 * @param string $single      The text to be used if the number is singular.
   322 	 * @param string $plural      The text that will be used if $number is not 1.
   373 	 * @param string $plural      The text to be used if the number is plural.
   323 	 * @param string $number      The number to compare against to use either $single or $plural.
   374 	 * @param string $number      The number to compare against to use either the singular or plural form.
   324 	 * @param string $domain      Text domain. Unique identifier for retrieving translated strings.
   375 	 * @param string $domain      Text domain. Unique identifier for retrieving translated strings.
   325 	 */
   376 	 */
   326 	return apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain );
   377 	return apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain );
   327 }
   378 }
   328 
   379 
   329 /**
   380 /**
   330  * Retrieve the plural or single form based on the supplied amount with gettext context.
   381  * Translates and retrieves the singular or plural form based on the supplied number, with gettext context.
   331  *
   382  *
   332  * This is a hybrid of _n() and _x(). It supports contexts and plurals.
   383  * This is a hybrid of _n() and _x(). It supports context and plurals.
       
   384  *
       
   385  * Used when you want to use the appropriate form of a string with context based on whether a
       
   386  * number is singular or plural.
       
   387  *
       
   388  * Example of a generic phrase which is disambiguated via the context parameter:
       
   389  *
       
   390  *     printf( _nx( '%s group', '%s groups', $people, 'group of people', 'text-domain' ), number_format_i18n( $people ) );
       
   391  *     printf( _nx( '%s group', '%s groups', $animals, 'group of animals', 'text-domain' ), number_format_i18n( $animals ) );
   333  *
   392  *
   334  * @since 2.8.0
   393  * @since 2.8.0
   335  *
   394  *
   336  * @param string $single  The text that will be used if $number is 1.
   395  * @param string $single  The text to be used if the number is singular.
   337  * @param string $plural  The text that will be used if $number is not 1.
   396  * @param string $plural  The text to be used if the number is plural.
   338  * @param int    $number  The number to compare against to use either $single or $plural.
   397  * @param int    $number  The number to compare against to use either the singular or plural form.
   339  * @param string $context Context information for the translators.
   398  * @param string $context Context information for the translators.
   340  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
   399  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
   341  * @return string Either $single or $plural translated text with context.
   400  *                        Default 'default'.
       
   401  * @return string The translated singular or plural form.
   342  */
   402  */
   343 function _nx($single, $plural, $number, $context, $domain = 'default') {
   403 function _nx($single, $plural, $number, $context, $domain = 'default') {
   344 	$translations = get_translations_for_domain( $domain );
   404 	$translations = get_translations_for_domain( $domain );
   345 	$translation = $translations->translate_plural( $single, $plural, $number, $context );
   405 	$translation  = $translations->translate_plural( $single, $plural, $number, $context );
       
   406 
   346 	/**
   407 	/**
   347 	 * Filter text with its translation while plural option and context are available.
   408 	 * Filters the singular or plural form of a string with gettext context.
   348 	 *
   409 	 *
   349 	 * @since 2.8.0
   410 	 * @since 2.8.0
   350 	 *
   411 	 *
   351 	 * @param string $translation Translated text.
   412 	 * @param string $translation Translated text.
   352 	 * @param string $single      The text that will be used if $number is 1.
   413 	 * @param string $single      The text to be used if the number is singular.
   353 	 * @param string $plural      The text that will be used if $number is not 1.
   414 	 * @param string $plural      The text to be used if the number is plural.
   354 	 * @param string $number      The number to compare against to use either $single or $plural.
   415 	 * @param string $number      The number to compare against to use either the singular or plural form.
   355 	 * @param string $context     Context information for the translators.
   416 	 * @param string $context     Context information for the translators.
   356 	 * @param string $domain      Text domain. Unique identifier for retrieving translated strings.
   417 	 * @param string $domain      Text domain. Unique identifier for retrieving translated strings.
   357 	 */
   418 	 */
   358 	return apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain );
   419 	return apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain );
   359 }
   420 }
   360 
   421 
   361 /**
   422 /**
   362  * Register plural strings in POT file, but don't translate them.
   423  * Registers plural strings in POT file, but does not translate them.
   363  *
   424  *
   364  * Used when you want to keep structures with translatable plural
   425  * Used when you want to keep structures with translatable plural
   365  * strings and use them later.
   426  * strings and use them later when the number is known.
   366  *
   427  *
   367  * Example:
   428  * Example:
   368  *
   429  *
       
   430  *     $message = _n_noop( '%s post', '%s posts', 'text-domain' );
       
   431  *     ...
       
   432  *     printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) );
       
   433  *
       
   434  * @since 2.5.0
       
   435  *
       
   436  * @param string $singular Singular form to be localized.
       
   437  * @param string $plural   Plural form to be localized.
       
   438  * @param string $domain   Optional. Text domain. Unique identifier for retrieving translated strings.
       
   439  *                         Default null.
       
   440  * @return array {
       
   441  *     Array of translation information for the strings.
       
   442  *
       
   443  *     @type string $0        Singular form to be localized. No longer used.
       
   444  *     @type string $1        Plural form to be localized. No longer used.
       
   445  *     @type string $singular Singular form to be localized.
       
   446  *     @type string $plural   Plural form to be localized.
       
   447  *     @type null   $context  Context information for the translators.
       
   448  *     @type string $domain   Text domain.
       
   449  * }
       
   450  */
       
   451 function _n_noop( $singular, $plural, $domain = null ) {
       
   452 	return array( 0 => $singular, 1 => $plural, 'singular' => $singular, 'plural' => $plural, 'context' => null, 'domain' => $domain );
       
   453 }
       
   454 
       
   455 /**
       
   456  * Registers plural strings with gettext context in POT file, but does not translate them.
       
   457  *
       
   458  * Used when you want to keep structures with translatable plural
       
   459  * strings and use them later when the number is known.
       
   460  *
       
   461  * Example of a generic phrase which is disambiguated via the context parameter:
       
   462  *
   369  *     $messages = array(
   463  *     $messages = array(
   370  *      	'post' => _n_noop( '%s post', '%s posts' ),
   464  *      	'people'  => _nx_noop( '%s group', '%s groups', 'people', 'text-domain' ),
   371  *      	'page' => _n_noop( '%s pages', '%s pages' ),
   465  *      	'animals' => _nx_noop( '%s group', '%s groups', 'animals', 'text-domain' ),
   372  *     );
   466  *     );
   373  *     ...
   467  *     ...
   374  *     $message = $messages[ $type ];
   468  *     $message = $messages[ $type ];
   375  *     $usable_text = sprintf( translate_nooped_plural( $message, $count ), $count );
   469  *     printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) );
   376  *
   470  *
   377  * @since 2.5.0
   471  * @since 2.8.0
   378  *
   472  *
   379  * @param string $singular Single form to be i18ned.
   473  * @param string $singular Singular form to be localized.
   380  * @param string $plural   Plural form to be i18ned.
   474  * @param string $plural   Plural form to be localized.
       
   475  * @param string $context  Context information for the translators.
   381  * @param string $domain   Optional. Text domain. Unique identifier for retrieving translated strings.
   476  * @param string $domain   Optional. Text domain. Unique identifier for retrieving translated strings.
   382  * @return array array($singular, $plural)
   477  *                         Default null.
   383  */
   478  * @return array {
   384 function _n_noop( $singular, $plural, $domain = null ) {
   479  *     Array of translation information for the strings.
   385 	return array( 0 => $singular, 1 => $plural, 'singular' => $singular, 'plural' => $plural, 'context' => null, 'domain' => $domain );
   480  *
   386 }
   481  *     @type string $0        Singular form to be localized. No longer used.
   387 
   482  *     @type string $1        Plural form to be localized. No longer used.
   388 /**
   483  *     @type string $2        Context information for the translators. No longer used.
   389  * Register plural strings with context in POT file, but don't translate them.
   484  *     @type string $singular Singular form to be localized.
   390  *
   485  *     @type string $plural   Plural form to be localized.
   391  * @since 2.8.0
   486  *     @type string $context  Context information for the translators.
   392  * @param string $singular
   487  *     @type string $domain   Text domain.
   393  * @param string $plural
   488  * }
   394  * @param string $context
       
   395  * @param string|null $domain
       
   396  * @return array
       
   397  */
   489  */
   398 function _nx_noop( $singular, $plural, $context, $domain = null ) {
   490 function _nx_noop( $singular, $plural, $context, $domain = null ) {
   399 	return array( 0 => $singular, 1 => $plural, 2 => $context, 'singular' => $singular, 'plural' => $plural, 'context' => $context, 'domain' => $domain );
   491 	return array( 0 => $singular, 1 => $plural, 2 => $context, 'singular' => $singular, 'plural' => $plural, 'context' => $context, 'domain' => $domain );
   400 }
   492 }
   401 
   493 
   402 /**
   494 /**
   403  * Translate the result of _n_noop() or _nx_noop().
   495  * Translates and retrieves the singular or plural form of a string that's been registered
       
   496  * with _n_noop() or _nx_noop().
       
   497  *
       
   498  * Used when you want to use a translatable plural string once the number is known.
       
   499  *
       
   500  * Example:
       
   501  *
       
   502  *     $message = _n_noop( '%s post', '%s posts', 'text-domain' );
       
   503  *     ...
       
   504  *     printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) );
   404  *
   505  *
   405  * @since 3.1.0
   506  * @since 3.1.0
   406  *
   507  *
   407  * @param array  $nooped_plural Array with singular, plural and context keys, usually the result of _n_noop() or _nx_noop()
   508  * @param array  $nooped_plural Array with singular, plural, and context keys, usually the result of _n_noop() or _nx_noop().
   408  * @param int    $count         Number of objects
   509  * @param int    $count         Number of objects.
   409  * @param string $domain        Optional. Text domain. Unique identifier for retrieving translated strings. If $nooped_plural contains
   510  * @param string $domain        Optional. Text domain. Unique identifier for retrieving translated strings. If $nooped_plural contains
   410  *                              a text domain passed to _n_noop() or _nx_noop(), it will override this value.
   511  *                              a text domain passed to _n_noop() or _nx_noop(), it will override this value. Default 'default'.
   411  * @return string Either $single or $plural translated text.
   512  * @return string Either $single or $plural translated text.
   412  */
   513  */
   413 function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) {
   514 function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) {
   414 	if ( $nooped_plural['domain'] )
   515 	if ( $nooped_plural['domain'] )
   415 		$domain = $nooped_plural['domain'];
   516 		$domain = $nooped_plural['domain'];
   429  * On success, the .mo file will be placed in the $l10n global by $domain
   530  * On success, the .mo file will be placed in the $l10n global by $domain
   430  * and will be a MO object.
   531  * and will be a MO object.
   431  *
   532  *
   432  * @since 1.5.0
   533  * @since 1.5.0
   433  *
   534  *
       
   535  * @global array $l10n          An array of all currently loaded text domains.
       
   536  * @global array $l10n_unloaded An array of all text domains that have been unloaded again.
       
   537  *
   434  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   538  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   435  * @param string $mofile Path to the .mo file.
   539  * @param string $mofile Path to the .mo file.
   436  * @return bool True on success, false on failure.
   540  * @return bool True on success, false on failure.
   437  */
   541  */
   438 function load_textdomain( $domain, $mofile ) {
   542 function load_textdomain( $domain, $mofile ) {
   439 	global $l10n;
   543 	global $l10n, $l10n_unloaded;
       
   544 
       
   545 	$l10n_unloaded = (array) $l10n_unloaded;
   440 
   546 
   441 	/**
   547 	/**
   442 	 * Filter text domain and/or MO file path for loading translations.
   548 	 * Filters whether to override the .mo file loading.
   443 	 *
   549 	 *
   444 	 * @since 2.9.0
   550 	 * @since 2.9.0
   445 	 *
   551 	 *
   446 	 * @param bool   $override Whether to override the text domain. Default false.
   552 	 * @param bool   $override Whether to override the .mo file loading. Default false.
   447 	 * @param string $domain   Text domain. Unique identifier for retrieving translated strings.
   553 	 * @param string $domain   Text domain. Unique identifier for retrieving translated strings.
   448 	 * @param string $mofile   Path to the MO file.
   554 	 * @param string $mofile   Path to the MO file.
   449 	 */
   555 	 */
   450 	$plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );
   556 	$plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );
   451 
   557 
   452 	if ( true == $plugin_override ) {
   558 	if ( true == $plugin_override ) {
       
   559 		unset( $l10n_unloaded[ $domain ] );
       
   560 
   453 		return true;
   561 		return true;
   454 	}
   562 	}
   455 
   563 
   456 	/**
   564 	/**
   457 	 * Fires before the MO translation file is loaded.
   565 	 * Fires before the MO translation file is loaded.
   462 	 * @param string $mofile Path to the .mo file.
   570 	 * @param string $mofile Path to the .mo file.
   463 	 */
   571 	 */
   464 	do_action( 'load_textdomain', $domain, $mofile );
   572 	do_action( 'load_textdomain', $domain, $mofile );
   465 
   573 
   466 	/**
   574 	/**
   467 	 * Filter MO file path for loading translations for a specific text domain.
   575 	 * Filters MO file path for loading translations for a specific text domain.
   468 	 *
   576 	 *
   469 	 * @since 2.9.0
   577 	 * @since 2.9.0
   470 	 *
   578 	 *
   471 	 * @param string $mofile Path to the MO file.
   579 	 * @param string $mofile Path to the MO file.
   472 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   580 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   479 	if ( !$mo->import_from_file( $mofile ) ) return false;
   587 	if ( !$mo->import_from_file( $mofile ) ) return false;
   480 
   588 
   481 	if ( isset( $l10n[$domain] ) )
   589 	if ( isset( $l10n[$domain] ) )
   482 		$mo->merge_with( $l10n[$domain] );
   590 		$mo->merge_with( $l10n[$domain] );
   483 
   591 
       
   592 	unset( $l10n_unloaded[ $domain ] );
       
   593 
   484 	$l10n[$domain] = &$mo;
   594 	$l10n[$domain] = &$mo;
   485 
   595 
   486 	return true;
   596 	return true;
   487 }
   597 }
   488 
   598 
   489 /**
   599 /**
   490  * Unload translations for a text domain.
   600  * Unload translations for a text domain.
   491  *
   601  *
   492  * @since 3.0.0
   602  * @since 3.0.0
       
   603  *
       
   604  * @global array $l10n          An array of all currently loaded text domains.
       
   605  * @global array $l10n_unloaded An array of all text domains that have been unloaded again.
   493  *
   606  *
   494  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   607  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   495  * @return bool Whether textdomain was unloaded.
   608  * @return bool Whether textdomain was unloaded.
   496  */
   609  */
   497 function unload_textdomain( $domain ) {
   610 function unload_textdomain( $domain ) {
   498 	global $l10n;
   611 	global $l10n, $l10n_unloaded;
       
   612 
       
   613 	$l10n_unloaded = (array) $l10n_unloaded;
   499 
   614 
   500 	/**
   615 	/**
   501 	 * Filter the text domain for loading translation.
   616 	 * Filters whether to override the text domain unloading.
   502 	 *
   617 	 *
   503 	 * @since 3.0.0
   618 	 * @since 3.0.0
   504 	 *
   619 	 *
   505 	 * @param bool   $override Whether to override unloading the text domain. Default false.
   620 	 * @param bool   $override Whether to override the text domain unloading. Default false.
   506 	 * @param string $domain   Text domain. Unique identifier for retrieving translated strings.
   621 	 * @param string $domain   Text domain. Unique identifier for retrieving translated strings.
   507 	 */
   622 	 */
   508 	$plugin_override = apply_filters( 'override_unload_textdomain', false, $domain );
   623 	$plugin_override = apply_filters( 'override_unload_textdomain', false, $domain );
   509 
   624 
   510 	if ( $plugin_override )
   625 	if ( $plugin_override ) {
       
   626 		$l10n_unloaded[ $domain ] = true;
       
   627 
   511 		return true;
   628 		return true;
       
   629 	}
   512 
   630 
   513 	/**
   631 	/**
   514 	 * Fires before the text domain is unloaded.
   632 	 * Fires before the text domain is unloaded.
   515 	 *
   633 	 *
   516 	 * @since 3.0.0
   634 	 * @since 3.0.0
   519 	 */
   637 	 */
   520 	do_action( 'unload_textdomain', $domain );
   638 	do_action( 'unload_textdomain', $domain );
   521 
   639 
   522 	if ( isset( $l10n[$domain] ) ) {
   640 	if ( isset( $l10n[$domain] ) ) {
   523 		unset( $l10n[$domain] );
   641 		unset( $l10n[$domain] );
       
   642 
       
   643 		$l10n_unloaded[ $domain ] = true;
       
   644 
   524 		return true;
   645 		return true;
   525 	}
   646 	}
   526 
   647 
   527 	return false;
   648 	return false;
   528 }
   649 }
   535  *
   656  *
   536  * @see load_textdomain()
   657  * @see load_textdomain()
   537  *
   658  *
   538  * @since 1.5.0
   659  * @since 1.5.0
   539  *
   660  *
   540  * @param string $locale Optional. Locale to load. Default is the value of {@see get_locale()}.
   661  * @param string $locale Optional. Locale to load. Default is the value of get_locale().
   541  * @return bool Whether the textdomain was loaded.
   662  * @return bool Whether the textdomain was loaded.
   542  */
   663  */
   543 function load_default_textdomain( $locale = null ) {
   664 function load_default_textdomain( $locale = null ) {
   544 	if ( null === $locale ) {
   665 	if ( null === $locale ) {
   545 		$locale = get_locale();
   666 		$locale = is_admin() ? get_user_locale() : get_locale();
   546 	}
   667 	}
   547 
   668 
   548 	// Unload previously loaded strings so we can switch translations.
   669 	// Unload previously loaded strings so we can switch translations.
   549 	unload_textdomain( 'default' );
   670 	unload_textdomain( 'default' );
   550 
   671 
   553 	if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists(  WP_LANG_DIR . "/admin-$locale.mo" ) ) {
   674 	if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists(  WP_LANG_DIR . "/admin-$locale.mo" ) ) {
   554 		load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo" );
   675 		load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo" );
   555 		return $return;
   676 		return $return;
   556 	}
   677 	}
   557 
   678 
   558 	if ( is_admin() || defined( 'WP_INSTALLING' ) || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) ) {
   679 	if ( is_admin() || wp_installing() || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) ) {
   559 		load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" );
   680 		load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" );
   560 	}
   681 	}
   561 
   682 
   562 	if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) )
   683 	if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) )
   563 		load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo" );
   684 		load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo" );
   564 
   685 
   565 	return $return;
   686 	return $return;
   566 }
   687 }
   567 
   688 
   568 /**
   689 /**
   569  * Load a plugin's translated strings.
   690  * Loads a plugin's translated strings.
   570  *
   691  *
   571  * If the path is not given then it will be the root of the plugin directory.
   692  * If the path is not given then it will be the root of the plugin directory.
   572  *
   693  *
   573  * The .mo file should be named based on the text domain with a dash, and then the locale exactly.
   694  * The .mo file should be named based on the text domain with a dash, and then the locale exactly.
   574  *
   695  *
   575  * @since 1.5.0
   696  * @since 1.5.0
       
   697  * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
   576  *
   698  *
   577  * @param string $domain          Unique identifier for retrieving translated strings
   699  * @param string $domain          Unique identifier for retrieving translated strings
   578  * @param string $deprecated      Use the $plugin_rel_path parameter instead.
   700  * @param string $deprecated      Optional. Use the $plugin_rel_path parameter instead. Default false.
   579  * @param string $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR where the .mo file resides.
   701  * @param string $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR where the .mo file resides.
   580  *                                Default false.
   702  *                                Default false.
   581  * @return bool True when textdomain is successfully loaded, false otherwise.
   703  * @return bool True when textdomain is successfully loaded, false otherwise.
   582  */
   704  */
   583 function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) {
   705 function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) {
   584 	$locale = get_locale();
       
   585 	/**
   706 	/**
   586 	 * Filter a plugin's locale.
   707 	 * Filters a plugin's locale.
   587 	 *
   708 	 *
   588 	 * @since 3.0.0
   709 	 * @since 3.0.0
   589 	 *
   710 	 *
   590 	 * @param string $locale The plugin's current locale.
   711 	 * @param string $locale The plugin's current locale.
   591 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   712 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   592 	 */
   713 	 */
   593 	$locale = apply_filters( 'plugin_locale', $locale, $domain );
   714 	$locale = apply_filters( 'plugin_locale', is_admin() ? get_user_locale() : get_locale(), $domain );
   594 
   715 
   595 	if ( false !== $plugin_rel_path	) {
   716 	$mofile = $domain . '-' . $locale . '.mo';
       
   717 
       
   718 	// Try to load from the languages directory first.
       
   719 	if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile ) ) {
       
   720 		return true;
       
   721 	}
       
   722 
       
   723 	if ( false !== $plugin_rel_path ) {
   596 		$path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
   724 		$path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
   597 	} elseif ( false !== $deprecated ) {
   725 	} elseif ( false !== $deprecated ) {
   598 		_deprecated_argument( __FUNCTION__, '2.7' );
   726 		_deprecated_argument( __FUNCTION__, '2.7.0' );
   599 		$path = ABSPATH . trim( $deprecated, '/' );
   727 		$path = ABSPATH . trim( $deprecated, '/' );
   600 	} else {
   728 	} else {
   601 		$path = WP_PLUGIN_DIR;
   729 		$path = WP_PLUGIN_DIR;
   602 	}
   730 	}
   603 
   731 
   604 	// Load the textdomain according to the plugin first
   732 	return load_textdomain( $domain, $path . '/' . $mofile );
   605 	$mofile = $domain . '-' . $locale . '.mo';
       
   606 	if ( $loaded = load_textdomain( $domain, $path . '/'. $mofile ) )
       
   607 		return $loaded;
       
   608 
       
   609 	// Otherwise, load from the languages directory
       
   610 	$mofile = WP_LANG_DIR . '/plugins/' . $mofile;
       
   611 	return load_textdomain( $domain, $mofile );
       
   612 }
   733 }
   613 
   734 
   614 /**
   735 /**
   615  * Load the translated strings for a plugin residing in the mu-plugins directory.
   736  * Load the translated strings for a plugin residing in the mu-plugins directory.
   616  *
   737  *
   617  * @since 3.0.0
   738  * @since 3.0.0
       
   739  * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
   618  *
   740  *
   619  * @param string $domain             Text domain. Unique identifier for retrieving translated strings.
   741  * @param string $domain             Text domain. Unique identifier for retrieving translated strings.
   620  * @param string $mu_plugin_rel_path Relative to WPMU_PLUGIN_DIR directory in which the .mo file resides.
   742  * @param string $mu_plugin_rel_path Optional. Relative to `WPMU_PLUGIN_DIR` directory in which the .mo
   621  *                                   Default empty string.
   743  *                                   file resides. Default empty string.
   622  * @return bool True when textdomain is successfully loaded, false otherwise.
   744  * @return bool True when textdomain is successfully loaded, false otherwise.
   623  */
   745  */
   624 function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) {
   746 function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) {
   625 	/** This filter is documented in wp-includes/l10n.php */
   747 	/** This filter is documented in wp-includes/l10n.php */
   626 	$locale = apply_filters( 'plugin_locale', get_locale(), $domain );
   748 	$locale = apply_filters( 'plugin_locale', is_admin() ? get_user_locale() : get_locale(), $domain );
   627 	$path = trailingslashit( WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' ) );
   749 
   628 
       
   629 	// Load the textdomain according to the plugin first
       
   630 	$mofile = $domain . '-' . $locale . '.mo';
   750 	$mofile = $domain . '-' . $locale . '.mo';
   631 	if ( $loaded = load_textdomain( $domain, $path . $mofile ) )
   751 
   632 		return $loaded;
   752 	// Try to load from the languages directory first.
   633 
   753 	if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile ) ) {
   634 	// Otherwise, load from the languages directory
   754 		return true;
   635 	$mofile = WP_LANG_DIR . '/plugins/' . $mofile;
   755 	}
   636 	return load_textdomain( $domain, $mofile );
   756 
       
   757 	$path = WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' );
       
   758 
       
   759 	return load_textdomain( $domain, $path . '/' . $mofile );
   637 }
   760 }
   638 
   761 
   639 /**
   762 /**
   640  * Load the theme's translated strings.
   763  * Load the theme's translated strings.
   641  *
   764  *
   643  * will be included in the translated strings by the $domain.
   766  * will be included in the translated strings by the $domain.
   644  *
   767  *
   645  * The .mo files must be named based on the locale exactly.
   768  * The .mo files must be named based on the locale exactly.
   646  *
   769  *
   647  * @since 1.5.0
   770  * @since 1.5.0
       
   771  * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
   648  *
   772  *
   649  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   773  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   650  * @param string $path   Optional. Path to the directory containing the .mo file.
   774  * @param string $path   Optional. Path to the directory containing the .mo file.
   651  *                       Default false.
   775  *                       Default false.
   652  * @return bool True when textdomain is successfully loaded, false otherwise.
   776  * @return bool True when textdomain is successfully loaded, false otherwise.
   653  */
   777  */
   654 function load_theme_textdomain( $domain, $path = false ) {
   778 function load_theme_textdomain( $domain, $path = false ) {
   655 	$locale = get_locale();
       
   656 	/**
   779 	/**
   657 	 * Filter a theme's locale.
   780 	 * Filters a theme's locale.
   658 	 *
   781 	 *
   659 	 * @since 3.0.0
   782 	 * @since 3.0.0
   660 	 *
   783 	 *
   661 	 * @param string $locale The theme's current locale.
   784 	 * @param string $locale The theme's current locale.
   662 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   785 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   663 	 */
   786 	 */
   664 	$locale = apply_filters( 'theme_locale', $locale, $domain );
   787 	$locale = apply_filters( 'theme_locale', is_admin() ? get_user_locale() : get_locale(), $domain );
   665 
   788 
   666 	if ( ! $path )
   789 	$mofile = $domain . '-' . $locale . '.mo';
       
   790 
       
   791 	// Try to load from the languages directory first.
       
   792 	if ( load_textdomain( $domain, WP_LANG_DIR . '/themes/' . $mofile ) ) {
       
   793 		return true;
       
   794 	}
       
   795 
       
   796 	if ( ! $path ) {
   667 		$path = get_template_directory();
   797 		$path = get_template_directory();
   668 
   798 	}
   669 	// Load the textdomain according to the theme
   799 
   670 	$mofile = untrailingslashit( $path ) . "/{$locale}.mo";
   800 	return load_textdomain( $domain, $path . '/' . $locale . '.mo' );
   671 	if ( $loaded = load_textdomain( $domain, $mofile ) )
       
   672 		return $loaded;
       
   673 
       
   674 	// Otherwise, load from the languages directory
       
   675 	$mofile = WP_LANG_DIR . "/themes/{$domain}-{$locale}.mo";
       
   676 	return load_textdomain( $domain, $mofile );
       
   677 }
   801 }
   678 
   802 
   679 /**
   803 /**
   680  * Load the child themes translated strings.
   804  * Load the child themes translated strings.
   681  *
   805  *
   696 		$path = get_stylesheet_directory();
   820 		$path = get_stylesheet_directory();
   697 	return load_theme_textdomain( $domain, $path );
   821 	return load_theme_textdomain( $domain, $path );
   698 }
   822 }
   699 
   823 
   700 /**
   824 /**
       
   825  * Loads plugin and theme textdomains just-in-time.
       
   826  *
       
   827  * When a textdomain is encountered for the first time, we try to load
       
   828  * the translation file from `wp-content/languages`, removing the need
       
   829  * to call load_plugin_texdomain() or load_theme_texdomain().
       
   830  *
       
   831  * @since 4.6.0
       
   832  * @access private
       
   833  *
       
   834  * @see get_translations_for_domain()
       
   835  * @global array $l10n_unloaded An array of all text domains that have been unloaded again.
       
   836  *
       
   837  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   838  * @return bool True when the textdomain is successfully loaded, false otherwise.
       
   839  */
       
   840 function _load_textdomain_just_in_time( $domain ) {
       
   841 	global $l10n_unloaded;
       
   842 
       
   843 	$l10n_unloaded = (array) $l10n_unloaded;
       
   844 
       
   845 	// Short-circuit if domain is 'default' which is reserved for core.
       
   846 	if ( 'default' === $domain || isset( $l10n_unloaded[ $domain ] ) ) {
       
   847 		return false;
       
   848 	}
       
   849 
       
   850 	$translation_path = _get_path_to_translation( $domain );
       
   851 	if ( false === $translation_path ) {
       
   852 		return false;
       
   853 	}
       
   854 
       
   855 	return load_textdomain( $domain, $translation_path );
       
   856 }
       
   857 
       
   858 /**
       
   859  * Gets the path to a translation file for loading a textdomain just in time.
       
   860  *
       
   861  * Caches the retrieved results internally.
       
   862  *
       
   863  * @since 4.7.0
       
   864  * @access private
       
   865  *
       
   866  * @see _load_textdomain_just_in_time()
       
   867  *
       
   868  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   869  * @param bool   $reset  Whether to reset the internal cache. Used by the switch to locale functionality.
       
   870  * @return string|false The path to the translation file or false if no translation file was found.
       
   871  */
       
   872 function _get_path_to_translation( $domain, $reset = false ) {
       
   873 	static $available_translations = array();
       
   874 
       
   875 	if ( true === $reset ) {
       
   876 		$available_translations = array();
       
   877 	}
       
   878 
       
   879 	if ( ! isset( $available_translations[ $domain ] ) ) {
       
   880 		$available_translations[ $domain ] = _get_path_to_translation_from_lang_dir( $domain );
       
   881 	}
       
   882 
       
   883 	return $available_translations[ $domain ];
       
   884 }
       
   885 
       
   886 /**
       
   887  * Gets the path to a translation file in the languages directory for the current locale.
       
   888  *
       
   889  * Holds a cached list of available .mo files to improve performance.
       
   890  *
       
   891  * @since 4.7.0
       
   892  * @access private
       
   893  *
       
   894  * @see _get_path_to_translation()
       
   895  *
       
   896  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   897  * @return string|false The path to the translation file or false if no translation file was found.
       
   898  */
       
   899 function _get_path_to_translation_from_lang_dir( $domain ) {
       
   900 	static $cached_mofiles = null;
       
   901 
       
   902 	if ( null === $cached_mofiles ) {
       
   903 		$cached_mofiles = array();
       
   904 
       
   905 		$locations = array(
       
   906 			WP_LANG_DIR . '/plugins',
       
   907 			WP_LANG_DIR . '/themes',
       
   908 		);
       
   909 
       
   910 		foreach ( $locations as $location ) {
       
   911 			$mofiles = glob( $location . '/*.mo' );
       
   912 			if ( $mofiles ) {
       
   913 				$cached_mofiles = array_merge( $cached_mofiles, $mofiles );
       
   914 			}
       
   915 		}
       
   916 	}
       
   917 
       
   918 	$locale = is_admin() ? get_user_locale() : get_locale();
       
   919 	$mofile = "{$domain}-{$locale}.mo";
       
   920 
       
   921 	$path = WP_LANG_DIR . '/plugins/' . $mofile;
       
   922 	if ( in_array( $path, $cached_mofiles ) ) {
       
   923 		return $path;
       
   924 	}
       
   925 
       
   926 	$path = WP_LANG_DIR . '/themes/' . $mofile;
       
   927 	if ( in_array( $path, $cached_mofiles ) ) {
       
   928 		return $path;
       
   929 	}
       
   930 
       
   931 	return false;
       
   932 }
       
   933 
       
   934 /**
   701  * Return the Translations instance for a text domain.
   935  * Return the Translations instance for a text domain.
   702  *
   936  *
   703  * If there isn't one, returns empty Translations instance.
   937  * If there isn't one, returns empty Translations instance.
   704  *
   938  *
   705  * @since 2.8.0
   939  * @since 2.8.0
   706  *
   940  *
       
   941  * @global array $l10n
       
   942  *
   707  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   943  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   708  * @return NOOP_Translations A Translations instance.
   944  * @return Translations|NOOP_Translations A Translations instance.
   709  */
   945  */
   710 function get_translations_for_domain( $domain ) {
   946 function get_translations_for_domain( $domain ) {
   711 	global $l10n;
   947 	global $l10n;
   712 	if ( !isset( $l10n[$domain] ) ) {
   948 	if ( isset( $l10n[ $domain ] ) || ( _load_textdomain_just_in_time( $domain ) && isset( $l10n[ $domain ] ) ) ) {
   713 		$l10n[$domain] = new NOOP_Translations;
   949 		return $l10n[ $domain ];
   714 	}
   950 	}
   715 	return $l10n[$domain];
   951 
       
   952 	static $noop_translations = null;
       
   953 	if ( null === $noop_translations ) {
       
   954 		$noop_translations = new NOOP_Translations;
       
   955 	}
       
   956 
       
   957 	return $noop_translations;
   716 }
   958 }
   717 
   959 
   718 /**
   960 /**
   719  * Whether there are translations for the text domain.
   961  * Whether there are translations for the text domain.
   720  *
   962  *
   721  * @since 3.0.0
   963  * @since 3.0.0
       
   964  *
       
   965  * @global array $l10n
   722  *
   966  *
   723  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   967  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
   724  * @return bool Whether there are translations.
   968  * @return bool Whether there are translations.
   725  */
   969  */
   726 function is_textdomain_loaded( $domain ) {
   970 function is_textdomain_loaded( $domain ) {
   727 	global $l10n;
   971 	global $l10n;
   728 	return isset( $l10n[$domain] );
   972 	return isset( $l10n[ $domain ] );
   729 }
   973 }
   730 
   974 
   731 /**
   975 /**
   732  * Translates role name.
   976  * Translates role name.
   733  *
   977  *
   734  * Since the role names are in the database and not in the source there
   978  * Since the role names are in the database and not in the source there
   735  * are dummy gettext calls to get them into the POT file and this function
   979  * are dummy gettext calls to get them into the POT file and this function
   736  * properly translates them back.
   980  * properly translates them back.
   737  *
   981  *
   738  * The before_last_bar() call is needed, because older installs keep the roles
   982  * The before_last_bar() call is needed, because older installations keep the roles
   739  * using the old context format: 'Role name|User role' and just skipping the
   983  * using the old context format: 'Role name|User role' and just skipping the
   740  * content after the last bar is easier than fixing them in the DB. New installs
   984  * content after the last bar is easier than fixing them in the DB. New installations
   741  * won't suffer from that problem.
   985  * won't suffer from that problem.
   742  *
   986  *
   743  * @since 2.8.0
   987  * @since 2.8.0
   744  *
   988  *
   745  * @param string $name The role name.
   989  * @param string $name The role name.
   753  * Get all available languages based on the presence of *.mo files in a given directory.
   997  * Get all available languages based on the presence of *.mo files in a given directory.
   754  *
   998  *
   755  * The default directory is WP_LANG_DIR.
   999  * The default directory is WP_LANG_DIR.
   756  *
  1000  *
   757  * @since 3.0.0
  1001  * @since 3.0.0
       
  1002  * @since 4.7.0 The results are now filterable with the {@see 'get_available_languages'} filter.
   758  *
  1003  *
   759  * @param string $dir A directory to search for language files.
  1004  * @param string $dir A directory to search for language files.
   760  *                    Default WP_LANG_DIR.
  1005  *                    Default WP_LANG_DIR.
   761  * @return array An array of language codes or an empty array if no languages are present. Language codes are formed by stripping the .mo extension from the language file names.
  1006  * @return array An array of language codes or an empty array if no languages are present. Language codes are formed by stripping the .mo extension from the language file names.
   762  */
  1007  */
   763 function get_available_languages( $dir = null ) {
  1008 function get_available_languages( $dir = null ) {
   764 	$languages = array();
  1009 	$languages = array();
   765 
  1010 
   766 	foreach( (array)glob( ( is_null( $dir) ? WP_LANG_DIR : $dir ) . '/*.mo' ) as $lang_file ) {
  1011 	$lang_files = glob( ( is_null( $dir ) ? WP_LANG_DIR : $dir ) . '/*.mo' );
   767 		$lang_file = basename($lang_file, '.mo');
  1012 	if ( $lang_files ) {
   768 		if ( 0 !== strpos( $lang_file, 'continents-cities' ) && 0 !== strpos( $lang_file, 'ms-' ) &&
  1013 		foreach ( $lang_files as $lang_file ) {
   769 			0 !== strpos( $lang_file, 'admin-' ))
  1014 			$lang_file = basename( $lang_file, '.mo' );
   770 			$languages[] = $lang_file;
  1015 			if ( 0 !== strpos( $lang_file, 'continents-cities' ) && 0 !== strpos( $lang_file, 'ms-' ) &&
   771 	}
  1016 				0 !== strpos( $lang_file, 'admin-' ) ) {
   772 
  1017 				$languages[] = $lang_file;
   773 	return $languages;
  1018 			}
       
  1019 		}
       
  1020 	}
       
  1021 
       
  1022 	/**
       
  1023 	 * Filters the list of available language codes.
       
  1024 	 *
       
  1025 	 * @since 4.7.0
       
  1026 	 *
       
  1027 	 * @param array  $languages An array of available language codes.
       
  1028 	 * @param string $dir       The directory where the language files were found.
       
  1029 	 */
       
  1030 	return apply_filters( 'get_available_languages', $languages, $dir );
   774 }
  1031 }
   775 
  1032 
   776 /**
  1033 /**
   777  * Get installed translations.
  1034  * Get installed translations.
   778  *
  1035  *
   801 		return array();
  1058 		return array();
   802 
  1059 
   803 	$language_data = array();
  1060 	$language_data = array();
   804 
  1061 
   805 	foreach ( $files as $file ) {
  1062 	foreach ( $files as $file ) {
   806 		if ( '.' === $file[0] || is_dir( $file ) ) {
  1063 		if ( '.' === $file[0] || is_dir( WP_LANG_DIR . "$dir/$file" ) ) {
   807 			continue;
  1064 			continue;
   808 		}
  1065 		}
   809 		if ( substr( $file, -3 ) !== '.po' ) {
  1066 		if ( substr( $file, -3 ) !== '.po' ) {
   810 			continue;
  1067 			continue;
   811 		}
  1068 		}
   812 		if ( ! preg_match( '/(?:(.+)-)?([A-Za-z_]{2,6}).po/', $file, $match ) ) {
  1069 		if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?).po/', $file, $match ) ) {
   813 			continue;
  1070 			continue;
   814 		}
  1071 		}
   815 		if ( ! in_array( substr( $file, 0, -3 ) . '.mo', $files ) )  {
  1072 		if ( ! in_array( substr( $file, 0, -3 ) . '.mo', $files ) )  {
   816 			continue;
  1073 			continue;
   817 		}
  1074 		}
   849 
  1106 
   850 /**
  1107 /**
   851  * Language selector.
  1108  * Language selector.
   852  *
  1109  *
   853  * @since 4.0.0
  1110  * @since 4.0.0
       
  1111  * @since 4.3.0 Introduced the `echo` argument.
       
  1112  * @since 4.7.0 Introduced the `show_option_site_default` argument.
   854  *
  1113  *
   855  * @see get_available_languages()
  1114  * @see get_available_languages()
   856  * @see wp_get_available_translations()
  1115  * @see wp_get_available_translations()
   857  *
  1116  *
   858  * @param string|array $args {
  1117  * @param string|array $args {
   859  *     Optional. Array or string of arguments for outputting the language selector.
  1118  *     Optional. Array or string of arguments for outputting the language selector.
   860  *
  1119  *
   861  *     @type string  $id                           ID attribute of the select element. Default empty.
  1120  *     @type string   $id                           ID attribute of the select element. Default 'locale'.
   862  *     @type string  $name                         Name attribute of the select element. Default empty.
  1121  *     @type string   $name                         Name attribute of the select element. Default 'locale'.
   863  *     @type array   $languages                    List of installed languages, contain only the locales.
  1122  *     @type array    $languages                    List of installed languages, contain only the locales.
   864  *                                                 Default empty array.
  1123  *                                                  Default empty array.
   865  *     @type array   $translations                 List of available translations. Default result of
  1124  *     @type array    $translations                 List of available translations. Default result of
   866  *                                                 {@see wp_get_available_translations()}.
  1125  *                                                  wp_get_available_translations().
   867  *     @type string  $selected                     Language which should be selected. Default empty.
  1126  *     @type string   $selected                     Language which should be selected. Default empty.
   868  *     @type bool    $show_available_translations  Whether to show available translations. Default true.
  1127  *     @type bool|int $echo                         Whether to echo the generated markup. Accepts 0, 1, or their
       
  1128  *                                                  boolean equivalents. Default 1.
       
  1129  *     @type bool     $show_available_translations  Whether to show available translations. Default true.
       
  1130  *     @type bool     $show_option_site_default     Whether to show an option to fall back to the site's locale. Default false.
   869  * }
  1131  * }
       
  1132  * @return string HTML content
   870  */
  1133  */
   871 function wp_dropdown_languages( $args = array() ) {
  1134 function wp_dropdown_languages( $args = array() ) {
   872 
  1135 
   873 	$args = wp_parse_args( $args, array(
  1136 	$parsed_args = wp_parse_args( $args, array(
   874 		'id'           => '',
  1137 		'id'           => 'locale',
   875 		'name'         => '',
  1138 		'name'         => 'locale',
   876 		'languages'    => array(),
  1139 		'languages'    => array(),
   877 		'translations' => array(),
  1140 		'translations' => array(),
   878 		'selected'     => '',
  1141 		'selected'     => '',
       
  1142 		'echo'         => 1,
   879 		'show_available_translations' => true,
  1143 		'show_available_translations' => true,
       
  1144 		'show_option_site_default'    => false,
   880 	) );
  1145 	) );
   881 
  1146 
   882 	$translations = $args['translations'];
  1147 	// Bail if no ID or no name.
       
  1148 	if ( ! $parsed_args['id'] || ! $parsed_args['name'] ) {
       
  1149 		return;
       
  1150 	}
       
  1151 
       
  1152 	// English (United States) uses an empty string for the value attribute.
       
  1153 	if ( 'en_US' === $parsed_args['selected'] ) {
       
  1154 		$parsed_args['selected'] = '';
       
  1155 	}
       
  1156 
       
  1157 	$translations = $parsed_args['translations'];
   883 	if ( empty( $translations ) ) {
  1158 	if ( empty( $translations ) ) {
   884 		require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
  1159 		require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
   885 		$translations = wp_get_available_translations();
  1160 		$translations = wp_get_available_translations();
   886 	}
  1161 	}
   887 
  1162 
   888 	/*
  1163 	/*
   889 	 * $args['languages'] should only contain the locales. Find the locale in
  1164 	 * $parsed_args['languages'] should only contain the locales. Find the locale in
   890 	 * $translations to get the native name. Fall back to locale.
  1165 	 * $translations to get the native name. Fall back to locale.
   891 	 */
  1166 	 */
   892 	$languages = array();
  1167 	$languages = array();
   893 	foreach ( $args['languages'] as $locale ) {
  1168 	foreach ( $parsed_args['languages'] as $locale ) {
   894 		if ( isset( $translations[ $locale ] ) ) {
  1169 		if ( isset( $translations[ $locale ] ) ) {
   895 			$translation = $translations[ $locale ];
  1170 			$translation = $translations[ $locale ];
   896 			$languages[] = array(
  1171 			$languages[] = array(
   897 				'language'    => $translation['language'],
  1172 				'language'    => $translation['language'],
   898 				'native_name' => $translation['native_name'],
  1173 				'native_name' => $translation['native_name'],
   908 				'lang'        => '',
  1183 				'lang'        => '',
   909 			);
  1184 			);
   910 		}
  1185 		}
   911 	}
  1186 	}
   912 
  1187 
   913 	$translations_available = ( ! empty( $translations ) && $args['show_available_translations'] );
  1188 	$translations_available = ( ! empty( $translations ) && $parsed_args['show_available_translations'] );
   914 
       
   915 	printf( '<select name="%s" id="%s">', esc_attr( $args['name'] ), esc_attr( $args['id'] ) );
       
   916 
  1189 
   917 	// Holds the HTML markup.
  1190 	// Holds the HTML markup.
   918 	$structure = array();
  1191 	$structure = array();
   919 
  1192 
   920 	// List installed languages.
  1193 	// List installed languages.
   921 	if ( $translations_available ) {
  1194 	if ( $translations_available ) {
   922 		$structure[] = '<optgroup label="' . esc_attr_x( 'Installed', 'translations' ) . '">';
  1195 		$structure[] = '<optgroup label="' . esc_attr_x( 'Installed', 'translations' ) . '">';
   923 	}
  1196 	}
   924 	$structure[] = '<option value="" lang="en" data-installed="1">English (United States)</option>';
  1197 
       
  1198 	// Site default.
       
  1199 	if ( $parsed_args['show_option_site_default'] ) {
       
  1200 		$structure[] = sprintf(
       
  1201 			'<option value="site-default" data-installed="1"%s>%s</option>',
       
  1202 			selected( 'site-default', $parsed_args['selected'], false ),
       
  1203 			_x( 'Site Default', 'default site language' )
       
  1204 		);
       
  1205 	}
       
  1206 
       
  1207 	// Always show English.
       
  1208 	$structure[] = sprintf(
       
  1209 		'<option value="" lang="en" data-installed="1"%s>English (United States)</option>',
       
  1210 		selected( '', $parsed_args['selected'], false )
       
  1211 	);
       
  1212 
       
  1213 	// List installed languages. 
   925 	foreach ( $languages as $language ) {
  1214 	foreach ( $languages as $language ) {
   926 		$structure[] = sprintf(
  1215 		$structure[] = sprintf(
   927 			'<option value="%s" lang="%s"%s data-installed="1">%s</option>',
  1216 			'<option value="%s" lang="%s"%s data-installed="1">%s</option>',
   928 			esc_attr( $language['language'] ),
  1217 			esc_attr( $language['language'] ),
   929 			esc_attr( $language['lang'] ),
  1218 			esc_attr( $language['lang'] ),
   930 			selected( $language['language'], $args['selected'], false ),
  1219 			selected( $language['language'], $parsed_args['selected'], false ),
   931 			esc_html( $language['native_name'] )
  1220 			esc_html( $language['native_name'] )
   932 		);
  1221 		);
   933 	}
  1222 	}
   934 	if ( $translations_available ) {
  1223 	if ( $translations_available ) {
   935 		$structure[] = '</optgroup>';
  1224 		$structure[] = '</optgroup>';
   941 		foreach ( $translations as $translation ) {
  1230 		foreach ( $translations as $translation ) {
   942 			$structure[] = sprintf(
  1231 			$structure[] = sprintf(
   943 				'<option value="%s" lang="%s"%s>%s</option>',
  1232 				'<option value="%s" lang="%s"%s>%s</option>',
   944 				esc_attr( $translation['language'] ),
  1233 				esc_attr( $translation['language'] ),
   945 				esc_attr( current( $translation['iso'] ) ),
  1234 				esc_attr( current( $translation['iso'] ) ),
   946 				selected( $translation['language'], $args['selected'], false ),
  1235 				selected( $translation['language'], $parsed_args['selected'], false ),
   947 				esc_html( $translation['native_name'] )
  1236 				esc_html( $translation['native_name'] )
   948 			);
  1237 			);
   949 		}
  1238 		}
   950 		$structure[] = '</optgroup>';
  1239 		$structure[] = '</optgroup>';
   951 	}
  1240 	}
   952 
  1241 
   953 	echo join( "\n", $structure );
  1242 	// Combine the output string.
   954 
  1243 	$output  = sprintf( '<select name="%s" id="%s">', esc_attr( $parsed_args['name'] ), esc_attr( $parsed_args['id'] ) );
   955 	echo '</select>';
  1244 	$output .= join( "\n", $structure );
   956 }
  1245 	$output .= '</select>';
       
  1246 
       
  1247 	if ( $parsed_args['echo'] ) {
       
  1248 		echo $output;
       
  1249 	}
       
  1250 
       
  1251 	return $output;
       
  1252 }
       
  1253 
       
  1254 /**
       
  1255  * Checks if current locale is RTL.
       
  1256  *
       
  1257  * @since 3.0.0
       
  1258  *
       
  1259  * @global WP_Locale $wp_locale
       
  1260  *
       
  1261  * @return bool Whether locale is RTL.
       
  1262  */
       
  1263 function is_rtl() {
       
  1264 	global $wp_locale;
       
  1265 	if ( ! ( $wp_locale instanceof WP_Locale ) ) {
       
  1266 		return false;
       
  1267 	}
       
  1268 	return $wp_locale->is_rtl();
       
  1269 }
       
  1270 
       
  1271 /**
       
  1272  * Switches the translations according to the given locale.
       
  1273  *
       
  1274  * @since 4.7.0
       
  1275  *
       
  1276  * @global WP_Locale_Switcher $wp_locale_switcher
       
  1277  *
       
  1278  * @param string $locale The locale.
       
  1279  * @return bool True on success, false on failure.
       
  1280  */
       
  1281 function switch_to_locale( $locale ) {
       
  1282 	/* @var WP_Locale_Switcher $wp_locale_switcher */
       
  1283 	global $wp_locale_switcher;
       
  1284 
       
  1285 	return $wp_locale_switcher->switch_to_locale( $locale );
       
  1286 }
       
  1287 
       
  1288 /**
       
  1289  * Restores the translations according to the previous locale.
       
  1290  *
       
  1291  * @since 4.7.0
       
  1292  *
       
  1293  * @global WP_Locale_Switcher $wp_locale_switcher
       
  1294  *
       
  1295  * @return string|false Locale on success, false on error.
       
  1296  */
       
  1297 function restore_previous_locale() {
       
  1298 	/* @var WP_Locale_Switcher $wp_locale_switcher */
       
  1299 	global $wp_locale_switcher;
       
  1300 
       
  1301 	return $wp_locale_switcher->restore_previous_locale();
       
  1302 }
       
  1303 
       
  1304 /**
       
  1305  * Restores the translations according to the original locale.
       
  1306  *
       
  1307  * @since 4.7.0
       
  1308  *
       
  1309  * @global WP_Locale_Switcher $wp_locale_switcher
       
  1310  *
       
  1311  * @return string|false Locale on success, false on error.
       
  1312  */
       
  1313 function restore_current_locale() {
       
  1314 	/* @var WP_Locale_Switcher $wp_locale_switcher */
       
  1315 	global $wp_locale_switcher;
       
  1316 
       
  1317 	return $wp_locale_switcher->restore_current_locale();
       
  1318 }
       
  1319 
       
  1320 /**
       
  1321  * Whether switch_to_locale() is in effect.
       
  1322  *
       
  1323  * @since 4.7.0
       
  1324  *
       
  1325  * @global WP_Locale_Switcher $wp_locale_switcher
       
  1326  *
       
  1327  * @return bool True if the locale has been switched, false otherwise.
       
  1328  */
       
  1329 function is_locale_switched() {
       
  1330 	/* @var WP_Locale_Switcher $wp_locale_switcher */
       
  1331 	global $wp_locale_switcher;
       
  1332 
       
  1333 	return $wp_locale_switcher->is_switched();
       
  1334 }