Just started experimenting again with i18n.module. Very nice changes you've made in the past few months.

I like the handling of translated menu and taxonomy items. Was wondering if something similar could be introduced for user-defined menu items.

Comments

mikeryan’s picture

Second the request!

loony’s picture

We need this! :)

Marc Bijl’s picture

Nearly December again...

jose reyero’s picture

> Nearly December again...

It only means that nobody who needs it has done it yet -or did it but didnt contribute it back. But thanks for the reminder anyway. So should we have like an anniversary party? ;-)

Some good news is that I'm implementing translatable user-defined menu items for a client, so it will be here soon.

Marc Bijl’s picture

WOW... FAB, FAB, FAB!!! I'm really looking forward to it...

Sorry if my post sounded a bit frustrated, but that was just how I felt that night. Searched so long, tried so many things, but just walked in circles all the time. Wish I was a programmer, so I could help and do some additional work... Therefore: I really appreciate the things you guys do!!!

Right now I hack around this using the following code (i.e. for submenu 74 and its subs):

<?php
$TheMenu = theme_menu_tree(74); 
print preg_replace ("/(>[^<\w]*)(\w+[^<]*\w+)([^<\w]*<\/)/e", "'\\1'.t('\\2').'\\3'", $TheMenu);
?>

And then translate the separate menu-item-strings using localization. Got it from Bert somewhere at the forum. Can you please tell me Jose, if this is the best way to -temporary- solve the problem?

Thanks,
Marc

jose reyero’s picture

StatusFileSize
new1.59 KB

Ok, understood.

As I told, it's in the works. Here's a "preview". Maybe someone can help me testing it? :-)

This is a new small module that runs configurable menu items through localization system. Bit tricky, but doesn't need patching :-)

Marc Bijl’s picture

Of course I want to help testing; would be great is this module is gonna work!

Can you please tell me what need to be done? Make a seperate directory for this module? Or save it in the i18n directory? Then I suppose I have to visit all of my pages (so menus) and translate the items using localization?

Marc Bijl’s picture

First test results are here! Probably I did something wrong, but it doesn't seem to work right now. Here's an overview of what I've done:

