route() helper function in a different locale - laravel

I'm trying to create a language switcher, so that you can easily change language on the fly (without being redirected to the home page).
The thing I can't seem to accomplish is getting a url from a route name in a different locale.
Imagine your on mydomain.com/events (or mydomain.com/en/events since these are the same) and I want to get url in french (mydomain.com/fr/evenements)...
In my routes.php I have:
$locale = Request::segment(1);
if ( !array_key_exists($locale, Config::get('translatable.languages'))) {
$locale = null;
App::setlocale(Config::get('translatable.fallback_locale'));
}else{
App::setLocale($locale);
}
Route::group(array('prefix' => $locale), function(){
Route::get(Lang::get('routes.events'), array('as' => 'events.index', 'uses' => 'EventController#index'));
});
I have tried
setting the application locale right before calling the route($route_name) helper function
Setting a session variable with the requested locale (in this example 'fr'), then calling the route($route_name) function. For this I also added at the top of routes.php:
if( Session::has('requested_locale') ){
$locale = Session::pull('requested_locale');
}
I have no idea's left on how to handle this...
I know there is a package Laravel Localization that can do this, but I need it to work without that package (if possible)...

My solution on Laravel 5.1 was...
Defined locales in the config/app.php to create routes using the language files
'locale' => 'en',
'locales' => [
'en'=>'English',
'fr'=>'Français'
],
I've defined my routes in the resources/lang/ directory ('en/routes.php' and 'fr/routes.php' in my case)
return [
'about' => 'a-propos',
];
Defined routes using the language keys, example:
Route::get(trans('routes.about'), ['as' => 'about', function () {
return view('pages.'.App::getLocale().'.about');
}]);
Then I've created dummy route that would be used only for switching to another locale, ONLY after the current route has been matched to request
`
Route::matched(function($route) {
$route = Route::current();
$route_name = $route->getName();
$route_uri = $route->uri();
$locales = Config::get('app.locales');
foreach ($locales as $locale_code => $locale_name) {
if ($locale_code == App::getLocale()) {
continue;
}
if (Lang::has('routes.'.$route_name, $locale_code)) {
$route_uri = $locale_code . '/' . Lang::get('routes.'.$route_name, [], $locale_code);
}
else {
$route_uri = $locale_code . '/' . substr($route_uri, 3);
}
Route::get($route_uri, ['as' => 'change_locale_to_'.$locale_code, function(){
}]);
}
});
`
Finally, I use the dummy route in the view I want. $locale_toggle is a Locale eloquent Model that I'm setting in a Middleware for handling the language with a language code route prefix.
<a href="{{ route('change_locale_to_'.$locale_toggle->code, Route::current()->parameters()) }}" class="dropdown-toggle">

Related

Router redirecting to the another page

I have route like
Route::get('admin/selfcontacteditdata','SelfcontectController#edit')->name('selfcontectedit');
Route::post('admin/selfcontactupdatedata','SelfcontectController#update')->name('selfcontectupdate');
If i just go to my browser and right admin/selfcontacteditdata it redirect me to
admin/newsshowdata
And my index function is
public function __construct()
{
return $this->middleware('auth');
}
public function index()
{
request()->validate([
'email' => 'required',
'mobileno' => 'required',
'facebook'=>'required',
'google'=>'required',
'map'=>'required',
]);
$data = selfcontect::find(1);
return view('/admin/selfcontectedit',compact('data'));
}
And my middleware is
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
My rest admin routes are working fine.
I had the same problem but I was writing table name wrong and my file was not saved as .blade please check are you also doing the same thing and there is no meaning of validation in edit function your edit function must be like
public function edit()
{
$data = selfcontect::find(1);
return view('/admin/selfcontectedit',compact('data'));
}
and your function name should be edit
You should use Accept key not Content/type
You can't redirect through view, actually your are calling view.
Correct syntax is
return view('view_name',compact('data'));
If you want to redirect to any route you have to call like this
return redirect()->to('admin/selfcontacteditdata');
Redirect to a Route
If in your routes.php file you have a route with a name, you can redirect a user to this particular route, whatever its URL is:
app/Http/routes.php:
get('books', ['as' => 'books_list', 'uses' => 'BooksController#index']);
app/Http/Controllers/SomeController.php
return redirect()->route('books');
This is really useful if in the future you want to change the URL structure – all you would need to change is routes.php (for example, get(‘books’, … to get(‘books_list’, …), and all the redirects would refer to that route and therefore would change automatically.
And you can also use parameters for the routes, if you have any:
app/Http/routes.php:
get('book/{id}', ['as' => 'book_view', 'uses' => 'BooksController#show']);
app/Http/Controllers/SomeController.php
return redirect()->route('book_view', 1);
In case of more parameters – you can use an array:
app/Http/routes.php:
get('book/{category}/{id}', ['as' => 'book_view', 'uses' =>
'BooksController#show']);
app/Http/Controllers/SomeController.php
return redirect()->route('book_view', [513, 1]);
Or you can specify names of the parameters:
return redirect()->route('book_view', ['category'=>513, 'id'=>1]);

Localization in laravel

I designed a site with Laravel. now I want add new language to it.I read laravel document . It was good but I have a problem.suppose I have a page that show detail of products so I have a route like mysite.com/product/id that get product's id and show it.also I have a method in controller like
public function showProduct($id){
...
}
If I add new Language , the route will change to this: mysite/en/product/id
now I must change my method because now two parameter send my method.something like this :
public function showProduct($lang,$id){
...
}
So two problems arise:
I must change all method in my site which is time consuming
I do not need language parameter in methods because I set $locan via middleware
pay attention that I do not want remove for example en from my URL (because of SEO)
Open your RouteServiceProvider and say that language parameter actually is not a parameter, it's a global prefix.
protected function mapWebRoutes()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
'prefix' => Request::segment(1) // but also you need a middleware about that for making controls..
], function ($router) {
require base_path('routes/web.php');
});
}
here is sample language middleware, but it's need to be improve
public function handle($request, Closure $next)
{
$langSegment = $request->segment(1);
// no need for admin side right ?
if ($langSegment === "admin")
return $next($request);
// if it's home page, get language but if it's not supported, then fallback locale gonna run
if (is_null($langSegment)) {
app()->setLocale($request->getPreferredLanguage((config("app.locales"))));
return $next($request);
}
// if first segment is language parameter then go on
if (strlen($langSegment) == 2)
return $next($request);
else
// if it's not, then you may want to add locale language parameter or you may want to abort 404
return redirect(url(config("app.locale") . "/" . implode($request->segments())));
}
So in your controller, or in your routes. you don't have deal with language parameter
Something like
Route::group(['prefix' => 'en'], function () {
App::setLocale('en');
//Same routes pointing to the same methods...
});
Or
Route::group(['prefix' => 'en', 'middleware' => 'yourMiddleware'], function () {
//Same routes pointing to the same methods...
});

How to add dynamically prefix to routes?

In session i set default language code for example de. And now i want that in link i have something like this: www.something.com/de/something.
Problem is that i cant access session in routes. Any suggestion how can i do this?
$langs = Languages::getLangCode();
if (in_array($lang, $langs)) {
Session::put('locale', $lang);
return redirect::back();
}
return;
Route::get('blog/articles', 'StandardUser\UserBlogController#AllArticles');
So i need to pass to route as prefix this locale session.
If you want to generate a link to your routes with the code of the current language, then you need to create routes group with a dynamic prefix like this:
Example in Laravel 5.7:
Route::prefix(app()->getLocale())->group(function () {
Route::get('/', function () {
return route('index');
})->name('index');
Route::get('/post/{id}', function ($id) {
return route('post', ['id' => $id]);
})->name('post');
});
When you use named routes, URLs to route with current language code will be automatically generated.
Example links:
http://website.com/en/
http://website.com/en/post/16
Note: Instead of laravel app()->getLocale() method you can use your own Languages::getLangCode() method.
If you have more questions about this topic then let me know about it.
Maybe
Route::group([
'prefix' => Languages::getLangCode()
], function () {
Route::get('/', ['as' => 'main', 'uses' => 'IndexController#index']);
});

Laravel application language change?

