This issue is a bit odd to explain, and it might belong in the Panels queue. I'm going to bring it up in #drupal-views again today.

Using i18nmenu, we expect to be able to translate menu items and have those translated titles rendered appropriately. However, it seems that Page Manager (CTools, Panels 3) disables this feature by passing a blank menu title to t(). Panels later changes the page title manually with drupal_set_title().

To try to make Panels correctly display translated titles for menu items it controls, I wrote the following code. And I wonder if this is the right approach, of if there is something in the i18n suite that I just missed or failed to understand.

Essentially, I had to rewrite theme_menu_item_link() in order to ensure that translations were applied. I also use hook_ctools_render_alter() to affect the proper page title.

Note: this does not handle the translation of content on the Panel page, which is a separate issue.

/**
 * Implement hook_theme_registry_alter().
 *
 * Make menu translations work correctly for i18n, Panels and Views.
 */
function custom_theme_registry_alter(&$theme_registry) {
  if (module_exists('i18nmenu')) {
    $path = drupal_get_path('module', 'custom');
    $theme_registry['menu_item_link']['function'] = 'custom_menu_item_link';
  }
}

/**
 * Alter the way that menu links are handled.
 *
 * This function ensures that menu items are translated correctly. Two big
 * notes: 
 *
 *   1) Only works on menu items!
 *   2) Does not work on items in the 'Navigation' menu!
 *
 * This requires the i18nmenu module.
 */
function custom_menu_item_link($link) {
  // Checking every link may be resource intensive, but let's try it!
  $link['title'] = custom_alter_link_title($link['title'], $link['mlid']);
  // For Panels and Views, wrap the above in this IF statement.
  //  if (!empty($link['page_callback']) && $link['page_callback'] == 'page_manager_page_execute') {
  // }
  if (empty($link['localized_options'])) {
    $link['localized_options'] = array();
  }
  return l($link['title'], $link['href'], $link['localized_options']);
}

/**
 * Given a menu title, try to translate it.
 *
 * @param $title
 *   The menu link title.
 * @param $mlid
 *   The menu link ID (see the {menu_links} table.
 * @return
 *   The properly translated text.
 */
function custom_alter_link_title($title, $mlid) {
  static $lang, $titles;
  if (!isset($lang)) {
    $lang = $GLOBALS['language']->language;
  }
  if (isset($titles[$mlid])) {
    return $titles[$mlid];
  }
  $trans = db_decode_blob(db_result(db_query("SELECT lt.translation FROM {locales_target} lt INNER JOIN {i18n_strings} i ON lt.lid = i.lid WHERE i.type = 'item' AND i.objectid = %d AND lt.language = '%s'", $mlid, $lang)));
  if (!empty($trans)) {
    $titles[$mlid] = $trans;
  }
  else {
    $titles[$mlid] = $title;
  }
  return $titles[$mlid];
}

/**
 * Try to translate a Panels page title.
 *
 * drupal_alter('ctools_render', $info, $page, $args, $contexts, $task, $subtask);
 */
function custom_ctools_render_alter(&$info, $page, $args, $contexts, $task, $subtask) {
  $item = menu_get_item();
  if (isset($info['title'])) {
    $mlid = db_result(db_query("SELECT mlid FROM {menu_links} WHERE link_path = '%s' AND menu_name <> 'navigation'", $item['path']));
    $info['title'] = custom_alter_link_title($info['title'], $mlid);
  }
}


Feedback welcome. If you want to move the issue, that's fine, too. If this should be a patch to some module, I can whip one up.

CommentFileSizeAuthor
#2 709140-i18n-default.patch651 bytesagentrickard
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

agentrickard’s picture

Category: support » bug

OK. More digging today, and this isn't entirely a Panels issue. Here's the problem.

1) We're using Domain Access, and have 6 sites, each with a different default language (much like you might find with traditional db prefixing.)

2) Items marked for 'All languages' that get run through i18nmenu_translated_menu_link_alter do not get translated if the $langcode is the same as the site's default language. This is an obvious optimization, but it is a big fail in our usage, because the menu item essentially has a default language of English.

Forcing tt() to return regardless of language seems to fix the issue...

agentrickard’s picture

Status: Active » Needs review
FileSize
651 bytes

And the patch I was forced to use.

Jose Reyero’s picture

Status: Needs review » Needs work

Sorry but this translating from default language doesn't make too much sense to me. However, when you don't have the source string, you can use i18nstrings_ts(), take a look at that one (used for content type help text).

Also, the i18nstrings module has gone through major rework so the tt() function is now obsoleted.

agentrickard’s picture

The only way (AFAIK) to get content to appear for all languages is to set it to 'default', which then requires translation-sensitivity when languages are switched.

nonsie’s picture

Jose Reyero’s picture

Project: Internationalization » Internationalization Views
Version: 6.x-1.2 » 6.x-2.x-dev
Component: Compatibility » Code