diff --git a/README.md b/README.md index 6f0633d..d539756 100644 --- a/README.md +++ b/README.md @@ -438,6 +438,16 @@ Asset::add( 'my-thing', 'js/something.js' ) Note: You can provide the JS file extension (`other-asset-directory/something.js`), the asset file extension (`other-asset-directory/something.asset.php`), or leave it off entirely (`other-asset-directory/something`). +#### Specifying translations for a JS asset + +You can specify translations for a JS asset like so: + +```php +Asset::add( 'my-thing', 'js/something.js' ) + ->with_translations( $textdomain, 'relative/path/to/json/lang/files' ) + ->register(); +``` + ### Conditional enqueuing It is rare that you will want to enqueue an asset on every page load. Luckily, you can specify a condition for when an diff --git a/src/Assets/Asset.php b/src/Assets/Asset.php index 683d6aa..29b95c9 100644 --- a/src/Assets/Asset.php +++ b/src/Assets/Asset.php @@ -217,6 +217,20 @@ class Asset { */ protected ?string $slug = null; + /** + * The asset textdomain. + * + * @var string + */ + protected string $textdomain = ''; + + /** + * Translation path. + * + * @var string + */ + protected string $translations_path = ''; + /** * The asset type. * @@ -947,6 +961,26 @@ public function get_slug(): string { return $this->slug; } + /** + * Get the asset textdomain. + * + * @return string + */ + public function get_textdomain(): string { + return $this->textdomain; + } + + /** + * Get the asset translation path. + * + * @since 1.3.1 + * + * @return string + */ + public function get_translation_path(): string { + return Config::get_path() . $this->translations_path; + } + /** * Get the asset style data. * @@ -1663,6 +1697,19 @@ public function set_priority( int $priority ) { return $this; } + /** + * Set the translation path. Alias of with_translations(). + * + * @since 1.3.1 + * + * @param string $textdomain The textdomain of the asset. + * @param string $path Relative path to the translations directory. + * @return self + */ + public function set_translations( string $textdomain, string $path ): self { + return $this->with_translations( $textdomain, $path ); + } + /** * Set the asset type. * @@ -1700,4 +1747,26 @@ public function use_asset_file( bool $use_asset_file = true ): self { $this->use_asset_file = $use_asset_file; return $this; } + + /** + * Set the translation path. + * + * @since 1.3.1 + * + * @param string $textdomain The textdomain of the asset. + * @param string $path Relative path to the translations directory. + * + * @throws InvalidArgumentException If the asset is not a JS asset. + * + * @return self + */ + public function with_translations( string $textdomain, string $path ): self { + if ( ! $this->is_js() ) { + throw new InvalidArgumentException( 'Translations may only be set for JS assets.' ); + } + + $this->translations_path = $path; + $this->textdomain = $textdomain; + return $this; + } } diff --git a/src/Assets/Assets.php b/src/Assets/Assets.php index feb8f04..e9f719a 100755 --- a/src/Assets/Assets.php +++ b/src/Assets/Assets.php @@ -713,37 +713,46 @@ public function register_in_wp( $assets = null ) { continue; } + $asset_slug = $asset->get_slug(); + if ( 'js' === $asset->get_type() ) { // Script is already registered. - if ( wp_script_is( $asset->get_slug(), 'registered' ) ) { + if ( wp_script_is( $asset_slug, 'registered' ) ) { continue; } - wp_register_script( $asset->get_slug(), $asset->get_url(), $asset->get_dependencies(), $asset->get_version(), $asset->is_in_footer() ); + wp_register_script( $asset_slug, $asset->get_url(), $asset->get_dependencies(), $asset->get_version(), $asset->is_in_footer() ); // Register that this asset is actually registered on the WP methods. // @phpstan-ignore-next-line - if ( wp_script_is( $asset->get_slug(), 'registered' ) ) { + if ( wp_script_is( $asset_slug, 'registered' ) ) { $asset->set_as_registered(); } + + if ( + ! empty( $asset->get_translation_path() ) + && ! empty( $asset->get_textdomain() ) + ) { + wp_set_script_translations( $asset_slug, $asset->get_textdomain(), $asset->get_translation_path() ); + } } else { // Style is already registered. - if ( wp_style_is( $asset->get_slug(), 'registered' ) ) { + if ( wp_style_is( $asset_slug, 'registered' ) ) { continue; } - wp_register_style( $asset->get_slug(), $asset->get_url(), $asset->get_dependencies(), $asset->get_version(), $asset->get_media() ); + wp_register_style( $asset_slug, $asset->get_url(), $asset->get_dependencies(), $asset->get_version(), $asset->get_media() ); // Register that this asset is actually registered on the WP methods. // @phpstan-ignore-next-line - if ( wp_style_is( $asset->get_slug(), 'registered' ) ) { + if ( wp_style_is( $asset_slug, 'registered' ) ) { $asset->set_as_registered(); } $style_data = $asset->get_style_data(); if ( $style_data ) { foreach ( $style_data as $datum_key => $datum_value ) { - wp_style_add_data( $asset->get_slug(), $datum_key, $datum_value ); + wp_style_add_data( $asset_slug, $datum_key, $datum_value ); } } } diff --git a/tests/_data/lang/fake1-en_US-fake1.json b/tests/_data/lang/fake1-en_US-fake1.json new file mode 100644 index 0000000..28265bd --- /dev/null +++ b/tests/_data/lang/fake1-en_US-fake1.json @@ -0,0 +1,8 @@ +{ + "fake1.php": { + "Fake plugin": "" + }, + "src/fake1.php:82": { + "Page title": "Fake title" + } +} \ No newline at end of file diff --git a/tests/acceptance/EnqueueJSCest.php b/tests/acceptance/EnqueueJSCest.php index d018b99..b9bca81 100644 --- a/tests/acceptance/EnqueueJSCest.php +++ b/tests/acceptance/EnqueueJSCest.php @@ -303,4 +303,23 @@ public function it_should_enqueue_css_when_using_register_with_css( AcceptanceTe $I->seeElement( 'link', [ 'href' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/build/something.css?ver=1.0.0' ] ); $I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/build/something.js?ver=12345' ] ); } -} + + public function it_should_register_translations( AcceptanceTester $I ) { + $code = file_get_contents( codecept_data_dir( 'enqueue-template.php' ) ); + $code .= <<enqueue_on( 'wp_enqueue_scripts' ) + ->with_translations( 'fake1', 'tests/_data/lang' ) + ->register(); + }, 100 ); + PHP; + + $I->haveMuPlugin( 'enqueue.php', $code ); + + + $I->amOnPage( '/' ); + $I->seeElement( '#fake1-js-translations' ); + } + +} \ No newline at end of file diff --git a/tests/wpunit/AssetsTest.php b/tests/wpunit/AssetsTest.php index 45d2200..56ddcbe 100644 --- a/tests/wpunit/AssetsTest.php +++ b/tests/wpunit/AssetsTest.php @@ -771,6 +771,32 @@ public function it_should_throw_errors_when_cloning_css_to_css() { ->clone_to( 'css' ); } + /** + * @test + */ + public function it_should_register_translations() { + $slug = 'something-' . uniqid() . '-js'; + + $asset = Asset::add( $slug, 'something.js' ) + ->set_translations( 'fake1', 'tests/_data/lang' ) + ->register(); + + $this->assertEquals( 'fake1', $asset->get_textdomain() ); + $this->assertEquals( dirname( dirname( __DIR__ ) ) . '/tests/_data/lang', $asset->get_translation_path() ); + } + + /** + * @test + */ + public function it_should_throw_exception_when_registering_translations_for_css() { + $this->expectException( \InvalidArgumentException::class ); + $slug = 'something-' . uniqid() . '-css'; + + Asset::add( $slug, 'something.css' ) + ->set_translations( 'fake1', 'tests/_data/lang' ) + ->register(); + } + /** * Evaluates if a script and style have been registered. */