First, I saved the file as i18n_menu.module in the existing i18n directory (not sure if this is right - can it be the module must be saved in it's own and separate directory?);

Second, I switched the recognized module on (aminister > modules);

Third, I deleted the code from above (#5) in my page template and changed it back into:

<div id="submenu">
  <?php $TheMenu = theme_menu_tree(74); print $TheMenu; ?>
</div>

Fourth, I deleted the rows from locales_source which were created by the code / workaround I mentioned a few posts earlier (#5), in this case rows with lid 1632, 1633, 1634, 1635, 1636;

Fifth, I deleted rows with the same lid from locales_target;

Sixth, I surfed a bit accross my website;

Seventh, I noticed a lot of new rows were created in both locales_source and locales_target;

Eighth, I translated one of the submenu-options: searched for the term "realisatie" (which means realization or building) and translated it into dutch: "realisatie" and into english: "realization";

Nineth, I surfed across the english site (newoceans.nl/en-local);

Tenth, unfortunately nothing happened. Well, nothing happened with the submenu: it's still dutch...

Marc Bijl’s picture

This is interesting!

I managed to get the translated item visible. Only once...
Then, after quiet a struggle, I managed to get it visible again. Indeed, only once...

Finally I found out how to reproduce. It seems there's only one situation in which I can get the translated item visible, and then still once. This is the situation I'm talking about:

- I log into the dutch(!) administration using newoceans.nl/user
- I go to administer > settings, just do nothing but save configuration.
- I logout and will be redirected to newoceans.nl/nl

The first (front-) page is a kind of journal, so:

- I click on primary link webdesign, which directs to page newoceans.nl/nl/webdesign
    This is the dutch page about webdesign, in an overall dutch site
    The dutch page's URL alias is: "webdesign" (no language prefix in this alias)
- I click on the english language icon in the block, which goes to newoceans.nl/en-local/webdesign
    This is the dutch page about webdesign, in an overall english site
    The english page's URL alias is: web-design (no language prefix in this alias)

In this overall english site, there's a submenu (theme_menu_tree(74)) with indeed, the english term "realization". However...

After clicking only once on another primary link (as going to another page), to come back immediately(!), the term has already changed into "realisatie" again, and there seems to be no way to get it visible as "realization" anymore...

The only way I got it reproduced (I mean, visible as "realization" again) is as written above: log into the dutch administration, save the settings, logout (being redirected to dutch site newoceans.nl/nl), goto page webdesign, and finally click on english language button in block.

Hope this info can help...

jose reyero’s picture

The menu items are cached, so in order to refresh the cache, you'd need to edit/save any menu item, or, in the db: "DELETE FROM cache".

Then you switch languages to any non english one, and the new strings will be in locale. After you translate them, you have to refresh the menus again.

Hope this helps

Marc Bijl’s picture

Just tried what you explained. Using "delete from cache;" has the same effect as what I found out another way, namely saving the settings. The effect is: the into english translated submenu-items are only shown once, after that, they will be shown as dutch items again - and persist in being so :-)

Summary
- login (to newoceans.nl/user = dutch site administration)
- in the database: delete from cache;
- logout (being directed to newoceans.nl/nl = dutch site = default!)
- goto page webdesign (primary link directing to newoceans.nl/nl/webdesign = dutch page in dutch site)
- english button in block (directing to newoceans.nl/en-local/webdesign = dutch page in english site*)

* Which I think is wrong; this should be newoceans.nl/en-local/web-design = english page in english site (URL alias dutch webdesignpage = "webdesign", URL alias english webdesignpage = "web design". But don't worry, that's not part of this problem - I think

Doing things written above, the submenu at the english webdesignpage shows english items (the correct translations of the dutch terms), but only once. So, after visiting any other page at this english site (newoceans.nl/en-local/...), and coming back to the webdesign page, the items are dutch again...

Even stranger than this: when looking to the page with the english submenu-items and pressing F5 (refresh)... Indeed, the submenu becomes dutch again. Just in front of my eyes :-\

Some additional information
- language: en (drupal's standard definitions, turned of)
- language: nl (custom dutch language, turned on, default)
- language: en-local (custom english language, turned on)

- In drupal I have cache support disabled**
- In firefox I have set the buffer to zero**

** Both to have a kind of "refresh" every time I visit any page (for testing purpose).

And then this info about my database tables:

After running the site with i18n_menu.module the first time, I got lots of extra rows in table locales_source and locales_target. Translating i.e. "realisatie" into "realisatie" (dutch) and into "realization" (english), I got this situation:

locales_source
- 1655 (lid)
- /en-local/admin/modules?PHPSESSID=e4378e6ffb2ef5d742616f256186c1dc (location)
- realisatie (source)

locales_target
- 1655 (lid)
- realisatie (translation)
- nl (locale)
- 0 (plid)
- 0 (plural)

- 1655 (lid)
- realization (translation)
- en-local (locale)
- 0 (plid)
- 0 (plural)

For some strange reason, later I got these rows too:

locales_source
- 1681 (lid)
- /en-local/webdesign (location) ***
- realization (source)

*** Which I think is wrong, and might be caused by clicking the english language icon in the block, directing to the wrong page (dutch page in english site) - URL alias problem?

locales_target
- 1681 (lid)
- [empty] (translation) ****
- en-local (locale)
- 0 (plid)
- 0 (plural)

**** Not too sure, but should this be empty indeed?

Well, that's quiet a lot of stuff to dig into (are you still there :-D), but I hope it makes some sense and can help solving the problems. If you have any questions, just ask; if you want me to run a kind of checklist, I'll be all yours!

Marc Bijl’s picture

It has been changed, and it's working now - although I get some errors when translating strings...

I studied the code of i18n_menu.module, but -as not being a programmer- I didn't understand a word :-\ So I tried to do the best I could and find some logic. I recognized an if-else statement, which had to do something with the cache. Moreover, it seemed "everything" only gets translated if a certain part of the statement runs twice(?).

I thought, let's push it to translate at any run :-D Therefore I changed:

function i18n_menu_menu($may_cache){
  static $menu_translate;
  if($may_cache){
    // The menu is being rebuilt. Prepares to translate on second call.
    $menu_translate = TRUE;
  } elseif($menu_translate) {
    // This runs only when menu_hook is called twice
    i18n_menu_translate_all();
    //drupal_set_message(t("Custom menu items have been translated."));
  }
}

into:

function i18n_menu_menu($may_cache){
    i18n_menu_translate_all();
    //drupal_set_message(t("Custom menu items have been translated."));
}

A bit rude, but hey, just to give it a try and see what happens... Well, the good news is: it works! No, it rocks! The bad news is: I now get an error message everytime a translate a string... The message is like:

user error: Duplicate entry 'menu::' for key 1
query: INSERT INTO cache (cid, data, created, expire, headers) VALUES ('menu::', 'a:2:{s:10:\"path index\";a:0:{}s:5:\"items\";a:2:{i:0;a:3:{s:4:\"path\";s:0:\"\";s:5:\"title\";s:0:\"\";s:4:\"type\";i:1;}i:1;a:6:{s:3:\"pid\";i:0;s:4:\"path\";s:0:\"\";s:5:\"title\";s:9:\"Navigatie\";s:6:\"weight\";i:-50;s:6:\"access\";b:1;s:4:\"type\";i:3;}}}', 1130445679, 1130532079, '') in /home/newoceans.nl/public_html/includes/database.mysql.inc on line 66.

It's good to know where it goes wrong. I will take a further look and see what I can do... But it would be great to get some response, and maybe a hint ;-)

Marc Bijl’s picture

Get even errors at every save... So this is not the way to go :-(

Marc Bijl’s picture

Another solution, that seems to work pretty fine (wow, exciting :-D) can be found here:
- http://drupal.org/node/25847

It's a function that I've tried to implement in:
- either page.tpl.php
- or menu.inc

Both options show the results I've been hunting for. Therefore I decided to "patch" (and document for myself) menu.inc - as it only requires one edit (I know, I know it's core...). This is the code where it's all about:

/**
* Override theme_menu_item_link() from includes/menu.inc
* to translate menu item titles and descriptions
* and to get the right url for the current language
*/
function phptemplate_menu_item_link($item, $link_item) {
  // get the currently selected language:
  $lang = i18n_get_lang();
  // initialise link attributes array:
  $attributes = array();
  // if a menu item desciption is given, add it as link title:
  if (array_key_exists('description', $item)) {
    $attributes['title'] = t($item['description']);
  }
  // get the current drupal path without the language code:
  $path = i18n_get_normal_path(_i18n_get_original_path());
  // highlight the active menu item:
  if ($link_item['path'] == $path) {
    if (isset($attributes['class'])) {
      $attributes['class'] .= ' active';
    }
    else {
      $attributes['class'] = 'active';
    }
  }
  // build a link that points to the translated version of a node/term
  // (if a translation exists):
  $link = i18n_l(t($item['title']), $lang , $link_item['path'], $attributes);
  return $link;
}

Wonder if this solution can make a chance...

jose reyero’s picture

Wow!, you've been working really hard :-)

I still insist in the one I proposed -the small i18n_menu module- , but I realize it needs some more instructions. So let's try some step by step:

0. Enable i18n_menu.module
1. Create all your custom menus / menu items in English (If they're already created, it's ok)
3. Display your menu in a block
4. Switch language to some non english one -while viewing the block-, so the 'locales' table gets populated with the new strings
5. Translate the strings with the localization (manage strings) interface

6. Refresh the menu cache, for which you can:
a) Edit and save any custom menu item
or
b) In the database: DELETE FROM cache

7. Play!

When you switch languages, the *custom* menu item names should be translated.

Marc Bijl’s picture

Thanks for your reply, good to hear from you! I will give your instructions a go (of course I will :-D). And while I'm doing this, I hope you're still online and see this post as I have a few questions:

  1. My locales tables (locales_source and locales_target) have become quiet messy playing around with all this stuff last few days; do you know the best way to clean it up (= get rid of the unused strings)? Just delete them manually?
  2. Did you notice my language structure is like this:
    • en
      drupal's english -> turned off(!)
    • nl
      custom dutch   -> turned on -> default
    • en-local
      custom english -> turned on

    And if you have noticed, don't you think it will conflict with your proposed solution?

I also want to mention that the last post I made (#14) is not an ideal solution either, as it does not work with URL aliases. Trying to fix that, I created a situation in which my sections.module started to scream too.

Pfff, quiet some digging ahead :-\

Hope you will reply soon, in the meantime I will start working with your instructions. Thanks mate!

Marc Bijl’s picture

Wow, this is whole thing is driving me crazy...

I started all over, from the very, very, very beginning, and stil it doesn't work. Here's what I did, and I'll try to explain it step by step - by step:

  • Enabled i18n_menu.module
  • Deleted all custom menus - all of them
  • Deleted all strings related to these menus
  • Set the languages like (different from other tests):
    • en
      > enabled, default
    • nl
      > enabled
    • en-local
      > enabled
  • Checked the administration language to be english (en)
  • Added custom menu new oceans
  • Added menu-item webdesign (english), path webdesign*, parent new oceans
  • Added menu-item analysis (english), path webdesign/analyse*, parent webdesign (english)
  • * Both dutch pages with these URL aliases

  • Checked id of menu-item webdesign (english), which was 148
  • Added this code in page.tpl.php to show this submenu:
    <?php $TheMenu = theme_menu_tree(148); print $TheMenu; ?>
    
  • Browsed to newoceans.nl/en/webdesign (to show menu as suggested)
    The submenu-item shown was analysis (english) - so far so good...
  • Browsed to newoceans.nl/nl/webdesign (to switch language, only by adjusting prefix in address)
    The submenu-item shown was analysis (english) - of course not translated yet...
  • Managed strings, searched for analysis (english) and translated this into:
    • analyse (translated dutch) in the field Dutch
    • analysis (translated english) in the field English
  • Deleted cache in the database: DELETE FROM CACHE;
  • Browsed to newoceans.nl/nl/webdesign
    the submenu-item shown was analyse (translated dutch) - mmm, very promising...
  • Browsed to just another page on my site
  • Browsed to newoceans.nl/nl/webdesign
    the submenu-item shown was analysis (english) - indeed, translation gone...

I give up...

I tried these kind of things so many times, with all kind of settings. Every time it is like this: the right submenu-item shows up only once and that's it. Even pressing F5 (refresh) makes it disappear, right in front of my eyes. And if I do not browse to the right page immediately after deleting cache, I don't see the translated dutch submenu-item at all...

Where do I go wrong? Has it something to do with:

  • Use of URL alias in webdesign page?
    • With language prefix?
    • Without language prefix?
  • Automatic browser language detection?
  • Enabling/disabling cache support in drupal?
  • Enabling/disabling cache support in browser?
  • Language used during administering?
  • Something else?

Help...

Marc Bijl’s picture

Can it be caused by a conflict with any other module may be (i.e. sections.module)?

Marc Bijl’s picture

Can it be caused by using this for showing a (sub-) menu:

<div id="submenu">
  <?php $TheMenu = theme_menu_tree(74); print $TheMenu; ?>
</div>

I'm lost...

Marc Bijl’s picture

Something with $cid may be?

Jose, I've tried to track what's going on in the cache by using drupal messages after every declaration, if-then-else, et cetera.

Can it be $cid get's a wrong value by using $cid = "menu:$user->uid:$locale";? The one and only value I see it's getting is "menu::" both for english and dutch...

jose reyero’s picture

Status: Active » Needs review
StatusFileSize
new1.63 KB

This was really some help, thanks :-)

Added two missing 'global' definitions. That explains why the site was working for me -developing, testing only as a single user- but not for anybody else.

Hope this one is better - I din't have the chance to test it though.

Btw: sorry abt delay, but travelling this week and really busy!. Posting from some hotel room in Barcelona :-)

Marc Bijl’s picture

Hey Jose!

Good to hear from you! You're crazy man, posting from a hotel room in Barcelona... ;-)

You should be at the Ramblas! So therefore thanks very much for all your effort! And I have to say, there's some good news -well I think I can even say some excellent news(!)- and there's some "bad" news...

First things first, the good news. It works! No, it rocks! It's fab, it's neat, it's everything I have been dreaming about! And that's no joke. This is so excellent stuff, and many people have been waiting for this! Good job mate!

Second things second, the bad news... There are some errors, and warnings. Taken these into account, it's quite a "struggle" to get at the end of the road. The errors appeared when I started administering the menus and their translations - with the administration environment in the default english language (en). So I thought it had to do something with the fact I was administering. Then I found out the errors were still there when surfing the site (still logged in) in the english (en) environment, but disappeared in the dutch (nl) environment and local english (en-local) environment. So it should be something with the languages, with english (en) as my default. But then I noticed the errors disappeared in the english (en) environment too!

Hard for me to say where the consistency of this behaviour can be found. So the only thing I can do is describe what happened when I first added and administered a menu and its items. Here we go!

First is when administering and pressing "menus". Then I get this:

user error: Duplicate entry 'menu:1:en' for key 1
query: INSERT INTO cache (cid, data, created, expire, headers) VALUES ('menu:1:en', 'a:3:{s:10:\"path index\";a:191:{s:7:\"archive\";s:2:\"32\";s:11:\"admin/block\";s:2:\"33\";s:16:\"admin/block/list\";i:-3;s:21:\"admin/block/configure\";
i:-4;s:18:\"admin/block/delete\";i:-5;s:15:\"admin/block/add\";i:-6;s:13:\"node/add/blog\";s:2:\"34\";s:4:\"blog\";s:2:\"35\";
s:13:\"admin/comment\";s:2:\"36\";s:18:\"admin/comment/edit\";i:-10;s:20:\"admin/comment/delete\";i:-11;s:18:\"admin/comment/list\";
i:-12;s:23:\"admin/comment/configure\";i:-13;s:22:\"admin/comment/list/new\";i:-14;s:27:\"admin/comment/list/approval\";i:-15;
s:32:\"admin/comment/configure/settings\";i:-16;s:30:\"admin/comment/configure/matrix\";i:-17;s:34:\"admin/comment/configure/thr in /home/newoceans.nl/public_html/includes/database.mysql.inc on line 66.

In the Netherlands we would say: I can't make any chocolate of this :-D

Second is pressing "add menu item". Then I get this (seems to be pretty much the same...):

user error: Duplicate entry 'menu:1:en' for key 1
query: INSERT INTO cache (cid, data, created, expire, headers) VALUES ('menu:1:en', 'a:3:{s:10:\"path index\";a:191:{s:7:\"archive\";s:2:\"32\";s:11:\"admin/block\";s:2:\"33\";s:16:\"admin/block/list\";i:-3;s:21:\"admin/block/configure\";
i:-4;s:18:\"admin/block/delete\";i:-5;s:15:\"admin/block/add\";i:-6;s:13:\"node/add/blog\";s:2:\"34\";s:4:\"blog\";s:2:\"35\";
s:13:\"admin/comment\";s:2:\"36\";s:18:\"admin/comment/edit\";i:-10;s:20:\"admin/comment/delete\";i:-11;s:18:\"admin/comment/list\";
i:-12;s:23:\"admin/comment/configure\";i:-13;s:22:\"admin/comment/list/new\";i:-14;s:27:\"admin/comment/list/approval\";i:-15;
s:32:\"admin/comment/configure/settings\";i:-16;s:30:\"admin/comment/configure/matrix\";i:-17;s:34:\"admin/comment/configure/thr in /home/newoceans.nl/public_html/includes/database.mysql.inc on line 66.

Going on, which is saving the menu item, no error message appears. So, the next step is to show the menu on a webpage. Then I get both an error and a warning.

The error is (yes indeed, it's the same again...):

user error: Duplicate entry 'menu:1:en' for key 1
query: INSERT INTO cache (cid, data, created, expire, headers) VALUES ('menu:1:en', 'a:3:{s:10:\"path index\";a:192:{s:7:\"archive\";s:2:\"32\";s:11:\"admin/block\";s:2:\"33\";s:16:\"admin/block/list\";i:-3;s:21:\"admin/block/configure\";
i:-4;s:18:\"admin/block/delete\";i:-5;s:15:\"admin/block/add\";i:-6;s:13:\"node/add/blog\";s:2:\"34\";s:4:\"blog\";s:2:\"35\";
s:13:\"admin/comment\";s:2:\"36\";s:18:\"admin/comment/edit\";i:-10;s:20:\"admin/comment/delete\";i:-11;s:18:\"admin/comment/list\";
i:-12;s:23:\"admin/comment/configure\";i:-13;s:22:\"admin/comment/list/new\";i:-14;s:27:\"admin/comment/list/approval\";i:-15;
s:32:\"admin/comment/configure/settings\";i:-16;s:30:\"admin/comment/configure/matrix\";i:-17;s:34:\"admin/comment/configure/thr in /home/newoceans.nl/public_html/includes/database.mysql.inc on line 66.

And the warning is:

warning: Cannot modify header information - headers already sent by (output started at /home/newoceans.nl/public_html/includes/common.inc:320) in /home/newoceans.nl/public_html/includes/common.inc on line 140.

Well, it goes on pretty much this way. But as said before, at the end of the road it rocks! Hope my description and error messages can help you adding the finishing touch. Loads of succes!

BTW
Trying to get translation of menu items working, my locales tables (both source and target) are quiet a mess... Duplicate entries, I mean, related to items with the same meaning but stored twice as some are english, and some are dutch. Some of them are related to a long path without absolute language prefix and with a session id, some of them are related to a short path with an absolute language prefix and without session id. Et cetera. Can you advice a good way to clean it up a bit?

Cheers,
Marc

Marc Bijl’s picture

And another question...

Is there any difference using this module between this:

  • language en (drupal's english), turned on, default
  • language nl (custom dutch), turned on
  • language en-local (custom english), turned on

and this:

  • language en (drupal's english), turned off
  • language nl (custom dutch), turned on, default
  • language en-local (custom english), turned on

And the same way: can I define my menu items in dutch (nl) and translate them into other languages,
or is it neccessary to define them in english (en) and then translate them?

Cheers,
Marc

jose reyero’s picture

Well, these errors look like it lacks something like

function i18n_menu_translate_all(){
global $_menu;
global $user;
global $locale;
$cid = "menu:$user->uid:$locale";
cache_clear_all($cid);
...
...

And about the questions, I think you could try any language for the original menu items, but for consistency with the localization system, they *must* be defined in english (en).

Marc Bijl’s picture

Excellent, this seems to do the trick!

Just implemented the latest addition, and everything seems to work fine now. Only played a bit around, will test it more extensively next few days when implementing several international menus!

Thanks so far, good job!

Marc Bijl’s picture

Hi Jose!

I'm stuck, and I have a strong feeling that a solution is just around the corner :\

As the menu-items are translated by using localization now,
every menu-item has only one basic form to edit things like title, description and path.

Is that right? If so, does it mean I can only link to one, single page?
Instead I would love to link to language dependant pages...

For example, I have these two pages:

- "grafische vormgeving" (dutch page)
- "graphic design" (english page)

In fact, they're the same page (translated v.v.), but have different node id's and URL aliases.
How can I link one menu-item to any of these pages, dependant of the language the site is viewed in?

The same way, I like to link from one menu-item to nodes that have the same taxonomy term,
but which is translated and therefore is stored as two actual terms:

- "nieuws" (dutch, term 5)
- "news" (english, term 69)

Hope this makes a bit sense, and hope even more that there's a solution close by...

Thanks!

Marc Bijl’s picture

Additional note:

I use different URL aliases because they're defined in the right language too.
This is mainly because of dutch people searching for dutch terms in search engines.

chombium’s picture

Hi,

I've done some test myself 'cos I need translatable menus on the

web site I'm working on.

I'm using the English locale (that comes with Drupal) and

Macedonian (mk) locale for my native language. Default locale is English

I've done the things described in #15.

At first sight everything seemed perfect.

As I translated the "custom" menus they were appearing in the non-english

(particulary Macedonian) locale that was selected and I strated playing around.

I divided my test in two parts:

1. to check the links (browse the site) without changing the locale

2. to change the locale to English and back to Macedonian and to

do the first test again.

Here are results:

Frist test:

After translating the strings they were there in the selected locale.

Then I clicked on one link in the menu and they were gone,

tried another link and they were ok again. I've experienced something

really weird, it seems that menus appear correctly every 2nd/3rd click

click on one of the links.Sometimes I've deleted the cache, but it didn't help.

This is really weird, maybe it's just my old rusty home machine. I'll test

this on few other machines and I'll write the results.

Second test:

Switched to English. Browsing in it (the default locale) was good.

Back to Macedonian. First impression, bad. The menus were still in English.

Tried to switch the locale vice-versa but the result was same.

Contiued browsing of the site, no sight of menus translated in Macedonian.

Lastly I've set Macedonian as default locale. Nothing changed, everything

was in English.

After this unsuccessful tests, I tried to add another menu and to translated

it in Macedonian, just to see if I'll get back at the begining.

I was succesful, got back to test number 1 :-/

I'll do the same tests on some other machines in the next few days and I'll keep you

informed.

btw. Jose, Can you write some simmilar module for user created blocks? It seems to me

there wouldn't be much things to do when you'll get the menu module working.

GREETZ, chombium

Marc Bijl’s picture

Hi Jovan,

Just to be sure, did you check:

• #21: http://drupal.org/node/14783#comment-52608 ?
• #24: http://drupal.org/node/14783#comment-52805 ?

chombium’s picture

Hi Marc,

Seems like you had the same problems but I didn't have any problems with
the database.

I didn't read this discussion that well to find and add the code to the module :(

I'll try that now to see if it will do any good.

What do you think? Is it hard to get this working with custom blocks

GREETZ, Jovan aka chombium ;)

Marc Bijl’s picture

No worries mate!

About translating user defined blocks: I managed to do that using i18n.module, flexinode.module and a custom defined block. You can find my solution here:

http://drupal.org/node/37118

But it's not the best solution there is... It's pretty complex. Too complex may be. Jose Reyero (maintainer i18n.module) gave me the advice not to do that much php coding in blocks, because they are stored as field data in the database. Instead he suggested to get the same thing done creating my own modules. But therefore I need to do some homework first :-D

I would say, let's stay on topic in this post; if you want to ask me anything about the way I translated blocks, please use http://drupal.org/node/37118. Hope the info there will be helpful for you!

Success!
Marc

chombium’s picture

Thank's alot mate, for pointing those posts that
i didn't read.

You saved my life ;)

After pathcing the i18n_menu.module
everything's going great.

GREETZ, Jovan

pepeek’s picture

Since there was so many changes/patch-patching going on, could you please post the very latest patched i18n_menu.module?

Thanks a lot!
--Josef

pepeek’s picture

OK, I think I've managed to get the latest module. It is the combination of #21 + added one bold line from #24 (the 'cache_clear_all' one).

What puzzles me is the behavior of i18n module itself.

I have 2 translations of one page (page translated via the i18n module: translation):
/node/12 -> English
/node/19 -> Czech

Which one should I use for the menu item path? There is only one menu Item and therefore only one path!

The behavior I got is the following:
- I've used the /node/19 (Czech) path for the menu item
- I've followed the instructions from #15 the got the i18n menu and sure it works great (Czech label for Czech language and English label for English language)
- if my starting language is Czech, then everything works great
- however, if I start browsing the site in English and I hit this menu item (pointing to /en/node/19) then the resulting page shows in Czech (remember? 19 -> Czech) instead of English.

Now the questions:
1) Should the request for /en/node/19 be inteligent and return/redirect to /node/12 (by knowing that EN is requested, which for node 19 is actualy node 12)
2) or should the menu item have two paths, one for each language?
3) Do I totaly miss something?

Your help is very apprecieted!
--Josef

Marc Bijl’s picture

Hi Josef,

Just like you, I had the problem of pointing from 1 menu-item to 2 possible nodes,
depending on the sites language: http://drupal.org/node/37168

I managed to get it work, although it might not be a very clean solution...

Now I use i18n.module, and i18n_menu.module.
Besides I made some changes i18n.inc of i18n.module.
Got the idea from here: http://drupal.org/node/25847

What I did is this:

  • I added an extra function phptemplate_menu_item_link($item, $link_item) to i18n.inc
  • I added an extra line to the existing function i18n_l($text, $lang , $url = '' , $attributes = array(), $query = NULL) in i18n.inc

The code of the extra function:

/**
 *	Revision by New Oceans - Starts here
 *	------------------------------------
 *
 * Override theme_menu_item_link() from includes/menu.inc
 * to translate menu item titles and descriptions
 * and to get the right url for the current language
 *
 *	Got this workaround from http://drupal.org/node/25847
 */
 
function phptemplate_menu_item_link($item, $link_item) {
  // get the currently selected language:
  $lang = i18n_get_lang();
  // initialise link attributes array:
  $attributes = array();
  // if a menu item desciption is given, add it as link title:
  if (array_key_exists('description', $item)) {
    $attributes['title'] = t($item['description']);
  }
  // build a link that points to the translated version of a node/term
  $link = i18n_l(t($item['title']), $lang , $link_item['path'], $attributes);
  return $link;
}

/**
 *	Revision by New Oceans - Ends here
 *	==================================
 */  

The code of the changed function:

/**
 * Links for different languages
 */

function i18n_l($text, $lang , $url = '' , $attributes = array(), $query = NULL) {
  global $i18n_langpath;
  // If !url get from original request
  if (!$url) {
    $url = _i18n_get_original_path();
  }
  // If url has lang_prefix, remove it
  i18n_get_lang_prefix($url, true);
	//are we looking at a node?
  if (preg_match("/^(node\/)([0-9]*)$/",$url,$matches)) {
    if ($nid = i18n_node_l($matches[2], $lang)) {
      $url = "node/$nid";
    }
  }
  elseif (preg_match("/^(taxonomy\/term\/)([^\/]*)$/",$url,$matches)) {//or at a taxonomy-listing?
    if ($str_tids = i18n_taxonomy_l($matches[2], $lang)) {
      $url = "taxonomy/term/$str_tids";
    }
  }
	
/**
 *	Revision by New Oceans - Starts here
 *	------------------------------------
 *
 *	From here one extra line to get the alias for the url
 *
 */
 
  $url = drupal_get_path_alias($url);
	
/**
 *	Revision by New Oceans - Ends here
 *	==================================
 */  
	
  return '<a href="'. i18n_url($url, $lang, $query) .'"'. drupal_attributes($attributes) .'>'. $text .'</a>';
}

Hope this can help...

Cheers,
Marc (www.newoceans.nl/en-local)

pepeek’s picture

I've done the mods according to your instructions, but nothing has changed. The menu item still points to the node with incorrect language. Do I have to change theme_menu_item_link() function in my theme's template.php as noted in http://drupal.org/node/25847 ?
--Pp

pepeek’s picture

I've tried to understand your suggestion but could not make any sence of it, sorry.

If I think about my problem, here is the solution. Currently my custom menu item path is a static one as entered during the menu item creation. I need this path not to be static (as entered) but dynamic according to the current language/locale.

That means:
- while having the two nodes:
/node/12 -> English
/node/19 -> Czech

- staticly entered path in the custom menu item is:
/node/12 (English)

- now when my current language is English, my custom menu item must point to /node/12
- and when I switch to Czech then my custom menu item must also switch to point to /node/19

The best place to make this change is where the menu label is changed, which is in i18n_menu.module:

  foreach($_menu['items'] as $mid => $item) {
    if($item['type'] & MENU_CREATED_BY_ADMIN) {
      $_menu['items'][$mid]['title'] = t($_menu['items'][$mid]['title']);
    }
  }

so the resulting code should be:

  foreach($_menu['items'] as $mid => $item) {
    if($item['type'] & MENU_CREATED_BY_ADMIN) {
      $_menu['items'][$mid]['title'] = t($_menu['items'][$mid]['title']);
      $_menu['items'][$mid]['path'] = getPathForLocale($_menu['items'][$mid]['path'], $locale);
    }
  }

and the magic bit getPathForLocale is my puzzle (sorry again).

How can I get the path to the node which is a $locale translation of $_menu['items'][$mid]['path'] node? In my above example it is '/node/19' for language/locale 'cs' and original path '/node/12'.

Marc Bijl’s picture

To point to the right node (I have 2 nodes for 1 menu-item too - dutch and english),
I added this new, extra function to i18n.inc:

function phptemplate_menu_item_link($item, $link_item) {
  // get the currently selected language:
  $lang = i18n_get_lang();
  // initialise link attributes array:
  $attributes = array();
  // if a menu item desciption is given, add it as link title:
  if (array_key_exists('description', $item)) {
    $attributes['title'] = t($item['description']);
  }
  // build a link that points to the translated version of a node/term
  $link = i18n_l(t($item['title']), $lang , $link_item['path'], $attributes);
  return $link;
}

In addition, I use URL aliases, which means that the path found above
needs to be turned into the right alias.

Therefore, I added this line to the existing function
i18n_l($text, $lang , $url = '' , $attributes = array(), $query = NULL) in i18n.inc:

$url = drupal_get_path_alias($url);

For me these changes do the trick:

I'm not sure about how to change i18n_menu.module to get the same effect...

plj’s picture

Hello Jose, Marc and others,

I've basically same requirements as Marc. What I'd have also liked, however, would have been the ability to translate the menu links manually, so that I could have pointed different languages to totally different pages – for example, one to a taxonomy term and another to a specific node.

I first turned on i18nmenu.module, and make the following change into it:

--- i18nmenu.module     2006-03-03 21:18:40.000000000 +0200
+++ i18nmenu.module.new 2006-03-06 13:03:34.000000000 +0200
@@ -31,6 +31,7 @@
   foreach($_menu['items'] as $mid => $item) {
     if($item['type'] & MENU_CREATED_BY_ADMIN) {
       $_menu['items'][$mid]['title'] = t($_menu['items'][$mid]['title']);
+      $_menu['items'][$mid]['path'] = t($_menu['items'][$mid]['path']);
     }
   }
   // Update cache
@@ -56,4 +57,4 @@
   return $output;
 }

-?>
\ No newline at end of file
+?>

I also tried Marc's approach. Unfortunately, the problem with both of these approaches is that they do not work if some of the translated menu items are collapsing, as they both break menu.inc's menu_set_location(). This is quite nasty, because clicking a parent menu item won't then reveal its children, unless user switches to english site.

Any suggestions? All hacks are welcome, as this came as a nasty surprise, and I should get the site to function Real Soon Now.

adixon’s picture

i think i had this same problem (though i just had a little line of code to translate menu items that are nodes), and solved it by going into the $_menu internals to also change the reverse path stored in the 'path index' key. In other words, if your change path $path for menu item $mid to $new_path, you also need to do this:

            unset($_menu['path index'][$path]);
            $_menu['path index'][$new_path] = $mid;

in order for menu_active_trail to behave properly.

Note - this was in 4.6, i haven't looked at 4.7 to know whether this would work.

adixon’s picture

see my patch here:

http://drupal.org/node/76631

jose reyero’s picture

Status: Needs review » Fixed

This is already implemented in i18n DRUPAL-5 branch

Anonymous’s picture

Status: Fixed » Closed (fixed)