Skip to content

Commit

Permalink
Merge pull request #22 from stellarwp/feature/translations
Browse files Browse the repository at this point in the history
Adding support to setting translations for JS assets
  • Loading branch information
borkweb authored Sep 28, 2024
2 parents 10874c7 + 7020071 commit dd6e75c
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 23 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ A library for managing asset registration and enqueuing in WordPress.
* [Support for wp-scripts](#support-for-wp-scripts)
* [Default example](#default-example)
* [Overriding the default asset file location](#overriding-the-default-asset-file-location)
* [Specifying translations for a JS asset](#specifying-translations-for-a-js-asset)
* [Conditional enqueuing](#conditional-enqueuing)
* [Firing a callback after enqueuing occurs](#firing-a-callback-after-enqueuing-occurs)
* [Output JS data](#output-js-data)
Expand Down Expand Up @@ -438,6 +439,27 @@ 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
// Using the default path of 'languages/'.
Asset::add( 'my-thing', 'js/something.js' )
->with_translations( $textdomain )
->register();

// Specifying a different path.
Asset::add( 'my-thing', 'js/something.js' )
->with_translations( $textdomain, 'relative/path/to/json/lang/files' )
->register();

// Using the 'default' textdomain and the default path of 'languages/'.
Asset::add( 'my-thing', 'js/something.js' )
->with_translations()
->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 @@ -1664,6 +1698,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 @@ -1701,4 +1748,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 = 'default', string $path = 'languages' ): 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"
}
}
35 changes: 19 additions & 16 deletions tests/acceptance/EnqueueJSCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public function it_should_register_and_enqueue_js( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/js/fake.js?ver=1.0.0' ] );
}
Expand All @@ -35,7 +34,6 @@ public function it_should_enqueue_from_alternate_path( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/other-asset-root/js/fake-alt.js?ver=1.0.0' ] );
}
Expand All @@ -53,7 +51,6 @@ public function it_should_enqueue_from_alternate_path_with_js_in_path( Acceptanc

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/other-asset-root/js/fake-alt.js?ver=1.0.0' ] );
}
Expand Down Expand Up @@ -91,7 +88,6 @@ public function it_should_enqueue_min( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/js/fake-with-min.min.js?ver=1.0.0' ] );
}
Expand All @@ -109,7 +105,6 @@ public function it_should_enqueue_min_from_different_dir( AcceptanceTester $I )

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/minified/js/fake.min.js?ver=1.0.0' ] );
}
Expand All @@ -127,7 +122,6 @@ public function it_should_not_enqueue_if_dependencies_missing( AcceptanceTester

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->dontSeeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/js/fake.js?ver=1.0.0' ] );
}
Expand All @@ -144,7 +138,6 @@ public function it_should_enqueue_with_custom_version( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/js/fake.js?ver=2.0.0' ] );
}
Expand All @@ -162,7 +155,6 @@ public function it_should_enqueue_when_missing_extension( AcceptanceTester $I )

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/js/fake-js-with-no-extension?ver=1.0.0' ] );
}
Expand All @@ -179,7 +171,6 @@ public function it_should_not_enqueue_if_action_is_not_fired( AcceptanceTester $

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->dontSeeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/js/fake.js?ver=1.0.0' ] );
}
Expand All @@ -197,7 +188,6 @@ public function it_should_be_deferred( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( '#fake-js-js[defer]' );
}
Expand All @@ -215,7 +205,6 @@ public function it_should_be_async( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( '#fake-js-js[async]' );
}
Expand All @@ -233,7 +222,6 @@ public function it_should_be_a_module( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( '#fake-js-js[type=module]' );
}
Expand All @@ -260,7 +248,6 @@ public function it_should_localize( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( '#fake-js-js-extra' );
$contents = $I->grabTextFrom( '#fake-js-js-extra' );
Expand All @@ -280,7 +267,6 @@ public function it_should_enqueue_and_use_asset_file( AcceptanceTester $I ) {

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$I->seeElement( 'script', [ 'src' => 'http://wordpress.test/wp-content/plugins/assets/tests/_data/js/fake4.js?ver=12345' ] );
}
Expand All @@ -298,9 +284,26 @@ public function it_should_enqueue_css_when_using_register_with_css( AcceptanceTe

$I->haveMuPlugin( 'enqueue.php', $code );


$I->amOnPage( '/' );
$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 dd6e75c

Please sign in to comment.