Make WordPress Core

Changeset 43859


Ignore:
Timestamp:
11/01/2018 01:50:59 PM (8 years ago)
Author:
herregroen
Message:

I18N: Improve JavaScript translation support.

Improves upon [43825] by adding unit tests to cover additional use-cases and changes loading translations to only occur when outputting the script to allow setting translations on dependencies.

Props atimmer, omarreiss, nerrad, swissspidy, ocean90.
Fixes #45103.

Location:
branches/5.0
Files:
3 added
5 edited
1 moved

Legend:

Unmodified
Added
Removed
  • branches/5.0/src/wp-includes/class-wp-dependency.php

    r41162 r43859  
    6969
    7070        /**
     71         * Translation textdomain set for this dependency.
     72         *
     73         * @since 5.0.0
     74         * @var string
     75         */
     76        public $textdomain;
     77
     78        /**
     79         * Translation path set for this dependency.
     80         *
     81         * @since 5.0.0
     82         * @var string
     83         */
     84        public $translations_path;
     85
     86        /**
    7187         * Setup dependencies.
    7288         *
     
    95111        }
    96112
     113        public function set_translations( $domain, $path = null ) {
     114                if ( !is_string($domain) )
     115                        return false;
     116                $this->textdomain        = $domain;
     117                $this->translations_path = $path;
     118                return true;
     119        }
    97120}
  • branches/5.0/src/wp-includes/class.wp-scripts.php

    r43825 r43859  
    326326                }
    327327
     328                $translations = $this->print_translations( $handle, false );
     329                if ( $translations ) {
     330                        $translations = sprintf( "<script type='text/javascript'>\n%s\n</script>\n", $translations );
     331                }
     332
    328333                if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $this->content_url && 0 === strpos( $src, $this->content_url ) ) ) {
    329334                        $src = $this->base_url . $src;
     
    339344                        return true;
    340345
    341                 $tag = "{$cond_before}{$before_handle}<script type='text/javascript' src='$src'></script>\n{$after_handle}{$cond_after}";
     346                $tag = "{$translations}{$cond_before}{$before_handle}<script type='text/javascript' src='$src'></script>\n{$after_handle}{$cond_after}";
    342347
    343348                /**
     
    479484
    480485        /**
    481          * Register a translation textdomain.
     486         * Sets a translation textdomain.
    482487         *
    483488         * @since 5.0.0
     
    494499                }
    495500
    496                 $json_translations = load_script_textdomain( $handle, $domain, $path );
    497 
    498                 if ( ! $json_translations ) {
    499                         return false;
    500                 }
    501 
    502501                /** @var \_WP_Dependency $obj */
    503502                $obj = $this->registered[ $handle ];
    504                 $obj->deps[] = 'wp-i18n';
    505 
    506                 return $this->add_inline_script(
    507                         $handle,
    508                         '(function( translations ){' .
    509                             'wp.i18n.setLocaleData( translations.locale_data, "' . $domain . '" );' .
    510                         '})(' . $json_translations . ');',
    511                         'before'
    512                 );
     503
     504                if ( ! in_array( 'wp-i18n', $obj->deps, true ) ) {
     505                        $obj->deps[] = 'wp-i18n';
     506                }
     507                return $obj->set_translations( $domain, $path );
     508        }
     509
     510        /**
     511         * Prints translations set for a specific handle.
     512         *
     513         * @since 5.0.0
     514         *
     515         * @param string $handle Name of the script to add the inline script to. Must be lowercase.
     516         * @param bool   $echo   Optional. Whether to echo the script instead of just returning it.
     517         *                       Default true.
     518         * @return string|false Script on success, false otherwise.
     519         */
     520        public function print_translations( $handle, $echo = true ) {
     521                if ( ! isset( $this->registered[ $handle ] ) || empty( $this->registered[ $handle ]->textdomain ) ) {
     522                        return false;
     523                }
     524
     525                $domain = $this->registered[ $handle ]->textdomain;
     526                $path   = $this->registered[ $handle ]->translations_path;
     527
     528                $json_translations = load_script_textdomain( $handle, $domain, $path );
     529
     530                if ( ! $json_translations ) {
     531                        return false;
     532                }
     533
     534                $output = '(function( translations ){' .
     535                              'wp.i18n.setLocaleData( translations.locale_data, "' . $domain . '" );' .
     536                          '})(' . $json_translations . ');';
     537
     538                if ( $echo ) {
     539                        printf( "<script type='text/javascript'>\n%s\n</script>\n", $output );
     540                }
     541
     542                return $output;
    513543        }
    514544
  • branches/5.0/src/wp-includes/functions.wp-scripts.php

    r43827 r43859  
    194194
    195195/**
    196  * Register translated strings for a script.
     196 * Sets translated strings for a script.
    197197 *
    198198 * Works only if the script has already been added.
    199199 *
    200200 * @see WP_Scripts::set_translations()
    201  * @link https://core.trac.wordpress.org/ticket/45103
    202201 * @global WP_Scripts $wp_scripts The WP_Scripts object for printing scripts.
    203202 *
     
    215214                _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
    216215                return false;
    217         }
    218 
    219         if ( ! wp_script_is( $handle, 'enqueued' ) ) {
    220                 _doing_it_wrong( __FUNCTION__, __( 'Script translations may only be set if the script is enqueued.' ), '5.0.0' );
    221216        }
    222217
  • branches/5.0/src/wp-includes/l10n.php

    r43846 r43859  
    877877 * @global WP_Scripts $wp_scripts The WP_Scripts object for printing scripts.
    878878 *
     879 * @since 5.0.0
     880 *
    879881 * @param string $handle Name of the script to register a translation domain to.
    880882 * @param string $domain The textdomain.
     
    887889        global $wp_scripts;
    888890
     891        $path   = untrailingslashit( $path );
    889892        $locale = is_admin() ? get_locale() : get_user_locale();
    890893
    891894        // If a path was given and the handle file exists simply return it.
    892         $handle_filename = $domain . '-' . $locale . '-' . $handle . '.json';
     895        $file_base       = $domain === 'default' ? $locale : $domain . '-' . $locale;
     896        $handle_filename = $file_base . '-' . $handle . '.json';
    893897        if ( $path && file_exists( $path . '/' . $handle_filename ) ) {
    894898                return file_get_contents( $path . '/' . $handle_filename );
     
    909913        // If the host is the same or it's a relative URL.
    910914        if (
    911                 strpos( $content_url['path'], $src_url['path'] ) === 0 &&
     915                strpos( $src_url['path'], $content_url['path'] ) === 0 &&
    912916                ( ! isset( $src_url['host'] ) || $src_url['host'] !== $content_url['host'] )
    913917        ) {
     
    926930                $relative = trim( $src_url['path'], '/' );
    927931        } else if (
    928                 ( strpos( $site_url['path'], $src_url['path'] ) === 0 ) &&
     932                ( strpos( $src_url['path'], $site_url['path'] ) === 0 ) &&
    929933                ( ! isset( $src_url['host'] ) || $src_url['host'] !== $site_url['host'] )
    930934        ) {
     
    944948        }
    945949
    946         $md5_filename = $domain . '-' . $locale . '-' . md5( $relative ) . '.json';
     950        $md5_filename = $file_base . '-' . md5( $relative ) . '.json';
    947951        if ( $path && file_exists( $path . '/' . $md5_filename ) ) {
    948952                return file_get_contents( $path . '/' . $md5_filename );
  • branches/5.0/tests/phpunit/tests/dependencies/scripts.php

    r43828 r43859  
    771771         * @ticket 45103
    772772         */
    773         public function test_wp_set_script_translation() {
     773        public function test_wp_set_script_translations() {
     774                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
     775                wp_enqueue_script( 'test-example', '/wp-includes/js/script.js', array(), null );
     776                wp_set_script_translations( 'test-example', 'default',  DIR_TESTDATA . '/languages' );
     777
     778                $expected  = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js'></script>";
     779                $expected .= "\n<script type='text/javascript'>\n(function( translations ){" .
     780                            "wp.i18n.setLocaleData( translations.locale_data, \"default\" );" .
     781                        "})(" . file_get_contents( DIR_TESTDATA . '/languages/en_US-813e104eb47e13dd4cc5af844c618754.json' ) . ");\n</script>\n";
     782                $expected .= "<script type='text/javascript' src='/wp-includes/js/script.js'></script>\n";
     783
     784                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     785        }
     786
     787        /**
     788         * @ticket 45103
     789         */
     790        public function test_wp_set_script_translations_for_plugin() {
     791                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
     792                wp_enqueue_script( 'plugin-example', '/wp-content/plugins/my-plugin/js/script.js', array(), null );
     793                wp_set_script_translations( 'plugin-example', 'internationalized-plugin',  DIR_TESTDATA . '/languages/plugins' );
     794
     795                $expected  = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js'></script>";
     796                $expected .= "\n<script type='text/javascript'>\n(function( translations ){" .
     797                             "wp.i18n.setLocaleData( translations.locale_data, \"internationalized-plugin\" );" .
     798                             "})(" . file_get_contents( DIR_TESTDATA . '/languages/plugins/internationalized-plugin-en_US-2f86cb96a0233e7cb3b6f03ad573be0b.json' ) . ");\n</script>\n";
     799                $expected .= "<script type='text/javascript' src='/wp-content/plugins/my-plugin/js/script.js'></script>\n";
     800
     801                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     802        }
     803
     804        /**
     805         * @ticket 45103
     806         */
     807        public function test_wp_set_script_translations_for_theme() {
     808                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
     809                wp_enqueue_script( 'theme-example', '/wp-content/themes/my-theme/js/script.js', array(), null );
     810                wp_set_script_translations( 'theme-example', 'internationalized-theme',  DIR_TESTDATA . '/languages/themes' );
     811
     812                $expected  = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js'></script>";
     813                $expected .= "\n<script type='text/javascript'>\n(function( translations ){" .
     814                             "wp.i18n.setLocaleData( translations.locale_data, \"internationalized-theme\" );" .
     815                             "})(" . file_get_contents( DIR_TESTDATA . '/languages/themes/internationalized-theme-en_US-2f86cb96a0233e7cb3b6f03ad573be0b.json' ) . ");\n</script>\n";
     816                $expected .= "<script type='text/javascript' src='/wp-content/themes/my-theme/js/script.js'></script>\n";
     817
     818                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     819        }
     820
     821        /**
     822         * @ticket 45103
     823         */
     824        public function test_wp_set_script_translations_with_handle_file() {
     825                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
     826                wp_enqueue_script( 'script-handle', '/wp-admin/js/script.js', array(), null );
     827                wp_set_script_translations( 'script-handle', 'admin',  DIR_TESTDATA . '/languages/' );
     828
     829                $expected  = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js'></script>";
     830                $expected .= "\n<script type='text/javascript'>\n(function( translations ){" .
     831                             "wp.i18n.setLocaleData( translations.locale_data, \"admin\" );" .
     832                             "})(" . file_get_contents( DIR_TESTDATA . '/languages/admin-en_US-script-handle.json' ) . ");\n</script>\n";
     833                $expected .= "<script type='text/javascript' src='/wp-admin/js/script.js'></script>\n";
     834
     835                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     836        }
     837
     838        /**
     839         * @ticket 45103
     840         */
     841        public function test_wp_set_script_translations_i18n_dependency() {
     842                global $wp_scripts;
     843
    774844                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
    775845                wp_enqueue_script( 'test-example', '/wp-includes/js/script.js', array(), null );
    776846                wp_set_script_translations( 'test-example', 'default',  DIR_TESTDATA . '/languages/' );
    777847
     848                $script = $wp_scripts->registered[ 'test-example' ];
     849
     850                $this->assertContains( 'wp-i18n', $script->deps );
     851        }
     852
     853        /**
     854         * @ticket 45103
     855         */
     856        public function test_wp_set_script_translations_when_translation_file_does_not_exist() {
     857                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
     858                wp_enqueue_script( 'test-example', '/wp-admin/js/script.js', array(), null );
     859                wp_set_script_translations( 'test-example', 'admin',  DIR_TESTDATA . '/languages/' );
     860
     861                $expected  = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js'></script>";
     862                $expected .= "\n<script type='text/javascript' src='/wp-admin/js/script.js'></script>\n";
     863
     864                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     865        }
     866
     867        /**
     868         * @ticket 45103
     869         */
     870        public function test_wp_set_script_translations_after_register() {
     871                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
     872                wp_register_script( 'test-example', '/wp-includes/js/script.js', array(), null );
     873                wp_set_script_translations( 'test-example', 'default',  DIR_TESTDATA . '/languages' );
     874
     875                wp_enqueue_script( 'test-example' );
     876
    778877                $expected  = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js'></script>";
    779878                $expected .= "\n<script type='text/javascript'>\n(function( translations ){" .
    780                             "wp.i18n.setLocaleData( translations.locale_data, \"default\" );" .
    781                         "})(" . file_get_contents( DIR_TESTDATA . '/languages/default-en_US-813e104eb47e13dd4cc5af844c618754.json') . ");\n</script>\n";
     879                             "wp.i18n.setLocaleData( translations.locale_data, \"default\" );" .
     880                             "})(" . file_get_contents( DIR_TESTDATA . '/languages/en_US-813e104eb47e13dd4cc5af844c618754.json' ) . ");\n</script>\n";
    782881                $expected .= "<script type='text/javascript' src='/wp-includes/js/script.js'></script>\n";
     882
     883                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     884        }
     885
     886        /**
     887         * @ticket 45103
     888         */
     889        public function test_wp_set_script_translations_dependency() {
     890                wp_register_script( 'wp-i18n', '/wp-includes/js/dist/wp-i18n.js', array(), null );
     891                wp_register_script( 'test-dependency', '/wp-includes/js/script.js', array(), null );
     892                wp_set_script_translations( 'test-dependency', 'default',  DIR_TESTDATA . '/languages' );
     893
     894                wp_enqueue_script( 'test-example', '/wp-includes/js/script2.js', array( 'test-dependency' ), null );
     895
     896                $expected  = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js'></script>";
     897                $expected .= "\n<script type='text/javascript'>\n(function( translations ){" .
     898                             "wp.i18n.setLocaleData( translations.locale_data, \"default\" );" .
     899                             "})(" . file_get_contents( DIR_TESTDATA . '/languages/en_US-813e104eb47e13dd4cc5af844c618754.json' ) . ");\n</script>\n";
     900                $expected .= "<script type='text/javascript' src='/wp-includes/js/script.js'></script>\n";
     901                $expected .= "<script type='text/javascript' src='/wp-includes/js/script2.js'></script>\n";
    783902
    784903                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
Note: See TracChangeset for help on using the changeset viewer.