Problem/Motivation
The _potx_find_language_names() function fails to parse LanguageManager.php in Drupal 11 due to PHP array syntax changes.
Drupal 11's LanguageManager.php uses modern short array syntax:
public static function getStandardLanguageList() {
return [
'af' => ['Afrikaans', 'Afrikaans'],
// ...
];
}
But potx's parsing logic only handles old array syntax:
public static function getStandardLanguageList() {
return array(
'af' => array('Afrikaans', 'Afrikaans'),
// ...
);
}
The parser looks for T_ARRAY tokens which are only generated by array() syntax. The modern short array syntax [] uses character tokens ([
and ]) instead, causing the parser to fail extracting language names.
Proposed resolution
Update _potx_find_language_names() to handle both array syntaxes by:
- Looking for
T_DOUBLE_ARROW(=>) tokens to locate each language's inner array - Detecting whether the inner array uses
T_ARRAY(old syntax) or[character (new syntax) - Extracting language names from both
array(...)and[...]structures
On the 7.x-3.x branch, also extract _potx_parse_php_file() as a separate function from _potx_process_file() to enable direct testing of PHP parsing logic without
duplicating tokenization code in tests.
Remaining tasks
None.
User interface changes
None.
API changes
7.x-3.x only: New function _potx_parse_php_file() extracted from _potx_process_file(). This is an internal API function for parsing PHP code.
Data model changes
None.
AI usage
AI assistance was used to generate this issue summary and to generate the fixes. Claude Code Soonet 4.5 to be more precise.
Issue fork potx-3570518
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 #2
debdeep.mukhopadhyay commentedHello @stefan.korn,
thank you for your work on the German translations.
I was able to reproduce this locally. After updating translations, the file
drupal-11.3.2.de.po does not contain the translation:
msgid "German"
msgstr "Deutsch"
Running grep "German" drupal-11*.de.po returns no result for Drupal 11, while the same translation exists in the Drupal 10.6.2 PO file.
With respect, this seems to be a missing translation on localize.drupal.org for the Drupal 11 branch rather than a code issue.
Thank you.
Comment #3
joachim namysloBasically, I can already tell you that you are welcome to write in German here. I don't know if the issue has been moved from the core, but here in the project, you can and should even write in German, because translating the user interface is a task for Drupal beginners. Carsten does the same when he replies here. Greetings from rus. If in doubt, they just want to read along, and they are welcome to do so in their native language. I don't think we have a problem here. I'll take a look at it now and then get back to you.
Comment #4
joachim namysloHallo zusammen,
ich habe mir die Mühe gemacht, das lokal in einer frischen Drupal 11.3 Installation zu untersuchen. Mein Verdacht ist, dass das Fehlen der Übersetzungen für "German" (und andere Sprachen) kein Fehler in den Übersetzungsdaten selbst ist, sondern eine Folge von Code-Änderungen im Drupal 11 Core.
Hier ist meine Herleitung:
core/-Verzeichnis nach dem statischen String liefert kein Ergebnis:grep -rnE "t\(['\"]German['\"]\)" core/-> Keine Treffer.Im Vergleich dazu liefert die Suche nach
t('Log in')durchaus Treffer. Das beweist, dass das Wort "German" im Core nicht mehr innerhalb dert()-Funktion vorkommt.core/lib/Drupal/Core/Language/LanguageManager.phpin der FunktiongetStandardLanguageList()stehen die Namen "nackt" in einem Array:'de' => ['German', 'Deutsch'],t()-Wrapper (oder ein Translation-Wrapper) verwendet wird, kann der automatisierte Parser von localize.drupal.org diese Strings nicht als übersetzbare Texte erkennen und extrahieren. In Drupal 10 waren diese Begriffe vermutlich noch an anderer Stelle im Code (z.B. in mittlerweile entfernten Formular-Definitionen) durcht()abgesichert. Durch das "Aufräumen" im Drupal 11 Core sind diese Referenzen nun verschwunden, wodurch die Strings für den Parser unsichtbar wurden.Vielleicht kann das jemand aus dem Core-Team validieren? Wenn die Strings nicht im
.pot-Template landen, können sie logischerweise auch nicht in der.po-Datei auftauchen.Hi everyone,
I took some time to investigate this locally on a fresh Drupal 11.3 installation. My suspicion is that the missing translations for "German" (and potentially other languages) aren't an issue with the translation sets themselves, but rather a side effect of code refactoring within Drupal 11 core.
Here is my analysis:
core/directory for the static string yields no results:grep -rnE "t\(['\"]German['\"]\)" core/-> No matches.In contrast, searching for
t('Log in')returns results. This confirms that "German" is no longer wrapped in at()function anywhere in the core codebase.core/lib/Drupal/Core/Language/LanguageManager.php, within thegetStandardLanguageList()method, the language names are stored as plain strings in an array:'de' => ['German', 'Deutsch'],t()wrapper or any other translation hint, the automated parser on localize.drupal.org cannot identify or extract them. It's likely that in Drupal 10, these strings were still present elsewhere in the code (e.g., in now-removed form definitions) wrapped int(), which kept them in the translation templates. With the cleanup in Drupal 11, these references are gone, making the strings "invisible" to the parser.Could someone from the core/localization team verify this? If the strings don't make it into the
.pottemplate, they won't appear in the exported.pofiles either.Comment #5
drummMoving to potx module since this currently seems like an issue with translation template extraction.
Comment #6
gábor hojtsyThis is where the standard language list PHP is parsed. Anyone want to check why is this not parsing the language names in Drupal 11 anymore? I assume there is PHP syntax changes that this code is not ready for anymore.
Comment #7
gábor hojtsyComment #8
gábor hojtsyI have a local setup of potx and I asked Claude this for demo purposes:
Answer from Claude is spot on:
The
_potx_find_language_names()function fails to parseLanguageManager.phpin Drupal 11 due to a PHP syntax change.The Problem
Drupal 11's LanguageManager.php uses modern short array syntax:
But potx's parsing logic expects old array syntax:
Technical Issue
In
_potx_find_language_names()at line 1662:The function looks for
T_ARRAYtokens, which are only generated by the oldarray()syntax. The modern short array syntax[]uses different tokens(
[and]characters), so the parser never finds what it's looking for and can't extract the language names.The Fix
The function needs to be updated to handle both syntaxes:
T_ARRAYtokens[bracket charactersThe parsing logic would need to:
array(...)and[...]structuresThis explains why potx works fine with older Drupal versions but fails with Drupal 11's modernized syntax in the core LanguageManager.php file.
Comment #10
gábor hojtsySummary from Claude that I agree with:
Summary of Changes
Problem:
_potx_find_language_names()could not parseLanguageManager.phpin Drupal 11 because:T_ARRAYtokens (oldarray()syntax), but Drupal 11 uses modern[]syntax which creates different token sequences.return [];statements).Solution:
T_DOUBLE_ARROW(=>) tokens instead of array openings. This correctly identifies inner language arrays likeregardless of whether they use
array()or[]syntax.$endboundary from_potx_find_end_of_function()already properly handles the function scope.Test Coverage Added:
testDrupal8LanguageManager- Tests oldarray()syntax with multiple languagestestDrupal8LanguageManagerShortArraySyntax- Tests new[]syntaxtestDrupal8LanguageManagerMixedSyntax- Tests mixedarray()outer with[]inner arraystestDrupal8LanguageManagerEdgeCases- Tests functions with control flow (early returns, conditionals)All 4 tests pass.
Comment #12
gábor hojtsyUpdated issue summary directly from Claude.
Comment #13
gábor hojtsyComment #14
gábor hojtsy