Download & Extend

Very fast t() for a small set of strings

Project:Drupal core
Version:6.x-dev
Component:language system
Category:feature request
Priority:normal
Assigned:moshe weitzman
Status:closed (fixed)

Issue Summary

One common need since forever is to change just a few strings on the site. For example, change 'blog' => 'journal', 'forum' => 'discussion board', and so on.

today our solution is to create a new variation on english language and transate a few strings. this results in loads of DB queries for just a small need.

this lets admin setup a $t_pairs array in settings.php which hard codes a set of string replacements. if present, t() uses this array instead of consulting the database.

note that this same technique applies to url aliases. one step at a time ...

AttachmentSizeStatusTest resultOperations
mw_5.patch1.47 KBIgnored: Check issue status.NoneNone

Comments

#1

subscribing. something like this would be fantastic for ecommerce project.

#2

Status:needs review» needs work

patch contains cruft.

I am wondering if it would be worthwhile to move the result of the variable_get test into a static var considering that t() is called very often.

#3

Status:needs work» needs review

rerolled without cruft

since variable_get() has own static, i see little point in maintaining another one just one function call away.

AttachmentSizeStatusTest resultOperations
mw_7.patch1.43 KBIgnored: Check issue status.NoneNone

#4

Rerolled without tabs.

AttachmentSizeStatusTest resultOperations
patch_104.txt1.43 KBIgnored: Check issue status.NoneNone

#5

Status:needs review» needs work

As we cache clean_url inside url() so should we cache this variable inside t(). Way, way too many calls to t() to allow for another variable_get.

#6

Status:needs work» needs review

OK, with static $t_pairs variable now.

AttachmentSizeStatusTest resultOperations
mw_8.patch1.55 KBIgnored: Check issue status.NoneNone

#7

To avoid losing a little performance for busy translated sites, could you check for locale() before checking for $t_pairs?

#8

Grumble, grumble. count is slower than empty, leaving out isset causes notices.

AttachmentSizeStatusTest resultOperations
mw_9.patch1.56 KBIgnored: Check issue status.NoneNone

#9

@sime - that would avoid one call to variable_get() which is extremely fast. no need to over engineer here.

@chx - thanks for reroll and reminder about speed.

can someone please test this and move along to RTBC is you are satsfied. in order to test, just uncomment the t_pairs item and $conf lines in

#10

mw_9.patch has 2 side-effects.

1. If you set any pair in t_pairs then you cannot translate anything else because it returns the preset value or the untranslated $string value.
2. Placeholders(@count, ...) do not work.

I have attached a new patch that avoids these side-effects.

AttachmentSizeStatusTest resultOperations
mw_10.patch1.61 KBIgnored: Check issue status.NoneNone

#11

Great idea, this would also be fantastic for buddylist module. I can't see any functional problems with the latest patch.

Small semantic note: should 'else if' be 'elseif'? Other than that great.

#12

Status:needs review» needs work

Yeah, a couple things...

  • else if needs to be elseif.
  • comments need to wrap at 80 chars.
  • "t_strings" is not a good name for this variable... unlike "site_name" and "theme_default" which are very intuitive, "t_strings" provides no indication of what that variable is for (the vast majority of Drupal users know nothing of the t() function). How about something like 'custom_text' instead?

#13

That having been said, a huge +1 for this functionality! :)

#14

I aggree that t_pairs is not descriptive enough. custom_text may be a better choice but I would like to see a variable name which indicates that it holds translations. I cannot find a good name right now but it should be something like custom_translation. And one thing that you may not notice is settings.php file must be edited with a UTF-8 capable editor. We might put a warning before the $conf array.

BTW, I was trying to add sample translations into the settings.php for two languages and I think this is not a good way to do this. The array structure and => operator is not so easy and people can break their site. Can we provide the same functionality in an easier way?

I couldn't tested the attached patch, I apologize if it does not work.

AttachmentSizeStatusTest resultOperations
translation_override.patch2.18 KBIgnored: Check issue status.NoneNone

#15

