This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

This thread is resolved. Here is a description of the problem and solution.

Problem:
We would like to define short links. Suppose we have the primary page "Test DE" with the URL "xyz.tld/test-de". The following translations exist for this page:
- "Test EN": xyz.tld/en/test-en
- "Test FR": xyz.tld/fr/test-fr
- "Test IT": xyz.tld/it/test-it
Now we want to define the short link /test, which refers to these pages, where the language of the page should be defined automatically based on the browser language.
Solution:

if( !is_admin() ) {
		global $sitepress;

		$page_id = url_to_postid( $_SERVER['REQUEST_URI'] );

		// Determine available translations of the current article
		$translation_id = $sitepress->get_element_trid( $page_id );
		$translations = $sitepress->get_element_translations( $translation_id );
		$supported_lang = array_keys( $translations );

		// Set language according to supported browser languages. If there is no match,
		// first value of $supported_lang is set as language.
		$lang = http_negotiate_language( $supported_lang );

		// Overwrite language with value from cookie
		$lang_cookie = isset( $_COOKIE[ 'lang' ] ) ? $_COOKIE[ 'lang' ]: '';
		if ( in_array( $lang_cookie, $supported_lang ) ) {
			$lang = $lang_cookie;
		}

		// Overwrite language with value from URL parameter "lang"
		$lang_url = isset( $_GET[ 'lang' ] ) ? $_GET[ 'lang' ] : '';
		if ( in_array( $lang_url, $supported_lang ) ) {
			$lang = $lang_url;
		}

		// If previous language differs from newly defined language, set/adjust cookie and change language
		if ( in_array( $lang, $supported_lang ) ) {
			if ( $sitepress->get_current_language() != $lang ) {
				setcookie ( 'lang', $lang, time() + (10 * 365 * 24 * 60 * 60), '/' );
				do_action( 'wpml_switch_language', $lang );
			}
		}

	}

This topic contains 7 replies, has 2 voices.

Last updated by Radu 3 months, 2 weeks ago.

Assigned support staff: Radu.

Author Posts
July 2, 2019 at 9:33 am #4125381

jeannetteM

Hi

We would like to define short links. Suppose we have the primary page "Test DE" with the URL "xyz.tld/test-de". The following translations exist for this page:
- "Test EN": xyz.tld/en/test-en
- "Test FR": xyz.tld/fr/test-fr
- "Test IT": xyz.tld/it/test-it
Now we want to define the short link /test, which refers to these pages, where the language of the page should be defined automatically based on the browser language. In addition there should be the possibility to call the page in a specific language via /test?lang=it.

In Joomla we had solved this by defining the short URLs as 301 redirects in a htaccess file, each containing the ID of the primary page. So e.g.
RewriteRule ^test$ hidden link{HTTP_HOST}/index.php?page_id=14 [R=301,QSA,L]

The page was displayed according to the browser language, but we were able to override it using the URL parameter.
In WordPress we could also call the page with ?page_id=, but only the directly called page is displayed, regardless of the browser language used. The parameter ?lang= is also ignored.

Any tips on how to realize these shortlinks? We are using WPML in directory mode (different languages in directories).

Many thanks

July 2, 2019 at 10:29 am #4125735

Radu
Supporter

Languages: English (English )

Timezone: Europe/Bucharest (GMT+03:00)

Hey Jeanette,

Thank you for reaching out the WPML support!

I just tested this out and it seems that no matter what URL are you using, when it's accessed (even through shortlink), the redirection will be done.
For example, I have a website with English and French. I got the French URL, made the shortlink for it, and then checked it on my English browser. The redirect worked very well. Can you try to do this too, and tell me how it works for you, please?

Thanks,
Radu

July 2, 2019 at 11:32 am #4126375

jeannetteM

Hi Radu

Thanks for your support.

After some tests i've found out that the redirection works, but only if the cookie "_icl_visitor_lang_js" is not set. after i deleted all cookies and opened the page, i was automatically redirected to the page in the browser language. But even if I closed the browser and called the short link again, I was always redirected to the primary page in german.

Kind regards
Daniel

July 2, 2019 at 11:57 am #4126521

Radu
Supporter

Languages: English (English )

Timezone: Europe/Bucharest (GMT+03:00)

Hey Daniel,

Have you tried to change the redirect option from Dashboard → WPML → Languages → Browser language redirect section? As you can see in the description of these options, the redirect can be made to work just once and remember the language preference for a certain amount of hours (24 by default). I think that this is the reason why the redirect works just one time for you.

Thanks,
Radu

July 2, 2019 at 2:20 pm #4127889

jeannetteM

Hi Radu

The redirect option is set to only redirect, if there is a translation available (2nd option). The value to store the language is set to 24 hours. However, I cannot enter a value less then 24. So how can I stop the system from saving the value?

Thanks
Daniel

July 3, 2019 at 6:04 am #4131931

Radu
Supporter

Languages: English (English )

Timezone: Europe/Bucharest (GMT+03:00)

Hey Daniel,

WPML will do this language redirect only once and then not redirect anymore. We do this to allow visitors to still switch languages. If we always push back to the browser’s language, visitors will not be able to manually switch languages after WPML redirects them to the language set by their browser. This is why the value for that field cannot be set to less than 24 hours. I looked at this to see if there's any way to overwrite this behaviour but I couldn't find anything that might help. I will look a bit more and let you know if I find something that might do the trick.

Thanks,
Radu

July 3, 2019 at 10:15 pm #4139091

jeannetteM

Hi

Based on this https://stackoverflow.com/a/54761486/4163207 post, I came up with the following code:

if( !is_admin() ) {
		global $sitepress;

		$page_id = url_to_postid( $_SERVER['REQUEST_URI'] );

		// Determine available translations of the current article
		$translation_id = $sitepress->get_element_trid( $page_id );
		$translations = $sitepress->get_element_translations( $translation_id );
		$supported_lang = array_keys( $translations );

		// Set language according to supported browser languages. If there is no match,
		// first value of $supported_lang is set as language.
		$lang = http_negotiate_language( $supported_lang );

		// Overwrite language with value from cookie
		$lang_cookie = isset( $_COOKIE[ 'lang' ] ) ? $_COOKIE[ 'lang' ]: '';
		if ( in_array( $lang_cookie, $supported_lang ) ) {
			$lang = $lang_cookie;
		}

		// Overwrite language with value from URL parameter "lang"
		$lang_url = isset( $_GET[ 'lang' ] ) ? $_GET[ 'lang' ] : '';
		if ( in_array( $lang_url, $supported_lang ) ) {
			$lang = $lang_url;
		}

		// If previous language differs from newly defined language, set/adjust cookie and change language
		if ( in_array( $lang, $supported_lang ) ) {
			if ( $sitepress->get_current_language() != $lang ) {
				setcookie ( 'lang', $lang, time() + (10 * 365 * 24 * 60 * 60), '/' );
				do_action( 'wpml_switch_language', $lang );
			}
		}

	}

Additionally, I've added a click listener to the language switcher, which updates the lang cookie when the language is switched.

Using this code, I was able to fulfill all our requirements. Would be nice, if you can have a look at it and inform me about possible problems.

Many thanks
Daniel

July 4, 2019 at 6:23 am #4140425

Radu
Supporter

Languages: English (English )

Timezone: Europe/Bucharest (GMT+03:00)

Hey Jeannette,

I'm glad to see that you managed to sort this out. It's hard to say what problems might appear if you use this code. If the language redirect works the way you want now, I guess that this is the code that you need to use.
I will mark this ticket as resolved now and, if you need help with any other issue or even just a quick question, feel free to open a new ticket.

Regards,
Radu