-
-
Notifications
You must be signed in to change notification settings - Fork 246
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
Regulation start from N segment #18
Comments
How about change $router = new \Bramus\Router\Router();
// before route middleware
$router->before('GET', '/(.*)', function($slug) {
if (in_array(segment(1), ['en', 'id'])) {
Session::set('language', segment(1));
} else {
redirect(DOMAIN . $slug);
}
});
$router->baseroute = '/' . segment(1);
$router->all('/(.*)', function($slug) {
echo $slug; // domain.com/en/title -> title
}); I just thinking about on/off multilingual, like $ismultilingual = true;
$router = new \Bramus\Router\Router();
if ($ismultilingual) {
// before route middleware
$router->before('GET', '/(.*)', function($slug) {
if (in_array(segment(1), ['en', 'id'])) {
Session::set('language', segment(1));
} else {
redirect(DOMAIN . $slug);
}
});
$router->baseroute = '/' . segment(1);
}
$router->all('/(.*)', function($slug) {
echo $slug; // domain.com/en/title -> title
}); |
If I had to manage a multilingual site, I would do something like this (of course, you should have your class in a different file): class Router extends \Bramus\Router\Router
{
/**
* List of accepted languages
* @var array
*/
public $langs = [
'en',
'id',
];
/**
* Default language
* @var string
*/
public $default_lang = 'en';
protected function getCurrentUri()
{
$uri = parent::getCurrentUri();
$uri = $this->parseLang($uri);
return $uri;
}
/**
* Parse the uri string
*
* @param string $uri
* @return string
* @throws \Exception
*/
protected function parseLang($uri)
{
$arr_uri = explode('/', $uri);
if (in_array($arr_uri[1], $this->langs)) {
// if a lang was given and it is in the list
$lang = $arr_uri[1];
$uri = $arr_uri[2];
} else {
// if no lang was given or the one given is not in the list
if (!in_array($this->default_lang, $this->langs)) {
// exception if the default language is not in the list
throw new \Exception('The default language is not valid.');
}
$lang = $this->default_lang;
}
$this->useLang($lang);
return $uri;
}
/**
* Use the language string
* @param string $lang Language string
*/
protected function useLang($lang)
{
// do whatever you want with lang
var_dump($lang);
}
}
$router = new Router;
$router->get('/hello', function () {
echo 'Hello World!';
});
$router->run(); What this does is quite simple:
I will do a PR to change the visibility of $router->run(null, function ($lang) { /* use $lang */ }); This would lead to a cleaner code than having a Another option would be to have a property containing a callable, which would be called (if it is callable) by |
Hi all, Checking the replies further I can see benefits into making
The suggested quick fix to "just use Changing the visibility of Based on the idea of the custom
<?php
// Require the base Router classes
require_once __DIR__ . '/../src/Bramus/Router/Router.php';
/**
* A Multilingual Router
*/
class MultilangRouter extends \Bramus\Router\Router {
/**
* The Default language
* @var string
*/
private $defaultLanguage;
/**
* List of allowed languages
* @var array
*/
private $allowedLanguages= [];
/**
* A Multilingual Router
* @param array $allowedLanguages
* @param string $defaultLanguage
*/
public function __construct(array $allowedLanguages, $defaultLanguage) {
// Store passed in data
$this->allowedLanguages = $allowedLanguages;
$this->defaultLanguage = (in_array($defaultLanguage, $allowedLanguages) ? $defaultLanguage : $allowedLanguages[0]);
// Visiting the root? Redirect to the default language index
$this->match('GET|POST|PUT|DELETE|HEAD', '/', function() {
header('location: /' . $this->defaultLanguage);
exit();
});
// Create a before handler to make sure the language checks out when visiting anything but the root.
// If the language doesn't check out, redirect to the default language index
$this->before('GET|POST|PUT|DELETE|HEAD', '/([a-z0-9_-]+)(/.*)?', function($language, $slug = null) {
// The given language does not appear in the array of allowed languages
if (!in_array($language, $this->allowedLanguages)) {
header('location: /' . $this->defaultLanguage);
exit();
}
});
}
}
// Create a Multilingual Router. It will automatically validate the language parameter in the URL. If that fails it will redirect to the default language.
$router = new MultilangRouter(
['en','nl','fr'], //= allowed languages
'nl' // = default language
);
$router->get('/([a-z0-9_-]+)', function($language) {
exit('This is the ' . $language . ' index');
});
$router->get('/([a-z0-9_-]+)/([a-z0-9_-]+)', function($language, $slug) {
exit('This is the ' . $language . ' version of ' . $slug);
});
$router->get('/([a-z0-9_-]+)/(.*)', function($language, $slug) {
exit('This is the ' . $language . ' version of ' . $slug . ' (multiple segments allowed)');
});
// Thunderbirds are go!
$router->run(); (Note that I have defined the pattern for the language as being (Also note that one can still use the The
It also redirects nicely in case a faulty URL (viz. one with an invalid
Regards, |
I adapted my class to what @ncaneldiee wanted to do: execute a function which has as a parameter the language, then create routes as normal. As you showed in your example, their are different ways of implementing a multilingual router. One could be what @ncaneldiee is looking for, another one could be the one you showed and I am sure many other ways could be found. Of course, no solution is perfect, they all have their advantages and drawbacks. The reason I wanted to change the visibility of Router::run()
Router::handle()
Router::getCurrentUri()
Router::parseLang() I know this seems weird, but, in a multilingual router, passing a callable to the // could be used to set some value in the configuration, for example
$router->run(null, 'set_lang_config'); This is just an example which (to me) shows that most/every methods in a non-final class should be set to Of course, this is just my opinion, and I'll just remove the concerned commit from #19 if you disagree. |
To be honest, I don't see the problem of setting |
Hi @tleb. What I'm still missing to understand your example completely is the altered |
Ok, I got lost in my own explanation, and ended up saying something completely wrong. Sorry I was blocked in my idea. What I was thinking about would need to a complete rewriting of the class. I'll remove the concerned commit. |
Heh, have that too sometimes :-) |
Need discussion about using this class in multilingual site, assumed domain.com will be redirect to domain.com/en (in english) and domain.com/id (in indonesia)
When i call domain.com/en/title, i expect
$slug = 'title';
not$slug = 'en';
Actually using
$router->mount($baseroute, $fn)
this issue completedBut i looking for some regulation to start from N segment, something like
$route->startfromsegment = 1;
Any other idea ? or mount a collection is a right way ?
The text was updated successfully, but these errors were encountered: