Background / motivation

Many implementations of hook_update_N() and hook_install() in contrib and core modules in D7 and D8/D9 contain calls to the t() function. In general, I think it is considered a "best practice" to use t() for all kinds of strings that will be displayed to any user unknown to us.

For custom site-specific modules, I often avoid the t(), if I know that the message will never be shown to anybody outside the developers. This applies especially to hook_update_N() and hook_install(). Sometimes I use format_string() instead, to get the replacement without the translation.

My own motivation is like this:

  • I don't want these one-off strings to pollute the database and the translations UI. (not sure under which circumstances this would happen)
  • The audience of an update hook is a small team of developers and devops, who are used to code comments written in English.
  • I want the original English message to appear in logs, UI and CLI output, and in copy+paste snippets sent around between developers.
  • I want developers / site builders to always see the same string.

Personally, I sometimes even go further, and don't use t() for names of custom field formatters, plugins etc.

I have a colleague who is not convinced by my pragmatic arguments, and wants to do things "by the book". He places high value on consistency, and wants to use t() everywhere.

Perhaps one argument in favor of t() is that it would make it easier to later copy parts of the code into a contrib or in-house module, without having to modify all the strings. Not very likely for a typical hook_update_N(), but the possibility exists.


Can it be "acceptable" as a team policy to not require t() for strings with an "internal" audience?

In which cases could it be acceptable to not use t()?

Is there any convention or good reason we could use to decide this, beyond personal preference?


There are some more specific questions hiding in the original question. I am putting these in a section clearly marked as "EDIT" to not be accused of a Heisenberging.

In which cases could it be acceptable to not use t()?

Specific cases which could be discussed:

  • Messages returned from hook_update_N().
  • Exceptions which are thrown in hook_update_N() on failure. (#817160 suggests to NOT translate exception messages.)
  • Names of field formatters and other plugins defined in custom modules. An argument could be made that original names should not be translated.
  • (watchdog() / Drupal::logger() calls are mentioned in a comment, but I am less interested in those atm)

The arguments for/against apply differently to these cases.

  • 2
    I don't want these one-off strings pollute the database and the translations UI These will only get added until someone attempts to see the page that contains those t() strings in a different language. See Why is an untranslated string not showing up?.
    – No Sssweat
    Nov 5, 2020 at 6:08
  • For the database pollution, isn't there also a mechanism that detects t() calls by looking directly at the code? I think it only looks at specific files, I don't know if *.install is one of them.
    – donquixote
    Nov 5, 2020 at 10:59
  • isn't there also a mechanism that detects t() calls by looking directly at the code? possibly, but I don't really know the answer to that. You'll have to test it out, but my guess would be no with .install.
    – No Sssweat
    Nov 5, 2020 at 11:09
  • 2
    By the way, for watchdog known as Drupal::logger in D8 & D9. you don't pass t() to it as it automatically does the translation on output. See Watchdog and translations
    – No Sssweat
    Nov 5, 2020 at 11:14

1 Answer 1


Ever hear the expression "You Play Like You Practice"? If you get in the habit of NOT using t() for strings that are translatable just because it's only for your site ("practice"), then when it counts (i.e. "play") you will probably also leave out t(), because that's what you're used to.

There is really no downside to doing it correctly here. You're not saving anything or making any measurable difference in performance. The upside is that if you do it the same everywhere, you're not going to introduce a bug by leaving off t() where it is needed, and you can then also use the automated coding standards tools to check your code without seeing a lot of fails from your missing t() functions - that keeps these many fails from obscuring the few real problems you might have.

  • 3
    Nice slogan, "You Play Like You Practice".
    – donquixote
    Nov 5, 2020 at 10:58
  • Perhaps different arguments apply to plugin names, e.g. field formatters or custom views plugins. If people view those in a different language, the English name might still be preferable because it is more recognizable.
    – donquixote
    Nov 5, 2020 at 11:12
  • I am accepting this answer, but I also welcome others who want to share their own thoughts or go into more detail case by case.
    – donquixote
    Nov 6, 2020 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.