Problem/Motivation
Now, when we try to pass a constant to the t() function, the code sniffer shows the warning:
Only string literals should be passed to t() where possible
But, as for me, using a constant is also ok, it's the same as a string literal.
Using constants is very convenient when we have several places to insert the same text: with constants, we can just put it once in a constant, and reuse it in all needed places, especially in different classes.
So, maybe we can find some way to allow this?
The current workaround to dismiss the warning is to use // phpcs:ignore or @codingStandardsIgnoreStart / @codingStandardsIgnoreEnd tricks around the t() call.
Steps to reproduce
1. Get the code like this:
define("ALIAS_RULES_DESCRIPTION", "Alias should start with /");
$description = $this->t(ALIAS_RULES_DESCRIPTION);
2. Run the code sniffer and see the warning.
Proposed resolution
Try to detect if there is a constant passed, and if so - dismiss the warning.
Remaining tasks
User interface changes
API changes
Data model changes
Issue fork coder-3326197
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:
- 3326197-allow-constants-in-t
changes, plain diff MR !22
Comments
Comment #2
murzCurrently we have this code, that do this check, in the file
coder_sniffer/Drupal/Sniffs/Semantics/FunctionTSniff.php:Any ideas on how we can add here the detection of constants?
Comment #3
murzI've found a way via allowing also
T_STRINGargument type, via this change:It works well, and if I'm trying to pass a string with a inline variable like
"foo $bar"- the argument type is T_DOUBLE_QUOTED_STRING, so it still works well for such case.Could anyone check if this is a suitable fix, or it can also allow some "bad things" to pass?
Comment #5
klausiI think we can do this - although it is still not ideal to have translatable strings in constants in Drupal. Then you have the same problem again that translation extraction tools cannot find it in source code. I'm not sure if those extraction tools are still widely used, so I'm fine with relaxing this check.
Can you file a pull request against https://github.com/pfrenssen/coder and add a test case?
Comment #7
murzHere is my PR in GitHub tracker: https://github.com/pfrenssen/coder/pull/182
Comment #8
murzI've fixed all remarks by comments in the PR https://github.com/pfrenssen/coder/pull/182 - please review.
Comment #9
murzComment #12
klausiMerged, thanks!
Also pushed a small follow-up to fix spacing in the test.
Comment #13
penyaskitoThe main reason coder complained about constansts in t() was because potx cannot parse those.
potx is still relied by lots of people, and has no other solution solving that problem space in Drupal AFAIK.
localize.drupal.org relies heavily on potx for core and contrib modules translation, so I'd expect to have this rule still in coder.
If it's really gonna be removed, because of that impact, I'd hope it wouldn't happen in a minor release, and that's there some communication around it aside of release notes.
Comment #14
klausiThanks for checking in here! Hm, there is certainly a tradeoff here. In private projects it is fine if you use constants in t() when you don't use the potx extraction tools. When you use the same string multiple times a constant is also super helpful so that you don't have to maintain the same string in multiple places.
But maybe then private projects should simply disable this sniff if they want to use constants. I'm open to revert this change. Do we see public contrib projects often use constants where Coder should throw an error? Let me know if you have some examples!
Release policy: relaxing or hardening a sniff is perfectly fine in a minor/patch release of Coder (we are not fully following Semver regarding minor/patch releases yet for historic reasons). I would never make a major release because of tweaking a sniff.
Leaving this as active for now for more feedback.
Comment #15
penyaskitoSadly we can't (or I don't know how) search on drupalci reports to find how often this happens.
But if I search "Only string literals should be passed to t() where possible" on d.o issues I find several issues yet from 2022 or 2023.
Most of them are from patches/code from new contributors, but also found some instances from experienced contributors (not linking because there's no need of public pointing anyone).
But I agree with reverting this. Specially since it's a warning and afaik we can ignore it with
// @ignoreif you really need it.Comment #16
murzYeah, the potx issue seems an important reason to revert this, didn't know about this. Thanks for the investigation!
But maybe there are chances to improve/fix this on potx side? If no - seems yes, we should revert this.
But for me - using constants for repeatable strings is a very convenient tool, because in many contrib modules, and even in Core I see a lot of repeatable strings, and sometimes they should be the same but differ just because of paraphrasing or some punctuation, as result we have several almost equal strings in translation queue instead of one. So, the constants approach for translation strings should minimize such cases.
Comment #17
penyaskito@Murz: If you need
then better use
This limits you to use constants in classes which I'm guessing that's what you are looking for.
Potx situation won't change. For being able to parse strings in variables on t(), you'd need to execute the code (as this strings might have operations, concatenations, etc on them) and aside of the complexity of that, that would mean a security risk on localize.drupal.org.
Comment #18
murz@penyaskito, I need something like this:
So, I want to have the message text only in one single place, not the 3+ duplicates of it, where it can be typed differently like this:
in result, giving 4 almost the same strings in the translation queue.
So, the approach of defining the message text in a const variable to reuse in many places looks very convenient.
And replacing it with something like this:
looks much worse! At least, because it will require always passing the ModuleController as a dependency to the each class where we need this string.
Comment #19
murzAnd about potx - maybe we can extend it via catching constant values for translating, that are described via specific annotation tags like this:
We already have something similar in plugin annotations:
So, this approach will not require executing the code to get strings for translation, just a simple parsing should be enough.
What do you think about this approach?
Comment #20
penyaskitoYou can always use the "D7 features" approach:
You have an unused t() somewhere to ensure potx finds it, and then ignore the rest.
For new formats and parsers, better to discuss in potx queue itself.
Comment #21
klausiOK, since Murz also agrees that we can revert this I think we can go ahead with the revert before the next release. As the potx parsing is much harder to fix people should make an exception in their phpcs.xml config if they would like to use constants as Murz proposed.
Comment #23
klausiRevert pushed! Thanks both of you for your thoughtful comments.
Comment #24
klausiForgot credits for penyaskito, added now.
Comment #25
klausiComment #27
murzTo move on I created a feature request in the potx module: #3392795: Extract translatable strings from constants with @translation tag