We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 727
    • 502 Posts
    I’m not claiming this is the perfect solution, but it works for my needs.

    First download the free flag icons from:

    http://www.famfamfam.com/lab/icons/

    Copy the gif versions of the flags of the languages that you want to use to assets/images, keeping the filename the same (e.g. de.gif).

    Next create a snippet called "Redirect":

    <?php
    $url = $modx->makeUrl($id);
    ob_end_clean(); // this will end the output buffer and discard silently what ever was in it
    header('Location: '.$url);
    ?>
    


    and one called "Languages":

    <?php
    // get languages info
    $tv = $modx->getTemplateVar('languages', "", $modx->documentIdentifier);
    $languages = $tv['value'];
    
    if (!strlen($languages))
    {
      return "";
    }
    
    $langnames = array(
      "en" => "English",
      "de" => "Deutsch"
      );
    
    $output = "";
    
    // get entries in languages list
    $entries = explode(",", $languages);
    // loop through language entries
    for ($e = 0; $e < count($entries); $e++)
    {
      // seperate into lang code and target document id
      list($lang, $targetid) = explode("=", $entries[$e]);
      $image = '<img src="assets/images/'.$lang.'.gif" width="16" height="11" border="0" alt="'.$langnames[$lang].'" />';
      if (strlen($output))
      {
        $output .= ' ';
      }
      $output .= '<a href="'.$modx->makeUrl($targetid).'">'.$image.'</a>';
    }
    
    return $output;
    ?>
    


    Edit the langnames array in the Languages snippet to list all the languages you will support. The first two letters are the ISO country codes (http://www.bcpl.net/~j1m5path/isocodes.html) and will match the flag icons (which also use the same codes). Make sure to enter the country name in the native language of that country (e.g. "Deutsch" instead of "German").

    Next create a template variable called "languages", with the type "text". Associate this will your template(s).

    Edit your templates to call the Languages snippet with no parameters. Place it where you want the flags to appear. Users click on the flags to change the language.

    Create empty documents with names that match the ISO country codes. For example I created documents called "en" and "de" for an English/Deutsch website.
    Add documents under the country code documents. I.e. you are duplicating your entire site each time, once per language. For example I have:

    start (1)
    en
     |-> Welcome (2)
    de
     |-> Willkommen (3)
    


    For the "root" document, I.e. the one that shows by default (in my example it’s "start" with ID 1), add the Redirect snippet:

    Redirect?id=`2`
    


    so the page will redirect to one of the welcome pages. In my example the default language will be English. If I changed the ID in the redirect to 3 then the default language would be Deutsch.

    For each page on your site you need to specify which is the translated page. This is achieved using the languages template variable. The format of the template variable value is:

    two_letter_iso_country_code=document_id,two_letter_iso_country_code=document_id

    Here are some examples:

    de=3
    


    specifies that the Deutsch version of this page has the ID 3.

    en=2,pl=6,fr=7
    


    specifies that the English version of this page has the ID 2, the Polish version of this page has the ID 6 and the French version of this page has the ID 7.

    That’s it! The Languages snippet looks at the template variable for the current page and then uses the flag icons to build the links to the same page in different languages.

    To add more languages:


    • Duplicate all site pages in the new language
    • Add the new flag icon to assets/images
    • Add the new language to the array in the Languages snippet
    • Edit existing pages to specify where the new translated page is, using the languages template variable

    Comments welcome. I hope this is useful to someone else.

    Andy
      • 7923
      • 4,213 Posts
      Sounds good wiki stuff! smiley


        "He can have a lollipop any time he wants to. That's what it means to be a programmer."
        • 727
        • 502 Posts
        I’m swamped right now - sneaked the above post in my lunch break. So if you want to copy it to the Wiki, please go ahead. smiley

        Andy
          • 24330
          • 28 Posts
          Wow. Looks really clean and simple to integrate so far, but it raises a few questions.
          Please forgive me any ignorance or n00bish-ness... grin

          1. So how does this integrate with Dropmenu/Wayfinder? More specifically, as Wayfinder requires a startId when it’s called in the template, how do you avoid having to create a new template for each language?

          2. In the case of moving an existing site with only one language to using this method to internationalize, how would switching the site start page to a simple redirect affect search engine listings? In this type of case, would anyone agree that it’s better to not even use the redirect portion?

          3. I have some PHP coding experience, but not a ton. If I wanted to add a TITLE attribute to the A tag with the name of the language for more usability (tooltip popups), would this be the correct change to the output line?

          $output .= '<a href="'.$modx->makeUrl($targetid).'" title="'.$langnames[$lang].'">'.$image.'</a>';


          Thanks in advance!
            Rafael
            • 33372
            • 1,611 Posts
            I do something very similar for billingual sites. I have a TV called "Other Language Document ID" where I enter the corresponding document ID (since I only have two) and a couple snippets (one in English and one in Spanish) that shows a link to the other document if there is one. Each language is in its own folder, so WayFinder and things like that are very straightforward.

            What I really like about this sort of solution is that it allows you to jump to the same page in another language (not just to the other language’s home page, from which you’d have to search for the page you came from). Most people will probably come to your site via a search engine and they want to see that specific page. Since they might get results in a language they don’t understand, this is the quickest path (other than browser language detection, which I personally don’t like) to what they wanted to read.

            The only thing that you might consider adding to your snippet is appending any query strings to the the other languages URLs so that those are not lost when switching.
              "Things are not what they appear to be; nor are they otherwise." - Buddha

              "Well, gee, Buddha - that wasn&#39;t very helpful..." - ZAP

              Useful MODx links: documentation | wiki | forum guidelines | bugs & requests | info you should include with your post | commercial support options
              • 17883
              • 1,039 Posts
              Just an idea...

              In the Tiny MCE editor link popup you have an selection of existing documents. Wouldn´t it be possible to integrate this selection via plugin to the document´s editing screen (under the selected template e.g.)? So you can easily select the "original" document in a specified standard language. Secondly you have a tv where you specify the language pf the current document. After saving the document the language and the corresponding id (of the original language doc) is saved to a simple db-table.

              So we have table like this

              modx_lang_docs

              id native_id corresponding_id lang
              -----------------------

              1 2 17 en
              2 3 18 en
              3 3 19 fr
              4 5 22 en
              5 5 34 fr

              and so on,

              where native_id is the id of the native doc (the standard language), corresponding_id the id of the corresponding doc in the "lang" language.

              So you could create language-links e.g. for doc 3 with [~3~] for german (standard), [~18~] for english, [~19~] for french.

              Just thinking...

              And:
              1. So how does this integrate with Dropmenu/Wayfinder? More specifically, as Wayfinder requires a startId when it’s called in the template, how do you avoid having to create a new template for each language?

              No problem with ultimate parent I think (each language is in its own folder).



                • 17673
                • 194 Posts


                Interesting!
                ...after cloning your default language directory into a new language one though, you still need to edit all docs one-by-one and manually enter the corresponding ID in the ’Languages’ Template Variable.

                Maybe it wouldn’t be so hard to write a plugin that:

                [tt] foreach doc in the newLanguageDir {
                read the docTitle;
                find a matching title in the original dir;
                sets the Language TV values accordingly;
                }[/tt]


                ...then the editors can start translating the new docs, the titles should not be touched before the plugin is run!

                What do you think?


                  ----------------------------------------------------------
                  http://www.linkedin.com/in/lucapost/
                  http://www.twitter.com/lukwe/
                  ----------------------------------------------------------
                  • 24330
                  • 28 Posts
                  Marc wrote:
                  No problem with ultimate parent I think (each language is in its own folder).

                  ??? Sorry guys... I am still not clear on this answer to my first question...
                  I realize that each language is in its own folder, but within each folder you still have to call Wayfinder in a different way, no? And since Wayfinder is called in the template, it seems you’d have to either make a slightly different template for each language, or somehow turn wayfinder into a template variable, right? undecided
                    Rafael
                    • 7923
                    • 4,213 Posts
                    Quote from: NameCat.com at Jan 19, 2007, 01:26 PM

                    ??? Sorry guys... I am still not clear on this answer to my first question...
                    I realize that each language is in its own folder, but within each folder you still have to call Wayfinder in a different way, no? And since Wayfinder is called in the template, it seems you’d have to either make a slightly different template for each language, or somehow turn wayfinder into a template variable, right? undecided
                    Use [!Wayfinder? &startId=`[[UltimateParent]]`!] and it always lists the menu from the top folder of each language..


                      "He can have a lollipop any time he wants to. That's what it means to be a programmer."
                      • 33372
                      • 1,611 Posts
                      Quote from: doze at Jan 19, 2007, 01:44 PM

                      Use [!Wayfinder? &startId=`[[UltimateParent]]`!] and it always lists the menu from the top folder of each language..
                      Now that’s a neat trick...
                        "Things are not what they appear to be; nor are they otherwise." - Buddha

                        "Well, gee, Buddha - that wasn&#39;t very helpful..." - ZAP

                        Useful MODx links: documentation | wiki | forum guidelines | bugs & requests | info you should include with your post | commercial support options