Closed (fixed)
Project:
Translation template extractor
Version:
6.x-3.0
Component:
Code
Priority:
Normal
Category:
Support request
Assigned:
Unassigned
Reporter:
Created:
27 Aug 2009 at 16:33 UTC
Updated:
21 May 2010 at 14:30 UTC
This warning:
The first parameter to t() should be a literal string. There should be no variables, concatenation, constants or other non-literal strings there. At t($item['link_title'],array('!name'=>$name,'!realname'=>$realname))...
Should just be 'info' and not 'warning' because first argument to t() can be a variable. See line 496 and 499 of menu.inc:
if (!$link_translate || ($item['title'] == $item['link_title'])) {
// t() is a special case. Since it is used very close to all the time,
// we handle it directly instead of using indirect, slower methods.
if ($callback == 't') {
if (empty($item['title_arguments'])) {
$item['title'] = t($item['title']); //<<<<<<<< HERE
}
else {
$item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map)); //<<<<<<<<< AND HERE
}
}
it calls t($item['title']). I'm doing the same for my menu_link and get this warning message.
In most case, this warning is correct but for menu, link titles are stored in database so we can't call t() with constant. I wonder if you can reword this message to say in case like this, calling t() with a variable as first argument is okay.
Comments
Comment #1
gábor hojtsyThe link that is included with the error message explains this in more detail. Basically, if you translate this elsewhere and the text is not user input, then it is fine to do it this way. A static code analyzer obviously cannot tell whether your variable is user input. It might be :)
Comment #2
martin_qI've just been faced with a screen full of these errors. Unfortunately, the checks are too simplistic, as they are throwing up ugly red warning messages for some usage which is completely legal. I use logic to decide between a handful of literal strings which I put in a variable, then use t() on that variable - along with an array to replace the placeholders in the literal strings.
My code is neater, cleaner and shorter by doing it this way. It definitely does not contravene the practice of using t() only for hard-coded strings. So I do not wish users of the module to risk seeing all these horrible warnings.
Can they be taken away again, please? Thank you.
Comment #3
gábor hojtsy@martinquested: please explain how do you expect a static code analyzer to extract your translatable strings with the coding style you use. If I understand it right, it is something like:
Please elaborate on how can this code be parsed for translatable strings without running the code itself?
Comment #4
martin_qHi Gabor,
I don't expect a static code analyser to be able to handle this kind of thing successfully. I think it would therefore be better not to run an over-simplistic check at all.
I guess I feel that this kind of warning belongs in the documentation, not in a module which takes upon itself the responsibility/right to offer feedback other modules' code, whilst not being in a position to do this in a sufficiently sophisticated way. I know there have been serious problems with modules using t() incorrectly, but I struggle with this solution, seeing as how it gives big red error reports, potentially on a production site, about someone else's code that does not contain errors. That's sorta mean! :)
I apologise that my original message is somewhat terse.
Martin
Comment #5
gábor hojtsy@martinquested: this same module is used to generate .pot files for translations which are used by translators to translate your modules as well as feeds the data to localize.drupal.org based on parsing your module source code. If this parser cannot identify those strings as translatable, nobody will be able to pre-translate them using our standard Drupal tools. Since Drupal will only ever find these strings as translatable when certain conditions match, not even a running Drupal site will be able to achieve 100% translation coverage of your module. Since your code style makes portions of your module impossible to pre-translate and very hard to translate on a live site, the warning informs you that you'd better change your coding style.
Comment #6
martin_qAnd suddenly the penny drops. Of course, I had forgotten about the .pot generation, and hadn't sufficiently thought about how it would work. I had previously thought this was just about preventing misuse of t() with user-configuarable texts, whereas in fact it is much more fundamental.
You are right, and I am wrong. Thank you for your patient explanation.
I shall change my code.*
Martin
*But not my coding style! Doing this will require the use of less efficient code, which will be a concession - willingly made now - in order to make other things work. :P
Comment #7
gábor hojtsyRetitled, marking as solved support request.