Problem/Motivation
Some blocks in the block layout library are grouped under the label "System", some under the translation of "System"
Steps to reproduce
- Install in another language than english
- Login as admin
- Go to the block layout page admin/structure/block
Alternative:
- Login as admin
- Enable multilanguage modules
- Add another language
- Interface-translate "System"
- Go to the block layout page admin/structure/block
Multiple instances of "System" are not translated while some are. See the screenshots below, where "System" was translated to "TEST" in German.
Noticed in #2019511: Explain why the language switcher would not show under some configurations
Proposed resolution
- Add translatable category to all core block plugins
- Test coverage to ensure all core blocks have a category
Translate the fallback category (module name) for other blocks
Remaining tasks
User interface changes
Before


After

All system blocks are now in translatable categories.
API changes
No.
| Comment | File | Size | Author |
|---|---|---|---|
| #31 | Screen Shot 2018-11-30 at 9.57.51 AM.png | 55.86 KB | ethomas08 |
| #22 | after-list.png | 78.57 KB | john cook |
| #22 | after.png | 186.06 KB | john cook |
| #22 | before.png | 185.34 KB | john cook |
| #6 | system-translation-3.png | 331.22 KB | dschenk |
Issue fork drupal-2500607
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
yesct commentedMaybe there is a t() missing from some?
Comment #2
yesct commentedThose two that go into Systema, have explicit category set in their annotations with @Translation
For example, in LanguageBlock.php
compare to SystemMailBlock.php
but... how does it know that is system? is system the default category?
\Drupal\Core\Block\Annotation\Block
says
which looks like it is not setting a default category...
----
Here is one not in system, just for additional comparison, SearchBlock.php:
Comment #3
axooh commented@dschenk and me are working on this, while sprinting at DrupalCon in Barcelona.
Comment #4
dschenk commentedComment #5
axooh commentedIn this patch we added the category explicitly to the corresponding blocks in the system module, to make them translatable.
Comment #6
dschenk commentedI helped in the creation of the patch.
Comment #8
dschenk commentedComment #9
maxocub commentedI was able to reproduce the issue and confirm that the patch in #5 works.
Comment #10
xjmNice find! I noticed this once before but did not track down why it was happening. The fix seems correct.
I think we could provide test coverage to this to make sure future system blocks also get the correct category. The test might load the translated admin listing, assert that expected blocks are displayed, and assert that the untranslated word "system" does not appear.
Alternately (or additionally), is declaring a block without a category even valid? Should we warn developers of this somehow?
Comment #11
maxocub commentedI think that declaring a block without a category is valid, at least that's what I understand from the default empty value in the annotation. I haven't found out why and how (and I would like know if someone can illuminate me), but when we don't declare a category, it uses the module's name.
What's happening here is that the 5 blocks from the system module don't declared a category (so it uses 'System' as a fall back), and that two blocks from other modules declared there category as 'System' and made it translatable. I think the module's name fall back is OK.
On a different note, the admin label too is optional, and it doesn't have a fall back, so when you don't declare one it stays blank. Shouldn't we use the block's ID in that case for the admin label?
Comment #13
gábor hojtsySounds like a backwards incompatible change to require categories. But fixing this problem by adding categories sounds fine. So maybe we should test that all core blocks provide a category as a best practice, but not as a requirement.
Comment #14
gábor hojtsyComment #16
maxocub commentedHere's a test to check that every core block have a category.
Comment #18
maxocub commentedHmm, it seems like my test does not catch all blocks without a category.
I guess it's because the namespaces array is only filled with enabled modules.
Is there a way to get ALL namespaces?
Comment #19
maxocub commentedHere's a way to find all block plugins: loading every (non-test) modules to fill the namespaces array.
Comment #20
maxocub commentedJust found a better way to get a list of all modules, thanks to @heddn!
Comment #21
maxocub commentedComment #22
john cook commentedI started out by testing the patch from #20 using the Korean translation.
Before:

After:


