_locale_rebuild_js doesn't store plural forms correctly
Pancho - September 10, 2008 - 23:10
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | locale.module |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | needs work |
Description
If Vertical Tabs is installed, attaching a file (via the core Upload module) to a node screws up the node edit form.
Not only the fieldgroups aren't rendered as Vertical Tabs, they are not shown at all (except for the troublemaker "File attachments"!). Plus: editing and saving now empties all affected fields including "author", "URL alias" and all publishing options, so the node gets unpublished.
For some strange reason this happens 10 times, and is consistently reproducible (upload file => problem, delete file => okay again,...) and then suddenly it works correctly several times. Can anyone else reproduce this bug?

#1
I suspect this is the same problem as #297507: validation error causes vertical tabs to disappear, where Vertical Tabs was using #after_build to add the JavaScript to the page. Since #after_build functions are not called when validation fails or when rebuilding a cached form, I suspect this was the problem. Vertical Tabs now used #theme, which consistently rendered.
#2
Moving to fixed, as I believe this problem was fixed in #297507: validation error causes vertical tabs to disappear, please reopen if it still has the problem.
#3
Automatically closed -- issue fixed for two weeks with no activity.
#4
This bug is yet present in 6.x-1.0-beta3 version. Upload file corrupts tabs display and fields values ("author" to anomymous, etc... node gets unpublished).
#5
+1, the bug is still present on last version (beta 3).
#6
This is likely due to a bug in the JS translation parser.
<?php// In function _locale_rebuild_js
if ($data->plural) {
// When the translation is a plural form, first add it to another array and
// wait for the singular (parent) translation.
if (!isset($plurals[$data->plid])) {
$plurals[$data->plid] = array($data->plural => $data->translation);
}
else {
$plurals[$data->plid] += array($data->plural => $data->translation);
}
}
elseif (isset($plurals[$data->lid])) {
// There are plural translations for this translation, so get them from
// the plurals array and add them to the final translations array.
$translations[$data->source] = array($data->plural => $data->translation) + $plurals[$data->lid];
unset($plurals[$data->lid]);
}
else {
// There are no plural forms for this translation, so just add it to
// the translations array.
$translations[$data->source] = $data->translation;
}
?>
As you can see, the source for plurals is thrown away, instead an array "singular" => "singular", "plural1", ... is formed.
This means we get the following example array in Drupal.locale.strings:
"1 attachment": [ "1 bijlage", "@count bijlagen" ]Now:
For a singular, Drupal.formatplural will return Drupal.t(singular, args);Drupal.t then fetches the array:
if (Drupal.locale.strings && Drupal.locale.strings[str]) {str = Drupal.locale.strings[str];
}
And tries to replace @count:
str = str.replace(key, args[key]);As str is an array, this fails and all JS dies :(
For a plural, there won't be a string in Drupal.locale.strings (via
return Drupal.t(plural, args);)The bug is rare due to another bug: #532512: Autodetected plural strings are stored as singular; it only occurs for imported translations.
#7
Promoted.
#8
Hi there,
will this be solved for D6?
The solution I've used (not very elegant...) was to replace :
str = str.replace(key, args[key]);by
function is_array(input){return typeof(input)=='object'&&(input instanceof Array);
}
if (is_array(str)){
var n = str.length;
for (var i=0; i<n; i++){
str[i] = str[i].replace(key, args[key]);
}
}else{
str = str.replace(key, args[key]);
}
in misc/drupal.js
I think too that plural/singular distinction must be handled before a string can be manipulated.
Regards,
cfab
#9
I'm not sure this is the right approach. Another approach would be to duplicate a part of t in Drupal.Plural so it doesn't call Drupal.t anymore.
#10
The last submitted patch failed testing.