grav icon indicating copy to clipboard operation
grav copied to clipboard

Fix multilang redirects and routes

Open nbusseneau opened this issue 3 years ago • 10 comments

Multilang redirects and routes were not working as per the documentation ("All redirect rules apply on the slug-path beginning after the language part (if you use multi-language pages)") due to language prefixes being included in URL when trying to match source URL and redirect/route source pattern.

Using $route parameter fixes the issue as given route does not include language prefixes (coming from $uri->path() in PagesServiceProvider).

Fixes #2435.

nbusseneau avatar Sep 12 '20 19:09 nbusseneau

Note: see issue #2435 for discussion regarding potential shortcomings.

Thus, the question is: why are regex redirects and routes relying on $uri->uri(false) rather than the given dispatch() $route? Is there any specific reason?

nbusseneau avatar Sep 12 '20 19:09 nbusseneau

Bumping this :)

nbusseneau avatar Dec 09 '20 22:12 nbusseneau

@rhukster Can you confirm my findings?

The issue is that the redirect is done based on the CURRENT URL and not the route which was given as a parameter to the method.

mahagr avatar Dec 10 '20 11:12 mahagr

OK, looking into the history of this, the code used to be using $route however, about 3 years ago it was changed to use the URL because the prior approach didn't take into account any query or params on the URL. I think the ultimate solution would be to use the $route plus rebuild any query or params that were requested in the original URL.

rhukster avatar Dec 10 '20 18:12 rhukster

I think the ultimate solution would be to use the $route plus rebuild any query or params that were requested in the original URL.

I can have a poke at that. I take it query parameters are ?foo=bar&bar=qux and params are Grav-specific parameters /foo:bar/baz:qux?

nbusseneau avatar Dec 11 '20 17:12 nbusseneau

I think that the whole concept of having redirect in that method is wrong. Redirecting should be part of routing, not in method that gets a page. I will need to think a bit, but in the mean time there is this in Grav 1.7:

https://github.com/getgrav/grav/blob/1.7/system/src/Grav/Common/Service/PagesServiceProvider.php#L79-L105

It is not being called in this case as there's $page = $pages->dispatch($path); call in line 63, but I'm wondering if we should have the whole logic here and just call $pages->find(), which doesn't do the redirecting.

mahagr avatar Dec 11 '20 20:12 mahagr

@mahagr ~~I don't know if something changed in 1.7 since your last message, but I can't reproduce the issue anymore after upgrading to 1.7.3. I didn't investigate to understand why dispatch() is now correctly handling multilang redirects even though code did not change, but I can if it's not something you changed intentionally.~~

Forget what I said, I'm stupid and forgot that redirects work when using the workaround stated in #2435 (prefixing with (/.*)? to catch language fragment). Without the workaround, redirects still fail.

nbusseneau avatar Jan 24 '21 20:01 nbusseneau

You are right, looks like configuration redirects still happen and are wrong, even when you're using $pages->find().

mahagr avatar Jan 25 '21 13:01 mahagr

The above pull request will not fix the language redirects needing the language code, but will only separate the logic between find() and dispatch() methods and make site.routes more usable.

For the language codes, I still think that site.redirects should not be based on routes, but they should blindly match the current URL (including query parameters etc) and do transformation based on that.

However it could be a good idea to be able to pass more information to the redirects, such as '/({LANG})/foo/(\d+)': '/$1/bar/$2' which would match all language codes.

The reason why I'd like to do it in that way is that you do not want to restrict redirects to Grav routes as you may have migrated from another CMS.

mahagr avatar Mar 12 '21 10:03 mahagr

@mahagr Revisiting old PRs -- I see there was some work on this via #3266. If you have some additional thoughts on how to advance this further I am open for taking a jab at it. The workaround outlined above has been working fine forever, but still think it would be nice to have it work as intended by the documentation (or fix the documentation, which I can also do if we think that's better).

nbusseneau avatar Oct 19 '21 22:10 nbusseneau