Hello,

I have a multilingual website which uses Views extensively in combination with i18n. Both these modules are great. My problem is I can't get my views to switch from one language to another, even with the following (very clear) instructions:

Since there is no simple way -- yet -- to fully translate a view (i.e. to translate its title, header, footer, and other labels), I have a view for each language on my site, with views urls like "news_en", "news_fr", "news_es"...

Then, I have aliases for each view to make the translation magic work:
- Url "news_en" aliased as "en/news"
- Url "news_fr" aliased as "fr/news"
- Url "news_es" aliased as "es/news"

My problem comes from the language switcher block provided by the i18n module. Say I'm viewing the English page (URL = "en/news"):

  • when I click on French it goes to "fr/news_en" instead of "fr/news"
  • when I click on Spanish it goes to "es/news_en" instead of "es/news"

I've tried numerous ways to set up the menu items (via views or via admin > menus) and the url aliases, but I can't get this to work. Any idea why?

Thank you,
Vincent

Comments

damianrr’s picture

Has anyone a clue about this?

Moxide’s picture

Same problem here !
Investigating...

csautot’s picture

I would also like to build a multilingual site, and have a news/blog section in different languages and with different posts. I am trying to build a view for showing the 5 most recent posts which is dependent on the chosen language. I don't think there is an easy fix to this.

Moxide’s picture

Here is a temporary solution that makes this technique work (in my case, at least !).

In i18n.module, replace the i18n_path function by this one :

function i18n_path($path, $lang) {
  if (!$path || $path == i18n_frontpage($lang)) {
    return $lang;
  } elseif($alias = drupal_lookup_path('alias', $path)) {
    // TESTING : fix Views translation
    // Strips the existing language from alias, and adds the requested language
	  i18n_get_lang_prefix($alias, TRUE);
    return $lang.'/'.$alias;
	} else { // Alias for language path will be searched later
    return $lang.'/'.$path;  
  } 
}

This will affect every aliases which contain a language prefix.

enxox’s picture

I've found another solution using the insert_view module
I've created different views for every language. So I've created a node for every language with in the body only the insert_view command that calls the respective view.

Every node is the translation of the others, so the translation link works!

maulwuff’s picture

great and easy workaround!

moritzz’s picture

Just add the following function to your template.php to translate table headers in general:


/**
 * Pass header cells through localization (manly for views)
 */

function mythemename_table($header, $rows, $attributes = array(), $caption = NULL) {
  
  if (count($header)){
  
    foreach($header as &$cell) {
    
      $cell['data'] = t($cell['data']);
    
    }
  
  }
  
  return theme_table($header, $rows, $attributes, $caption);
  
}

Im not sure if there is a cleaner way to call the native theme_table function.

light-blue’s picture

