I'm using Laravel 5.6 and trying to sort out what's the best method to translate a route.
I use top level domain to sort the locale so
mydomain.pt -> locale pt
mydomain.es -> locale es
mydomain.com -> locale en
I created a middleware to handle this
class Language
{
public function handle($request, Closure $next)
{
$url_array = explode('.', parse_url($request->url(), PHP_URL_HOST));
$top_domain = end($url_array);
if(!empty($top_domain)){
App::setLocale($top_domain);
}
}
}
This is working fine and the translated strings within the respective files work when i switch domain.
However i want to be able, for SEO purposes, to have links like this
mydomain.pt/dynamic/perto-de-mim
mydomain.es/dynamic/cerca-de-mi
mydomain.com/dynamic/near-me
What's the best approach in laravel to get my route
Route::get('{category}/near-me/', 'ServicesController#nearMe');
To work with all the examples above?
Thank you
Laravel allow you to provide translation string :
/resources
/lang
/en
routes.json
/es
routes.json
In resources/lang/es/routes.json :
{
"near-me": "cerca-de-mi"
}
And your route become :
Route::get('{category}/' . __('routes.near-me') . '/', 'ServicesController#nearMe');
You could see here the use of the Laravel helper method __() to retrieve the translation from the xx/routes.json files.
Related
As in the laravel documentation I have configured my application as below to change languages.
Created sub-directories inside the resources lang folder with each directory contain a messages.php file with relevant languages. Like below
/resources
/lang
/si
messages.php
/ta
messages.php
Then made a get route as in the documentation and it's same as in the documentation
Route::get('change-lang/{locale}', function ($locale) {
if (! in_array($locale, ['en', 'si', 'ta'])) {
abort(400);
}
(dd(App::getLocale()); // this gives me the default lang en
App::setLocale($locale);
// (dd(App::getLocale()); // this gives me the setted language
});
This is the first time I'm using this setLocale() method. Usually, I used to change the language via passing additional parameters with each route and when I did it it's working fine. But I want to make new application with setLocale() method since it is very easy to woking. So I have done everything according to the documentation but still, the language doesn't get changed.
Can anybody please help me to fix this.
I am developing a multi-language web app using Laravel framework. So in this app, I have a special condition to do multi-language feature as below.
a user can select from some flags and change the language manually.
It changes his URL to /{lang} .. so, for example, webapp.com/cs - so he will see everything that in Czech language. webapp.com/en - see everything in English.
Chosen localization should be persistent so would not disappear when user change page or something - it should always be in the URL.
I created Route to set locale in session as follows.
Route::get('/{locale}', function ($locale) {
session()->put('locale', $locale);
return back();
});
And created middleware and added it to $middlewareGroups in the http\Kernel as well.
Below is my middleware.
public function handle($request, Closure $next)
{
if (session()->has('locale')) {
app()->setLocale(session('locale'));
}
return $next($request);
}
Localization is going well and it gives correct translations and everything. But what I need is to show in the URL what is the language is. as example webapp.com/cs,webapp.com/en. It would be great if anyone can help me with this problem.
Thanks.
You can try this,
In your every route you can append current local language like this
Route::get('/home/'.app()->getLocale(),'HomeController#index');
and one more thing you should see this
Laravel app()->getLocale() inside routes always print the default "en"
Hope this helps :)
I'm looking into using Lumen or possibly Slim for a project and wondered whether it was possible to autoload controllers based on directory structure rather than having to register all routes.
This is how I would like the autoloading to work .
Example Directory/class structure:
/app/Http/Controllers/
Foo/
BarController.php # App\Http\Controllers\Foo\BarController
If the route were
example.com/foo/bar == App\Http\Controllers\Foo\BarController::index()
example.com/foo/bar/add == App\Http\Controllers\Foo\BarController::add()
Registered routes should take priority over the autoloaded classes.
I have found a way of doing this based on Opencart's routing method.
They have 1145 different public methods over 396 controllers which are all called without explicitly stating the controller & method.
Here is my attempt.
.htaccess
RewriteRule ^([^?]*) index.php?route=$1 [L,QSA]
app/Http/routes.php
$route = array_shift($_GET);
$method_name = '';
$parts = explode('/', preg_replace('/[^a-zA-Z0-9_\/]/', '', (string)$route));
while ($parts) {
$class = '\App\Http\Controllers\\' . implode('\\', $parts);
if (class_exists($class)){
$app->match($route, $class . '#' . method_exists($class, $method_name) ? $method_name : 'index');
break;
} else {
$method_name = array_pop($parts);
}
}
If a route is required which differs from the default the Opencart then use .htaccess RewriteRule or a response->redirect to route to an alternative controller.
I would to use their approach but state my route overrides in
app/Http/routes.php. like so
// route overrides
$app->get('/', 'common/home#index');
$app->get('/home', 'common/home#index');
Am I right in thinking this would make the application run faster as it wouldn't have to search all registered routes for a match ?
Is there a better way of performing this automatic routing process ?
I think you could make this work with a combination of reflection and Slim 3's support for defining routes with controller methods instead of closures.
The basic strategy would be as follows:
Search through each of your controller classes (using glob or an autoloader);
For each class, call ReflectionClass::getMethods, using the ReflectionMethod::IS_PUBLIC filter so you only get the public methods for the class;
Get the class name using ReflectionClass::getName and namespace (if necessary) using ReflectionClass::getNamespaceName;
Build your route signature from the namespace, class name, and method name, perhaps using a slugification library like https://github.com/cocur/slugify;
Generate the corresponding route $app->get($route_signature, "$class_name:$method_name").
This is an interesting idea, although you need to be extremely careful that this doesn't accidentally expose any methods that you don't want directly accessible to the client. A few other notes:
Reflection is very slow so you will probably want to implement this as more of a build step, caching the generated routes rather than regenerating them on the fly with each request.
You may need some additional naming convention to distinguish HTTP verbs. For example, beginning all method names that correspond to GET routes with get. So you might have \Foo\BarController::getAdd, \Foo\BarController::postAdd, etc.
Constructing parameterized routes (/bar/add/{id}) will be a little more work, as you will probably want to extract the corresponding method arguments using ReflectionFunctionAbstract::getParameters. Again, you would need to decide on some convention as to how the routes should be constructed based on these parameters.
I want to add a localization information to my routes.
Currently my route definitions are:
Route::controller('browse');
Route::controller('search');
Route::controller('support');
Route::controller('filter');
I want to change URLs from /url/browse to /url/en/browse etc.
If language is missing from the URL then the application should redirect to the same route with default language. This means accessing the old /url/browse would redirect to /url/default/browse.
I tried to make or find some simple solution with filters, unsuccessfully.
Thanks for help!
Try to use the Default Application Language and Supported Languages array in config.
If you put a language in the supported languages any route starting with that segment will set the current language and that will be considered the root url.
One difference from your requirements is instead of a redirection the default language will be accepted without the language in the url.
Edit: A filter which may help you with the redirect.
Route::filter('pattern: *', array('name' => 'langredirect', function()
{
$uri = Request::server('request_uri');
$segments = explode('/', $uri);
if ( ! array_get(Config::get('application.languages'), $segments[1]) )
{
return Redirect::to(URL::base() . '/' . Config::get('application.language') . $uri);
}
}));
So redmine has a very peculiar url mapping style that i observed :
http://demo.redmine.org/projects/<project-name>/controller/action
samples :
http://demo.redmine.org/projects/produto/activity
http://demo.redmine.org/projects/produto/issues/new
http://demo.redmine.org/projects/produto/issues/gantt
http://demo.redmine.org/projects/produto/files
and the url changes as the project changes.
how do i do this in codeigniter ? I'm thinking it can be done with routes.php but so far i'm not able to get anywhere.
Looking for any help. Thanks.
Use the following function inside your "application/controllers/projects.php" controller:
public function _remap($method)
{
if ($method == 'project-name')
{
//display project1
}
elseif($method == 'project-name2')
{
//display project2
}
}
You can do the same for varying methods by extracting them from database
take a look here:
http://codeigniter.com/user_guide/general/controllers.html#remapping
you can also route your controller by using custom routes in application/config/routes.php
$route['example'] = "controller/function";
$route['example2/(:any)'] = "controller/function";
You use the routes file in application/config/routes.php
You would use something like this:
// the $1 maps to :any
$route['projects/produto/:any'] = "$1";
// the $1 maps to the first any, $2 maps to the second :any
$route['projects/produto/:any/:any'] = "$1/$2";
You will want mod_rewrite enabled if you are handling clean URL's. Otherwise expect the index.php/controller/action. I cant test it myself there, but you should refer to:
Once you add a route (It has to be called $route[] inside the configuration), refresh the page and try to go to the URL!
http://codeigniter.com/user_guide/general/routing.html
add this to your routes.php (btw: you need url-rewriting enabled for routes to work, ie. using .htaccess)
$route['projects/(:any)/(:any)/(:any)'] = "$2/$3/$1";
for example /projects/produto/issues/new will call the function new in the class issues and pass it the parameter 'produto'
also check http://codeigniter.com/user_guide/general/routing.html