Hi all,

my setup:

- no other menu modules installed

- Language negotiation: Domain name only.
( /admin/settings/language/configure )

- A new [i18n] block menu "about" created, multilingual settings for this block is setted up to "language: All languages".
( /admin/build/block/configure/i18nmenu_node/menu--menu-about )

Step to create the issue:
- I create a node in default language (en), and create its menu item directly inside the "add node" creation page
- I DO NOT translate this node in other languages

Result:
The menu item is always shown between languages, pointing to default original creation node.

Instead I think the menu item should not be shown in languages where its node is not translated.

I'm missing something?

Thank you very much

CommentFileSizeAuthor
#9 hide-untranslated-1231196-9.patch4.13 KBgaëlg

Comments

plach’s picture

Category: bug » support
Status: Active » Fixed

Just uncheck the "Enable node translations" checkbox on the node form menu item widget, save, and you should be done.

mxt’s picture

Thank you very much for your answer platch, but I can't apply your suggestion: I have MANY languages available in my site, and menu item translation have to be available only for SOME languages.

E.g:

node/2 must have a translation in Italian and German, but NOT in Spanish for example.

So, its menu item translation must be available for Italian and German.

How we can resolve?

Thank you very much!

mxt’s picture

Status: Fixed » Active
plach’s picture

Status: Active » Fixed

As I told you this cannot be covered by MTN: if you disable node translation for a menu item not having a translation for each language and then resave all the translations, for each one you should get a menu item with the corresponding language assigned. This will make it appear only when viewing that language and no menu item will appear when there is no translation for the current language.

Status: Fixed » Closed (fixed)

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

kork’s picture

You can just hide the menu item if no translation exits:

function YOURMODULE_translated_menu_link_alter(&$item, $map) {
  global $language;
  if ($item['module'] == 'menu' && $item['options']['translations']) {
    if (!array_key_exists($language->language, $item['options']['translations'])){
      $item['hidden']=1;
    }
  }
}
mxt’s picture

Thank you very much kork!

plach’s picture

Category: support » feature
Status: Closed (fixed) » Active

This looks like an useful optional behavior: we could have a checkbox in the menu settings. Patches welcome :)

gaëlg’s picture

Status: Active » Needs review
StatusFileSize
new4.13 KB

What about this?

plach’s picture

Status: Needs review » Needs work

@GaelG:

Thanks for working on this!

+++ b/i18nmenu_node.module
@@ -237,8 +237,20 @@ function _i18nmenu_node_get_tnid($nid) {
+  global $language;
+  if ($item['module'] == 'menu') {
+    $node_langcode = i18nmenu_node_get_lang($map);
+    // If the link go to a node which is not is the current language...
+    if ($node_langcode && $node_langcode != i18n_get_lang()) {
+      // We try to link to the translation of that node.
+      if ($map[1] = i18nmenu_node_translation($item, $map)) {
+        $item['href'] = implode('/', $map);
+      }
+      // There is no translation for the current language, we hide the link if the menu is configured to do so.
+      else {
+        $item['hidden'] = i18nmenu_node_hide_untranslated_enabled($item['menu_name']);
+      }
+    }

I tried hard not to introduce additional queries in this phase. You should check $item['options']['translations'] instead: if the translation key is defined but there is no entry for the current language then the optional hidden behavior should kick in. See also #6.

+++ b/i18nmenu_node.module
@@ -277,6 +289,16 @@ function i18nmenu_node_translation($item, $map, $langcode = NULL) {
+ * Return the language code of the item's node.
+ */
+function i18nmenu_node_get_lang($map) {
+  // If the current item is also the active item, in $map[1] we have a node
+  // object instead of a simple nid.
+  $nid = is_object($map[1]) ? $map[1]->nid : $map[1];
+  return db_result(db_query("SELECT n.language FROM {node} n WHERE nid=%d", $nid));
+}

As per the comment above I don't think this is actually needed.

+++ b/i18nmenu_node.module
@@ -678,6 +706,13 @@ function i18nmenu_node_enabled($item) {
+function i18nmenu_node_hide_untranslated_enabled($menu_name) {

I like this function, but I'd prefer to have shorter name. E.g. i18nmenu_node_hide_untranslated. Also, to preserve backward compatibility we should introduce an update function setting the variable value to false for existing sites.

gaëlg’s picture

Actually we need this function because if the content only exists for one language (the source node), $item['options']['translations'] is empty.

plach’s picture

Then we should try and see if populating the translations array with only the source value does not break everything, because introducing a query for each rendered menu item is a no go.

gaëlg’s picture

Indeed. But as I don't know well how this module is designed, maybe you could have a look at this by yourself? For sure it's the best way to handle this, but I don't want to introduce new bugs.