Problems, need help? Have a tip or advice? Post it here.
19 posts Page 1 of 2
greetings! I am doing a site which is in Norwegian and English and have followed the instructions given by KK here http://www.couchcms.com/forum/viewtopic.php?p=18928#p18928 i.e. I have put multi_lang.php into the couch/addons folder (I have renamed the couch folder to 'admin') and I have added "require_once( K_COUCH_DIR.'addons/multi_lang.php' );" to the kfunctions.php within the addons folder.

I have created two folders - 'en' and 'no' and have the following at the top of no/index.php and en/index.php:
Code: Select all
<?php require_once( '../admin/cms.php' ); ?>
<cms:lang_group
    en='en/index.php'
    no='no/index.php'
/>

But my links to switch languages
<a href="<cms:show my_link_en />">ENGLISH</a>|
<a href="<cms:show my_link_no />">NORSK</a>
aren't working correctly. If I do <cms:show my_link_en /> - nothing is displayed and the same for my_link_no


I have an index.php template at root level with:
Code: Select all
<?php require_once( 'admin/cms.php' ); ?>
<cms:template title='HOME' hidden='1' order='15' />

<cms:php>
    $lc = ""; // Initialize the language code variable
   
    // Check to see that the global language server variable isset()
    // If it is set, we cut the first two characters from that string
    if( isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ){
        $lc = strtolower( substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) );
    }
   
    // set it as a Couch variable
    global $CTX;
    $CTX->set( 'my_lang', $lc, 'global' );
</cms:php>

<cms:if "<cms:not my_lang='en' || my_lang='no' />" >
    <cms:set my_lang='no' 'global' />
</cms:if>

<cms:redirect "<cms:show my_lang />/index.php" />

<?php COUCH::invoke(); ?>


Which initially takes me to the en/index.php - as I'm based in the UK. But I can't then switch to the Norwegian template via the language links.
Any thoughts?
Hi @potato,

Could you please try placing a <cms:dump_all /> in your template and take a look at the variables made available by Couch? Please see if any variables beginning with 'my_link_' can be spotted.
in the en/index.php, yes:
Code: Select all
my_link_en: http://localhost/vertavofestivalen/en/index.php


in no/index.php, no

wondering why this is - I can't see anything obvious
OK, one more check -
are you sure you have defined the type 'relation' field named 'related_page' in the NO template e.g like this ? -
Code: Select all
<!-- related EN page -->
<cms:editable type='relation' name='related_page' label='Related English Page' masterpage='en/index.php' has='one' reverse_has='one' />

IMP: this region is required only in the secondary language templates (NO in your case) and has to be named 'related_page' (if the name is something else, you need to use the '_related_by' parameter of <cms:lang_group> tag to specify this). Make sure you are specifying the correct EN template (en/index.php in your case) with this region.

Please confirm.
yes that code is in the /no/index.php
Code: Select all
<!-- related EN page -->
    <cms:editable type='relation' name='related_page' label='Related English Page' masterpage='en/index.php' has='one' reverse_has='one' />
</cms:template>

But interestingly I deleted the /no/index.php template to see if it would help, and when I come to re-register the template by visiting the URL http://localhost/vertavofestivalen/no/index.php I now get the message
ERROR: Tag "related_pages": relation field 'related_page' not defined in no/index.php
- even though I promise you, it is in there!
Quite a mess, isn't it? :)

I think let us start afresh.
Please remove the cms:lang_group block the NO template -
Code: Select all
<cms:lang_group
    en='en/index.php'
    no='no/index.php'
/>

Re-register the template now. Shouldn't have any problem now. Once registered, make sure you can see the relation dropdown in it showing pages from the EN template. Now put back the cms:lang_group block in it.

See if that helps.

If the problem persists, I'd suggest you please move your site to an online test domain accessible to me so that I can actively try and do something useful. Troubleshooting localhost problems remotely feels like working both blindfolded and handcuffed :)
I did as you suggested and am back to square one.

In http://www.couchcms.com/forum/viewtopic.php?f=2&t=9078&start=20 you said
For non-clonable templates, using relations will work but would be redundant as there is only one page to relate to. You can explicitly use cms:pages with masterpage set to the other language template(s) to get the corresponding values.

Should I not put the following code into no/index.php after all?
Code: Select all
<!-- related EN page -->
    <cms:editable type='relation' name='related_page' label='Related English Page' masterpage='en/index.php' has='one' reverse_has='one' />

Will the solution work when I am listing a cloned template on a non-clonable template?

