Wordpress 3.0.3-scripts
[autoinstalls/wordpress.git] / wp-includes / l10n.php
1 <?php
2 /**
3  * WordPress Translation API
4  *
5  * @package WordPress
6  * @subpackage i18n
7  */
8
9 /**
10  * Gets the current locale.
11  *
12  * If the locale is set, then it will filter the locale in the 'locale' filter
13  * hook and return the value.
14  *
15  * 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  * for the locale global set and the locale is returned.
18  *
19  * The process to get the locale should only be done once but the locale will
20  * always be filtered using the 'locale' hook.
21  *
22  * @since 1.5.0
23  * @uses apply_filters() Calls 'locale' hook on locale value.
24  * @uses $locale Gets the locale stored in the global.
25  *
26  * @return string The locale of the blog or from the 'locale' hook.
27  */
28 function get_locale() {
29         global $locale;
30
31         if ( isset( $locale ) )
32                 return apply_filters( 'locale', $locale );
33
34         // WPLANG is defined in wp-config.
35         if ( defined( 'WPLANG' ) )
36                 $locale = WPLANG;
37
38         // If multisite, check options.
39         if ( is_multisite() && !defined('WP_INSTALLING') ) {
40                 $ms_locale = get_option('WPLANG');
41                 if ( $ms_locale === false )
42                         $ms_locale = get_site_option('WPLANG');
43
44                 if ( $ms_locale !== false )
45                         $locale = $ms_locale;
46         }
47
48         if ( empty( $locale ) )
49                 $locale = 'en_US';
50
51         return apply_filters( 'locale', $locale );
52 }
53
54 /**
55  * Retrieves the translation of $text. If there is no translation, or
56  * the domain isn't loaded the original text is returned.
57  *
58  * @see __() Don't use translate() directly, use __()
59  * @since 2.2.0
60  * @uses apply_filters() Calls 'gettext' on domain translated text
61  *              with the untranslated text as second parameter.
62  *
63  * @param string $text Text to translate.
64  * @param string $domain Domain to retrieve the translated text.
65  * @return string Translated text
66  */
67 function translate( $text, $domain = 'default' ) {
68         $translations = &get_translations_for_domain( $domain );
69         return apply_filters( 'gettext', $translations->translate( $text ), $text, $domain );
70 }
71
72 function before_last_bar( $string ) {
73         $last_bar = strrpos( $string, '|' );
74         if ( false == $last_bar )
75                 return $string;
76         else
77                 return substr( $string, 0, $last_bar );
78 }
79
80 function translate_with_gettext_context( $text, $context, $domain = 'default' ) {
81         $translations = &get_translations_for_domain( $domain );
82         return apply_filters( 'gettext_with_context', $translations->translate( $text, $context ), $text, $context, $domain );
83 }
84
85 /**
86  * Retrieves the translation of $text. If there is no translation, or
87  * the domain isn't loaded the original text is returned.
88  *
89  * @see translate() An alias of translate()
90  * @since 2.1.0
91  *
92  * @param string $text Text to translate
93  * @param string $domain Optional. Domain to retrieve the translated text
94  * @return string Translated text
95  */
96 function __( $text, $domain = 'default' ) {
97         return translate( $text, $domain );
98 }
99
100 /**
101  * Retrieves the translation of $text and escapes it for safe use in an attribute.
102  * If there is no translation, or the domain isn't loaded the original text is returned.
103  *
104  * @see translate() An alias of translate()
105  * @see esc_attr()
106  * @since 2.8.0
107  *
108  * @param string $text Text to translate
109  * @param string $domain Optional. Domain to retrieve the translated text
110  * @return string Translated text
111  */
112 function esc_attr__( $text, $domain = 'default' ) {
113         return esc_attr( translate( $text, $domain ) );
114 }
115
116 /**
117  * Retrieves the translation of $text and escapes it for safe use in HTML output.
118  * If there is no translation, or the domain isn't loaded the original text is returned.
119  *
120  * @see translate() An alias of translate()
121  * @see esc_html()
122  * @since 2.8.0
123  *
124  * @param string $text Text to translate
125  * @param string $domain Optional. Domain to retrieve the translated text
126  * @return string Translated text
127  */
128 function esc_html__( $text, $domain = 'default' ) {
129         return esc_html( translate( $text, $domain ) );
130 }
131
132 /**
133  * Displays the returned translated text from translate().
134  *
135  * @see translate() Echoes returned translate() string
136  * @since 1.2.0
137  *
138  * @param string $text Text to translate
139  * @param string $domain Optional. Domain to retrieve the translated text
140  */
141 function _e( $text, $domain = 'default' ) {
142         echo translate( $text, $domain );
143 }
144
145 /**
146  * Displays translated text that has been escaped for safe use in an attribute.
147  *
148  * @see translate() Echoes returned translate() string
149  * @see esc_attr()
150  * @since 2.8.0
151  *
152  * @param string $text Text to translate
153  * @param string $domain Optional. Domain to retrieve the translated text
154  */
155 function esc_attr_e( $text, $domain = 'default' ) {
156         echo esc_attr( translate( $text, $domain ) );
157 }
158
159 /**
160  * Displays translated text that has been escaped for safe use in HTML output.
161  *
162  * @see translate() Echoes returned translate() string
163  * @see esc_html()
164  * @since 2.8.0
165  *
166  * @param string $text Text to translate
167  * @param string $domain Optional. Domain to retrieve the translated text
168  */
169 function esc_html_e( $text, $domain = 'default' ) {
170         echo esc_html( translate( $text, $domain ) );
171 }
172
173 /**
174  * Retrieve translated string with gettext context
175  *
176  * Quite a few times, there will be collisions with similar translatable text
177  * found in more than two places but with different translated context.
178  *
179  * By including the context in the pot file translators can translate the two
180  * string differently.
181  *
182  * @since 2.8.0
183  *
184  * @param string $text Text to translate
185  * @param string $context Context information for the translators
186  * @param string $domain Optional. Domain to retrieve the translated text
187  * @return string Translated context string without pipe
188  */
189 function _x( $single, $context, $domain = 'default' ) {
190         return translate_with_gettext_context( $single, $context, $domain );
191 }
192
193 /**
194  * Displays translated string with gettext context
195  *
196  * @see _x
197  * @since 3.0.0
198  *
199  * @param string $text Text to translate
200  * @param string $context Context information for the translators
201  * @param string $domain Optional. Domain to retrieve the translated text
202  * @return string Translated context string without pipe
203  */
204 function _ex( $single, $context, $domain = 'default' ) {
205         echo _x( $single, $context, $domain );
206 }
207
208 function esc_attr_x( $single, $context, $domain = 'default' ) {
209         return esc_attr( translate_with_gettext_context( $single, $context, $domain ) );
210 }
211
212 function esc_html_x( $single, $context, $domain = 'default' ) {
213         return esc_html( translate_with_gettext_context( $single, $context, $domain ) );
214 }
215
216 /**
217  * Retrieve the plural or single form based on the amount.
218  *
219  * If the domain is not set in the $l10n list, then a comparison will be made
220  * and either $plural or $single parameters returned.
221  *
222  * If the domain does exist, then the parameters $single, $plural, and $number
223  * will first be passed to the domain's ngettext method. Then it will be passed
224  * to the 'ngettext' filter hook along with the same parameters. The expected
225  * type will be a string.
226  *
227  * @since 2.8.0
228  * @uses $l10n Gets list of domain translated string (gettext_reader) objects
229  * @uses apply_filters() Calls 'ngettext' hook on domains text returned,
230  *              along with $single, $plural, and $number parameters. Expected to return string.
231  *
232  * @param string $single The text that will be used if $number is 1
233  * @param string $plural The text that will be used if $number is not 1
234  * @param int $number The number to compare against to use either $single or $plural
235  * @param string $domain Optional. The domain identifier the text should be retrieved in
236  * @return string Either $single or $plural translated text
237  */
238 function _n( $single, $plural, $number, $domain = 'default' ) {
239         $translations = &get_translations_for_domain( $domain );
240         $translation = $translations->translate_plural( $single, $plural, $number );
241         return apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain );
242 }
243
244 /**
245  * A hybrid of _n() and _x(). It supports contexts and plurals.
246  *
247  * @see _n()
248  * @see _x()
249  *
250  */
251 function _nx($single, $plural, $number, $context, $domain = 'default') {
252         $translations = &get_translations_for_domain( $domain );
253         $translation = $translations->translate_plural( $single, $plural, $number, $context );
254         return apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain );
255 }
256
257 /**
258  * Register plural strings in POT file, but don't translate them.
259  *
260  * Used when you want do keep structures with translatable plural strings and
261  * use them later.
262  *
263  * Example:
264  *  $messages = array(
265  *      'post' => _n_noop('%s post', '%s posts'),
266  *      'page' => _n_noop('%s pages', '%s pages')
267  *  );
268  *  ...
269  *  $message = $messages[$type];
270  *  $usable_text = sprintf(_n($message[0], $message[1], $count), $count);
271  *
272  * @since 2.5
273  * @param $single Single form to be i18ned
274  * @param $plural Plural form to be i18ned
275  * @return array array($single, $plural)
276  */
277 function _n_noop( $single, $plural ) {
278         return array( $single, $plural );
279 }
280
281 /**
282  * Register plural strings with context in POT file, but don't translate them.
283  *
284  * @see _n_noop()
285  */
286 function _nx_noop( $single, $plural, $context ) {
287         return array( $single, $plural, $context );
288 }
289
290 /**
291  * Loads a MO file into the domain $domain.
292  *
293  * If the domain already exists, the translations will be merged. If both
294  * sets have the same string, the translation from the original value will be taken.
295  *
296  * On success, the .mo file will be placed in the $l10n global by $domain
297  * and will be a MO object.
298  *
299  * @since 1.5.0
300  * @uses $l10n Gets list of domain translated string objects
301  *
302  * @param string $domain Unique identifier for retrieving translated strings
303  * @param string $mofile Path to the .mo file
304  * @return bool true on success, false on failure
305  */
306 function load_textdomain( $domain, $mofile ) {
307         global $l10n;
308
309         $plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );
310
311         if ( true == $plugin_override ) {
312                 return true;
313         }
314
315         do_action( 'load_textdomain', $domain, $mofile );
316
317         $mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain );
318
319         if ( !is_readable( $mofile ) ) return false;
320
321         $mo = new MO();
322         if ( !$mo->import_from_file( $mofile ) ) return false;
323
324         if ( isset( $l10n[$domain] ) )
325                 $mo->merge_with( $l10n[$domain] );
326
327         $l10n[$domain] = &$mo;
328
329         return true;
330 }
331
332 /**
333  * Unloads translations for a domain
334  *
335  * @since 3.0.0
336  * @param string $domain Textdomain to be unloaded
337  * @return bool Whether textdomain was unloaded
338  */
339 function unload_textdomain( $domain ) {
340         global $l10n;
341
342         $plugin_override = apply_filters( 'override_unload_textdomain', false, $domain );
343
344         if ( $plugin_override )
345                 return true;
346
347         do_action( 'unload_textdomain', $domain );
348
349         if ( isset( $l10n[$domain] ) ) {
350                 unset( $l10n[$domain] );
351                 return true;
352         }
353
354         return false;
355 }
356
357 /**
358  * Loads default translated strings based on locale.
359  *
360  * Loads the .mo file in WP_LANG_DIR constant path from WordPress root. The
361  * translated (.mo) file is named based off of the locale.
362  *
363  * @since 1.5.0
364  */
365 function load_default_textdomain() {
366         $locale = get_locale();
367
368         load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo" );
369
370         if ( is_multisite() || ( defined( 'WP_NETWORK_ADMIN_PAGE' ) && WP_NETWORK_ADMIN_PAGE ) ) {
371                 load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo" );
372         }
373 }
374
375 /**
376  * Loads the plugin's translated strings.
377  *
378  * If the path is not given then it will be the root of the plugin directory.
379  * The .mo file should be named based on the domain with a dash, and then the locale exactly.
380  *
381  * @since 1.5.0
382  *
383  * @param string $domain Unique identifier for retrieving translated strings
384  * @param string $abs_rel_path Optional. Relative path to ABSPATH of a folder,
385  *      where the .mo file resides. Deprecated, but still functional until 2.7
386  * @param string $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR. This is the preferred argument to use. It takes precendence over $abs_rel_path
387  */
388 function load_plugin_textdomain( $domain, $abs_rel_path = false, $plugin_rel_path = false ) {
389         $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
390
391         if ( false !== $plugin_rel_path ) {
392                 $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
393         } else if ( false !== $abs_rel_path ) {
394                 _deprecated_argument( __FUNCTION__, '2.7' );
395                 $path = ABSPATH . trim( $abs_rel_path, '/' );
396         } else {
397                 $path = WP_PLUGIN_DIR;
398         }
399
400         $mofile = $path . '/'. $domain . '-' . $locale . '.mo';
401         return load_textdomain( $domain, $mofile );
402 }
403
404 /**
405  * Load the translated strings for a plugin residing in the mu-plugins dir.
406  *
407  * @since 3.0.0
408  *
409  * @param string $domain Unique identifier for retrieving translated strings
410  * @param strings $mu_plugin_rel_path Relative to WPMU_PLUGIN_DIR directory in which
411  * the MO file resides. Defaults is empty string.
412  */
413 function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) {
414         $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
415         $path = WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' );
416         load_textdomain( $domain, trailingslashit( $path ) . "$domain-$locale.mo" );
417 }
418
419 /**
420  * Loads the theme's translated strings.
421  *
422  * If the current locale exists as a .mo file in the theme's root directory, it
423  * will be included in the translated strings by the $domain.
424  *
425  * The .mo files must be named based on the locale exactly.
426  *
427  * @since 1.5.0
428  *
429  * @param string $domain Unique identifier for retrieving translated strings
430  */
431 function load_theme_textdomain( $domain, $path = false ) {
432         $locale = apply_filters( 'theme_locale', get_locale(), $domain );
433
434         $path = ( empty( $path ) ) ? get_template_directory() : $path;
435
436         $mofile = "$path/$locale.mo";
437         return load_textdomain($domain, $mofile);
438 }
439
440 /**
441  * Loads the child themes translated strings.
442  *
443  * If the current locale exists as a .mo file in the child themes root directory, it
444  * will be included in the translated strings by the $domain.
445  *
446  * The .mo files must be named based on the locale exactly.
447  *
448  * @since 2.9.0
449  *
450  * @param string $domain Unique identifier for retrieving translated strings
451  */
452 function load_child_theme_textdomain( $domain, $path = false ) {
453         $locale = apply_filters( 'theme_locale', get_locale(), $domain );
454
455         $path = ( empty( $path ) ) ? get_stylesheet_directory() : $path;
456
457         $mofile = "$path/$locale.mo";
458         return load_textdomain($domain, $mofile);
459 }
460
461 /**
462  * Returns the Translations instance for a domain. If there isn't one,
463  * returns empty Translations instance.
464  *
465  * @param string $domain
466  * @return object A Translation instance
467  */
468 function &get_translations_for_domain( $domain ) {
469         global $l10n;
470         if ( !isset( $l10n[$domain] ) ) {
471                 $l10n[$domain] = &new NOOP_Translations;
472         }
473         return $l10n[$domain];
474 }
475
476 /**
477  * Whether there are translations for the domain
478  *
479  * @since 3.0.0
480  * @param string $domain
481  * @return bool Whether there are translations
482  */
483 function is_textdomain_loaded( $domain ) {
484         global $l10n;
485         return isset( $l10n[$domain] );
486 }
487
488 /**
489  * Translates role name. Since the role names are in the database and
490  * not in the source there are dummy gettext calls to get them into the POT
491  * file and this function properly translates them back.
492  *
493  * The before_last_bar() call is needed, because older installs keep the roles
494  * using the old context format: 'Role name|User role' and just skipping the
495  * content after the last bar is easier than fixing them in the DB. New installs
496  * won't suffer from that problem.
497  */
498 function translate_user_role( $name ) {
499         return translate_with_gettext_context( before_last_bar($name), 'User role' );
500 }
501
502 /**
503  * Get all available languages based on the presence of *.mo files in a given directory. The default directory is WP_LANG_DIR.
504  *
505  * @since 3.0.0
506  *
507  * @param string $dir A directory in which to search for language files. The default directory is WP_LANG_DIR.
508  * @return array 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.
509  */
510 function get_available_languages( $dir = null ) {
511         $languages = array();
512
513         foreach( (array)glob( ( is_null( $dir) ? WP_LANG_DIR : $dir ) . '/*.mo' ) as $lang_file ) {
514                 $lang_file = basename($lang_file, '.mo');
515                 if ( 0 !== strpos( $lang_file, 'continents-cities' ) && 0 !== strpos( $lang_file, 'ms-' ) )
516                         $languages[] = $lang_file;
517         }
518
519         return $languages;
520 }