So I would say that the patch works as designed.
Then I followed the code a bit down the call stack and made a new patch. The only change is in
core/lib/Drupal/Core/Plugin/CategorizingPluginManagerTrait.php:processDefinitionCategory()where I've passed the retrieved module name intot(). This would allow all categories that haven't been set to be translatable.Comment #24
john cook commentedChanged the test to expect a TranslatableMarkup object instead of a string as default category.
Comment #25
john cook commentedComment #27
john cook commentedThe category was accidentally removed from PageTitleBlock.
Comment #31
ethomas08 commentedUploading re-rolled patch. It fixes the bug (see attached screenshot), but I haven't ran the tests to see if anything breaks. Lots of changes between 8.4.x and 8.7.x!
Comment #32
ethomas08 commentedRan tests -- the 2 that had been altered passed. All the reroll changes were the same as in the 8.4.x patch so marking this RTBC. Great job on this, looks great!
Comment #33
alexpottI'm not sure this is correct. The
@translationshould pass a TranslationMarkup object into the definition.Also we should have the test that ensures all the blocks have categories that was in #27.
Comment #41
quietone commentedThis is still relevant and the patch applies to 9.5.x.
Comment #46
mstrelan commentedSpun up an MR and started with the (slightly refactored) test from #27. Can see the test-only results at https://git.drupalcode.org/issue/drupal-2500607/-/jobs/5680572
I then applied all the same categories from the existing patches, but of course we have attributes instead of annotations now, so had to be done manually. There were some new plugins revealed by the failing test so I added categories for those as well.
Then I added in the changes to
CategorizingPluginManagerTraitandCategorizingPluginManagerTraitTest, but didn't quite follow @alexpott's comment in #33. Maybe it wasn't clear that this is a fallback, so we get the "provider" and try to translate that.Guessing the IS needs an update, maybe some new screenshots.
Comment #47
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue.
While you are making the above changes, we recommend that you convert this patch to a merge request. Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)
Comment #48
mstrelan commentedOk thanks bot. Hiding patches, even though I think they are useful for confirming that the MR is on the right track.
Comment #49
xjmAmending attribution.
Comment #50
smustgrave commentedCan we update the summary with a proposed solution.
Also this brings up a question about attributes, if we are adding a new key how do we ensure contrib/custom modules update theirs too? WOuld have to be done in the attribute itself?
Comment #51
mstrelan commentedDone
The key already exists in the attribute, but it's optional. We're ensuring all core blocks have a category set. Contrib/custom will fallback to the module name, which we're now translating. Although I was under the impression we're only meant to translate string literals, so not sure if that part is suitable. We could always deprecate not passing a category, but that could be pretty annoying.
Comment #52
smustgrave commentedDid a search for #[Block and there appear to still be other instances
Mainly test blocks, if those aren't needed can we least update the block.api
If you are another contributor eager to jump in, please allow the previous poster(s) at least 48 hours to respond to feedback first, so they have the opportunity to finish what they started!
Comment #53
mstrelan commentedI don't think we need to do the test blocks. Category is still optional, we're just ensuring core blocks set the category. I've updated the example in block.api.php
I'm still unsure about the fallback translation in CategorizingPluginManagerTrait. If we have that, why bother enforcing all the core blocks have a category?
Comment #54
smustgrave commentedidk if a good search but I looked for $definition['provider'] and didn't see any other spots that are doing translations.
Comment #55
smustgrave commentedwhat you say that's a blocker for this moving forward?
Comment #56
smustgrave commentedMR still applies and don't think my comment should hold things
Comment #58
nod_I have a problem with this line, There is not a finite amount of values for $definition['provider'] passing that through t() is not a good idea.
The rest is fine.
Comment #59
mstrelan commentedUpdated the proposed resolution to delete "Translate the fallback category (module name) for other blocks". Updated the MR as per #58.
Comment #60
dcam commentedSince the change to
CategorizingPluginManagerTraitwas reverted nowCategorizingPluginManagerTraitTestis failing.