Another thing I'm confused about is the code to redirect to the correct language
Code: Select all
<cms:redirect "<cms:show my_lang />/index.php" />
Does this snippet need to be in each template e.g. for contact.php
Code: Select all
<cms:redirect "<cms:show my_lang />/contact.php" />

And does the language setting code
Code: Select all
<cms:php>
    $lc = ""; // Initialize the language code variable
   
    // Check to see that the global language server variable isset()
    // If it is set, we cut the first two characters from that string
    if( isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ){
        $lc = strtolower( substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) );
    }
   
    // set it as a Couch variable
    global $CTX;
    $CTX->set( 'my_lang', $lc, 'global' );
</cms:php>

<cms:if "<cms:not my_lang='en' || my_lang='no' />" >
    <cms:set my_lang='no' 'global' />
</cms:if>
have to be in every template? What if the visitor arrives on say, contact.php?

Sorry I'm finding this heavy going ...
Hi @potato,

I am taking the liberty of quoting a part of the message that you PMed me - it describes in more detail exactly what points are getting you confused -
The site will display Norwegian by default and offer language switching to English via a text link: NORSK | ENGLISH Looking at the topic viewtopic.php?f=2&t=9078&start=10 I'm not sure how it's all going to hang together. Should I be reading more instructions in conjunction with this? How will the my_lang variable get set if arriving on a page other than the home page for example? If someone gets the site in Norwegian but wants to read the site in English - they click on ENGLISH and then navigate the site - will it remain in English? How should I set up my main navigation links? How do I handle non-clonable pages? How would I handle non-clonable pages with a listing of cloned pages? Sorry - I'm not asking you to do all the work for me but I can't see how to plan this site at the outset or where to begin ...

I will try to give you the over-all picture that you are looking for.

As our example, let us assume following is your proposed setup -
Code: Select all
site_root
  |_couch (folder)
  |_en (folder)
  |   |_index.php
  |   |_about.php
  |   |_news.php
  |_no (folder)
  |   |_index.php
  |   |_omkring.php
  |   |_nyhet.php
  |_index.php
 

As can be seen, each of the two languages has three templates in its respective folder.
The news template is clonable while the other two are non-clonable.
Outside the two language folders, there is one 'index.php' directly in the root.

To implement such multi-lingual site, it would be helpful to consider each language component as a *separate site*.

Allow me to elaborate on that point. In our example we have two languages. The 'en' part comprises of 'en/index.php', 'en/about.php' and 'en/news.php' while the 'no' part consists of 'no/index.php', 'no/omkring.php' and 'nyhet.php'.

While implementing any of the three 'en' template, forget the 'no' part totally and refer *only* to the other 'en' templates. Similarly while implementing any of the three 'no' templates, forget the 'en' part totally and refer only the other 'no' templates.

Take a look at the following sample 'en/news.php' -
Code: Select all
<!-- menu -->
<ul>
    <li><a href="<cms:link 'en/index.php' />">Home</a></li>
    <li><a href="<cms:link 'en/about.php' />">About</a></li>
    <li><a href="<cms:link 'en/news.php' />">News</a></li>
</ul>

<!-- list of pages -->
<cms:pages masterpage='en/news.php' >
    <h2><cms:show k_page_title /><h2>
    ..
</cms:pages>
As you can see, all the templates referred to within it belong to the 'en' group. No 'no' templates anywhere.

The counterpart sample 'no/nyhet.php' would look like this -
Code: Select all
<!-- menu -->
<ul>
    <li><a href="<cms:link 'no/index.php' />">Hjem</a></li>
    <li><a href="<cms:link 'no/omkring.php' />">Omkring</a></li>
    <li><a href="<cms:link 'no/nyhet.php' />">Nyhet</a></li>
</ul>

<!-- list of pages -->
<cms:pages masterpage='no/nyhet.php' >
    <h2><cms:show k_page_title /><h2>
    ..
</cms:pages>
As again you can see, there are no references to any 'en' group templates. All the links point to only 'no' templates.
Same pattern would be followed in all the templates.

This way, whenever a visitor is on any page of a particular language, all the links visible to her would lead to the other sections of the *same* language.

In a way we have created each language section as a water-tight component totally isolated from the other languages. This is what I meant by my earlier expression about considering each language component as a *separate site*.

I know, you will have some questions at this point but please bear with me for a while and continue exactly as I am proposing.

Ok, so now we have two 'sub' sites - the entry point into 'en' being 'http://yoursite.com/en/' while for the other one being 'http://yoursite.com/no/'.
However, when a visitor arrives first at your site she is likely to land at 'http://yoursite.com/'.
This is where the 'index.php' placed directly in the site root comes into play.

The sole purpose of this template is to redirect the visitor to the proper language sub-site.
This is done by placing the following within it -
Code: Select all
<cms:php>
    $lc = ""; // Initialize the language code variable
   
    // Check to see that the global language server variable isset()
    // If it is set, we cut the first two characters from that string
    if( isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ){
        $lc = strtolower( substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) );
    }
   
    // set it as a Couch variable
    global $CTX;
    $CTX->set( 'my_lang', $lc, 'global' );
</cms:php>

<cms:if "<cms:not my_lang='en' || my_lang='no' />" >
    <cms:set my_lang='no' 'global' />
</cms:if>

<cms:redirect "<cms:show my_lang />/index.php" />

Moving on, now suppose a visitor gets redirected to the 'no' sub-site. She can navigate further deep into the site but all the pages would be of 'no' group (as we have seen).

What if now she decides to take a look at the 'en' section?
We have to provide a conduit somewhere between our two watertight sections.

To do that, we can place a link somewhere at the top-right (as is the convention using little flags) providing a link to the home page of 'en' section.
If she clicks that, she is now in the 'en' sub-site with all the links now pointing to the 'en' pages. To grant her a way back into the 'no' section, again we can place a little link pointing to the home page of the 'no' section.

So this association between the two language sub-sites is an after-thought - it needs to be done after the two sub-sites have been completed independent of each other.

The technique above will work but the drawback is that the link we provided above always makes the visitor land on one fixed location of the other language (home page in our example). Ideally we would like the visitor to land in the part of the opposite language that *exactly* corresponds to her current location e.g. if she is in 'en/about/', the flag link should lead her to 'no/omkring/'. If she on a cloned page of news section, clicking the link should take her to the corresponding news item in the other language.

Setting up such kind of corresponding links manually would be quite a chore.
This is where the 'multi_lang' addon steps in (I won't go into the details of using it - it is explained at viewtopic.php?p=18928#p18928).

Whatever page the visitor might be at, this addon automatically sets up the links of the corresponding pages of the other languages.

So if we were to place the following 'flag' menu somewhere at the top right of all templates, it would automatically lead to the correct location -
Code: Select all
<a href="<cms:show my_link_en />">EN</a> |
<a href="<cms:show my_link_no />">NO</a>

As a variation of the above, we could place only the 'NO' link in 'en' group templates -
Code: Select all
<a href="<cms:show my_link_no />">NO</a>

and vice-versa in 'no' group as follows -
Code: Select all
<a href="<cms:show my_link_en />">EN</a>

With that explanation, let us review the doubts that you had and let us see if we can explain those -

How will the my_lang variable get set if arriving on a page other than the home page for example?
The 'my_lang' you are referring to is used only by the root index.php template only for the purpose of determining which language sub-site to redirect the visitor to. To set it, we have already seen the code placed in that template. For the rest of the site, this variable is not needed so you don't have to worry about it.


If someone gets the site in Norwegian but wants to read the site in English - they click on ENGLISH and then navigate the site - will it remain in English?
As explained above, once the visitor manages to reach the 'en' site, all the links there would point to 'en' templates. So, once again, you don't have to worry about this - the other pages will remain in English.


How should I set up my main navigation links?
As explained above, using templates of the same language group as the one you are displaying the menu on.


How do I handle non-clonable pages?
Exactly as you would handle the clonable ones. Use the relation field also - it'd look funny displaying only a single page to select but would give you a uniform way of dealing with all templates.


How would I handle non-clonable pages with a listing of cloned pages?
Again, by setting the 'masterpage' parameter of cms:pages to point to clonable template of the same language group as the non-clonable one doing the listing.


I can't see how to plan this site at the outset or where to begin
Sincerely hope this won't be the case after reading this lengthy post :)

To make things a bit more simpler for you, I am attaching a complete skeletal implementation of the kind of site we discussed.
You may register the seven templates and play around to get a hang of things before getting into implementing your own site.

www.zip
(4.21 KiB) Downloaded 476 times

Note: the attached site is functional and has been tested.
The code for menu and the language switcher in each template could be moved into separate snippets thus simplifying the overall code a lot.

Hope it helps.
as is the convention using little flags

Actually it's not the best practice. The multi-lingual community has pointed to many mistakes, associated with using of flags.
Some resource to start with: http://flagsarenotlanguages.com/ and another nice one (and short) is http://wplang.org/never-use-flags-language-selection/
Thank you do @kk for taking the time to write one of your small masterpieces. You have a gift for communication and making things clear! I have problems at the moment with wifi connection on my desktop so can't download at the moment. Will get back to it as soon as possible. Thanks again :D
19 posts Page 1 of 2
cron