FarCry - navigation in a multi language site

A client wanted a site that should have content in Norwegian, English and French. In the design file there was separate choises for the three different languages, and then a navigation area, where the navigation should be in the currently selected language.

This could be solved in different ways. One could make three different page templates calling the three different language navigations - or one could make categories for each of the languages and make pages belong to one of these.

However we wanted to have only one template, and not to have categories. We wanted to sort it with three different top nodes in the site tree. Looking like this:

Then we gave aliases to these three navigation nodes.

We then made a new method in a utilities cfc we use in our company, and call it like this from out header template (before the navigation section):

<cfinvoke component="farcry.idlmedia_core.utilities" method="searchForParentAlias" returnvariable="parentAlias">
   <cfinvokeargument name="objectID" value="#request.navid#">
   <cfinvokeargument name="aliases" value="home,engelsk,fransk">
</cfinvoke>

The method then checks if the current page, or any of it's ancestors have an alias of one of those provided with the cfinvokeargument. It then returns the alias, and we can make the navigation like so:

<skin:genericNav navID="#application.navid[parentAlias]#"
   id="nav"
   depth="2"
   bActive="true"
   bIncludeHome="false">

Here's the code for the method (first version - it still needs some work):

<cffunction name="searchForParentAlias" access="public" returntype="any" hint="searches up the navigation tree for a node with alias from argument.aliases">
   <cfargument name="objectID" hint="Navigation ObjectID" type="uuid" required="yes" />
   <cfargument name="aliases" required="yes" type="string" hint="list of aliases to search for">
      
      
   <cfset qAncestors = request.factory.oTree.getAncestors(objectid=arguments.objectid)>
   <cfset listAncestors = QuotedValueList(qAncestors.objectid)>
   <cfset listAncestors = ListAppend(listAncestors,"'#arguments.objectid#'")>
         
   <cfloop list="#arguments.aliases#" index="i">
            
      <cfset thisaliasid = application.navid[i]>
      
      <cfif ListFind(listAncestors, "'#thisaliasid#'")>
         <cfset foundParentAlias = i>
      </cfif>
         
   </cfloop>
      
   <cfreturn foundParentAlias>
      
</cffunction>

By doing it this way we have a reusable way of handling this, without the hassle of managing several very similar templates, and with a very intuitive grouping of the different articles in the site tree.

Comments
This works a treat and is the simplest and most elegant solution that I've seen for multilingual sites in FarCry. An addes bonus is that if you have a site map for example, it generates a new one for each language depending on where you are in the tree. I need to create a FarCry site that has versions in English, Spanish and Basque so thanks very much.
# Posted By Simon Clarke | 4/7/07 11:04 AM
I there a more complete version of this code? Or is this the final version?

Thanks,

Josen
# Posted By Josen Ruiseco | 9/10/07 9:35 AM
Josen - at the moment I've made nothing more out of this code. It works pretty well as is though :)
# Posted By Trond Ulseth | 9/11/07 2:09 AM
Hi Josen,

I'm starting my first site with Farcry and it's a multilingual site (it would be too easy if not ;) ).
I'm trying to implant your solution but if I trace the parentAlias variable I just get nothing (in fact foundParentAlias in the function is empty).

My structure is like that:
Home
-fr
--subsec
--...
-en
--sebsec
--..
-es
...

So I think that the problem come from the fact each top level are under Home (I splash page), not under the root.

Could you give me a hand on that ?

Thanks !
# Posted By Pv Ledoux | 12/13/07 11:15 AM
Hi Pv

Make sure that the navigation aliases are in place on the top navigation nodes for each language (this is not the same as the title of the navigation links - even though they are in my example above), and that these aliases match the ones you write in the cfinvokeargument.

Something like this for you:

<cfinvokeargument name="aliases" value="fr,en,es">
# Posted By Trond Ulseth | 12/14/07 3:21 AM
# Posted By feromon | 12/30/07 3:17 PM