Sod translators, abuse t()

Not all CVS application reviews result in a decline of the application. Many get through even though it contains some "bugs". Here's an example that is in some sense classic.

Lets look at a snippet...

  1. $warning = variable_get('foo_warning', NULL);
  2.  
  3. $tokens = array<(
  4.   '%user' => $account->name,
  5.   '!edit_url' => url('user/'.$account->uid.'/edit',array<('absolute'=>TRUE)),
  6.   '%expiry_date' => date<("F j, Y", $expiry_date),
  7.   '%days_left' => round<(($expiry_date - $today[0]) / 86400),
  8. );
  9.  
  10. // ... and then
  11.  
  12. drupal_set_message(t($warning, $tokens), 'warning');

So, what's the problem here? Well, it's in the use of t()< or abuse of it I should say. The translators function t() is designed so translators can extract the fixed strings and provide a translation. $warning passed to t() here is clearly a variable and not a fixed string. This will cause the string extractor that translators use to bork on this and render this module pretty much untranslatable. If a translator can't use their tool to get the strings then they'll soon let you know in your issue queue :)

So, what should have been done? Well, PHP's str_replace()< could be used to manufacture your own token replacement system or, better still, there is a module designed to help out with tokens. The token< module is a better choice.

Update: here's a similar mistake on the above that came in recently...

  1. $text = 'Added %count new stories from the feed.';
  2. drupal_set_message(t($text, array<('%count' => $i, 'error')));

Again, $text cannot be translated and additionally there's a bug. Why is 'error' a parameter to t()< when it should be a parameter to drupal_set_message()<?

Update: and here's yet another recent entry into the abuse t() hall of shame!

  1.   drupal_set_message(
  2.     t('Order #' . $order_id . ' updated to status: ') .
  3.     $new_status
  4.   );