Open perspolise opened 6 years ago
From my experience, it is better to remove the language from the URI before using it with FastRoute.
// ...
$uri = rawurldecode($uri);
$parts = explode('/', ltrim($uri, '/'));
$lang = array_shift($parts);
$uriWithoutLang = implode('/', $parts);
$routeInfo = $dispatcher->dispatch($httpMethod, $uriWithoutLang );
// ...
:warning: Note: the piece of code above doesn't work properly if a URL is called without any language (example.com/articles), you have to set the default language and process the URI correctly.
My Problem Exactly this: I need to Call Url for default language(en) Without language
example.com/articles/
And Call For Another Language With fr
example.com/fr/articles/
there are various ways to manage a default language. This could be the topic of en whole article... so basically our starting point is this: your website is multilingual and accepts a limited set of languages (for example : "en", "fr", "es", "de") and you have a default language (for example "en"). Here's the code:
// ...
// this is list of languages my site accepts
$languages = ['en', 'fr', 'es', 'de'];
// this is my default language
$defaultLang = 'en';
// $currentLang is the language I'll use to show the contents
$currentLang = $defaultLang;
$uri = ltrim(rawurldecode($uri), '/');
$parts = explode('/', $uri);
if( ! empty($parts) && in_array(strtolower($parts[0]), $languages)) {
$currentLang = array_shift($parts);
}
// routableUri is the URI you'll provide to FastRoute
$routableUri = implode('/', $parts);
// ...
You can go further... for example, if no language is found in the URI, you can look into the request headers (the "accept" header).
You test This Code?! I change your code for test to the function like this:
function urlss(){
$uri = $_SERVER['REQUEST_URI'];
$languages = ['en', 'fr', 'es', 'de'];
// this is my default language
$defaultLang = 'en';
// $currentLang is the language I'll use to show the contents
$currentLang = $defaultLang;
$uri = ltrim(rawurldecode($uri), '/');
$parts = explode('/', $uri);
if( ! empty($parts) && in_array(strtolower($parts[0]), $languages)) {
$currentLang = array_shift($parts);
}
// routableUri is the URI you'll provide to FastRoute
$routableUri = implode('/', $parts);
return $routableUri;
}]
Now, test in my localhost:
localhost/cms/users
echo $routableUri;
And output is:
cms/users
this output not true for your idea and not work true. can u check your idea in full code and then share it. Thanks
The easiest way would be to move the language after the "articles" bit, so that you could have an /{section}[/{lang}]
route definition. You could also write a second route with the same handler but without the lang part, and you'd be settled.
@perspolise : no I didn't test the code I sent. It wasn't meant to be taken "as-is". The idea was more to give a track/hint. I think it's difficult to provide a code you can simply copy/paste and push the button to get it run (a dream we all share to save time and go running in fields of flowers). My main point is to invite you thinking of a strategy to manage the languages for your application. My basic suggestion is:
I hope I was clear enough and good luck to you!
@perspolise I had the same issue a couple of weeks a go, I was trying to implement exactly what you need for a website built with Slim framework
domain.com
domain.com/es
domain.com/es/about
domain.com/about
but, this is not possible :(
$r->get('/{lang}/{page}')
I found a (possible) solution building a dispatcher using FastRoute and parsing my url manually.
Url parsing (pseudo code):
$langs = ['en', 'es'];
$url = '/es/about';
if ($url string has any of $langs) then
remove url id from url
define('lang', 'es') so, now I can use the selected language from anywhere in my page code
My new url after removing the language:
$url = '/about';
You can see the working code here
Now I only had to build a dispatcher for my well formatted url (without language id on it)
// New RouteCollector
$router = new \FastRoute\RouteCollector(
new \FastRoute\RouteParser\Std,
new \FastRoute\DataGenerator\GroupCountBased
);
// Building routes for website
$router->get('/', 'landing');
$router->get('/about/', 'about');
// Create new dispatcher object
$dispatcher = new \FastRoute\Dispatcher\GroupCountBased($router->getData());
// Dispatch for the current route
// remember that at this point my $url is "/about" and my language is in a defined constant
$dispatcher = $dispatcher->dispatch('GET', $url);
// Website found HTTP_OK
if ($dispatcher[0] === \FastRoute\Dispatcher::FOUND) {
// code to show my website
}
You can see the working code here
This is just an experiment just to solve the problem with the optional language parameter in url, I'm working so hard testing this "framework" to migrate my websites from Slim framework some point in the future.
Any comments are always welcomed :)
@ldonis : Working code link is not found. please update
Personal preference:
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/{lang:(?:en|fr)}/articles', 'get_all_users_handler');
$r->addRoute('GET', '/articles', 'get_all_users_handler');
});
Where lang is defined as: $lang = $args['lang'] ?? $default_lang;
I have Multi language CMS For Front and Admin Page.
For English language(defualt without
en
):example.com/articles/
For France Language(with
fr
):example.com/fr/articles/
Now, for my url Like This code:
My Url Routed And Work With (
fr
anden
) path method:example.com/en/articles
andexample.com/fr/articles
.But I need to remove default language from url. How do fix this problem ?!