Problem/Motivation

There's many places in core where t() function is used in classes without dependency injection.
It makes this classes hard to unit test because t() defined in core/includes/bootstrap.inc
Also it makes harder to get rid of this include in later core

The sniff is already enabled for Plugins, in phpcs.xml.dist

  <rule ref="DrupalPractice.Objects.GlobalFunction">
    <include-pattern>*/Plugin/*</include-pattern>
  </rule>

Proposed resolution

Replace usage with one of following ways
- $this->t() for controllers using StringTranslationTrait or add if it's missing
- new TranslatableMarkup() in static methods

Remaining tasks

Final issue to enable the sniff and fix any remaining problems.
#3507043: Enable DrupalPractice.Objects.GlobalFunction

Cleanup

#3133726: [meta] Remove usage of t() in tests not testing translation

User interface changes

API changes

no

Data model changes

no

Release notes snippet

n/a

CommentFileSizeAuthor
#10 3113904.patch401 bytesalexpott

Comments

andypost created an issue. See original summary.

prabha1997’s picture

Assigned: Unassigned » prabha1997

I am working on this issue

prabha1997’s picture

Assigned: prabha1997 » Unassigned
alexpott’s picture

I disagree with the scoping here. The scope here should be to replace t() with $this->t() where that is available. For all of core. Breaking this up into a module by module feels like it will create a lot busywork for reviewers and committers. Let's roll all the sub issues up into this one. And then we can worry about the rest of the calls to t() from classes where we need to consider dependency inject etc.

alexpott’s picture

We also need to make a decision about whether we should only use the StringTranslationTrait or extend from ControllerBase. I'm not sure but I think we need the answer before we progress on all the issues here.

xjm’s picture

Note that replacing the same things on a per-module basis is explicitly disallowed by our scope guidelines. https://www.drupal.org/core/scope explains considerations for scoping these large changes.

If the patch would be too large or complicated as one thing here, we should group the replacements by concept instead. In this case, this would be the pattern of usage: Is the trait already available? Which base class is extended? Etc.

See https://www.drupal.org/core/scope#fix-scope for how to fix the scope of these sub-issues. Please mark them as duplicates and transfer issue credits for them over here. The usages should be audited for the presence or absence of the string trait instead.

andypost’s picture

use the StringTranslationTrait or extend from ControllerBase
That's the blocker, because it affects maintenance
- Extending from base classes bounds to constructors inheritance
- Using trait for t() looks more efficient for contrib
- OTOH new TranslatableMarkup(...) is the most straight-forward instead of "magic T"

From the last point following a question about usage in tests - @alexpott mentioned some issue about test config form which could be great example to copy/paste
but we got agreement to not use t() in tests (separate clean-up)

EDIT #3109743-14: t() calls should be avoided , use $this->t() instead in Config module

alexpott’s picture

@andypost controllerbase has no constructor.

alexpott’s picture

So I think we need

  • an issue fixing all the simple ones
  • Then separate issues for the more complex grouped by type.
  • And we also need an issue to enable the coder rule so we don’t introduce new usages of t()
alexpott’s picture

StatusFileSize
new401 bytes

Here's a patch that enables the sniff. The end goal has to be to commit a patch containing this sniff so we know that we'll not introduce anymore in core.

alexpott’s picture

Note I think we'll need to address t() in tests to order to do this. Or maybe we need to update the rule to have an option to ignore tests.

cilefen’s picture

Just FYI there are a number of sub-issues that don't list this as a parent.

andypost’s picture

Quick numbers of usage t(
- 295 in *Form.php
- 45 in *Controller.php

swatichouhan012’s picture

I tried to cover all t calls() in form and controller here wrt scope, kindly review.
https://www.drupal.org/project/drupal/issues/3116874

xjm’s picture

Thanks @swatichouhan012, that's a better approach than per module. I think we should split it a bit more though. As I said on that issue:

  1. Form builders (which inherit the trait from their base class)
  2. Controllers that already have the trait available.
  3. Controllers that do not have the trait available.

A fourth category is just simply removing t() calls from tests, as per: https://www.drupal.org/docs/8/testing/phpunit-in-drupal-8/phpunit-browse...

I've closed most of the per-module children as duplicates. Let's get consensus on the parent here before proceeding with the rest of the children.

andypost’s picture

Then goes plugins and services

Also while it happening some places could use new TranslatableMarkup() instead of trait

andypost’s picture

Can't find the issue about usage in tests - policy, it was about providing testing modules with t() property used to make copy/paste less buggy

Another related here is #1532612: Move Examples Project into Drupal core

xjm’s picture

Version: 9.0.x-dev » 9.1.x-dev

 

joseph.olstad’s picture

Please forgive me for thinking out loud and having an opinion on this, I know that all of you are working very hard on core and doing a lot of great work. However I've noticed a lot of convenient drupalisms disappear since Drupal 7 and this initiative has started to 'leak' into contrib and I'm looking for the rationale behind this initiative because t() is extremely widespread in it's usage. My inner child cries at the thought of thousands of modules going through yet another sort of a 'purist' cleansing initiative, I would like to follow the links to the rationale for pushing this into contrib?

Costs related to disrupting contrib with t(); "cleansing":
touching thousands of modules of code, subject to human error and also to custom code outside of contrib.

None of us are machines, we are humans and creatures of habit. Microsoft of all companies understood this since the 1970s when they introduced BASIC and made variants for all the computer platforms. Simple BASIC programs could work on several platforms, this was why Microsoft was propelled into billions and billions of dollars in revenues. Later in 2001 even their MFC (microsoft foundation classes API) has gone through relatively slow evolutionary changes, except once when they introduced major disruptions in 2001 and 2002 shifting to the .NET framework but they did make a very good effort to attempt to minimize the API changes and make the transition as smooth as possible.

frameworks like Django have promised API stability and forward compatibility(lmgtfy). Why is this important?

So far I have only heard promises of removing deprecated apis, how about promises to only deprecate when absolutely necessary?. (and rationale based on actual performance profiling tests to prove that there is a performance gain and that the gains are greater than the costs)?

I'd rather see real solutions, what is the actual problem that we trying to solve here other than to create disruption and introduce new human errors and disrupt contrib?

If we remove all the drupalisms in Drupal then maybe eventually it becomes something other than Drupal?

dww’s picture

@all Re: t() in tests. Now tracked in this child issue: #3133726: [meta] Remove usage of t() in tests not testing translation

@joseph.olstad re: #19: Yes, it's a big undertaking. Yes, it's error prone. But it's not just for the sake of making busy work and inconveniencing module maintainers. Please read the first 3 sentences of this issue summary:

There's many places in core where t() function is used in classes without dependency injection.
It makes this classes hard to unit test because t() defined in core/includes/bootstrap.inc
Also it makes harder to get rid of this include in later core

Are those reasons enough for all the work and effort that will be required? I'm not sure. Is this "technical debt" more expensive to the project as a whole than the vast hordes of known bugs that are languishing in the queue for years (most of which are already fixed, but haven't been committed since we require tests for every bug fix)? Almost certainly not. Will Drupal promise to "only deprecate when absolutely necessary"? No way. What can you do about it? Put your energies where you think they should go, and hope that they are well received. That's all any of us can do. /shrug

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

andypost’s picture

longwave’s picture

Closed a number of child issues as duplicate because they were scoped by module, and that approach was already rejected by core committers.

mradcliffe’s picture

Most of the forms in form_test module use t() directly rather than $this->t().

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Component: language system » other
Issue summary: View changes
Issue tags: +Coding standards

Gather the issue working to fix t() in one place, tag for Coding standards, update the IS and move to the 'other' component.

quietone’s picture

jonathan1055’s picture

Adding parent because this is fixing a DrupalPractice rule

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Issue summary: View changes
quietone’s picture

Issue summary: View changes
quietone’s picture

quietone’s picture

Issue summary: View changes
quietone’s picture

Status: Active » Fixed

Yay! All the child issues are fixed.

And related to this I made a Coding Standards to discuss making it a standard the t() is only used in tests for testing translations. #3508485: Discuss t() in tests

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.