Getting language from path
-
Hello Chouby,
In our settings. Polylang add the language as first parameter. ex next.ca/en/dl/…
with permalink Day and name /2015/07/06/sample-post/We are using an mobile application that does not recognize the language position. It needs only next.ca/dl/…
So my hope is to be able to pass the language info through &lang.
Could you please point me what function I should use to
- get the lang parameter in a URL like http://read.next.ca/dl/%5B…%5D/?lang=fr
- switch to appropriate page version (en|fr)
Here are what I have so far:
Permalink Settings: Day and name /2015/07/06/sample-post/
Link to use: http://read.next.ca/dl/content/cdb/2015-03-22/ri/ee7b1825-2df5-3fa0-bc83-85608eecf018/?lang=fr
Note: on mobile, this URL would be recognized and the App would load the right article. So all the work is to make the worpress page display the appropriate language.
rewrite rule (it works accorging Rewrite Rules Inspector plugin):
add_rewrite_rule( 'dl/([a-zA-Z]+)/([a-zA-Z]+)/([0-9-]+)/ri/([0-9a-zA-Z-]+)/?(.*)', 'index.php?pagename=dl&$matches[5]', 'top' );Note: dl page is the english version slug. French slug is dl-fr.
Thanks in advance,
-
Chouby,
My understanding is everything after the question mark in not taken care of in rewrite rules. So my rewrite rule would be incorrect. So the whole rule would not apply.
So please consider this
add_rewrite_rule( 'dl/([a-zA-Z]+)/([a-zA-Z]+)/([0-9-]+)/ri/([0-9a-zA-Z-]+)/?', 'index.php?pagename=dl', 'top' );The URL would be
http://read.next.ca/dl/content/cdb/2015-03-22/ri/ee7b1825-2df5-3fa0-bc83-85608eecf018/?lang=frand I need to use PLL functions to pick up the lang parameter
and set the page language accordingly.Please help,
ThanksHi!
Note: dl page is the english version slug. French slug is dl-fr.
I probably did not completely understood your problem. But what happens if you choose ‘dl’ as English language code and ‘dl-fr’ as French language code?
Chouby,
I have this language switch code for the template page yet.
global $polylang; if (isset($polylang)) { $lang_actual = pll_current_language(); $lang_requested = isset($_GET['lang']) ? $_GET['lang'] : null; /* Change language if * there is lang parameter define * and different than the one active * */ if ( $polylang->model->get_language($lang_requested) && $lang_actual !== $lang_requested ) { // Set Polylang language // Do anything need to get polylang/wordpress use the appropriate page. } // else: Keep Actual language no page switch // Anything else to do? }What would be need to switch the language?
Is there any extra step I would not thought of?Please advise,
ThanksThanks Chouby.
Because I must abide to how the mobile application need the URL, I must not use the language slug (en|fr) for all URLs starting with /dl.
For us, dl (and dl-fr) are page slugs.
So somehow, URLs to dl or dl-fr pages should not have a language slug. The language information would have to be passed as parameter.
The idea is, if the URL is read on a mobile, the app will load and go the requested article (deeplinking feature).
The page identifier dl must be used as first position.
Eg read.next.ca/dl/….If this is on a desktop, it would go the our WordPress site.
In this case read.next.ca/dl/…. would not have language slug and would fall on default english language.
I want to use the lang parameter and switch to another language if needed.
Eg read.next.ca/dl/….?lang=frPlease refer to my code in previous post.
Thanks in advance for your help.
To be honest, I did not forecasted such use case and thus Polylang is not very flexible to accept this. I did not test but maybe you can try to hook to ‘pll_language_defined’ action (with priority 0) and hack directly $polylang->curlang (it is public). Check the function set_language in frontend/choose-lang.php.
I was looking into a similar solution, just a simple query override. Here is my attempt w/the information you’ve provided Chouby. The majority of this code is just checking the query against known supported languages before making the override.
This doesn’t work 100%, 100% of the time – but it get’s pretty close.
The goal would be for anyone, even an FB crawler to specify a locale when linking to a page like https://black-buddha.com/?locale=zh_TW or https://black-buddha.com/zh_tw/watch/mott32-2/?fb_locale=en_US. I’ve been seeing a lot of log entries from facebook.com/externalhit_uatext.php lately and I wonder if this might be helpful.
Either way, I just want to solve this translation override for the login form, so here is a start.
Cheers
/* ================================================== * OVERRIDE CURRENT PLL LANGUAGE * ==================================================*/ /** * HiJack the pll_language_defined action and override the current language. * @param string $slug * @param PLL_Language $curlang * @example https://black-buddha.com/?l=zh_TW * @example https://black-buddha.com/zh_tw/city/θΊε/?locale=en_US * @example https://black-buddha.com/watch/flask/?fb_locale=zh_TW * @example https://black-buddha.com/?lang=zh_TW */ function ___pll_language_defined ( $slug, $curlang ) { static $override_language = FALSE; global $polylang; if ( ! $polylang ) { return; } if ( ! $override_language ) { $reqs = array( $_GET, $_POST ); $params = array( 'lang', 'locale', 'l' , 'fb_locale' ); foreach ( $reqs as $req ) { if ( $override_language ) break; foreach ( $params as $param ) { if ( $override_language ) break; if ( ! empty( $req[ $param ] ) ) { $override_language = sanitize_key( $req [ $param ] ); break; } } } } if ( $override_language ) { // validate against known languages $supported_languages = $polylang->model->get_languages_list ( ); foreach ($supported_languages as $lang) { if ( FALSE != preg_match( "/($override_language)/i", $lang->locale )) { $override_language = $lang->slug; break; } } if ( ! $override_language) { error_log ( 'FAILED to find language support for ' . $override_language ); $override_language = FALSE; return; } // try to get the language $nLanguage = $polylang->model->get_language( $override_language ); if ( $nLanguage ) { $polylang->curlang = $nLanguage; $GLOBALS [ 'text_direction' ] = $polylang->curlang->is_rtl ? 'rtl' : 'ltr'; stop_checking_language_code_in_url ( ); // NOTE: setcookie has been called already // (PLL_Choose_Lang)$this->maybe_setcookie(); } else { error_log ( 'FAILED to change language to ' . $override_language ); $override_language = FALSE; } } } // NOTE: do_action called from wp-content/plugins/polylang/frontend/choose-lang.php add_action('pll_language_defined', '___pll_language_defined', 0, 2); function stop_checking_language_code_in_url ( ) { global $polylang; if ( $polylang ) { remove_action('wp', array ( $polylang->choose_lang, 'check_language_code_in_url' )); } } // WARNING: Stops working well when you remove the code in url check... // if(did_action('plugins_loaded')) stop_checking_language_code_in_url(); // add_action( 'plugins_loaded', 'stop_checking_language_code_in_url', 10 );Chouby,
I have some difficulties to find the proper call of set_language().
Could you please help me find the proper object I should use?
global $polylang; $polylang-> ??? ->set_language('fr');Merci d’avance
Chouby,
Debuging I have found out the
– $polylang = new PLL_Frontend
– PLL_Frontend $class = ‘PLL_Choose_Lang_Url’
– $polylang->choose_lang = new PLL_Choose_Lang_Url($this); // this being PLL_Frontend instanciation, $polylang on final
– PLL_Choose_Lang_Url extends PLL_Choose_Lang which has the set_language method.So my call should be
$polylang->choose_lang->set_language($curlang)where $curlang is an object – not a string.
in set_language the line of code defining $curlang is
$this->curlang = ($curlang instanceof PLL_Language) ? $curlang : $this->model->get_language($this->options['default_lang']);So now I need to find how to instanciate the $curlang to pass. I am on it, but will appreciate any help π
Question:
Would it be possible to have a second method with a required_lang string parameter?
protected function set_to_required_language($req_lang) { // final check in case $curlang has an unexpected value // see https://ww.wp.xz.cn/support/topic/detect-browser-language-sometimes-setting-null-language // check to make sure $req_lang is valid // if not use $this->model->get_language($this->options['default_lang'] $this->curlang = $this->model->get_language($req_lang); $this->maybe_setcookie(); $GLOBALS['text_direction'] = $this->curlang->is_rtl ? 'rtl' : 'ltr'; do_action('pll_language_defined', $this->curlang->slug, $this->curlang); }Best,
Good news!
I am now able with only a few lines to change the language.
function detectDLPageLanguage() { //Hooked on PLL event, no need to check PLL existence global $polylang; $curLangSlug = pll_current_language(); $reqLangSlug = $_GET['lang']; /* bunch of validations here */ $polylang->curlang = $polylang->model->get_language($reqLangSlug); /* up to here, language is changed but page URL is unchanged. * Page is loaded with former language */ } add_action('pll_language_defined', 'detectDLPageLanguage');My concern now is even if the language has been changed the page is loading with the original language.
example:
URL: http://read.next.ca/dl?lang=fr
default language: en
Resulting URL: http://read.next.ca/en/dl?lang=fr
Expected result: page loading in requested language.
Expected URL: http://read.next.ca/fr/dl-fr?lang=frSo my question now is when in the load process the page is served based on the language?
After pll_language_defined hooked functions are executed, isn’t it?
So what am I missing?Thanks in advance for your help
My concern now is even if the language has been changed the page is loading with the original language.
What do you mean? The .mo files?
Could you try priority 0?
I mean the language slug is the current language when pll_language_defined fired.
Our default language is ‘en’.
http://read.next.ca/dl would normaly result to http://read.next.ca/en/dl.I was expecting the language slug to change accordingly.
Once my function is executed, I was expecting http://read.next.ca/dl?lang=fr to change to http://read.next.ca/fr/dl-fr?lang=fr – meaning loading the French equivalent page of /en/dl.So now I am wondering what else I have to do. Do I have to call/switch to (somehow) the page?
NOTE 1: Yes, I have tried with priority 0.
add_action(‘pll_language_defined’, ‘dlPageLanguageParameter’, 0);NOTE 2:
I have a mix of French and English.
– Menus are in French – managed by Polylang.
– Everything relating to the page ‘dl’ are in english – information is fetched from the page and this is the english page.Hello Chouby,
Came back to my code this morning and found out it is now working.
My last code is correct.On my localhost
http://next.localhost/dl/?lang=en goes to http://next.localhost/en/dl/?lang=en
http://next.localhost/dl/?lang=fr goes to http://next.localhost/fr/dl-fr/Thanks for your help.
I have learned a lot yesterday. πResolved
The topic ‘Getting language from path’ is closed to new replies.