Could you please give a quick yes/no answer on the same URL slugs issue – we’re rolling out the new blog this week and this is a determining factor on whether we will use the plugin across all our blogs or not.
Plugin Author
Chouby
(@chouby)
Hello,
I don’t know what this function switch_lang is useful for. Could you explain a use case?
Polylang does not allow identical slugs and although it is in the todo list, it’s not planned for near future.
Basically, we need to be able to set a language before the headers are sent, regardless of the URL. This is due to our load balancer setup, we made it look so it runs out of a subdirectory for SEO reasons (http://www.cheapflights.com/news/) whereas it’s actually hosted on a separate server and the load balancer forwards all /news/ traffic to it. With WPML, even though it’s set up as ‘domain per language’ it’s still not picking the language correctly, and so an extra check for the HTTP_HOST is needed.
What would it take to add the same URL feature? I could contribute to the plugin and find a solution myself – but could you point me in the right direction? The above code is sort of half-way there, I got it to save but then it will load only the first found post on the front-end and redirect the second, disregarding the language parameter.
Thanks.
Plugin Author
Chouby
(@chouby)
I know nothing on load balancing…
I don’t believe that it is possible to set the language before Polylang defines it (maybe that’s something I could think to). But you should be able to overwrite the choice with something like:
add_action('pll_language_defined', 'switch_lang');
function switch_lang() {
global $polylang;
$polylang->curlang = $polylang->model->get_language('en_US');
$GLOBALS['text_direction'] = $polylang->curlang->is_rtl ? 'rtl' : 'ltr';
}
without warranty…
but then it will load only the first found post on the front-end and redirect the second
Yes that’s a feature of Polylang to avoid duplicate content.
You should be able to remove it with something like:
global $polylang;
remove_action('wp', array($polylang->choose_lang, 'check_language_code_in_url'));
That’s exactly what I needed – to be able to force set a language regardless of the URL. Didn’t work inside the action, but did outside of it. Thanks.
This disables the redirection, but it loads the same post content on both URL’s – is there another hack that can fix this?
Plugin Author
Chouby
(@chouby)
I am sorry, but you are entering an area that I did not explore.
OK… that’d be critical if we were to move the existing blogs over so we’ll stick with what we have for now – but I’ll definitely keep an eye on new features, Polylang is a superior solution by far.
I may have found a fix – turns out it will display both post contents if the posts have the same URL – naturally, being part of a while loop. Just needed to filter out the correct language in single.php after the_post() (rather crudely, so feel free to point out a better solution):
global $polylang;
if($polylang->get_post_language(get_the_ID())->slug !== pll_current_language()) continue;
There’s still an issue with hreflang attributes pointing to the current language domain only, so I’m adding this to frontend-links.php:129 (again, rather crudely, so please feel free to provide an alternative):
if ($url = $this->get_translation_url($language)) {
$url = str_replace(pll_home_url(), pll_home_url($language->slug), $url);
$urls[$language->slug] = $url;
}
OK that didn’t quite work – however this did, at the top of single.php:
global $wp_query, $polylang;
if($wp_query->post_count > 1) {
foreach($wp_query->posts as $k=>$found_post) {
if($polylang->get_post_language($found_post->ID)->slug == pll_current_language()) {
$wp_query->post = $wp_query->posts[$k];
$wp_query->queried_object = $wp_query->posts[$k];
$wp_query->queried_object_id = $wp_query->posts[$k]->ID;
if(!$wp_query->posts[0]) {
$wp_query->posts[0] = $wp_query->posts[$k];
unset($wp_query->posts[$k]);
}
} else {
unset($wp_query->posts[$k]);
}
}
$wp_query->post_count = count($wp_query->posts);
$wp_query->found_posts = count($wp_query->posts);
}
No need to check the post lang in the while loop.
I managed to get duplicate slugs to save, but can’t get the above code to work. $wp_query->post_count is always 1, even when there are two pages with the same slug. Is there something I’m doing wrong?
It seems like the best solution would be a query like: WHERE post_name = %s AND language_id = %d. Then slugs wouldn’t be ambiguous on the front-end. But I have no idea how to make that kind of change.
Edit: Forgot to say that I’m trying to get this to work for pages, not blog posts.
@ivan – I have created a small plugin that should solve the issue of identical slug across multiple languages. It works for me but would love some other people to test it and provide feedback https://github.com/grappler/polylang-slug
@ulrich, I just installed your plugin and it works for me. Thanks for this!