2

My client is having a terrible time managing multi-lingual content in drupal 7. I'm using the internationalization module and drupal 7's default capabilities in managing multiple languages. Here's an example workflow my client executes, with bold statements that indicate challenges.

  1. Client begins to add new content of content type page. He fills out title and selects language as English.
  2. Client clicks on menu settings, and select Provide a menu link. Under Parent item, client selects from the drop down tree About.
  3. Client publishes the page.
  4. Client clicks on Translate to translate the page.
  5. Client clicks on add translation for French to see the add content page.
  6. Client notices all the fields except menu settings is populated. This irritates the client. Client expects the CMS to know that the A Propos menu link is the french equivalent for About menu link, and to have populated accordingly. But instead, client must go through hundreds of link.

Here's another example workflow that illustrates a big problem.

  1. Client wants to re-structure the site map.
  2. Client goes to an ENGLISH page in the CMS, goes to menu settings, and changes the Parent item to the Home menu link.
  3. Client presses Save.
  4. Client goes to FRENCH version of the same page. Client needs to repeat the process of Parent item but find Accuiel menu link. This irritates the client because client expects the CMS to be smart enough to know Accuiel menu link is the french version of Home menu link, and when the English page was moved from About to Home, then the French page should have moved from A Propos to Accuiel.

As it stands now, the client feels like he's managing two websites individually. Can anyone suggest a workflow that can reduce the client's workload by about half ? Simply having drupal reflect site map changes in english into french would reduce workload by about half.

1

As far as I can tell this is a problem, the menu items aren't connected so the only thing that links them is through the node they are connected to and their translation sets.

Another possibility, but I never used it like this, is to make the menu items translatable and there's a module inside i18n that redirect links to the right language.

  • man........do you think i have to reverse engineer or hack drupal 7 to create the multilingual-synchronization behaviour I want? – John Aug 24 '11 at 13:52
  • i think i18n allows you to translate menu items as well, so I guess if you choose this approach it will mean you create the menu item in 1 language form inside node/edit and you translate it using the built in translate tool. Since you do this for all menu items it will effectively mean that if you move the menu item, it will move for all languages. To be honest, I never tried that approach, but it should (hear say) work. – Attiks Aug 28 '11 at 19:29
1

Ok, I created a hack!!! And a very poorly done hack too. Here's what it does. My hack will put a button above the CMS>Add Content>Menu Settings>Parent Item. The button will say "Synchronize Menu Item with Main Language". So for example, if Awards move from Tournaments>Year 2011 to Achievements>Celebration, then you can go to CMS>A Propos>Menu Settings and click on "Synchronize Menu Item with Main Language" to automatically move Prix from Tournois>Annee 2011 to Réalisations>Célébration.

here's my code.....hopefully it's not too buggy...

Add to /themes/seven/seven.info the following line

scripts[] = lang.js

/themes/seven/lang.js

if (typeof jQuery == 'function'){
  jQuery(document).ready(function($) {

        var btn = document.createElement('input');
        btn.value = 'Synchronize Menu with Main Language';
        btn.type = 'button';
        btn.style.padding = '5px 15px';
        btn.style.border = '1px solid #666';
        $(btn).click(mapMenu);

        var loading = document.createElement('span');
        loading.style.display = 'none';
        loading.style.color = 'red';
        loading.id = 'loading-sync';
        loading.innerHTML = 'loading...';

        $('.form-item.form-type-select.form-item-menu-parent').prepend(loading);
        $('.form-item.form-type-select.form-item-menu-parent').prepend(btn);

  });
}


function mapMenu() {
        var sendurl = '/sync-menu/';
        var params = 'menu=main-menu&l='+jQuery('#edit-language').val();

        // translation already exists, so give nid
        if(location.href.match(/^.*node\/\d+.*$/))
        {
                var nid = location.href.replace(/^.*node\//,'').replace(/\/.*/,'');
                params += '&nid='+nid;
        }
        // no translation exists, so give the source nid
        else if(location.href.match(/^.*translation=/))
        {
                var snid = location.href.replace(/^.*translation=/,'').replace(/&.*$/, '');
                params += '&snid='+snid;
        }
        else
        {
                alert('No translation available for this menu');
        }
        jQuery.ajax({ url: sendurl, context: document.body, success: mapMenuCallBack, data:params, type:"GET"});
        jQuery('#loading-sync').css('display','inline');
}

function mapMenuCallBack(responseText)
{
        jQuery('#loading-sync').css('display','none');
        if(!responseText) {alert('No translation available for this menu'); return;}

        eval('var obj = '+responseText);
        if(obj.plid) jQuery('#edit-menu-parent').val('main-menu:'+obj.plid);
        if(obj.weight) jQuery('#edit-menu-weight').val(obj.weight);
}

/sync-menu/index.php

<?php
// this script is a hack to synchronize multilingual menues.  i don't have time to learn Drupal 7 and the proper way to do things.

include('../sites/default/settings.php');

$cnx = mysql_connect($databases['default']['default']['host'], $databases['default']['default']['username'], $databases['default']['default']['password']);
if(!$cnx) die('failed to connect');

$db = mysql_select_db($databases['default']['default']['database'], $cnx);
if(!$db) die('failed to select db');

$arr_translation = array();
//$menu_name = $_GET['menu'];
$menu_name = 'main-menu';
$lang = substr($_GET['l'],0,2);
$nid = isset($_GET['nid']) ? intval($_GET['nid']) : 0;
$src_nid = isset($_GET['snid']) ? intval($_GET['snid']) : 0;

if($nid)
{
        $sql = "SELECT tnid FROM `node` WHERE nid = $nid";
        $result = mysql_query($sql);
        $row = mysql_fetch_assoc($result);
        if($row)
        {
                $src_nid = $row['tnid'];
        }
}

if($src_nid && $lang && $menu_name)
{
        // find the menu id of source node
        $sql = "SELECT * FROM `menu_links` WHERE menu_name = '$menu_name' AND link_path = 'node/$src_nid'";
        $result = mysql_query($sql);
        $row = mysql_fetch_assoc($result);
        if($row)
        {
                $arr_translation['weight'] = $row['weight'];

                // find the parent menu id of source node
                $sql = "SELECT * FROM `menu_links` WHERE menu_name = '$menu_name' AND mlid = $row[plid]";
                $result= mysql_query($sql);
                $row = mysql_fetch_assoc($result);
                if(!$row) exit;
                // if parent menu item uses a "menu translation"
                if($row['i18n_tsid'])
                {
                        $sql = "SELECT * FROM `menu_links` WHERE i18n_tsid = $row[i18n_tsid] AND language = '$lang' AND i18n_tsid <> 0";
                        $result = mysql_query($sql);
                        $row = mysql_fetch_assoc($result);
                        if($row)
                        {
                                $arr_translation['plid'] = $row['mlid'];
                                print json_encode($arr_translation);
                        }
                }
                // if parent menu item uses a node translation, find the node it links to, get it's translation, get the relevant menu item
                else
                {
                        $src_nid = str_replace('node/','',$row['link_path']);
                        $sql = "SELECT nid FROM `node` WHERE language = '$lang' AND tnid = $src_nid";
                        $result = mysql_query($sql);
                        $row = mysql_fetch_assoc($result);
                        if($row)
                        {
                                $sql = "SELECT mlid FROM `menu_links` WHERE link_path = 'node/$row[nid]'";
                                $result = mysql_query($sql);
                                $row = mysql_fetch_assoc($result);
                                if($row)
                                {
                                        $arr_translation['plid'] = $row['mlid'];
                                        print json_encode($arr_translation);
                                }

                        }
                }
        }
}
?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.