at path:ROOT / wp-includes / l10n.php
run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
23.8 KB
2026-03-11 16:18:51
R W Run
7.8 KB
2026-03-11 16:18:52
R W Run
36.1 KB
2026-03-11 16:18:51
R W Run
11.9 KB
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:52
R W Run
28.6 KB
2026-03-11 16:18:51
R W Run
316 By
2026-03-11 16:18:51
R W Run
12.9 KB
2026-03-11 16:18:51
R W Run
61.02 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:51
R W Run
112.05 KB
2026-03-11 16:18:51
R W Run
12.47 KB
2026-03-11 16:18:51
R W Run
15.07 KB
2026-03-11 16:18:52
R W Run
9.84 KB
2026-03-11 16:18:52
R W Run
13.17 KB
2026-03-11 16:18:52
R W Run
33.83 KB
2026-03-11 16:18:51
R W Run
42.63 KB
2026-03-11 16:18:51
R W Run
55.71 KB
2026-03-11 16:18:52
R W Run
12.53 KB
2026-03-11 16:18:51
R W Run
2.55 KB
2026-03-11 16:18:52
R W Run
28.92 KB
2026-03-11 16:18:52
R W Run
539 By
2026-03-11 16:18:51
R W Run
367 By
2026-03-11 16:18:52
R W Run
42.65 KB
2026-03-11 16:18:51
R W Run
401 By
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
664 By
2026-03-11 16:18:52
R W Run
20.63 KB
2026-03-11 16:18:51
R W Run
2.18 KB
2026-03-11 16:18:52
R W Run
453 By
2026-03-11 16:18:52
R W Run
457 By
2026-03-11 16:18:51
R W Run
36.83 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
13.89 KB
2026-03-11 16:18:51
R W Run
11.76 KB
2026-03-11 16:18:51
R W Run
2.65 KB
2026-03-11 16:18:51
R W Run
7.43 KB
2026-03-11 16:18:51
R W Run
17.46 KB
2026-03-11 16:18:51
R W Run
5.14 KB
2026-03-11 16:18:52
R W Run
16.7 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:52
R W Run
2.92 KB
2026-03-11 16:18:52
R W Run
1.32 KB
2026-03-11 16:18:51
R W Run
4.6 KB
2026-03-11 16:18:52
R W Run
11.62 KB
2026-03-11 16:18:52
R W Run
2.5 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
11.25 KB
2026-03-11 16:18:52
R W Run
5.32 KB
2026-03-11 16:18:51
R W Run
10.99 KB
2026-03-11 16:18:52
R W Run
68.32 KB
2026-03-11 16:18:51
R W Run
6.34 KB
2026-03-11 16:18:51
R W Run
5.49 KB
2026-03-11 16:18:51
R W Run
1.99 KB
2026-03-11 16:18:52
R W Run
7.02 KB
2026-03-11 16:18:51
R W Run
4.91 KB
2026-03-11 16:18:52
R W Run
16.86 KB
2026-03-11 16:18:51
R W Run
24.23 KB
2026-03-11 16:18:51
R W Run
3.97 KB
2026-03-11 16:18:51
R W Run
47.66 KB
2026-03-11 16:18:51
R W Run
9.22 KB
2026-03-11 16:18:51
R W Run
25.51 KB
2026-03-11 16:18:51
R W Run
198.38 KB
2026-03-11 16:18:52
R W Run
56.65 KB
2026-03-11 16:18:51
R W Run
10.46 KB
2026-03-11 16:18:51
R W Run
10.95 KB
2026-03-11 16:18:52
R W Run
29.26 KB
2026-03-11 16:18:51
R W Run
70.91 KB
2026-03-11 16:18:52
R W Run
35.3 KB
2026-03-11 16:18:52
R W Run
16.61 KB
2026-03-11 16:18:52
R W Run
2.57 KB
2026-03-11 16:18:52
R W Run
39.83 KB
2026-03-11 16:18:51
R W Run
70.64 KB
2026-03-11 16:18:51
R W Run
15.56 KB
2026-03-11 16:18:52
R W Run
7.33 KB
2026-03-11 16:18:52
R W Run
253 By
2026-03-11 16:18:51
R W Run
7.96 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
969 By
2026-03-11 16:18:52
R W Run
16.28 KB
2026-03-11 16:18:51
R W Run
7.22 KB
2026-03-11 16:18:51
R W Run
12.95 KB
2026-03-11 16:18:51
R W Run
6.53 KB
2026-03-11 16:18:51
R W Run
3.42 KB
2026-03-11 16:18:52
R W Run
5.84 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
4.3 KB
2026-03-11 16:18:52
R W Run
2.91 KB
2026-03-11 16:18:51
R W Run
16.46 KB
2026-03-11 16:18:52
R W Run
40.6 KB
2026-03-11 16:18:51
R W Run
20.22 KB
2026-03-11 16:18:51
R W Run
36.11 KB
2026-03-11 16:18:52
R W Run
17.01 KB
2026-03-11 16:18:51
R W Run
7.27 KB
2026-03-11 16:18:52
R W Run
6.62 KB
2026-03-11 16:18:52
R W Run
16.49 KB
2026-03-11 16:18:52
R W Run
1.79 KB
2026-03-11 16:18:52
R W Run
29.82 KB
2026-03-11 16:18:51
R W Run
6.67 KB
2026-03-11 16:18:52
R W Run
8.98 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:51
R W Run
12.01 KB
2026-03-11 16:18:51
R W Run
17.11 KB
2026-03-11 16:18:51
R W Run
6.74 KB
2026-03-11 16:18:52
R W Run
30.93 KB
2026-03-11 16:18:51
R W Run
4.99 KB
2026-03-11 16:18:51
R W Run
4.25 KB
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
29.96 KB
2026-03-11 16:18:52
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
160 KB
2026-03-11 16:18:51
R W Run
6.72 KB
2026-03-11 16:18:52
R W Run
10.92 KB
2026-03-11 16:18:51
R W Run
4.77 KB
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
11.18 KB
2026-03-11 16:18:51
R W Run
62.19 KB
2026-03-11 16:18:51
R W Run
2.46 KB
2026-03-11 16:18:51
R W Run
9.17 KB
2026-03-11 16:18:51
R W Run
32.15 KB
2026-03-11 16:18:51
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
7.15 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:52
R W Run
1.87 KB
2026-03-11 16:18:52
R W Run
30.91 KB
2026-03-11 16:18:51
R W Run
7.29 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:51
R W Run
12.54 KB
2026-03-11 16:18:51
R W Run
19.12 KB
2026-03-11 16:18:51
R W Run
18.12 KB
2026-03-11 16:18:52
R W Run
39.99 KB
2026-03-11 16:18:52
R W Run
5.17 KB
2026-03-11 16:18:52
R W Run
979 By
2026-03-11 16:18:51
R W Run
18.44 KB
2026-03-11 16:18:52
R W Run
10.24 KB
2026-03-11 16:18:51
R W Run
1.77 KB
2026-03-11 16:18:52
R W Run
34.9 KB
2026-03-11 16:18:51
R W Run
7.19 KB
2026-03-11 16:18:52
R W Run
160.5 KB
2026-03-11 16:18:51
R W Run
64.27 KB
2026-03-11 16:18:51
R W Run
27.95 KB
2026-03-11 16:18:51
R W Run
4.69 KB
2026-03-11 16:18:51
R W Run
2.94 KB
2026-03-11 16:18:51
R W Run
43.13 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
22.5 KB
2026-03-11 16:18:51
R W Run
13.01 KB
2026-03-11 16:18:52
R W Run
3.27 KB
2026-03-11 16:18:51
R W Run
18 KB
2026-03-11 16:18:51
R W Run
210.4 KB
2026-03-11 16:18:52
R W Run
25.86 KB
2026-03-11 16:18:52
R W Run
115.85 KB
2026-03-11 16:18:51
R W Run
373 By
2026-03-11 16:18:52
R W Run
343 By
2026-03-11 16:18:52
R W Run
338 By
2026-03-11 16:18:51
R W Run
100.73 KB
2026-03-11 16:18:52
R W Run
130.93 KB
2026-03-11 16:18:51
R W Run
19.1 KB
2026-03-11 16:18:51
R W Run
17.41 KB
2026-03-11 16:18:52
R W Run
41.98 KB
2026-03-11 16:18:52
R W Run
400 By
2026-03-11 16:18:52
R W Run
11.1 KB
2026-03-11 16:18:52
R W Run
37.02 KB
2026-03-11 16:18:51
R W Run
2.24 KB
2026-03-11 16:18:51
R W Run
188.13 KB
2026-03-11 16:18:51
R W Run
338 By
2026-03-11 16:18:51
R W Run
38 KB
2026-03-11 16:18:51
R W Run
4.02 KB
2026-03-11 16:18:52
R W Run
5.38 KB
2026-03-11 16:18:51
R W Run
3.05 KB
2026-03-11 16:18:52
R W Run
2.61 KB
2026-03-11 16:18:51
R W Run
1.16 KB
2026-03-11 16:18:52
R W Run
4.04 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
24.6 KB
2026-03-11 16:18:51
R W Run
9.56 KB
2026-03-11 16:18:51
R W Run
346.43 KB
2026-03-11 16:18:52
R W Run
281.84 KB
2026-03-11 16:18:52
R W Run
14.95 KB
2026-03-11 16:18:51
R W Run
8.44 KB
2026-03-11 16:18:52
R W Run
168.95 KB
2026-03-11 16:18:52
R W Run
20.71 KB
2026-03-11 16:18:52
R W Run
25.27 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
4.63 KB
2026-03-11 16:18:52
R W Run
81.73 KB
2026-03-11 16:18:51
R W Run
67.18 KB
2026-03-11 16:18:51
R W Run
156.36 KB
2026-03-11 16:18:52
R W Run
55.19 KB
2026-03-11 16:18:51
R W Run
162 By
2026-03-11 16:18:51
R W Run
61.72 KB
2026-03-11 16:18:51
R W Run
216.06 KB
2026-03-11 16:18:52
R W Run
65.09 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:52
R W Run
4.81 KB
2026-03-11 16:18:51
R W Run
6.48 KB
2026-03-11 16:18:52
R W Run
21.25 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:52
R W Run
89.69 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:52
R W Run
3.69 KB
2026-03-11 16:18:52
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
40.74 KB
2026-03-11 16:18:51
R W Run
25.38 KB
2026-03-11 16:18:51
R W Run
43.31 KB
2026-03-11 16:18:52
R W Run
102.57 KB
2026-03-11 16:18:52
R W Run
6.18 KB
2026-03-11 16:18:51
R W Run
124.47 KB
2026-03-11 16:18:52
R W Run
35.65 KB
2026-03-11 16:18:52
R W Run
6.94 KB
2026-03-11 16:18:52
R W Run
67.04 KB
2026-03-11 16:18:52
R W Run
10.62 KB
2026-03-11 16:18:51
R W Run
289.35 KB
2026-03-11 16:18:52
R W Run
36.23 KB
2026-03-11 16:18:51
R W Run
200 By
2026-03-11 16:18:52
R W Run
200 By
2026-03-11 16:18:52
R W Run
98.29 KB
2026-03-11 16:18:52
R W Run
30.02 KB
2026-03-11 16:18:52
R W Run
19.03 KB
2026-03-11 16:18:52
R W Run
5.06 KB
2026-03-11 16:18:52
R W Run
255 By
2026-03-11 16:18:51
R W Run
22.66 KB
2026-03-11 16:18:52
R W Run
154.63 KB
2026-03-11 16:18:51
R W Run
9.68 KB
2026-03-11 16:18:51
R W Run
258 By
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
3.16 KB
2026-03-11 16:18:51
R W Run
8.4 KB
2026-03-11 16:18:52
R W Run
441 By
2026-03-11 16:18:51
R W Run
7.39 KB
2026-03-11 16:18:51
R W Run
173 KB
2026-03-11 16:18:52
R W Run
544 By
2026-03-11 16:18:52
R W Run
4.17 KB
2026-03-11 16:18:51
R W Run
35.97 KB
2026-03-11 16:18:52
R W Run
1.69 KB
2026-03-11 16:18:51
R W Run
2.84 KB
2026-03-11 16:18:52
R W Run
6.09 KB
2026-03-11 16:18:51
R W Run
8.71 KB
2026-03-11 16:18:51
R W Run
131.84 KB
2026-03-11 16:18:51
R W Run
37.45 KB
2026-03-11 16:18:51
R W Run
173.89 KB
2026-03-11 16:18:51
R W Run
7.09 KB
2026-03-11 16:18:51
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
1.08 KB
2026-03-11 16:18:51
R W Run
69.46 KB
2026-03-11 16:18:52
R W Run
445 By
2026-03-11 16:18:51
R W Run
799 By
2026-03-11 16:18:52
R W Run
error_log
📄l10n.php
1<?php
2/**
3 * Core Translation API
4 *
5 * @package WordPress
6 * @subpackage i18n
7 * @since 1.2.0
8 */
9
10/**
11 * Retrieves the current locale.
12 *
13 * If the locale is set, then it will filter the locale in the {@see 'locale'}
14 * filter hook and return the value.
15 *
16 * If the locale is not set already, then the WPLANG constant is used if it is
17 * defined. Then it is filtered through the {@see 'locale'} filter hook and
18 * the value for the locale global set and the locale is returned.
19 *
20 * The process to get the locale should only be done once, but the locale will
21 * always be filtered using the {@see 'locale'} hook.
22 *
23 * @since 1.5.0
24 *
25 * @global string $locale The current locale.
26 * @global string $wp_local_package Locale code of the package.
27 *
28 * @return string The locale of the blog or from the {@see 'locale'} hook.
29 */
30function get_locale() {
31 global $locale, $wp_local_package;
32
33 if ( isset( $locale ) ) {
34 /** This filter is documented in wp-includes/l10n.php */
35 return apply_filters( 'locale', $locale );
36 }
37
38 if ( isset( $wp_local_package ) ) {
39 $locale = $wp_local_package;
40 }
41
42 // WPLANG was defined in wp-config.
43 if ( defined( 'WPLANG' ) ) {
44 $locale = WPLANG;
45 }
46
47 // If multisite, check options.
48 if ( is_multisite() ) {
49 // Don't check blog option when installing.
50 if ( wp_installing() ) {
51 $ms_locale = get_site_option( 'WPLANG' );
52 } else {
53 $ms_locale = get_option( 'WPLANG' );
54 if ( false === $ms_locale ) {
55 $ms_locale = get_site_option( 'WPLANG' );
56 }
57 }
58
59 if ( false !== $ms_locale ) {
60 $locale = $ms_locale;
61 }
62 } else {
63 $db_locale = get_option( 'WPLANG' );
64 if ( false !== $db_locale ) {
65 $locale = $db_locale;
66 }
67 }
68
69 if ( empty( $locale ) ) {
70 $locale = 'en_US';
71 }
72
73 /**
74 * Filters the locale ID of the WordPress installation.
75 *
76 * @since 1.5.0
77 *
78 * @param string $locale The locale ID.
79 */
80 return apply_filters( 'locale', $locale );
81}
82
83/**
84 * Retrieves the locale of a user.
85 *
86 * If the user has a locale set to a non-empty string then it will be
87 * returned. Otherwise it returns the locale of get_locale().
88 *
89 * @since 4.7.0
90 *
91 * @param int|WP_User $user User's ID or a WP_User object. Defaults to current user.
92 * @return string The locale of the user.
93 */
94function get_user_locale( $user = 0 ) {
95 $user_object = false;
96
97 if ( 0 === $user && function_exists( 'wp_get_current_user' ) ) {
98 $user_object = wp_get_current_user();
99 } elseif ( $user instanceof WP_User ) {
100 $user_object = $user;
101 } elseif ( $user && is_numeric( $user ) ) {
102 $user_object = get_user_by( 'id', $user );
103 }
104
105 if ( ! $user_object ) {
106 return get_locale();
107 }
108
109 $locale = $user_object->locale;
110
111 return $locale ? $locale : get_locale();
112}
113
114/**
115 * Determines the current locale desired for the request.
116 *
117 * @since 5.0.0
118 *
119 * @global string $pagenow The filename of the current screen.
120 * @global string $wp_local_package Locale code of the package.
121 *
122 * @return string The determined locale.
123 */
124function determine_locale() {
125 /**
126 * Filters the locale for the current request prior to the default determination process.
127 *
128 * Using this filter allows to override the default logic, effectively short-circuiting the function.
129 *
130 * @since 5.0.0
131 *
132 * @param string|null $locale The locale to return and short-circuit. Default null.
133 */
134 $determined_locale = apply_filters( 'pre_determine_locale', null );
135
136 if ( $determined_locale && is_string( $determined_locale ) ) {
137 return $determined_locale;
138 }
139
140 if (
141 isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] &&
142 ( ! empty( $_GET['wp_lang'] ) || ! empty( $_COOKIE['wp_lang'] ) )
143 ) {
144 if ( ! empty( $_GET['wp_lang'] ) ) {
145 $determined_locale = sanitize_locale_name( $_GET['wp_lang'] );
146 } else {
147 $determined_locale = sanitize_locale_name( $_COOKIE['wp_lang'] );
148 }
149 } elseif (
150 is_admin() ||
151 ( isset( $_GET['_locale'] ) && 'user' === $_GET['_locale'] && wp_is_json_request() )
152 ) {
153 $determined_locale = get_user_locale();
154 } elseif (
155 ( ! empty( $_REQUEST['language'] ) || isset( $GLOBALS['wp_local_package'] ) )
156 && wp_installing()
157 ) {
158 if ( ! empty( $_REQUEST['language'] ) ) {
159 $determined_locale = sanitize_locale_name( $_REQUEST['language'] );
160 } else {
161 $determined_locale = $GLOBALS['wp_local_package'];
162 }
163 }
164
165 if ( ! $determined_locale ) {
166 $determined_locale = get_locale();
167 }
168
169 /**
170 * Filters the locale for the current request.
171 *
172 * @since 5.0.0
173 *
174 * @param string $determined_locale The locale.
175 */
176 return apply_filters( 'determine_locale', $determined_locale );
177}
178
179/**
180 * Retrieves the translation of $text.
181 *
182 * If there is no translation, or the text domain isn't loaded, the original text is returned.
183 *
184 * *Note:* Don't use translate() directly, use __() or related functions.
185 *
186 * @since 2.2.0
187 * @since 5.5.0 Introduced `gettext-{$domain}` filter.
188 *
189 * @param string $text Text to translate.
190 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
191 * Default 'default'.
192 * @return string Translated text.
193 */
194function translate( $text, $domain = 'default' ) {
195 $translations = get_translations_for_domain( $domain );
196 $translation = $translations->translate( $text );
197
198 /**
199 * Filters text with its translation.
200 *
201 * @since 2.0.11
202 *
203 * @param string $translation Translated text.
204 * @param string $text Text to translate.
205 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
206 */
207 $translation = apply_filters( 'gettext', $translation, $text, $domain );
208
209 /**
210 * Filters text with its translation for a domain.
211 *
212 * The dynamic portion of the hook name, `$domain`, refers to the text domain.
213 *
214 * @since 5.5.0
215 *
216 * @param string $translation Translated text.
217 * @param string $text Text to translate.
218 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
219 */
220 $translation = apply_filters( "gettext_{$domain}", $translation, $text, $domain );
221
222 return $translation;
223}
224
225/**
226 * Removes last item on a pipe-delimited string.
227 *
228 * Meant for removing the last item in a string, such as 'Role name|User role'. The original
229 * string will be returned if no pipe '|' characters are found in the string.
230 *
231 * @since 2.8.0
232 *
233 * @param string $text A pipe-delimited string.
234 * @return string Either $text or everything before the last pipe.
235 */
236function before_last_bar( $text ) {
237 $last_bar = strrpos( $text, '|' );
238 if ( false === $last_bar ) {
239 return $text;
240 } else {
241 return substr( $text, 0, $last_bar );
242 }
243}
244
245/**
246 * Retrieves the translation of $text in the context defined in $context.
247 *
248 * If there is no translation, or the text domain isn't loaded, the original text is returned.
249 *
250 * *Note:* Don't use translate_with_gettext_context() directly, use _x() or related functions.
251 *
252 * @since 2.8.0
253 * @since 5.5.0 Introduced `gettext_with_context-{$domain}` filter.
254 *
255 * @param string $text Text to translate.
256 * @param string $context Context information for the translators.
257 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
258 * Default 'default'.
259 * @return string Translated text on success, original text on failure.
260 */
261function translate_with_gettext_context( $text, $context, $domain = 'default' ) {
262 $translations = get_translations_for_domain( $domain );
263 $translation = $translations->translate( $text, $context );
264
265 /**
266 * Filters text with its translation based on context information.
267 *
268 * @since 2.8.0
269 *
270 * @param string $translation Translated text.
271 * @param string $text Text to translate.
272 * @param string $context Context information for the translators.
273 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
274 */
275 $translation = apply_filters( 'gettext_with_context', $translation, $text, $context, $domain );
276
277 /**
278 * Filters text with its translation based on context information for a domain.
279 *
280 * The dynamic portion of the hook name, `$domain`, refers to the text domain.
281 *
282 * @since 5.5.0
283 *
284 * @param string $translation Translated text.
285 * @param string $text Text to translate.
286 * @param string $context Context information for the translators.
287 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
288 */
289 $translation = apply_filters( "gettext_with_context_{$domain}", $translation, $text, $context, $domain );
290
291 return $translation;
292}
293
294/**
295 * Retrieves the translation of $text.
296 *
297 * If there is no translation, or the text domain isn't loaded, the original text is returned.
298 *
299 * @since 2.1.0
300 *
301 * @param string $text Text to translate.
302 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
303 * Default 'default'.
304 * @return string Translated text.
305 */
306function __( $text, $domain = 'default' ) {
307 return translate( $text, $domain );
308}
309
310/**
311 * Retrieves the translation of $text and escapes it for safe use in an attribute.
312 *
313 * If there is no translation, or the text domain isn't loaded, the original text is returned.
314 *
315 * @since 2.8.0
316 *
317 * @param string $text Text to translate.
318 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
319 * Default 'default'.
320 * @return string Translated text on success, original text on failure.
321 */
322function esc_attr__( $text, $domain = 'default' ) {
323 return esc_attr( translate( $text, $domain ) );
324}
325
326/**
327 * Retrieves the translation of $text and escapes it for safe use in HTML output.
328 *
329 * If there is no translation, or the text domain isn't loaded, the original text
330 * is escaped and returned.
331 *
332 * @since 2.8.0
333 *
334 * @param string $text Text to translate.
335 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
336 * Default 'default'.
337 * @return string Translated text.
338 */
339function esc_html__( $text, $domain = 'default' ) {
340 return esc_html( translate( $text, $domain ) );
341}
342
343/**
344 * Displays translated text.
345 *
346 * @since 1.2.0
347 *
348 * @param string $text Text to translate.
349 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
350 * Default 'default'.
351 */
352function _e( $text, $domain = 'default' ) {
353 echo translate( $text, $domain );
354}
355
356/**
357 * Displays translated text that has been escaped for safe use in an attribute.
358 *
359 * Encodes `< > & " '` (less than, greater than, ampersand, double quote, single quote).
360 * Will never double encode entities.
361 *
362 * If you need the value for use in PHP, use esc_attr__().
363 *
364 * @since 2.8.0
365 *
366 * @param string $text Text to translate.
367 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
368 * Default 'default'.
369 */
370function esc_attr_e( $text, $domain = 'default' ) {
371 echo esc_attr( translate( $text, $domain ) );
372}
373
374/**
375 * Displays translated text that has been escaped for safe use in HTML output.
376 *
377 * If there is no translation, or the text domain isn't loaded, the original text
378 * is escaped and displayed.
379 *
380 * If you need the value for use in PHP, use esc_html__().
381 *
382 * @since 2.8.0
383 *
384 * @param string $text Text to translate.
385 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
386 * Default 'default'.
387 */
388function esc_html_e( $text, $domain = 'default' ) {
389 echo esc_html( translate( $text, $domain ) );
390}
391
392/**
393 * Retrieves translated string with gettext context.
394 *
395 * Quite a few times, there will be collisions with similar translatable text
396 * found in more than two places, but with different translated context.
397 *
398 * By including the context in the pot file, translators can translate the two
399 * strings differently.
400 *
401 * @since 2.8.0
402 *
403 * @param string $text Text to translate.
404 * @param string $context Context information for the translators.
405 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
406 * Default 'default'.
407 * @return string Translated context string without pipe.
408 */
409function _x( $text, $context, $domain = 'default' ) {
410 return translate_with_gettext_context( $text, $context, $domain );
411}
412
413/**
414 * Displays translated string with gettext context.
415 *
416 * @since 3.0.0
417 *
418 * @param string $text Text to translate.
419 * @param string $context Context information for the translators.
420 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
421 * Default 'default'.
422 */
423function _ex( $text, $context, $domain = 'default' ) {
424 echo _x( $text, $context, $domain );
425}
426
427/**
428 * Translates string with gettext context, and escapes it for safe use in an attribute.
429 *
430 * If there is no translation, or the text domain isn't loaded, the original text
431 * is escaped and returned.
432 *
433 * @since 2.8.0
434 *
435 * @param string $text Text to translate.
436 * @param string $context Context information for the translators.
437 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
438 * Default 'default'.
439 * @return string Translated text.
440 */
441function esc_attr_x( $text, $context, $domain = 'default' ) {
442 return esc_attr( translate_with_gettext_context( $text, $context, $domain ) );
443}
444
445/**
446 * Translates string with gettext context, and escapes it for safe use in HTML output.
447 *
448 * If there is no translation, or the text domain isn't loaded, the original text
449 * is escaped and returned.
450 *
451 * @since 2.9.0
452 *
453 * @param string $text Text to translate.
454 * @param string $context Context information for the translators.
455 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
456 * Default 'default'.
457 * @return string Translated text.
458 */
459function esc_html_x( $text, $context, $domain = 'default' ) {
460 return esc_html( translate_with_gettext_context( $text, $context, $domain ) );
461}
462
463/**
464 * Translates and retrieves the singular or plural form based on the supplied number.
465 *
466 * Used when you want to use the appropriate form of a string based on whether a
467 * number is singular or plural.
468 *
469 * Example:
470 *
471 * printf( _n( '%s person', '%s people', $count, 'text-domain' ), number_format_i18n( $count ) );
472 *
473 * @since 2.8.0
474 * @since 5.5.0 Introduced `ngettext-{$domain}` filter.
475 *
476 * @param string $single The text to be used if the number is singular.
477 * @param string $plural The text to be used if the number is plural.
478 * @param int $number The number to compare against to use either the singular or plural form.
479 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
480 * Default 'default'.
481 * @return string The translated singular or plural form.
482 */
483function _n( $single, $plural, $number, $domain = 'default' ) {
484 $translations = get_translations_for_domain( $domain );
485 $translation = $translations->translate_plural( $single, $plural, $number );
486
487 /**
488 * Filters the singular or plural form of a string.
489 *
490 * @since 2.2.0
491 *
492 * @param string $translation Translated text.
493 * @param string $single The text to be used if the number is singular.
494 * @param string $plural The text to be used if the number is plural.
495 * @param int $number The number to compare against to use either the singular or plural form.
496 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
497 */
498 $translation = apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain );
499
500 /**
501 * Filters the singular or plural form of a string for a domain.
502 *
503 * The dynamic portion of the hook name, `$domain`, refers to the text domain.
504 *
505 * @since 5.5.0
506 *
507 * @param string $translation Translated text.
508 * @param string $single The text to be used if the number is singular.
509 * @param string $plural The text to be used if the number is plural.
510 * @param int $number The number to compare against to use either the singular or plural form.
511 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
512 */
513 $translation = apply_filters( "ngettext_{$domain}", $translation, $single, $plural, $number, $domain );
514
515 return $translation;
516}
517
518/**
519 * Translates and retrieves the singular or plural form based on the supplied number, with gettext context.
520 *
521 * This is a hybrid of _n() and _x(). It supports context and plurals.
522 *
523 * Used when you want to use the appropriate form of a string with context based on whether a
524 * number is singular or plural.
525 *
526 * Example of a generic phrase which is disambiguated via the context parameter:
527 *
528 * printf( _nx( '%s group', '%s groups', $people, 'group of people', 'text-domain' ), number_format_i18n( $people ) );
529 * printf( _nx( '%s group', '%s groups', $animals, 'group of animals', 'text-domain' ), number_format_i18n( $animals ) );
530 *
531 * @since 2.8.0
532 * @since 5.5.0 Introduced `ngettext_with_context-{$domain}` filter.
533 *
534 * @param string $single The text to be used if the number is singular.
535 * @param string $plural The text to be used if the number is plural.
536 * @param int $number The number to compare against to use either the singular or plural form.
537 * @param string $context Context information for the translators.
538 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
539 * Default 'default'.
540 * @return string The translated singular or plural form.
541 */
542function _nx( $single, $plural, $number, $context, $domain = 'default' ) {
543 $translations = get_translations_for_domain( $domain );
544 $translation = $translations->translate_plural( $single, $plural, $number, $context );
545
546 /**
547 * Filters the singular or plural form of a string with gettext context.
548 *
549 * @since 2.8.0
550 *
551 * @param string $translation Translated text.
552 * @param string $single The text to be used if the number is singular.
553 * @param string $plural The text to be used if the number is plural.
554 * @param int $number The number to compare against to use either the singular or plural form.
555 * @param string $context Context information for the translators.
556 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
557 */
558 $translation = apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain );
559
560 /**
561 * Filters the singular or plural form of a string with gettext context for a domain.
562 *
563 * The dynamic portion of the hook name, `$domain`, refers to the text domain.
564 *
565 * @since 5.5.0
566 *
567 * @param string $translation Translated text.
568 * @param string $single The text to be used if the number is singular.
569 * @param string $plural The text to be used if the number is plural.
570 * @param int $number The number to compare against to use either the singular or plural form.
571 * @param string $context Context information for the translators.
572 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
573 */
574 $translation = apply_filters( "ngettext_with_context_{$domain}", $translation, $single, $plural, $number, $context, $domain );
575
576 return $translation;
577}
578
579/**
580 * Registers plural strings in POT file, but does not translate them.
581 *
582 * Used when you want to keep structures with translatable plural
583 * strings and use them later when the number is known.
584 *
585 * Example:
586 *
587 * $message = _n_noop( '%s post', '%s posts', 'text-domain' );
588 * ...
589 * printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) );
590 *
591 * @since 2.5.0
592 *
593 * @param string $singular Singular form to be localized.
594 * @param string $plural Plural form to be localized.
595 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
596 * Default null.
597 * @return array {
598 * Array of translation information for the strings.
599 *
600 * @type string $0 Singular form to be localized. No longer used.
601 * @type string $1 Plural form to be localized. No longer used.
602 * @type string $singular Singular form to be localized.
603 * @type string $plural Plural form to be localized.
604 * @type null $context Context information for the translators.
605 * @type string|null $domain Text domain.
606 * }
607 */
608function _n_noop( $singular, $plural, $domain = null ) {
609 return array(
610 0 => $singular,
611 1 => $plural,
612 'singular' => $singular,
613 'plural' => $plural,
614 'context' => null,
615 'domain' => $domain,
616 );
617}
618
619/**
620 * Registers plural strings with gettext context in POT file, but does not translate them.
621 *
622 * Used when you want to keep structures with translatable plural
623 * strings and use them later when the number is known.
624 *
625 * Example of a generic phrase which is disambiguated via the context parameter:
626 *
627 * $messages = array(
628 * 'people' => _nx_noop( '%s group', '%s groups', 'people', 'text-domain' ),
629 * 'animals' => _nx_noop( '%s group', '%s groups', 'animals', 'text-domain' ),
630 * );
631 * ...
632 * $message = $messages[ $type ];
633 * printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) );
634 *
635 * @since 2.8.0
636 *
637 * @param string $singular Singular form to be localized.
638 * @param string $plural Plural form to be localized.
639 * @param string $context Context information for the translators.
640 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
641 * Default null.
642 * @return array {
643 * Array of translation information for the strings.
644 *
645 * @type string $0 Singular form to be localized. No longer used.
646 * @type string $1 Plural form to be localized. No longer used.
647 * @type string $2 Context information for the translators. No longer used.
648 * @type string $singular Singular form to be localized.
649 * @type string $plural Plural form to be localized.
650 * @type string $context Context information for the translators.
651 * @type string|null $domain Text domain.
652 * }
653 */
654function _nx_noop( $singular, $plural, $context, $domain = null ) {
655 return array(
656 0 => $singular,
657 1 => $plural,
658 2 => $context,
659 'singular' => $singular,
660 'plural' => $plural,
661 'context' => $context,
662 'domain' => $domain,
663 );
664}
665
666/**
667 * Translates and returns the singular or plural form of a string that's been registered
668 * with _n_noop() or _nx_noop().
669 *
670 * Used when you want to use a translatable plural string once the number is known.
671 *
672 * Example:
673 *
674 * $message = _n_noop( '%s post', '%s posts', 'text-domain' );
675 * ...
676 * printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) );
677 *
678 * @since 3.1.0
679 *
680 * @param array $nooped_plural {
681 * Array that is usually a return value from _n_noop() or _nx_noop().
682 *
683 * @type string $singular Singular form to be localized.
684 * @type string $plural Plural form to be localized.
685 * @type string|null $context Context information for the translators.
686 * @type string|null $domain Text domain.
687 * }
688 * @param int $count Number of objects.
689 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. If $nooped_plural contains
690 * a text domain passed to _n_noop() or _nx_noop(), it will override this value. Default 'default'.
691 * @return string Either $singular or $plural translated text.
692 */
693function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) {
694 if ( $nooped_plural['domain'] ) {
695 $domain = $nooped_plural['domain'];
696 }
697
698 if ( $nooped_plural['context'] ) {
699 return _nx( $nooped_plural['singular'], $nooped_plural['plural'], $count, $nooped_plural['context'], $domain );
700 } else {
701 return _n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain );
702 }
703}
704
705/**
706 * Loads a .mo file into the text domain $domain.
707 *
708 * If the text domain already exists, the translations will be merged. If both
709 * sets have the same string, the translation from the original value will be taken.
710 *
711 * On success, the .mo file will be placed in the $l10n global by $domain
712 * and will be a MO object.
713 *
714 * @since 1.5.0
715 * @since 6.1.0 Added the `$locale` parameter.
716 *
717 * @global MO[] $l10n An array of all currently loaded text domains.
718 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again.
719 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
720 *
721 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
722 * @param string $mofile Path to the .mo file.
723 * @param string $locale Optional. Locale. Default is the current locale.
724 * @return bool True on success, false on failure.
725 */
726function load_textdomain( $domain, $mofile, $locale = null ) {
727 /** @var WP_Textdomain_Registry $wp_textdomain_registry */
728 global $l10n, $l10n_unloaded, $wp_textdomain_registry;
729
730 $l10n_unloaded = (array) $l10n_unloaded;
731
732 if ( ! is_string( $domain ) ) {
733 return false;
734 }
735
736 /**
737 * Filters whether to short-circuit loading .mo file.
738 *
739 * Returning a non-null value from the filter will effectively short-circuit
740 * the loading, returning the passed value instead.
741 *
742 * @since 6.3.0
743 *
744 * @param bool|null $loaded The result of loading a .mo file. Default null.
745 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
746 * @param string $mofile Path to the MO file.
747 * @param string|null $locale Locale.
748 */
749 $loaded = apply_filters( 'pre_load_textdomain', null, $domain, $mofile, $locale );
750 if ( null !== $loaded ) {
751 if ( true === $loaded ) {
752 unset( $l10n_unloaded[ $domain ] );
753 }
754
755 return $loaded;
756 }
757
758 /**
759 * Filters whether to override the .mo file loading.
760 *
761 * @since 2.9.0
762 * @since 6.2.0 Added the `$locale` parameter.
763 *
764 * @param bool $override Whether to override the .mo file loading. Default false.
765 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
766 * @param string $mofile Path to the MO file.
767 * @param string|null $locale Locale.
768 */
769 $plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile, $locale );
770
771 if ( true === (bool) $plugin_override ) {
772 unset( $l10n_unloaded[ $domain ] );
773
774 return true;
775 }
776
777 /**
778 * Fires before the MO translation file is loaded.
779 *
780 * @since 2.9.0
781 *
782 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
783 * @param string $mofile Path to the .mo file.
784 */
785 do_action( 'load_textdomain', $domain, $mofile );
786
787 /**
788 * Filters MO file path for loading translations for a specific text domain.
789 *
790 * @since 2.9.0
791 *
792 * @param string $mofile Path to the MO file.
793 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
794 */
795 $mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain );
796
797 if ( ! $locale ) {
798 $locale = determine_locale();
799 }
800
801 $i18n_controller = WP_Translation_Controller::get_instance();
802
803 // Ensures the correct locale is set as the current one, in case it was filtered.
804 $i18n_controller->set_locale( $locale );
805
806 /**
807 * Filters the preferred file format for translation files.
808 *
809 * Can be used to disable the use of PHP files for translations.
810 *
811 * @since 6.5.0
812 *
813 * @param string $preferred_format Preferred file format. Possible values: 'php', 'mo'. Default: 'php'.
814 * @param string $domain The text domain.
815 */
816 $preferred_format = apply_filters( 'translation_file_format', 'php', $domain );
817 if ( ! in_array( $preferred_format, array( 'php', 'mo' ), true ) ) {
818 $preferred_format = 'php';
819 }
820
821 $translation_files = array();
822
823 if ( 'mo' !== $preferred_format ) {
824 $translation_files[] = substr_replace( $mofile, ".l10n.$preferred_format", - strlen( '.mo' ) );
825 }
826
827 $translation_files[] = $mofile;
828
829 foreach ( $translation_files as $file ) {
830 /**
831 * Filters the file path for loading translations for the given text domain.
832 *
833 * Similar to the {@see 'load_textdomain_mofile'} filter with the difference that
834 * the file path could be for an MO or PHP file.
835 *
836 * @since 6.5.0
837 * @since 6.6.0 Added the `$locale` parameter.
838 *
839 * @param string $file Path to the translation file to load.
840 * @param string $domain The text domain.
841 * @param string $locale The locale.
842 */
843 $file = (string) apply_filters( 'load_translation_file', $file, $domain, $locale );
844
845 $success = $i18n_controller->load_file( $file, $domain, $locale );
846
847 if ( $success ) {
848 if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof MO ) {
849 $i18n_controller->load_file( $l10n[ $domain ]->get_filename(), $domain, $locale );
850 }
851
852 // Unset NOOP_Translations reference in get_translations_for_domain().
853 unset( $l10n[ $domain ] );
854
855 $l10n[ $domain ] = new WP_Translations( $i18n_controller, $domain );
856
857 $wp_textdomain_registry->set( $domain, $locale, dirname( $file ) );
858
859 return true;
860 }
861 }
862
863 return false;
864}
865
866/**
867 * Unloads translations for a text domain.
868 *
869 * @since 3.0.0
870 * @since 6.1.0 Added the `$reloadable` parameter.
871 *
872 * @global MO[] $l10n An array of all currently loaded text domains.
873 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again.
874 *
875 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
876 * @param bool $reloadable Whether the text domain can be loaded just-in-time again.
877 * @return bool Whether textdomain was unloaded.
878 */
879function unload_textdomain( $domain, $reloadable = false ) {
880 global $l10n, $l10n_unloaded;
881
882 $l10n_unloaded = (array) $l10n_unloaded;
883
884 /**
885 * Filters whether to override the text domain unloading.
886 *
887 * @since 3.0.0
888 * @since 6.1.0 Added the `$reloadable` parameter.
889 *
890 * @param bool $override Whether to override the text domain unloading. Default false.
891 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
892 * @param bool $reloadable Whether the text domain can be loaded just-in-time again.
893 */
894 $plugin_override = apply_filters( 'override_unload_textdomain', false, $domain, $reloadable );
895
896 if ( $plugin_override ) {
897 if ( ! $reloadable ) {
898 $l10n_unloaded[ $domain ] = true;
899 }
900
901 return true;
902 }
903
904 /**
905 * Fires before the text domain is unloaded.
906 *
907 * @since 3.0.0
908 * @since 6.1.0 Added the `$reloadable` parameter.
909 *
910 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
911 * @param bool $reloadable Whether the text domain can be loaded just-in-time again.
912 */
913 do_action( 'unload_textdomain', $domain, $reloadable );
914
915 // Since multiple locales are supported, reloadable text domains don't actually need to be unloaded.
916 if ( ! $reloadable ) {
917 WP_Translation_Controller::get_instance()->unload_textdomain( $domain );
918 }
919
920 if ( isset( $l10n[ $domain ] ) ) {
921 if ( $l10n[ $domain ] instanceof NOOP_Translations ) {
922 unset( $l10n[ $domain ] );
923
924 return false;
925 }
926
927 unset( $l10n[ $domain ] );
928
929 if ( ! $reloadable ) {
930 $l10n_unloaded[ $domain ] = true;
931 }
932
933 return true;
934 }
935
936 return false;
937}
938
939/**
940 * Loads default translated strings based on locale.
941 *
942 * Loads the .mo file in WP_LANG_DIR constant path from WordPress root.
943 * The translated (.mo) file is named based on the locale.
944 *
945 * @see load_textdomain()
946 *
947 * @since 1.5.0
948 *
949 * @param string $locale Optional. Locale to load. Default is the value of get_locale().
950 * @return bool Whether the textdomain was loaded.
951 */
952function load_default_textdomain( $locale = null ) {
953 if ( null === $locale ) {
954 $locale = determine_locale();
955 }
956
957 // Unload previously loaded strings so we can switch translations.
958 unload_textdomain( 'default', true );
959
960 $return = load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo", $locale );
961
962 if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists( WP_LANG_DIR . "/admin-$locale.mo" ) ) {
963 load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo", $locale );
964 return $return;
965 }
966
967 if ( is_admin() || wp_installing() || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) || doing_action( 'wp_maybe_auto_update' ) ) {
968 load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo", $locale );
969 }
970
971 if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) {
972 load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo", $locale );
973 }
974
975 return $return;
976}
977
978/**
979 * Loads a plugin's translated strings.
980 *
981 * If the path is not given then it will be the root of the plugin directory.
982 *
983 * The .mo file should be named based on the text domain with a dash, and then the locale exactly.
984 *
985 * @since 1.5.0
986 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
987 * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism.
988 *
989 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
990 * @global array<string, WP_Translations|NOOP_Translations> $l10n An array of all currently loaded text domains.
991 *
992 * @param string $domain Unique identifier for retrieving translated strings
993 * @param string|false $deprecated Optional. Deprecated. Use the $plugin_rel_path parameter instead.
994 * Default false.
995 * @param string|false $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR where the .mo file resides.
996 * Default false.
997 * @return bool True when textdomain is successfully loaded, false otherwise.
998 */
999function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) {
1000 /** @var WP_Textdomain_Registry $wp_textdomain_registry */
1001 /** @var array<string, WP_Translations|NOOP_Translations> $l10n */
1002 global $wp_textdomain_registry, $l10n;
1003
1004 if ( ! is_string( $domain ) ) {
1005 return false;
1006 }
1007
1008 if ( false !== $plugin_rel_path ) {
1009 $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
1010 } elseif ( false !== $deprecated ) {
1011 _deprecated_argument( __FUNCTION__, '2.7.0' );
1012 $path = ABSPATH . trim( $deprecated, '/' );
1013 } else {
1014 $path = WP_PLUGIN_DIR;
1015 }
1016
1017 $wp_textdomain_registry->set_custom_path( $domain, $path );
1018
1019 // If just-in-time loading was triggered before, reset the entry so it can be tried again.
1020 if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) {
1021 unset( $l10n[ $domain ] );
1022 }
1023
1024 return true;
1025}
1026
1027/**
1028 * Loads the translated strings for a plugin residing in the mu-plugins directory.
1029 *
1030 * @since 3.0.0
1031 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
1032 * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism.
1033 *
1034 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
1035 * @global array<string, WP_Translations|NOOP_Translations> $l10n An array of all currently loaded text domains.
1036 *
1037 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
1038 * @param string $mu_plugin_rel_path Optional. Relative to `WPMU_PLUGIN_DIR` directory in which the .mo
1039 * file resides. Default empty string.
1040 * @return bool True when textdomain is successfully loaded, false otherwise.
1041 */
1042function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) {
1043 /** @var WP_Textdomain_Registry $wp_textdomain_registry */
1044 /** @var array<string, WP_Translations|NOOP_Translations> $l10n */
1045 global $wp_textdomain_registry, $l10n;
1046
1047 if ( ! is_string( $domain ) ) {
1048 return false;
1049 }
1050
1051 $path = WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' );
1052
1053 $wp_textdomain_registry->set_custom_path( $domain, $path );
1054
1055 // If just-in-time loading was triggered before, reset the entry so it can be tried again.
1056 if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) {
1057 unset( $l10n[ $domain ] );
1058 }
1059
1060 return true;
1061}
1062
1063/**
1064 * Loads the theme's translated strings.
1065 *
1066 * If the current locale exists as a .mo file in the theme's root directory, it
1067 * will be included in the translated strings by the $domain.
1068 *
1069 * The .mo files must be named based on the locale exactly.
1070 *
1071 * @since 1.5.0
1072 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
1073 * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism.
1074 *
1075 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
1076 * @global array<string, WP_Translations|NOOP_Translations> $l10n An array of all currently loaded text domains.
1077 *
1078 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
1079 * @param string|false $path Optional. Path to the directory containing the .mo file.
1080 * Default false.
1081 * @return bool True when textdomain is successfully loaded, false otherwise.
1082 */
1083function load_theme_textdomain( $domain, $path = false ) {
1084 /** @var WP_Textdomain_Registry $wp_textdomain_registry */
1085 /** @var array<string, WP_Translations|NOOP_Translations> $l10n */
1086 global $wp_textdomain_registry, $l10n;
1087
1088 if ( ! is_string( $domain ) ) {
1089 return false;
1090 }
1091
1092 if ( ! $path ) {
1093 $path = get_template_directory();
1094 }
1095
1096 $wp_textdomain_registry->set_custom_path( $domain, $path );
1097
1098 // If just-in-time loading was triggered before, reset the entry so it can be tried again.
1099 if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) {
1100 unset( $l10n[ $domain ] );
1101 }
1102
1103 return true;
1104}
1105
1106/**
1107 * Loads the child theme's translated strings.
1108 *
1109 * If the current locale exists as a .mo file in the child theme's
1110 * root directory, it will be included in the translated strings by the $domain.
1111 *
1112 * The .mo files must be named based on the locale exactly.
1113 *
1114 * @since 2.9.0
1115 *
1116 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
1117 * @param string|false $path Optional. Path to the directory containing the .mo file.
1118 * Default false.
1119 * @return bool True when the theme textdomain is successfully loaded, false otherwise.
1120 */
1121function load_child_theme_textdomain( $domain, $path = false ) {
1122 if ( ! $path ) {
1123 $path = get_stylesheet_directory();
1124 }
1125 return load_theme_textdomain( $domain, $path );
1126}
1127
1128/**
1129 * Loads the script translated strings.
1130 *
1131 * @since 5.0.0
1132 * @since 5.0.2 Uses load_script_translations() to load translation data.
1133 * @since 5.1.0 The `$domain` parameter was made optional.
1134 *
1135 * @see WP_Scripts::set_translations()
1136 *
1137 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
1138 *
1139 * @param string $handle Name of the script to register a translation domain to.
1140 * @param string $domain Optional. Text domain. Default 'default'.
1141 * @param string $path Optional. The full file path to the directory containing translation files.
1142 * @return string|false The translated strings in JSON encoding on success,
1143 * false if the script textdomain could not be loaded.
1144 */
1145function load_script_textdomain( $handle, $domain = 'default', $path = '' ) {
1146 /** @var WP_Textdomain_Registry $wp_textdomain_registry */
1147 global $wp_textdomain_registry;
1148
1149 $wp_scripts = wp_scripts();
1150
1151 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
1152 return false;
1153 }
1154
1155 $locale = determine_locale();
1156
1157 if ( ! $path ) {
1158 $path = $wp_textdomain_registry->get( $domain, $locale );
1159 }
1160
1161 $path = untrailingslashit( $path );
1162
1163 // If a path was given and the handle file exists simply return it.
1164 $file_base = 'default' === $domain ? $locale : $domain . '-' . $locale;
1165 $handle_filename = $file_base . '-' . $handle . '.json';
1166
1167 if ( $path ) {
1168 $translations = load_script_translations( $path . '/' . $handle_filename, $handle, $domain );
1169
1170 if ( $translations ) {
1171 return $translations;
1172 }
1173 }
1174
1175 $src = $wp_scripts->registered[ $handle ]->src;
1176
1177 if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && str_starts_with( $src, $wp_scripts->content_url ) ) ) {
1178 $src = $wp_scripts->base_url . $src;
1179 }
1180
1181 $relative = false;
1182 $languages_path = WP_LANG_DIR;
1183
1184 $src_url = wp_parse_url( $src );
1185 $content_url = wp_parse_url( content_url() );
1186 $plugins_url = wp_parse_url( plugins_url() );
1187 $site_url = wp_parse_url( site_url() );
1188 $theme_root = get_theme_root();
1189
1190 // If the host is the same or it's a relative URL.
1191 if (
1192 ( ! isset( $content_url['path'] ) || str_starts_with( $src_url['path'], $content_url['path'] ) ) &&
1193 ( ! isset( $src_url['host'] ) || ! isset( $content_url['host'] ) || $src_url['host'] === $content_url['host'] )
1194 ) {
1195 // Make the src relative the specific plugin or theme.
1196 if ( isset( $content_url['path'] ) ) {
1197 $relative = substr( $src_url['path'], strlen( $content_url['path'] ) );
1198 } else {
1199 $relative = $src_url['path'];
1200 }
1201 $relative = trim( $relative, '/' );
1202 $relative = explode( '/', $relative );
1203
1204 /*
1205 * Ensure correct languages path when using a custom `WP_PLUGIN_DIR` / `WP_PLUGIN_URL` configuration,
1206 * a custom theme root, and/or using Multisite with subdirectories.
1207 * See https://core.trac.wordpress.org/ticket/60891 and https://core.trac.wordpress.org/ticket/62016.
1208 */
1209
1210 $theme_dir = array_slice( explode( '/', $theme_root ), -1 );
1211 $dirname = $theme_dir[0] === $relative[0] ? 'themes' : 'plugins';
1212
1213 $languages_path = WP_LANG_DIR . '/' . $dirname;
1214
1215 $relative = array_slice( $relative, 2 ); // Remove plugins/<plugin name> or themes/<theme name>.
1216 $relative = implode( '/', $relative );
1217 } elseif (
1218 ( ! isset( $plugins_url['path'] ) || str_starts_with( $src_url['path'], $plugins_url['path'] ) ) &&
1219 ( ! isset( $src_url['host'] ) || ! isset( $plugins_url['host'] ) || $src_url['host'] === $plugins_url['host'] )
1220 ) {
1221 // Make the src relative the specific plugin.
1222 if ( isset( $plugins_url['path'] ) ) {
1223 $relative = substr( $src_url['path'], strlen( $plugins_url['path'] ) );
1224 } else {
1225 $relative = $src_url['path'];
1226 }
1227 $relative = trim( $relative, '/' );
1228 $relative = explode( '/', $relative );
1229
1230 $languages_path = WP_LANG_DIR . '/plugins';
1231
1232 $relative = array_slice( $relative, 1 ); // Remove <plugin name>.
1233 $relative = implode( '/', $relative );
1234 } elseif ( ! isset( $src_url['host'] ) || ! isset( $site_url['host'] ) || $src_url['host'] === $site_url['host'] ) {
1235 if ( ! isset( $site_url['path'] ) ) {
1236 $relative = trim( $src_url['path'], '/' );
1237 } elseif ( str_starts_with( $src_url['path'], trailingslashit( $site_url['path'] ) ) ) {
1238 // Make the src relative to the WP root.
1239 $relative = substr( $src_url['path'], strlen( $site_url['path'] ) );
1240 $relative = trim( $relative, '/' );
1241 }
1242 }
1243
1244 /**
1245 * Filters the relative path of scripts used for finding translation files.
1246 *
1247 * @since 5.0.2
1248 *
1249 * @param string|false $relative The relative path of the script. False if it could not be determined.
1250 * @param string $src The full source URL of the script.
1251 */
1252 $relative = apply_filters( 'load_script_textdomain_relative_path', $relative, $src );
1253
1254 // If the source is not from WP.
1255 if ( false === $relative ) {
1256 return load_script_translations( false, $handle, $domain );
1257 }
1258
1259 // Translations are always based on the unminified filename.
1260 if ( str_ends_with( $relative, '.min.js' ) ) {
1261 $relative = substr( $relative, 0, -7 ) . '.js';
1262 }
1263
1264 $md5_filename = $file_base . '-' . md5( $relative ) . '.json';
1265
1266 if ( $path ) {
1267 $translations = load_script_translations( $path . '/' . $md5_filename, $handle, $domain );
1268
1269 if ( $translations ) {
1270 return $translations;
1271 }
1272 }
1273
1274 $translations = load_script_translations( $languages_path . '/' . $md5_filename, $handle, $domain );
1275
1276 if ( $translations ) {
1277 return $translations;
1278 }
1279
1280 return load_script_translations( false, $handle, $domain );
1281}
1282
1283/**
1284 * Loads the translation data for the given script handle and text domain.
1285 *
1286 * @since 5.0.2
1287 *
1288 * @param string|false $file Path to the translation file to load. False if there isn't one.
1289 * @param string $handle Name of the script to register a translation domain to.
1290 * @param string $domain The text domain.
1291 * @return string|false The JSON-encoded translated strings for the given script handle and text domain.
1292 * False if there are none.
1293 */
1294function load_script_translations( $file, $handle, $domain ) {
1295 /**
1296 * Pre-filters script translations for the given file, script handle and text domain.
1297 *
1298 * Returning a non-null value allows to override the default logic, effectively short-circuiting the function.
1299 *
1300 * @since 5.0.2
1301 *
1302 * @param string|false|null $translations JSON-encoded translation data. Default null.
1303 * @param string|false $file Path to the translation file to load. False if there isn't one.
1304 * @param string $handle Name of the script to register a translation domain to.
1305 * @param string $domain The text domain.
1306 */
1307 $translations = apply_filters( 'pre_load_script_translations', null, $file, $handle, $domain );
1308
1309 if ( null !== $translations ) {
1310 return $translations;
1311 }
1312
1313 /**
1314 * Filters the file path for loading script translations for the given script handle and text domain.
1315 *
1316 * @since 5.0.2
1317 *
1318 * @param string|false $file Path to the translation file to load. False if there isn't one.
1319 * @param string $handle Name of the script to register a translation domain to.
1320 * @param string $domain The text domain.
1321 */
1322 $file = apply_filters( 'load_script_translation_file', $file, $handle, $domain );
1323
1324 if ( ! $file || ! is_readable( $file ) ) {
1325 return false;
1326 }
1327
1328 $translations = file_get_contents( $file );
1329
1330 /**
1331 * Filters script translations for the given file, script handle and text domain.
1332 *
1333 * @since 5.0.2
1334 *
1335 * @param string $translations JSON-encoded translation data.
1336 * @param string $file Path to the translation file that was loaded.
1337 * @param string $handle Name of the script to register a translation domain to.
1338 * @param string $domain The text domain.
1339 */
1340 return apply_filters( 'load_script_translations', $translations, $file, $handle, $domain );
1341}
1342
1343/**
1344 * Loads plugin and theme text domains just-in-time.
1345 *
1346 * When a textdomain is encountered for the first time, we try to load
1347 * the translation file from `wp-content/languages`, removing the need
1348 * to call load_plugin_textdomain() or load_theme_textdomain().
1349 *
1350 * @since 4.6.0
1351 * @access private
1352 *
1353 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again.
1354 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
1355 *
1356 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
1357 * @return bool True when the textdomain is successfully loaded, false otherwise.
1358 */
1359function _load_textdomain_just_in_time( $domain ) {
1360 /** @var WP_Textdomain_Registry $wp_textdomain_registry */
1361 global $l10n_unloaded, $wp_textdomain_registry;
1362
1363 $l10n_unloaded = (array) $l10n_unloaded;
1364
1365 // Short-circuit if domain is 'default' which is reserved for core.
1366 if ( 'default' === $domain || isset( $l10n_unloaded[ $domain ] ) ) {
1367 return false;
1368 }
1369
1370 if ( ! $wp_textdomain_registry->has( $domain ) ) {
1371 return false;
1372 }
1373
1374 $locale = determine_locale();
1375 $path = $wp_textdomain_registry->get( $domain, $locale );
1376 if ( ! $path ) {
1377 return false;
1378 }
1379
1380 if ( ! doing_action( 'after_setup_theme' ) && ! did_action( 'after_setup_theme' ) ) {
1381 _doing_it_wrong(
1382 __FUNCTION__,
1383 sprintf(
1384 /* translators: 1: The text domain. 2: 'init'. */
1385 __( 'Translation loading for the %1$s domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the %2$s action or later.' ),
1386 '<code>' . $domain . '</code>',
1387 '<code>init</code>'
1388 ),
1389 '6.7.0'
1390 );
1391 }
1392
1393 // Themes with their language directory outside of WP_LANG_DIR have a different file name.
1394 $template_directory = trailingslashit( get_template_directory() );
1395 $stylesheet_directory = trailingslashit( get_stylesheet_directory() );
1396 if ( str_starts_with( $path, $template_directory ) || str_starts_with( $path, $stylesheet_directory ) ) {
1397 $mofile = "{$path}{$locale}.mo";
1398 } else {
1399 $mofile = "{$path}{$domain}-{$locale}.mo";
1400 }
1401
1402 return load_textdomain( $domain, $mofile, $locale );
1403}
1404
1405/**
1406 * Returns the Translations instance for a text domain.
1407 *
1408 * If there isn't one, returns empty Translations instance.
1409 *
1410 * @since 2.8.0
1411 *
1412 * @global MO[] $l10n An array of all currently loaded text domains.
1413 *
1414 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
1415 * @return Translations|NOOP_Translations A Translations instance.
1416 */
1417function get_translations_for_domain( $domain ) {
1418 global $l10n;
1419 if ( isset( $l10n[ $domain ] ) || ( _load_textdomain_just_in_time( $domain ) && isset( $l10n[ $domain ] ) ) ) {
1420 return $l10n[ $domain ];
1421 }
1422
1423 static $noop_translations = null;
1424 if ( null === $noop_translations ) {
1425 $noop_translations = new NOOP_Translations();
1426 }
1427
1428 $l10n[ $domain ] = &$noop_translations;
1429
1430 return $noop_translations;
1431}
1432
1433/**
1434 * Determines whether there are translations for the text domain.
1435 *
1436 * @since 3.0.0
1437 *
1438 * @global MO[] $l10n An array of all currently loaded text domains.
1439 *
1440 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
1441 * @return bool Whether there are translations.
1442 */
1443function is_textdomain_loaded( $domain ) {
1444 global $l10n;
1445 return isset( $l10n[ $domain ] ) && ! $l10n[ $domain ] instanceof NOOP_Translations;
1446}
1447
1448/**
1449 * Translates role name.
1450 *
1451 * Since the role names are in the database and not in the source there
1452 * are dummy gettext calls to get them into the POT file and this function
1453 * properly translates them back.
1454 *
1455 * The before_last_bar() call is needed, because older installations keep the roles
1456 * using the old context format: 'Role name|User role' and just skipping the
1457 * content after the last bar is easier than fixing them in the DB. New installations
1458 * won't suffer from that problem.
1459 *
1460 * @since 2.8.0
1461 * @since 5.2.0 Added the `$domain` parameter.
1462 *
1463 * @param string $name The role name.
1464 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
1465 * Default 'default'.
1466 * @return string Translated role name on success, original name on failure.
1467 */
1468function translate_user_role( $name, $domain = 'default' ) {
1469 return translate_with_gettext_context( before_last_bar( $name ), 'User role', $domain );
1470}
1471
1472/**
1473 * Gets all available languages based on the presence of *.mo and *.l10n.php files in a given directory.
1474 *
1475 * The default directory is WP_LANG_DIR.
1476 *
1477 * @since 3.0.0
1478 * @since 4.7.0 The results are now filterable with the {@see 'get_available_languages'} filter.
1479 * @since 6.5.0 The initial file list is now cached and also takes into account *.l10n.php files.
1480 *
1481 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
1482 *
1483 * @param string $dir A directory to search for language files.
1484 * Default WP_LANG_DIR.
1485 * @return string[] An array of language codes or an empty array if no languages are present.
1486 * Language codes are formed by stripping the file extension from the language file names.
1487 */
1488function get_available_languages( $dir = null ) {
1489 global $wp_textdomain_registry;
1490
1491 $languages = array();
1492
1493 $path = is_null( $dir ) ? WP_LANG_DIR : $dir;
1494 $lang_files = $wp_textdomain_registry->get_language_files_from_path( $path );
1495
1496 if ( $lang_files ) {
1497 foreach ( $lang_files as $lang_file ) {
1498 $lang_file = basename( $lang_file, '.mo' );
1499 $lang_file = basename( $lang_file, '.l10n.php' );
1500
1501 if ( ! str_starts_with( $lang_file, 'continents-cities' ) && ! str_starts_with( $lang_file, 'ms-' ) &&
1502 ! str_starts_with( $lang_file, 'admin-' ) ) {
1503 $languages[] = $lang_file;
1504 }
1505 }
1506 }
1507
1508 /**
1509 * Filters the list of available language codes.
1510 *
1511 * @since 4.7.0
1512 *
1513 * @param string[] $languages An array of available language codes.
1514 * @param string $dir The directory where the language files were found.
1515 */
1516 return apply_filters( 'get_available_languages', array_unique( $languages ), $dir );
1517}
1518
1519/**
1520 * Gets installed translations.
1521 *
1522 * Looks in the wp-content/languages directory for translations of
1523 * plugins or themes.
1524 *
1525 * @since 3.7.0
1526 *
1527 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
1528 *
1529 * @param string $type What to search for. Accepts 'plugins', 'themes', 'core'.
1530 * @return array Array of language data.
1531 */
1532function wp_get_installed_translations( $type ) {
1533 global $wp_textdomain_registry;
1534
1535 if ( 'themes' !== $type && 'plugins' !== $type && 'core' !== $type ) {
1536 return array();
1537 }
1538
1539 $dir = 'core' === $type ? WP_LANG_DIR : WP_LANG_DIR . "/$type";
1540
1541 if ( ! is_dir( $dir ) ) {
1542 return array();
1543 }
1544
1545 $files = $wp_textdomain_registry->get_language_files_from_path( $dir );
1546 if ( ! $files ) {
1547 return array();
1548 }
1549
1550 $language_data = array();
1551
1552 foreach ( $files as $file ) {
1553 if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?)\.(?:mo|l10n\.php)/', basename( $file ), $match ) ) {
1554 continue;
1555 }
1556
1557 list( , $textdomain, $language ) = $match;
1558 if ( '' === $textdomain ) {
1559 $textdomain = 'default';
1560 }
1561
1562 if ( str_ends_with( $file, '.mo' ) ) {
1563 $pofile = substr_replace( $file, '.po', - strlen( '.mo' ) );
1564
1565 if ( ! file_exists( $pofile ) ) {
1566 continue;
1567 }
1568
1569 $language_data[ $textdomain ][ $language ] = wp_get_pomo_file_data( $pofile );
1570 } else {
1571 $pofile = substr_replace( $file, '.po', - strlen( '.l10n.php' ) );
1572
1573 // If both a PO and a PHP file exist, prefer the PO file.
1574 if ( file_exists( $pofile ) ) {
1575 continue;
1576 }
1577
1578 $language_data[ $textdomain ][ $language ] = wp_get_l10n_php_file_data( $file );
1579 }
1580 }
1581 return $language_data;
1582}
1583
1584/**
1585 * Extracts headers from a PO file.
1586 *
1587 * @since 3.7.0
1588 *
1589 * @param string $po_file Path to PO file.
1590 * @return string[] Array of PO file header values keyed by header name.
1591 */
1592function wp_get_pomo_file_data( $po_file ) {
1593 $headers = get_file_data(
1594 $po_file,
1595 array(
1596 'POT-Creation-Date' => '"POT-Creation-Date',
1597 'PO-Revision-Date' => '"PO-Revision-Date',
1598 'Project-Id-Version' => '"Project-Id-Version',
1599 'X-Generator' => '"X-Generator',
1600 )
1601 );
1602 foreach ( $headers as $header => $value ) {
1603 // Remove possible contextual '\n' and closing double quote.
1604 $headers[ $header ] = preg_replace( '~(\\\n)?"$~', '', $value );
1605 }
1606 return $headers;
1607}
1608
1609/**
1610 * Extracts headers from a PHP translation file.
1611 *
1612 * @since 6.6.0
1613 *
1614 * @param string $php_file Path to a `.l10n.php` file.
1615 * @return string[] Array of file header values keyed by header name.
1616 */
1617function wp_get_l10n_php_file_data( $php_file ) {
1618 $data = (array) include $php_file;
1619
1620 unset( $data['messages'] );
1621 $headers = array(
1622 'POT-Creation-Date' => 'pot-creation-date',
1623 'PO-Revision-Date' => 'po-revision-date',
1624 'Project-Id-Version' => 'project-id-version',
1625 'X-Generator' => 'x-generator',
1626 );
1627
1628 $result = array(
1629 'POT-Creation-Date' => '',
1630 'PO-Revision-Date' => '',
1631 'Project-Id-Version' => '',
1632 'X-Generator' => '',
1633 );
1634
1635 foreach ( $headers as $po_header => $php_header ) {
1636 if ( isset( $data[ $php_header ] ) ) {
1637 $result[ $po_header ] = $data[ $php_header ];
1638 }
1639 }
1640
1641 return $result;
1642}
1643
1644/**
1645 * Displays or returns a Language selector.
1646 *
1647 * @since 4.0.0
1648 * @since 4.3.0 Introduced the `echo` argument.
1649 * @since 4.7.0 Introduced the `show_option_site_default` argument.
1650 * @since 5.1.0 Introduced the `show_option_en_us` argument.
1651 * @since 5.9.0 Introduced the `explicit_option_en_us` argument.
1652 *
1653 * @see get_available_languages()
1654 * @see wp_get_available_translations()
1655 *
1656 * @param string|array $args {
1657 * Optional. Array or string of arguments for outputting the language selector.
1658 *
1659 * @type string $id ID attribute of the select element. Default 'locale'.
1660 * @type string $name Name attribute of the select element. Default 'locale'.
1661 * @type string[] $languages List of installed languages, contain only the locales.
1662 * Default empty array.
1663 * @type array $translations List of available translations. Default result of
1664 * wp_get_available_translations().
1665 * @type string $selected Language which should be selected. Default empty.
1666 * @type bool|int $echo Whether to echo the generated markup. Accepts 0, 1, or their
1667 * boolean equivalents. Default 1.
1668 * @type bool $show_available_translations Whether to show available translations. Default true.
1669 * @type bool $show_option_site_default Whether to show an option to fall back to the site's locale. Default false.
1670 * @type bool $show_option_en_us Whether to show an option for English (United States). Default true.
1671 * @type bool $explicit_option_en_us Whether the English (United States) option uses an explicit value of en_US
1672 * instead of an empty value. Default false.
1673 * }
1674 * @return string HTML dropdown list of languages.
1675 */
1676function wp_dropdown_languages( $args = array() ) {
1677
1678 $parsed_args = wp_parse_args(
1679 $args,
1680 array(
1681 'id' => 'locale',
1682 'name' => 'locale',
1683 'languages' => array(),
1684 'translations' => array(),
1685 'selected' => '',
1686 'echo' => 1,
1687 'show_available_translations' => true,
1688 'show_option_site_default' => false,
1689 'show_option_en_us' => true,
1690 'explicit_option_en_us' => false,
1691 )
1692 );
1693
1694 // Bail if no ID or no name.
1695 if ( ! $parsed_args['id'] || ! $parsed_args['name'] ) {
1696 return;
1697 }
1698
1699 // English (United States) uses an empty string for the value attribute.
1700 if ( 'en_US' === $parsed_args['selected'] && ! $parsed_args['explicit_option_en_us'] ) {
1701 $parsed_args['selected'] = '';
1702 }
1703
1704 $translations = $parsed_args['translations'];
1705 if ( empty( $translations ) ) {
1706 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
1707 $translations = wp_get_available_translations();
1708 }
1709
1710 /*
1711 * $parsed_args['languages'] should only contain the locales. Find the locale in
1712 * $translations to get the native name. Fall back to locale.
1713 */
1714 $languages = array();
1715 foreach ( $parsed_args['languages'] as $locale ) {
1716 if ( isset( $translations[ $locale ] ) ) {
1717 $translation = $translations[ $locale ];
1718 $languages[] = array(
1719 'language' => $translation['language'],
1720 'native_name' => $translation['native_name'],
1721 'lang' => current( $translation['iso'] ),
1722 );
1723
1724 // Remove installed language from available translations.
1725 unset( $translations[ $locale ] );
1726 } else {
1727 $languages[] = array(
1728 'language' => $locale,
1729 'native_name' => $locale,
1730 'lang' => '',
1731 );
1732 }
1733 }
1734
1735 $translations_available = ( ! empty( $translations ) && $parsed_args['show_available_translations'] );
1736
1737 // Holds the HTML markup.
1738 $structure = array();
1739
1740 // List installed languages.
1741 if ( $translations_available ) {
1742 $structure[] = '<optgroup label="' . esc_attr_x( 'Installed', 'translations' ) . '">';
1743 }
1744
1745 // Site default.
1746 if ( $parsed_args['show_option_site_default'] ) {
1747 $structure[] = sprintf(
1748 '<option value="site-default" data-installed="1"%s>%s</option>',
1749 selected( 'site-default', $parsed_args['selected'], false ),
1750 _x( 'Site Default', 'default site language' )
1751 );
1752 }
1753
1754 if ( $parsed_args['show_option_en_us'] ) {
1755 $value = ( $parsed_args['explicit_option_en_us'] ) ? 'en_US' : '';
1756 $structure[] = sprintf(
1757 '<option value="%s" lang="en" data-installed="1"%s>English (United States)</option>',
1758 esc_attr( $value ),
1759 selected( '', $parsed_args['selected'], false )
1760 );
1761 }
1762
1763 // List installed languages.
1764 foreach ( $languages as $language ) {
1765 $structure[] = sprintf(
1766 '<option value="%s" lang="%s"%s data-installed="1">%s</option>',
1767 esc_attr( $language['language'] ),
1768 esc_attr( $language['lang'] ),
1769 selected( $language['language'], $parsed_args['selected'], false ),
1770 esc_html( $language['native_name'] )
1771 );
1772 }
1773 if ( $translations_available ) {
1774 $structure[] = '</optgroup>';
1775 }
1776
1777 // List available translations.
1778 if ( $translations_available ) {
1779 $structure[] = '<optgroup label="' . esc_attr_x( 'Available', 'translations' ) . '">';
1780 foreach ( $translations as $translation ) {
1781 $structure[] = sprintf(
1782 '<option value="%s" lang="%s"%s>%s</option>',
1783 esc_attr( $translation['language'] ),
1784 esc_attr( current( $translation['iso'] ) ),
1785 selected( $translation['language'], $parsed_args['selected'], false ),
1786 esc_html( $translation['native_name'] )
1787 );
1788 }
1789 $structure[] = '</optgroup>';
1790 }
1791
1792 // Combine the output string.
1793 $output = sprintf( '<select name="%s" id="%s">', esc_attr( $parsed_args['name'] ), esc_attr( $parsed_args['id'] ) );
1794 $output .= implode( "\n", $structure );
1795 $output .= '</select>';
1796
1797 if ( $parsed_args['echo'] ) {
1798 echo $output;
1799 }
1800
1801 return $output;
1802}
1803
1804/**
1805 * Determines whether the current locale is right-to-left (RTL).
1806 *
1807 * For more information on this and similar theme functions, check out
1808 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
1809 * Conditional Tags} article in the Theme Developer Handbook.
1810 *
1811 * @since 3.0.0
1812 *
1813 * @global WP_Locale $wp_locale WordPress date and time locale object.
1814 *
1815 * @return bool Whether locale is RTL.
1816 */
1817function is_rtl() {
1818 global $wp_locale;
1819 if ( ! ( $wp_locale instanceof WP_Locale ) ) {
1820 return false;
1821 }
1822 return $wp_locale->is_rtl();
1823}
1824
1825/**
1826 * Switches the translations according to the given locale.
1827 *
1828 * @since 4.7.0
1829 *
1830 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object.
1831 *
1832 * @param string $locale The locale.
1833 * @return bool True on success, false on failure.
1834 */
1835function switch_to_locale( $locale ) {
1836 /* @var WP_Locale_Switcher $wp_locale_switcher */
1837 global $wp_locale_switcher;
1838
1839 if ( ! $wp_locale_switcher ) {
1840 return false;
1841 }
1842
1843 return $wp_locale_switcher->switch_to_locale( $locale );
1844}
1845
1846/**
1847 * Switches the translations according to the given user's locale.
1848 *
1849 * @since 6.2.0
1850 *
1851 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object.
1852 *
1853 * @param int $user_id User ID.
1854 * @return bool True on success, false on failure.
1855 */
1856function switch_to_user_locale( $user_id ) {
1857 /* @var WP_Locale_Switcher $wp_locale_switcher */
1858 global $wp_locale_switcher;
1859
1860 if ( ! $wp_locale_switcher ) {
1861 return false;
1862 }
1863
1864 return $wp_locale_switcher->switch_to_user_locale( $user_id );
1865}
1866
1867/**
1868 * Restores the translations according to the previous locale.
1869 *
1870 * @since 4.7.0
1871 *
1872 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object.
1873 *
1874 * @return string|false Locale on success, false on error.
1875 */
1876function restore_previous_locale() {
1877 /* @var WP_Locale_Switcher $wp_locale_switcher */
1878 global $wp_locale_switcher;
1879
1880 if ( ! $wp_locale_switcher ) {
1881 return false;
1882 }
1883
1884 return $wp_locale_switcher->restore_previous_locale();
1885}
1886
1887/**
1888 * Restores the translations according to the original locale.
1889 *
1890 * @since 4.7.0
1891 *
1892 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object.
1893 *
1894 * @return string|false Locale on success, false on error.
1895 */
1896function restore_current_locale() {
1897 /* @var WP_Locale_Switcher $wp_locale_switcher */
1898 global $wp_locale_switcher;
1899
1900 if ( ! $wp_locale_switcher ) {
1901 return false;
1902 }
1903
1904 return $wp_locale_switcher->restore_current_locale();
1905}
1906
1907/**
1908 * Determines whether switch_to_locale() is in effect.
1909 *
1910 * @since 4.7.0
1911 *
1912 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object.
1913 *
1914 * @return bool True if the locale has been switched, false otherwise.
1915 */
1916function is_locale_switched() {
1917 /* @var WP_Locale_Switcher $wp_locale_switcher */
1918 global $wp_locale_switcher;
1919
1920 return $wp_locale_switcher->is_switched();
1921}
1922
1923/**
1924 * Translates the provided settings value using its i18n schema.
1925 *
1926 * @since 5.9.0
1927 * @access private
1928 *
1929 * @param string|string[]|array[]|object $i18n_schema I18n schema for the setting.
1930 * @param string|string[]|array[] $settings Value for the settings.
1931 * @param string $textdomain Textdomain to use with translations.
1932 *
1933 * @return string|string[]|array[] Translated settings.
1934 */
1935function translate_settings_using_i18n_schema( $i18n_schema, $settings, $textdomain ) {
1936 if ( empty( $i18n_schema ) || empty( $settings ) || empty( $textdomain ) ) {
1937 return $settings;
1938 }
1939
1940 if ( is_string( $i18n_schema ) && is_string( $settings ) ) {
1941 return translate_with_gettext_context( $settings, $i18n_schema, $textdomain );
1942 }
1943 if ( is_array( $i18n_schema ) && is_array( $settings ) ) {
1944 $translated_settings = array();
1945 foreach ( $settings as $value ) {
1946 $translated_settings[] = translate_settings_using_i18n_schema( $i18n_schema[0], $value, $textdomain );
1947 }
1948 return $translated_settings;
1949 }
1950 if ( is_object( $i18n_schema ) && is_array( $settings ) ) {
1951 $group_key = '*';
1952 $translated_settings = array();
1953 foreach ( $settings as $key => $value ) {
1954 if ( isset( $i18n_schema->$key ) ) {
1955 $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$key, $value, $textdomain );
1956 } elseif ( isset( $i18n_schema->$group_key ) ) {
1957 $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$group_key, $value, $textdomain );
1958 } else {
1959 $translated_settings[ $key ] = $value;
1960 }
1961 }
1962 return $translated_settings;
1963 }
1964 return $settings;
1965}
1966
1967/**
1968 * Retrieves the list item separator based on the locale.
1969 *
1970 * @since 6.0.0
1971 *
1972 * @global WP_Locale $wp_locale WordPress date and time locale object.
1973 *
1974 * @return string Locale-specific list item separator.
1975 */
1976function wp_get_list_item_separator() {
1977 global $wp_locale;
1978
1979 if ( ! ( $wp_locale instanceof WP_Locale ) ) {
1980 // Default value of WP_Locale::get_list_item_separator().
1981 /* translators: Used between list items, there is a space after the comma. */
1982 return __( ', ' );
1983 }
1984
1985 return $wp_locale->get_list_item_separator();
1986}
1987
1988/**
1989 * Retrieves the word count type based on the locale.
1990 *
1991 * @since 6.2.0
1992 *
1993 * @global WP_Locale $wp_locale WordPress date and time locale object.
1994 *
1995 * @return string Locale-specific word count type. Possible values are `characters_excluding_spaces`,
1996 * `characters_including_spaces`, or `words`. Defaults to `words`.
1997 */
1998function wp_get_word_count_type() {
1999 global $wp_locale;
2000
2001 if ( ! ( $wp_locale instanceof WP_Locale ) ) {
2002 // Default value of WP_Locale::get_word_count_type().
2003 return 'words';
2004 }
2005
2006 return $wp_locale->get_word_count_type();
2007}
2008
2009/**
2010 * Returns a boolean to indicate whether a translation exists for a given string with optional text domain and locale.
2011 *
2012 * @since 6.7.0
2013 *
2014 * @param string $singular Singular translation to check.
2015 * @param string $textdomain Optional. Text domain. Default 'default'.
2016 * @param ?string $locale Optional. Locale. Default current locale.
2017 * @return bool True if the translation exists, false otherwise.
2018 */
2019function has_translation( string $singular, string $textdomain = 'default', ?string $locale = null ): bool {
2020 return WP_Translation_Controller::get_instance()->has_translation( $singular, $textdomain, $locale );
2021}
2022
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1