wp-graphql-polylang
wp-graphql-polylang copied to clipboard
Language prefixes do not work in `idType: URI` queries
Hey,
I think at the current time it is literally impossible to fetch home page of non default language. Everything works fine for pages. Take look at full report listed below.
Fetching default home page
query Page {
pageBy(uri: "/") {
title
}
page(id: "/", idType: URI) {
title
}
}
- [x] Fetching using pageBy - works as expected
- [x] Fetching using page - works as expected
Fetching home page for selected language
Disclaimer: Expected page exists, uses directory based permalinks and is available through WordPress through URL like: wordpress-instance.com/pl
query Page {
pageBy(uri: "/pl") {
title
}
page(id: "/pl", idType: URI) {
title
}
}
- [ ] Fetching using pageBy - not working at all
- [ ] Fetching using page - not working at all
Fetching normal page for selected language
query Page {
pageBy(uri: "/pl/kontakt") {
title
}
page(id: "/pl/kontakt", idType: URI) {
title
}
}
- [x] Fetching using pageBy - works as expected
- [x] Fetching using page - works as expected
Fetching normal page for selected language without language prefix
query Page {
pageBy(uri: "/kontakt") {
title
}
page(id: "/kontakt", idType: URI) {
title
}
}
- [ ] Fetching using pageBy - works unexpected, as Page's permalink is /pl/kontakt not /kontakt
- [ ] Fetching using page - works unexpected, as Page's permalink is /pl/kontakt not /kontakt
Unless I am doing something wrong, I think there could be a great benefit by exposing additional language
parameter under pageBy
entity, alongside already existing id
, pageId
, and uri
so that individual page could be safely retrieved in expected language. This should also fix fetching home page for different language issue at the same time.
What do you think?
PS. Excellent package by the way!
@esamattis Could you provide a pointer here, where to start/ fix that? 🙏🏽
@gustavpursche
Hey, I ultimately use REST API altogether with GraphQL (yes, that means multiple network requests) to fetch page IDs.
Thanks for the report!
The id: "/kontakt", idType: URI
args are fairly new in wp-graphql and this plugin has been written before those, so there's no build-in support yet.
Quick look at the wp-graphql code points the issue here:
https://github.com/wp-graphql/wp-graphql/blob/f15bbb5044066c3d09dc96cd5c23acbade1a5727/src/Data/NodeResolver.php#L303
The frontpage logic is hard coded. We need to inject our own custom logic to detect the translated frontpages. Unfortunately the resolve_uri()
does not seem have any filters which we could use. There might be a way to process the id
field earlier and transform it to a format supported by the resolve_uri()
.
But @jasonbahl of wp-graphql has been very open to adding filters to wp-graphql to support things like this.
For example a short circuiting filter like graphql_pre_resolver_uri'
at the very begining of resolve_uri
would allow us to solve this like this:
$front_page_post = get_option('page_on_front');
foreach (pll_languages_list('slug') as $lang_slug) {
if ($parsed_url['path'] === "/$lang_slug") {
$post = pll_get_post($front_page_post, $lang_slug);
if ( $post ) {
return $post;
}
}
}
We might be able to wrap the existing page resolver function with the graphql_Page_fields
filter and first check if the the request is for a translated front page and then call the original resolver if not 🤔
Here's an example how to override it https://github.com/valu-digital/wp-graphql-polylang/issues/38
Ah, this would be nice. For now I will have to hard-code the frontpage slug in the code, but full support for the URI would be great.
There's an user land based workaround by @gorkalaucirica here: https://github.com/valu-digital/wp-graphql-polylang/issues/46#issuecomment-852849101
Maybe we can build something like that in to this plugin.
Any update on this ?
A temporary workaround. This fixed it for my use-case:
/**
* Bugfix: prevent fetching pages from other languages. Without below filter, /de/about-us would resolve
* to the english post called /en/about-us, which will give SEO issues. It also fixes an issue if two
* posts in two different languages had the same post_name, the wrong one would/could be resolved
* depending on what language you was requesting
*
* https://github.com/valu-digital/wp-graphql-polylang/issues/35
*/
add_filter( 'request', function ( $query_args) {
if(isset($query_args['uri']) && $query_args['uri'] && isset($query_args['lang'])) {
$explodedUri = explode('/', $query_args['uri']);
if($explodedUri[0] !== $query_args['lang']) {
// query was made without language slug in URI
return $query_args;
}
unset($explodedUri[0]); // remove language slug from URL
$uriWithoutLang = implode('/', $explodedUri); // rebuild the URI without the slug in front
if(function_exists('pll_get_post_language')) {
$post = get_page_by_path($uriWithoutLang);
if(!$post || $post && pll_get_post_language($post->ID) !== $query_args['lang']) {
$query_args = [];
}
}
}
return $query_args;
}, 10, 2);
It's not the prettiest, but it does it's job. We had an issue if two pages was called the same, e.g. /de/about us and /en/about-us, when requesting the /de/about-us, it would resolve the english version.
Also we had an issue where if you requested an english slug, on the german prefix, if a german page did not exist with that name, it would return the english page - on the german site. Above filter also fixes that.
Hey !
Any update about this issue ? I'm facing the same issue, with postQuery
and contentNodeQuery
With "Remove ID from slug home" settings checked in Polylang :
Without "Remove ID from slug home" settings checked in Polylang :