I put a warning in the settings.php file but I forgot to save it using utf-8 so you can see ? characters in the sample translation.

I am attaching the same file saved in utf-8. This is one reason of why we should seek for another way of managing translation overrides.

AttachmentSizeStatusTest resultOperations
translation_override_utf8.patch2.18 KBIgnored: Check issue status.NoneNone

#16

OK, i will move the customer UI for this out of settings.php and into a regular form in the Admin section. Makes no difference to Drupal performance wise. This also makes the naming of the variable a lot less important, and also the UTF8 issue goes away.

Note that this is not to be used in combination with regular translation. It is a very fast customized English. Thats all. If you want your site in another language, you use the usual .po => database way.

#17

Status:needs work» needs review

I agree that this functionality may be limited to English to keep it simple and fast. It doesn't help that much for other languages. If we all agree on that this functionality is only available to English, than it is OK to use settings.php, but don't use 'en' key since it is confusing.

I created a new seperate code region in settings.php for string override. Please review the patch.

AttachmentSizeStatusTest resultOperations
custom_texts.patch1.95 KBIgnored: Check issue status.NoneNone

#18

Status:needs review» needs work

This is getting _really_ pedantic now, but "texts" is not a proper English word; it should be just "text" and be referred to in singular rather than plural.

I would re-roll myself but am juggling 200 things atm.

#19

Status:needs work» reviewed & tested by the community

in my english, and in google's, there are acceptable uses for the word' texts'. i don't see much value in downgrading patches because of such a minor thing. if you are willing to reroll at same time, then sure.

i like this most recent approach by erdemkose. i hope to review it soon, though i'd be quite happy if others did that first.

#20

Status:reviewed & tested by the community» needs review

#21

Here's a reroll that uses "$custom_strings" rather than "$custom_texts" and clarifies a few of the code comments.

AttachmentSizeStatusTest resultOperations
patch_111.txt1.98 KBIgnored: Check issue status.NoneNone

#22

Fix a missing period in a comment.

AttachmentSizeStatusTest resultOperations
patch_112.txt1.98 KBIgnored: Check issue status.NoneNone

#23

+1 for the functionality, it adds some interesting options.

However, I'd like to be able to use it for other languages.

My use case for this: small site, not English, limited functionality for site visitors, when you only need to use a small number of translated strings. I'd like to be able to save all the performance cost that locale module introduces, and wouldn't mind about some English strings for site admins only.

So why don't we forget about checking for 'English', and better, use some variable like "custom_strings_$language->language" ??

#24

Rerolled to remove offset.

AttachmentSizeStatusTest resultOperations
patch_117.txt1.98 KBIgnored: Check issue status.NoneNone

#25

@moshe: You said you would move the customer UI for this out of settings.php to a form. Did you had time to work on this? I'm very interested in that feature and would like to provide help.

#26

I did not try to make a form for this. I don't think it is really needed, but it wouldn't hurt either. Meanwhile, the patch should not wait.

#27

Status:needs review» reviewed & tested by the community

I just tested this again. RTBC.

#28

Just reviewed the patch. Seems like a rather hackish way to speed things up... But I don't know a better way if you are into getting rid of locale module in your project. I don't see a reason not to support Jose's ideas here, although it is a very small segment, where you set up sites with a really dumbed down Drupal (like a small forum site or something), and need translation that way.

Modified patch attached (although not tested). It should have very similar performance impacts on both English and foreign language sites as the patch before, we just cache the strings in a two dimensional array. I also modified the variable naming, so developers know what the heck are those custom strings.

Handing to Dries for decision, as I am not entirely confident that this feature should be in Drupal.

AttachmentSizeStatusTest resultOperations
quickt.patch2.05 KBIgnored: Check issue status.NoneNone

#29

A big +1 for this patch. Like path aliasing, it's a potential performance hot-spot. Giving developers and site maintainers the ability to 'fast-track' specific t() strings is an important improvement.

#30

Status:reviewed & tested by the community» fixed