I have recently developed and application in Laravel for a German client. Now the client wishes to know if the application can viewed in German instead of English. I have designed all the views of the front end using Blade in English of course. Now is there a way in which the views translate to the desired language? Is there a package or another way to accomplish this?
Laravel provides localisation functionality baked in http://laravel.com/docs/4.2/localization though you are going to need to re-do your views to use the lang strings and add language detection to your controllers.
I would avoid "on-the-fly" translations as they are rarely reliable.
I'm using this composer package: https://github.com/mcamara/laravel-localization
But… it's not as simple as it was in Laravel 3.
You need to manually check user's lang and change the used language.
First, set the default locale in config/app.php:
'locale' => 'en',
Then, create a new array of used languages in the same file (config/app.php):
'languages' => array(
'en' => 'en_US',
'pt' => 'pt_BR',
'pl' => 'pl_PL',
'es' => 'es_LA',
'ru' => 'ru_RU',
'de' => 'de_DE',
'nl' => 'nl_NL',
'fi' => 'fi_FI',
'it' => 'it_IT',
'fr' => 'fr_FR',
),
In the route file, you'll verify the user language in a route group:
Route::group(
array('prefix' => LaravelLocalization::setLocale(), //Set the language using the package
'before' => 'LaravelLocalizationRedirectFilter', //Change the URL to match the language
),
function () {
Route::controller('upload', 'ImageUploadController');
Route::controller('faviconit', 'CreateController');
Route::controller('download/{folder?}', 'DownloadController');
Route::controller('/', 'HomeController');
}
);
And I have a helper class called LocalizationHelper.php with this code:
<?php
class LocalizationHelper
{
/**
* To use localization in an easier way, it's set as 'pt' instead of 'pt_BR'. To get the correct Brazilian
* localization in aviary, this function return 'pt_BR' when locale is set to 'pt'
*
* #return string The correct Aviary locale string
*/
public static function getUserLanguageFromSupportedLanguages()
{
$userLanguages = Request::getLanguages();
$supportedLanguages = Config::get('app.languages');
$userLanguage = Config::get('app.locale');
foreach ($userLanguages as $language) {
$language = substr($language, 0, 2);
if (false !== array_search($language, $supportedLanguages, true)) {
$userLanguage = $language;
break;
}
}
return $userLanguage;
}
/**
* Returns html with language selector. This code removes languages without URL.
* #return \Illuminate\View\View
*/
public static function getLanguageSelector()
{
//START - Delete in v1.0
$languages = LaravelLocalization::getSupportedLocales();
$active = LaravelLocalization::getCurrentLocale();
foreach ($languages as $localeCode => $language) {
$langUrl = LaravelLocalization::getLocalizedURL($localeCode);
// check if the url is set for the language
if ($langUrl) {
$language['url'] = $langUrl;
} else {
// the url is not set for the language (check lang/$lang/routes.php)
unset($languages[$localeCode]);
}
// fill the active language with it's data
if ($active == $localeCode)
$native = $language['native'];
}
return View::make('templates.languagebar', compact('languages', 'active', 'native'));
}
}
The selector setted on the code above is a blade file called in the header view:
<li class="dropdown">
{{ LocalizationHelper::getLanguageSelector() }}
</li>
Then, you have to set the config file in config/packages/mcamara/laravel-localization/config.php.
Just copy the languages you'll use to the uncommented array.
There's a thing that sucks… you have to add the used language in some links like this:
{{ Form::open(array('url' => LaravelLocalization::getCurrentLocale() . '/faviconit', 'files' => true, 'class' => 'form-horizontal')) }}
Last, all you have to do is add the code to translate the texts:
<span class="help-block">
{{ trans('faviconit.formFileHelp') }}</strong>
</span>
The language are located in the lang folder, with the country code.
Hope it helps you :)

Add prefix to all routes, links and urls

Is it possible to add some prefix to all routes, urls and links in the whole application at one place including blades?
For example I have route
Route::get('/', 'HomeController#showWelcome');
but instead of it I want to have
Route::get($prefix . '/', 'HomeController#showWelcome');
and in blade
{{ HTML::style('css/bootstrap.min.css') }}
to
{{ HTML::style($prefix . 'css/bootstrap.min.css') }}
I tried
Route::group(array('prefix' => $prefix), function() {});
but it did not apply prefix to links in blades.
I found simple solution. I created .env.php folder inside project which looks like
return array(
'ROUTES_PREFIX' => 'prefix',
);
then added this code to all routes
Route::group(array('prefix' => $_ENV['ROUTES_PREFIX']), function() {
// routes here
});
and created custom macro for style, script and image. For example my macro for style looks like this
HTML::macro('extendedStyle', function($url, $attributes = array(), $secure = null) {
$prefix = $_ENV['ROUTES_PREFIX'] == '' ? '' : $_ENV['ROUTES_PREFIX'] . '/';
return HTML::style($prefix . $url, $attributes, $secure);
});
I hope, someone will find this useful.

Resources