Open bobbingwide opened 3 years ago
The post edit block is currently produced as
<script id='oik-sb-sb-post-edit-block-editor-script-js-translations'>
(function(domain, translations) {
var localeData = translations.locale_data[domain] || translations.locale_data.messages;
localeData[""].domain = domain;
wp.i18n.setLocaleData(localeData, domain);
}
)("sb-post-edit-block", {
"locale_data": {
"messages": {
"": {}
}
}
});
</script>
<script src='https://s.b/cwiccer/wp-content/plugins/sb-post-edit-block/./build/index.js?ver=adcb066b64af553fb3daa0134a33ec2a' id='oik-sb-sb-post-edit-block-editor-script-js'></script>
There should be entries in the locale_data.messages
object
In the load_script_textdomain()
function in l10n.php
the value of the $relative
variable is set to ./build/index.js
.
The $md5_filename
for this
sb-post-edit-block-en_GB-1b3034803df8a21550db0d04471ea571.json
which is different from the file we've got.
sb-post-edit-block-bb_BB-dfbff627e6c248bcb3b61d7d06da9ca9.json
I then checked what the md5 value should be for build/index.js and found that I'd previously debugged this on 28th July 2020 with a routine called md5.php
<?php
//echo md5( 'sb-breadcrumbs-block-bb_BB' );
md5is( 'build/index.js' );
md5is( './build/index.js' );
md5is( 'src/index.js' );
md5is( 'src/sb-breadcrumbs-block/edit.js' );
function md5is( $file ) {
echo "md5 for $file is ";
echo md5( $file );
echo PHP_EOL;
}
C:\apache\htdocs\wordpress\wp-content\plugins\play>php md5.php
md5 for build/index.js is dfbff627e6c248bcb3b61d7d06da9ca9
md5 for ./build/index.js is 1b3034803df8a21550db0d04471ea571
md5 for src/index.js is 1fdf421c05c1140f6d71444ea2b27638
md5 for src/sb-breadcrumbs-block/edit.js is 30338b81b9d834a0a3ccc281c0c5c485
Then I re-read the issue https://github.com/bobbingwide/sb-breadcrumbs-block/issues/1 It's a very similar problem. I no longer understand what my Previous thoughts were.
Now I reckon that I can implement a filter function for
$relative = apply_filters( 'load_script_textdomain_relative_path', $relative, $src );
With the filter function changing relative to build/index.js
if it's ./build/index.js
or src/block-name/../../build/index.js
For the sb-post-edit-block plugin it wasn't necessary to implement the filter hook.
I just changed filenames in block.json
, removing the unnecessary .\
prefix.
But the code doesn't cater for the translatable fields in block.json
.
I've updated wp-cli
to v2.5.0 but that doesn't appear to process the file.
I'm going to see what happens with the latest version of npx @wordpress/create-block
.
The new plugin will be called local-eyes
.
C:\apache\htdocs\wordpress\wp-content\plugins>npx @wordpress/create-block
npx: installed 213 in 24.304s
Let's customize your block:
? The block slug used for identification (also the plugin and output folder name): local-eyes
? The internal namespace for the block name (something unique for your products): local-eyes
? The display title for your block: Localise
? The short description for your block (optional): Example block to test i18n/l10n
? The dashicon to make it easier to identify your block (optional): translation
? The category name to help users browse and discover your block: widgets
? The name of the plugin author (optional). Multiple authors may be listed using commas: bobbingwide
? The short name of the plugin’s license (optional): GPL-2.0-or-later
? A link to the full text of the license (optional): https://www.gnu.org/licenses/gpl-2.0.html
? The current version number of the plugin: 0.0.0
Creating a new WordPress block in "local-eyes" folder.
Creating a "block.json" file.
Creating a "package.json" file.
Installing npm dependencies. It might take a couple of minutes...
The plugin created by @wordpress/create-block is not internationalised.
It seems that the i18n package on wp-cli v2.5.0 is not the latest.
Trying to install it using wp package install git@github.com:wp-cli/i18n-command.git
Installing package wp-cli/i18n-command (dev-master)
Updating C:\Users\herb\.wp-cli\packages\composer.json to require the package...
Registering git@github.com:wp-cli/i18n-command.git as a VCS repository...
Using Composer to install the package...
---
Loading composer repositories with package information
Updating dependencies
Generating rules
Resolving dependencies through SAT
Looking at all rules.
Something's changed, looking at all rules again (pass #1)
Dependency resolution completed in 0.001 seconds
Analyzed 84 packages to resolve dependencies
Analyzed 99 rules to resolve dependencies
Lock file operations: 0 installs, 4 updates, 0 removals
Updates: gettext/languages:2.8.1, mck89/peast:v1.13.5, gettext/gettext:v4.8.5, wp-cli/i18n-command:dev-master 134784d
- Upgrading gettext/gettext (v4.6.2 => v4.8.5)
- Upgrading gettext/languages (2.5.0 => 2.8.1)
- Upgrading mck89/peast (v1.9.1 => v1.13.5)
- Upgrading wp-cli/i18n-command (dev-master 163ffd2 => dev-master 134784d)
Writing lock file
Installing dependencies from lock file
Package operations: 0 installs, 4 updates, 0 removals
Updates: gettext/languages:2.8.1, mck89/peast:v1.13.5, gettext/gettext:v4.8.5, wp-cli/i18n-command:dev-master 134784d
Generating autoload files
2 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
Having installed the latest version of the wp-cli i18n command I was able to get the strings from block.json
into the .pot
file.
In order to get the strings translated I needed to add code calling load_plugin_textdomain()
before registering the block.
For plugins where the block.json
files are in the block's subfolder within src
the definition of the makepot
command will need to be changed.
From
"makepot": "wp i18n make-pot . languages/sb-post-edit-block.pot --exclude=node_modules,vendor,src",
To
"makepot": "wp i18n make-pot . languages/sb-post-edit-block.pot --exclude=node_modules,vendor,src/*.js",
This will enable the routine to find the block.json files but ignore the source Javascript files.
The translatable strings are extracted from the build/index.js
file. Note: It's this file name that's used to create the md5 suffix.
( dfbff627e6c248bcb3b61d7d06da9ca9
). There should only be one file per locale.
To support internationalization of block.json
files you need to install the latest version of the wp-cli i18n command which provides internationalization tools for WordPress projects.
I used the latest version at the time, v2.2.9
You need to call load_text_domain()
before registering the blocks.
You need to call wp_set_script_translations()
to load the JavaScript translations
If your block.json file's editorScript
setting is a relative path such as below
"editorScript": "file:../../build/index.js",
then you need to implement a filter hook for load_script_textdomain_relative_path
to change the value to that used by the makejson
command.
Each time you change a translatable string in the JavaScript source you need to rebuild the language files
npm run dev or npm run build
npm run makepot
npm run l10n
npm run makejson
If you just change a string in a PHP file or block.json
then you don't need to build the JavaScript.
The npm commands are defined in package.json
as:
"makepot": "wp i18n make-pot . languages/sb-post-edit-block.pot --exclude=node_modules,vendor,src/*.js",
"makejson": "wp i18n make-json languages --no-purge",
"l10n": "l10n sb-post-edit-block"
See https://github.com/bobbingwide/oik-i18n/issues/6 for an explanation of these commands. I should really create a diagram.
Regarding "default"
values for "attributes"
in block.json
I don't yet know how to ensure that these get translated.
When building the .pot
file for oik I found that the block.json
files were ignored if they contained the textdomain
attribute, even if this was set to "oik"
and it matched the --domain=oik
parameter needed on the makepot
command to support the PHP shared library files.
The workaround was to
"makepot": "wp i18n make-pot . languages/oik.pot --ignore-domain --domain=oik --exclude=node_modules,vendor,src/*.js,tests",
"textdomain": "oik"
attribute from each block.json
file.This didn't resolve the problem of the strings from block.json
not being translated!
The textdomain
attribute is still needed in the block.json file.
Reinstating this attribute in the block.json file after it's been parsed by makepot could be used as a workaround.
Or can I remove --ignore-domain
?
Or can I remove --ignore-domain?
No. --ignore-domain
is required for the PHP shared library files which pass a domain of null
.
So why doesn't --domain=oik
match the textdomain
attribute?
It looks like there's a runtime workaround using the block_type_metadata
filter called in register_block_type_from_metadata
$metadata = apply_filters( 'block_type_metadata', $metadata );
If the $metadata['textdomain']
is not set, then set it to the prefix part of the block's name
eg for oik/address
set the textdomain
to oik
.
Regarding "default" values for "attributes" in block.json I don't yet know how to ensure that these get translated.
The link text attribute called label
is currently defined in the block.json file with a default value of (Edit)
.
This doesn't get translated.
So the default value if we enable example using block.json
is the untranslated string (Edit)
.
Let's just confirm this!
The official documentation for Metadata indicates that attributes
and example
are not automatically translated ( Localized: No ).
So we have to find another way to get the default values to be translated.
So we have to find another way to get the default values to be translated.
The solution is to not use default values for attributes and set the default value when the attribute is not set or completely empty.
So we have to find another way to get the default values to be translated.
Try translating in a filter run for register_block_type_from_metadata()
.
Questions:
The Post Edit block is registered from
block.json
but the internationalization and localization doesn't work. This is a simpler version of the problem reported in https://github.com/bobbingwide/oik/issues/177#issuecomment-898885822Requirement
__()
block.json
Proposed solution
Build the localized version using
Determine whether or not we need to call
wp_set_script_translations
. Find out what value for the$handle
parameter should be.