This approach may be imperfect (please leave comments), but effective (no need to change merlinofchaos' code, only one view required for all enabled translations), and will allow Drupal 5.x users to view translated titles, headers, and body content when displaying a view of nodes. It also checks for translations of the view's node(s) in the the active language, using the site default if no translation has been made yet. Translate the strings in the usual place: admin/settings/locale/string/search.

There are 3 steps and it takes about 3 minutes.

Step 1
=====
Copy and paste this somewhere like template.php:


function translate_view($viewName) {
global $i18n_langpath; //es, fr, it, and so on 
$view=views_get_view($viewName);

//translate the title
print('<h1>' . t((views_get_title($view))) . ' </h1>' );

//run the view in the active language looking for results
$items=views_build_view('items',$view,array($i18n_langpath),false,3);

//remove i18n filters. without this, $view accumulates them
foreach ($view->filter as $key=>$value) {
	if ($view->filter[$key]['field']=='i18n.language')
	   unset($view->filter[$key]);
}

//are there results in the active language? if so, run the view in that language, otherwise the default
if (count($items['items']))
{
  //translate the column labels
  foreach ($view->field as $key=>$value)
    $view->field[$key]['label']=t($view->field[$key]['label']);

  print views_build_view('embed',$view, array($i18n_langpath),false,3);
}
else
   print views_build_view('embed',$view,array(i18n_default_language()),false,3);
}

Step 2
====
Copy and paste this into your view under arguments, arguments handling code (without the php delimiters of course):

if (!$args[0])
  $args[0]=i18n_default_language();

if ($args[0]) {
  $view->filter[] = array(
    'vid' => $view->vid,
    'tablename' => '',
    'field' => 'i18n.language',
    'value' => array(0=>$args[0]),
    'operator' => 'OR',
    'options' => '',
    'position' => 1,
    'id' => 'i18n.language',
  );
}

Step 3
====
Anywhere that you have access to write PHP (I'm using a custom block with panels2), call the function with your view name:

translate_view('type_the_name_of_your_view_here');

Troubleshooting
==========
Double-check your i18n settings
Clear the cache (i've seen odd things otherwise, including a print_r($view) with niftyCorners as an argument)

kylehase’s picture

light-blue,
I'm assuming this code is for a D5.x install is that correct?

light-blue’s picture

Yes, sorry, that approach works on 5.x. I haven't tried other versions yet.

Bartezz’s picture

Thanx for sharing!
Subscribing...

________________
Live fast die young

seutje’s picture

ur solution resulted in my view getting printed in between the opening body-tag and the start of my header-region

so basically, it gets printed before anything else

I tried to change the print ... to $return .= ... and then just returning that $return-variable at the end of the function, but then it wouldn't show anything at all
and when I tried to put print translate_view('type_the_name_of_your_view_here'); it put everything above my header again

what did I do wrong? :x

using D5.10 with views2, panels2, garland theme (for now) and the usual i18n and l10n_client

gp.mazzola’s picture

Another temporary approach I am using, maybe awful, but it works for header and footer.
I am on D5.7, so don't know if it works on 4.x
I set input to PHP and use a if statement on $_SESSION[language] variable:

if ($_SESSION[language] == 'it'){
   print $italianHeader;
}
elseif ($_SESSION[language] == 'en') {
   print $englishHeader;
}

Ciao,
GP

Noira’s picture

Great! Works as a solution for me + I give the blocks visibility on en/* pages only, not the smoothest solution perhaps, but i18n isn´t perfect so far...

SocialNicheGuru’s picture

subscribing

http://SocialNicheGuru.com
Delivering inSITE(TM), we empower you to deliver the right product and the right message to the right NICHE at the right time across all product, marketing, and sales channels.

pfournier’s picture

Use the redirect module to redirect es/news_en to es/news_es.

Bartezz’s picture

Hi,

I've been messing about with this as well. I've come accross a similar solution as Enxox metioned (http://drupal.org/node/108117#comment-251689). A howto can be found here; http://www.computerminds.co.uk/multilingual-views-drupal-when-using-i18n...

But I'm using cck viewfield instead.
So you'll need cck and the extra viewfield modules.

What I've done is the following;
1 - create a new content-type, I called it page-view
2 - edit content-type -> Add field -> View field (select list)
3 - edit content-type -> Display fields -> View field -> Teaser and Full both as 'use view page settings' (this way the module uses the settings you've made in the view itself)
4 - edit content-type -> Manage fields -> View field -> configure
5 - under allowed views i checked all the views that are allowed to be inserted into the node

6 - I've created a view for each language on my site ie. news_en, news_fr, news_de etc...

Now instead of adding a view to my menu I add a page-view content-type.
I can change the title, body etc etc and insert a view news_en.
Save the node and click translation -> translate the title, body etc to French in this case and set the cck field to news_fr

You can keep doing this for each language :) Just make sure you've cloned your view to each language :)

Et voila :)

Cheers,
Bartezz

________________
Live fast die young

HnLn’s picture

subscribing

nco71’s picture

Hello thks a lot for the smart solution with viewfield module

I was already using this module in my website so I didn t need to add anything new.

I just want to add that in drupal 6 last view module , you can filter the views to show results related to the active language ( i18n argument in view )

So you don t need to create a new view for other translated version , just one view for all translated node, and maybe you ll need to use "all" as viewfield argument

I think it s a good temporary solution , untill it becomes possible to associate a translated view,

mariusilie’s picture

There's a module called "Views content panes" in the CTools package (http://www.drupal.org/project/ctools). This module lets you add a view to any node panel you create. And since you can translate any node to any language you want, all you have to do is to add the same view to the translated node.