Skip to content

Commit

Permalink
Adding support to setting translations for JS assets
Browse files Browse the repository at this point in the history
This provides a way to auto-invoke `wp_set_script_translations()` at the correct moment along with the registration of a JS file.
  • Loading branch information
borkweb committed Sep 28, 2024
1 parent 86e25d2 commit cb0c92d
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 8 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
69 changes: 69 additions & 0 deletions src/Assets/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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;
}
}
23 changes: 16 additions & 7 deletions src/Assets/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions tests/_data/lang/fake1-en_US-fake1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"fake1.php": {
"Fake plugin": ""
},
"src/fake1.php:82": {
"Page title": "Fake title"
}
}
21 changes: 20 additions & 1 deletion tests/acceptance/EnqueueJSCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 .= <<<PHP
add_action( 'wp_enqueue_scripts', function() {
Asset::add( 'fake1', 'fake1.js' )
->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' );
}

}
26 changes: 26 additions & 0 deletions tests/wpunit/AssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down

0 comments on commit cb0c92d

Please sign in to comment.