From 281ff4f2fb6a39f1600cf6a9bc8d7004f23cef98 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 29 Sep 2026 15:03:20 +0530 Subject: [PATCH 1/4] fix: add script translation support for the builder --- includes/Editor.php | 2 + includes/Elementor.php | 2 + includes/TI_Beaver.php | 14 ++++ tests/php/static-analysis/beaver.php | 7 ++ tests/script-translations-test.php | 106 +++++++++++++++++++++++++++ 5 files changed, 131 insertions(+) create mode 100644 tests/script-translations-test.php diff --git a/includes/Editor.php b/includes/Editor.php index 5a8db512..a8b2e6eb 100644 --- a/includes/Editor.php +++ b/includes/Editor.php @@ -75,6 +75,8 @@ public function register_block() { $deps['version'] ); + wp_set_script_translations( $this->handle, 'templates-patterns-collection' ); + wp_localize_script( $this->handle, 'tiTpc', diff --git a/includes/Elementor.php b/includes/Elementor.php index bd009e41..a2cba51c 100644 --- a/includes/Elementor.php +++ b/includes/Elementor.php @@ -46,6 +46,8 @@ public function register_script() { true ); + wp_set_script_translations( 'ti-tpc-elementor', 'templates-patterns-collection' ); + wp_localize_script( 'ti-tpc-elementor', 'tiTpc', diff --git a/includes/TI_Beaver.php b/includes/TI_Beaver.php index 8e15ef41..bf7ec4b1 100644 --- a/includes/TI_Beaver.php +++ b/includes/TI_Beaver.php @@ -47,6 +47,20 @@ public function __construct() { $this->add_css( 'ti-tpc-beaver', $this->url . 'build/index.css', array( 'wp-components' ), $deps['version'] ); } + /** + * Register the module script with its translations. + * + * Beaver calls this right before enqueueing the scripts added with add_js(). + * + * @return void + */ + public function enqueue_scripts() { + list( $src, $deps, $ver, $in_footer ) = $this->js['ti-tpc-beaver']; + + wp_register_script( 'ti-tpc-beaver', $src, $deps, $ver, $in_footer ); + wp_set_script_translations( 'ti-tpc-beaver', 'templates-patterns-collection' ); + } + /** * Get position of node. */ diff --git a/tests/php/static-analysis/beaver.php b/tests/php/static-analysis/beaver.php index 5252168f..9e504d9d 100644 --- a/tests/php/static-analysis/beaver.php +++ b/tests/php/static-analysis/beaver.php @@ -11,6 +11,13 @@ class FLBuilderModule { */ public $url; + /** + * Additional JS to enqueue. + * + * @var array|null, 2: string|bool|null, 3: bool|null}> $js + */ + public $js = array(); + /** * Module constructor. * diff --git a/tests/script-translations-test.php b/tests/script-translations-test.php new file mode 100644 index 00000000..ec403a27 --- /dev/null +++ b/tests/script-translations-test.php @@ -0,0 +1,106 @@ + + */ + private array $created_files = array(); + + /** + * Build dirs created by this test, removed in teardown. + * + * @var list + */ + private array $created_dirs = array(); + + public function set_up(): void { + parent::set_up(); + // CI does not build the JS bundles. + $this->maybe_stub_asset( 'editor' ); + $this->maybe_stub_asset( 'elementor' ); + } + + public function tear_down(): void { + wp_deregister_script( 'ti-tpc-block' ); + wp_deregister_script( 'ti-tpc-elementor' ); + wp_deregister_style( 'ti-tpc-block' ); + unregister_block_type( 'ti-tpc/templates-cloud' ); + set_current_screen( 'front' ); + + foreach ( $this->created_files as $file ) { + unlink( $file ); + } + foreach ( array_reverse( $this->created_dirs ) as $dir ) { + rmdir( $dir ); + } + parent::tear_down(); + } + + /** + * Gutenberg bundle loads its translations. + * + * @return void + */ + public function test_editor_script_has_text_domain(): void { + if ( ! defined( 'TPC_TEMPLATES_CLOUD_ENDPOINT' ) ) { + define( 'TPC_TEMPLATES_CLOUD_ENDPOINT', Admin::get_templates_cloud_endpoint() ); + } + if ( WP_Block_Type_Registry::get_instance()->is_registered( 'ti-tpc/templates-cloud' ) ) { + unregister_block_type( 'ti-tpc/templates-cloud' ); + } + wp_deregister_script( 'ti-tpc-block' ); + set_current_screen( 'post' ); + + ( new Editor() )->register_block(); + + $this->assertSame( 'templates-patterns-collection', wp_scripts()->registered['ti-tpc-block']->textdomain ); + } + + /** + * Elementor bundle loads its translations. + * + * @return void + */ + public function test_elementor_script_has_text_domain(): void { + wp_deregister_script( 'ti-tpc-elementor' ); + + ( new Elementor() )->register_script(); + + $this->assertSame( 'templates-patterns-collection', wp_scripts()->registered['ti-tpc-elementor']->textdomain ); + } + + /** + * Create a minimal build asset file when the bundle is not built. + * + * @param string $bundle Bundle directory. + * + * @return void + */ + private function maybe_stub_asset( string $bundle ): void { + $dir = TIOB_PATH . $bundle . '/build'; + $file = $dir . '/index.asset.php'; + if ( file_exists( $file ) ) { + return; + } + if ( ! is_dir( $dir ) ) { + mkdir( $dir ); + $this->created_dirs[] = $dir; + } + file_put_contents( $file, " array(), 'version' => 'test' );" ); + $this->created_files[] = $file; + } +} From 8fc6172c2802095b79db34a0d76803fef9a12b64 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 29 Sep 2026 15:24:39 +0530 Subject: [PATCH 2/4] fix: add Beaver Builder stubs --- tests/fixtures/beaver-builder-stub.php | 113 +++++++++++++++++++++++++ tests/script-translations-test.php | 26 +++++- 2 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/beaver-builder-stub.php diff --git a/tests/fixtures/beaver-builder-stub.php b/tests/fixtures/beaver-builder-stub.php new file mode 100644 index 00000000..3be35a14 --- /dev/null +++ b/tests/fixtures/beaver-builder-stub.php @@ -0,0 +1,113 @@ +|null, 2: string|bool|null, 3: bool|null}> + */ + public $js = array(); + + /** + * Styles added with add_css(), keyed by handle. + * + * @var array|null, 2: string|bool|null, 3: string|null}> + */ + public $css = array(); + + /** + * Module constructor. + * + * @param array{name: string, description: string, category: string, dir: string, url: string, icon: string} $params Module params. + */ + public function __construct( array $params ) { + $this->url = trailingslashit( $params['url'] ); + } + + /** + * Store a script for later enqueueing. + * + * @param string $handle Script handle. + * @param string|null $src Script url. + * @param list|null $deps Dependencies. + * @param string|bool|null $ver Version. + * @param bool|null $in_footer Load in footer. + * + * @return void + */ + public function add_js( string $handle, ?string $src = null, ?array $deps = null, $ver = null, ?bool $in_footer = null ): void { + $this->js[ $handle ] = array( $src, $deps, $ver, $in_footer ); + } + + /** + * Store a style for later enqueueing. + * + * @param string $handle Style handle. + * @param string|null $src Style url. + * @param list|null $deps Dependencies. + * @param string|bool|null $ver Version. + * @param string|null $media Media. + * + * @return void + */ + public function add_css( string $handle, ?string $src = null, ?array $deps = null, $ver = null, ?string $media = null ): void { + $this->css[ $handle ] = array( $src, $deps, $ver, $media ); + } + + /** + * Hook for subclasses; untyped so TI_Beaver's override stays compatible. + * + * @return void + */ + public function enqueue_scripts() { + } +} + +/** + * Class FLBuilder. + */ +class FLBuilder { + /** + * Register a module class. + * + * @param string $class Module class. + * @param array $form Settings form. + * + * @return void + */ + public static function register_module( string $class, array $form ): void { + } + + /** + * Same order as Beaver: module hook first, then the stored scripts. + * + * @param FLBuilderModule $module Module instance. + * + * @return void + */ + public static function enqueue_module_layout_styles_scripts( FLBuilderModule $module ): void { + $module->enqueue_scripts(); + + foreach ( $module->js as $handle => $props ) { + wp_enqueue_script( $handle, $props[0], $props[1], $props[2], $props[3] ); + } + } +} diff --git a/tests/script-translations-test.php b/tests/script-translations-test.php index ec403a27..e9c51155 100644 --- a/tests/script-translations-test.php +++ b/tests/script-translations-test.php @@ -8,6 +8,7 @@ use TIOB\Admin; use TIOB\Editor; use TIOB\Elementor; +use TIOB\TI_Beaver; /** * Builder bundles must be linked to the plugin text domain. @@ -32,13 +33,17 @@ public function set_up(): void { // CI does not build the JS bundles. $this->maybe_stub_asset( 'editor' ); $this->maybe_stub_asset( 'elementor' ); + $this->maybe_stub_asset( 'beaver' ); } public function tear_down(): void { wp_deregister_script( 'ti-tpc-block' ); wp_deregister_script( 'ti-tpc-elementor' ); + wp_deregister_script( 'ti-tpc-beaver' ); wp_deregister_style( 'ti-tpc-block' ); - unregister_block_type( 'ti-tpc/templates-cloud' ); + if ( WP_Block_Type_Registry::get_instance()->is_registered( 'ti-tpc/templates-cloud' ) ) { + unregister_block_type( 'ti-tpc/templates-cloud' ); + } set_current_screen( 'front' ); foreach ( $this->created_files as $file ) { @@ -83,6 +88,25 @@ public function test_elementor_script_has_text_domain(): void { $this->assertSame( 'templates-patterns-collection', wp_scripts()->registered['ti-tpc-elementor']->textdomain ); } + /** + * Beaver bundle loads its translations once Beaver enqueues the module. + * + * The FLBuilder* stubs are global, so they get a process of their own. + * + * @runInSeparateProcess + * @preserveGlobalState disabled + * + * @return void + */ + public function test_beaver_script_has_text_domain(): void { + require_once __DIR__ . '/fixtures/beaver-builder-stub.php'; + wp_deregister_script( 'ti-tpc-beaver' ); + + FLBuilder::enqueue_module_layout_styles_scripts( new TI_Beaver() ); + + $this->assertSame( 'templates-patterns-collection', wp_scripts()->registered['ti-tpc-beaver']->textdomain ); + } + /** * Create a minimal build asset file when the bundle is not built. * From ee3df6cc667082665dcdadde82dd6b4e63349718 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 29 Sep 2026 16:01:20 +0530 Subject: [PATCH 3/4] test: drop redundant pre-test cleanup --- tests/script-translations-test.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/script-translations-test.php b/tests/script-translations-test.php index e9c51155..46674dfc 100644 --- a/tests/script-translations-test.php +++ b/tests/script-translations-test.php @@ -64,10 +64,6 @@ public function test_editor_script_has_text_domain(): void { if ( ! defined( 'TPC_TEMPLATES_CLOUD_ENDPOINT' ) ) { define( 'TPC_TEMPLATES_CLOUD_ENDPOINT', Admin::get_templates_cloud_endpoint() ); } - if ( WP_Block_Type_Registry::get_instance()->is_registered( 'ti-tpc/templates-cloud' ) ) { - unregister_block_type( 'ti-tpc/templates-cloud' ); - } - wp_deregister_script( 'ti-tpc-block' ); set_current_screen( 'post' ); ( new Editor() )->register_block(); @@ -81,8 +77,6 @@ public function test_editor_script_has_text_domain(): void { * @return void */ public function test_elementor_script_has_text_domain(): void { - wp_deregister_script( 'ti-tpc-elementor' ); - ( new Elementor() )->register_script(); $this->assertSame( 'templates-patterns-collection', wp_scripts()->registered['ti-tpc-elementor']->textdomain ); @@ -100,7 +94,6 @@ public function test_elementor_script_has_text_domain(): void { */ public function test_beaver_script_has_text_domain(): void { require_once __DIR__ . '/fixtures/beaver-builder-stub.php'; - wp_deregister_script( 'ti-tpc-beaver' ); FLBuilder::enqueue_module_layout_styles_scripts( new TI_Beaver() ); From 2249dacaa3ad097554a4fe73ce3de00581ecc798 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Wed, 30 Sep 2026 15:30:47 +0530 Subject: [PATCH 4/4] fix: make error message translatable --- editor/src/plugins/extension.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/src/plugins/extension.js b/editor/src/plugins/extension.js index 6aadad26..f624a4cb 100644 --- a/editor/src/plugins/extension.js +++ b/editor/src/plugins/extension.js @@ -212,7 +212,7 @@ const Exporter = () => { if ( res.message ) { let message = res.message; if ( - message === 'Sorry, you are not allowed to do that.' + message === __( 'Sorry, you are not allowed to do that.', 'templates-patterns-collection' ) ) { message = __( 'Could not save template, check that the template is not empty.', @@ -313,7 +313,7 @@ const Exporter = () => { if ( res.message ) { let message = res.message; if ( - message === 'Sorry, you are not allowed to do that.' + message === __( 'Sorry, you are not allowed to do that.', 'templates-patterns-collection' ) ) { message = __( 'Could not save template, check that the template is not empty.',