OK, read through the all the support notes on the patch, simlified my last version, and landed that patch in core. Now t() caches in one associative array, because it has no notion of translating to multiple languages in the same request (yet), so that change should be for a different (larger scale) patch. Thanks to everyone who participated.

http://drupal.org/cvs?commit=66313

#31

Status:fixed» closed (fixed)

#32

Ooh! I just came across this. Thanks everyone.

How many strings is "a small set of strings"?

#33

you can put in hundreds of strings. More if your memory is widely available. i just said small because if you want a lot, you might prefer the user experience provided by a po editor and the usual locale stuff.

#34

The locale module working with the SQL backend was also improved lately, so there is a smaller cache used and the lookups are quicker (we look at smaller data sets too in the database). :)

#35

subscribe

#36

Hi,

I've created a 5.x version of this patch, since I needed it.
Is anybody interested?

Basically, in common.inc, DELETE:

if (function_exists('locale') && $language->language != 'en')

And put this instead:

  static $custom_strings;
  if (!isset($custom_strings)) {
    $custom_strings = variable_get('locale_custom_strings_en', array());
  }
  // Custom strings work for English too, even if locale module is disabled.

  if (isset($custom_strings[$string])) {
    $string = $custom_strings[$string];
  }

  // Translate with locale module if enabled.
  elseif (function_exists('locale') && $language->language != 'en') {

Then, in your settings.php, you can have:

$conf['locale_custom_strings_en'] = array(
   'Email this page'      => 'Email',
   'Add new comment'      => 'Discuss',
   'Add new comment'      => 'Discuss',
   'Best published scoops' => 'This week\'s highest ranked',
   'Best upcoming scoops' => 'Highest ranked upcoming',
);

Since I don't think there will be D5.4, I am not bothering with a patch. But, the good thing about this change is that it will be compatible with D6... so, feel free :-D

Bye,

Merc.

#37

Version:6.x-dev» 5.x-dev
Status:closed (fixed)» needs review

Bump. Can the above make it into the next 5.x release?
With the 6.x code committed, this backport would allow many of us who will continue to follow 5.x on production sites to officially begin to use a feature that 6.x will continue to support, rather than use locale hacks (or worse) just to change a few strings.

Yes, I realize it's a simple change and we could roll our own, but some of us work in production environments where core patching isn't allowed unless critical or security related.

#38

Version:5.x-dev» 6.x-dev
Status:needs review» closed (fixed)

Features are not added to stable releases.

#39

Hi,

Also, my patch above (which I use and I consider absolutely necessary to my Drupal installation) is just not quite production-ready... You'd need to make it a little configurable (that variable_get('locale_custom_strings_en', array()); is an eyesore) etc.

It's not really worth it, with D6 coming out soon... But it's cool to have it nevertheless :-D

Merc.

#40

Moshe pointed me to http://drupal.org/project/stringoverrides which implements this for 5.x

#41

Hi,

sethcohn, moshe:

*** WOW ***

What a fantastic module!

Merc.

#42

Title:Very fast t() for a small set of strings» Very fast t() for a small set of strings - Does not work on multi install

Hi,

On a multi install Drupal 6 strings are changed on the second installed website but not on the first one, anybody has met this trouble ?

Thanks.

#43

Any idea why changing stirngs in settings.php doesn't work on multi install websites ?

Thanks.

#44

@wwwoliondorcom I tried this on a basic installation in 6.14 with two sites and it worked as I expected. i.e., only changed on one site. One idea is to make sure you're adding it to the correct settings.php file.

Since settings.php files are specific to each site on a multi-site install, it'll only affect one at a time. To affect them all, you'd have to edit each settings.php file.

#45

Thank you, but I tried any possibility, and even when changing both Settings.php it still doesn't work on SOME of my multi installs, but working on others.

I don't know where to look now.

Thanks again.

#46

Hi,

So nobody has met the same problem as me on a multi install Drupal 6 ? (only one website translates)

Thanks.

#47

Title:Very fast t() for a small set of strings - Does not work on multi install» Very fast t() for a small set of strings

@wwwoliondorcom - please use a new issue or support forum for your question. this issue has been completed.

nobody click here