Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove defualt language from url #169

Open
perspolise opened this issue Jun 17, 2018 · 9 comments
Open

remove defualt language from url #169

perspolise opened this issue Jun 17, 2018 · 9 comments

Comments

@perspolise
Copy link

perspolise commented Jun 17, 2018

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:

$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
    $r->addRoute('GET', '/{lang:(?:en|fr)}/articles', 'get_all_users_handler');
});


$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];

// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
    $uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);

$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
    case FastRoute\Dispatcher::NOT_FOUND:
       echo 'BAd';
        break;
    case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
        $allowedMethods = $routeInfo[1];
        // ... 405 Method Not Allowed
        break;
    case FastRoute\Dispatcher::FOUND:
        $handler = $routeInfo[1];
        $vars = $routeInfo[2];
        echo 'Found Found';
        break;
}

My Url Routed And Work With (fr and en) path method:

example.com/en/articles and example.com/fr/articles.

But I need to remove default language from url. How do fix this problem ?!

@aromot
Copy link

aromot commented Jun 17, 2018

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 );
// ...

⚠️ 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.

@perspolise
Copy link
Author

perspolise commented Jun 17, 2018

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/

Example for Symphony url router

@aromot
Copy link

aromot commented Jun 18, 2018

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).

@perspolise
Copy link
Author

perspolise commented Jun 18, 2018

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

@Zvax
Copy link

Zvax commented Jun 18, 2018

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.

@aromot
Copy link

aromot commented Jun 18, 2018

@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:

  1. define a list of available languages for your application,
  2. define a default language you'll use when,
    a. there is no language provided (localhost/cms/users),
    b. the provided language is unknown (localhost/ru/cms/users).
  3. in your code, get the currentLanguage (ex: en) and the routableURI, a URI without any language in it (ex: cms/users): this is exactly what the purpose of the code I provided in my previous message.
  4. call FastRoute (indeed we're in a thread related to that repository) using the routableURI and store the currentLanguage somewhere so that you'll be able to use it in your route handler.

I hope I was clear enough and good luck to you!

@ldonis
Copy link

ldonis commented Jul 12, 2018

@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 :)

@perspolise
Copy link
Author

@ldonis : Working code link is not found. please update

@SignpostMarv
Copy link
Contributor

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;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants