Laravel localization with Route::group, prefix and namespace - php

"You may also change the active language at runtime using the setLocale method on the App facade:"
https://laravel.com/docs/5.3/localization#introduction
Route::get('welcome/{locale}', function ($locale) {
App::setLocale($locale);
//
});
How do we do that with $locale if we have something like this:
Route::group(['prefix' => 'admin/{id}/{locale}', 'namespace' => 'Admin'], function( $locale ) {
// this does not work.
App::setLocale( $locale );
// this does work.
App::setLocale( Request::segment( 3 ) );
Route::resource('product', 'ProductController', ['except' => [
'show'
]]);
});

The issue is with route parameters not with localization
Since you expect two params for the route you should pass two params for the closure.
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
//
});
In your example
Route::group(['prefix' => 'admin/{id}/{locale}', 'namespace' => 'Admin'], function( $id, $locale ) {
// this does not work.
App::setLocale( $locale );
// this does work.
App::setLocale( Request::segment( 3 ) );
Route::resource('product', 'ProductController', ['except' => [ 'show' ]]);
});
Refer route parameters for more info

Please note - Route::group callback executes on any request (even not for your prefix!). Route::group is not similar to Route::get/post/match, it is like a helper for internal get/post/match calls.
App::setLocale( $locale ); does not work because Laravel passes only instance of Illuminate\Routing\Router into group's callback. On this stage locale prefix has not been extracted and even URL has not been processed.
App::setLocale( Request::segment( 3 ) ); will be executed for 'one/two/three' with 'three' as a locale.
Your example should be:
Route::group(['prefix' => 'admin/{id}/{locale}', 'namespace' => 'Admin'], function() {
// test a locale
Route::get('test', function($locale){ echo $locale; });
// ProductController::index($locale)
Route::resource('product', 'ProductController', ['except' => [
'show'
]]);
});
So, just update your ProductController and add $locale as a parameter.
Alternative: if you want setLocale in one place update your routes:
// set locale for '/admin/anything/[en|fr|ru|jp]/anything' only
if (Request::segment(1) === 'admin' && in_array(Request::segment(3), ['en', 'fr', 'ru', 'jp'])) {
App::setLocale(Request::segment(3));
} else {
// set default / fallback locale
App::setLocale('en');
}
Route::group(['prefix' => 'admin/{id}/{locale}', 'namespace' => 'Admin'], function() {
Route::resource('product', 'ProductController', ['except' => [
'show'
]]);
});

Related

How merge route in Laravel

I am beginner in Laravel. I have project in Laravel 6
I have this code in routes/admin.php:
Route::name('admin.')->group(function(){
Auth::routes(['register' => false, 'reset' => false, 'confirm' => false, 'verify' => false]);
Route::get('/', 'HomeController#index')->name('admin.home');
Route::get('/', 'HomeController#index')->name('home');
});
Route::group(['prefix' => ''], function () {
//Auth::routes(['register' => false, 'reset' => false, 'confirm' => false, 'verify' => false]);
/* Pages */
Route::get('/pages', 'PageController#index')->name('page.index');
Route::get('/pages/create', 'Admin\PageController#create')->name('page.create');
Route::post('/pages/store', 'Admin\PageController#store')->name('page.store');
Route::get('/pages/edit' . '/{id?}', 'Admin\PageController#edit')->name('page.edit');
Route::put('/pages/update', 'Admin\PageController#update')->name('page.update');
Route::delete('/pages/destroy'. '/{id?}', 'Admin\PageController#destroy')->name('page.destroy');
/* Users */
Route::get('/users', 'Admin\UserController#index')->name('user.index');
Route::get('/users/create', 'Admin\UserController#create')->name('user.create');
Route::post('/users/store', 'Admin\UserController#store')->name('user.store');
Route::get('/users/edit' . '/{id?}', 'Admin\UserController#edit')->name('user.edit');
Route::put('/users/update', 'Admin\UserController#update')->name('user.update');
Route::delete('/users/destroy'. '/{id?}', 'Admin\UserController#destroy')->name('user.destroy');
});
All from this URL need login user (admin).
In RouteServiceProvider I have:
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
protected function mapAdminRoutes()
{
Route::prefix(config('app.admin_prefix'))
->middleware('web')
->namespace($this->namespace.'\Admin')
->group(base_path('routes/admin.php'));
}
protected function mapAdminOnlyRoutes()
{
Route::middleware('web')
->namespace($this->namespace. '\Admin')
->group(base_path('routes/admin.php'));
}
How can I change my admin.php?
Now user which is no login can view my url
CODE AFTER UPDATE:
Code after update. Is this code written in an optimal way?
Route::name('admin.')->group(function(){
Auth::routes(['register' => false, 'reset' => false, 'confirm' => false, 'verify' => false]);
Route::get('/', 'HomeController#index')->name('admin.home');
Route::get('/', 'HomeController#index')->name('home');
});
Route::group(['prefix' => ''], function () {
/* Pages */
Route::get('/pages', 'PageController#index')->middleware('auth')->name('page.index');
Route::get('/pages/create', 'PageController#create')->middleware('auth')->name('page.create');
Route::post('/pages/store', 'PageController#store')->middleware('auth')->name('page.store');
Route::get('/pages/edit' . '/{id?}', 'PageController#edit')->middleware('auth')->name('page.edit');
Route::put('/pages/update', 'PageController#update')->middleware('auth')->name('page.update');
Route::delete('/pages/destroy'. '/{id?}', 'PageController#destroy')->middleware('auth')->name('page.destroy');
/* Users */
Route::get('/users', 'UserController#index')->middleware('auth')->name('user.index');
Route::get('/users/create', 'UserController#create')->middleware('auth')->name('user.create');
Route::post('/users/store', 'UserController#store')->middleware('auth')->name('user.store');
Route::get('/users/edit' . '/{id?}', 'UserController#edit')->middleware('auth')->name('user.edit');
Route::put('/users/update', 'UserController#update')->middleware('auth')->name('user.update');
Route::delete('/users/destroy'. '/{id?}', 'UserController#destroy')->middleware('auth')->name('user.destroy');
});
Let's say you want to protect Route::get('/users', 'Admin\UserController#index')->name('user.index'); route so that only users may access it, you need to do like so:
Route::get('/users', 'Admin\UserController#index')->middleware('auth')->name('user.index');
But if you need to open it to only admin and not other users, you can create your own middleware. See docs https://laravel.com/docs/7.x/middleware#defining-middleware.
Then you need to register your middleware in $routeMiddleware in App\Http\Kernel.php. For example, you register your middleware as admin. Then you would protect your route like so:
Route::get('/users', 'Admin\UserController#index')->middleware('admin')->name('user.index');
in the first step you can use the resource method to create create, store, show, edit, update and delete routes. like this:
Route::resource('shops', 'ShopController');
and for authenticated users for can use the auth middleware to your routes like these ways:
Route::get('profile', ['middleware' => 'auth', function()
{
// Only authenticated users may enter...
}]);
// With A Controller...
Route::get('profile', ['middleware' => 'auth', 'uses' => 'ProfileController#show']);
Route::group(['prefix' => 'backend', 'as' => 'backend.', 'namespace' => 'Backend', 'middleware' => ['web', 'auth], function(){})

Laravel Route Middleware auth:admin not working for all Routes

I'd like to pre check two different Route Groups by the auth:admin middleware. This works perfectly for the first Route Group inside but not for the second which is in an other Namespace.
My Routes file looks like this:
Route::group(['middleware' => ['auth:admin']], function(){
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'as' => 'admin.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
Route::group(['prefix' => 'team/{team_id}', 'namespace' => 'Team', 'as' => 'team.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
});
If I'm not logged in and try to go to admin/dashboard, I'm redirected to login/admin. But if I try to go to team/1/dashboard it says Error 'Trying to get property 'headers' of non-object'.
How can I get the auth:admin Middleware to work with my Team Routes too?
create a middleware
class IsAdmin
{
public function handle($request, Closure $next)
{
if (Auth::user()->permission == 'admin') {
return $next($request);
}
return redirect()->route('some.route'); // If user is not an admin.
}
}
Register in kernel.php
protected $routeMiddleware = [
....
'is.admin' => \App\Http\Middleware\IsAdmin::class,
];
So your routes:
Route::group(['middleware' => 'is.admin'], function () {
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'as' => 'admin.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
Route::group(['prefix' => 'team/{team_id}', 'namespace' => 'Team', 'as' => 'team.'], function(){
Route::resource('dashboard', 'DashboardController')->only(['index', 'create', 'store']);
});
});
check app/Http/Controllers/Middleware/RedirectIfAuthenticated.php file and
update the code for different guard use
// app/Http/Controllers/Middleware/RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard = null)
{
if ($guard == "admin" && Auth::guard($guard)->check()) {
return redirect('/admin');
}
if ($guard == "writer" && Auth::guard($guard)->check()) {
return redirect('/writer');
}
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}

Route NotFoundHttpException after prefix with locale in Laravel

In Laravel 5.4 I want to prefix locale with base url.When i run php artisan serve then i get
notfoundhttpexception
. It does work if i put manually http://localhost:8000/en. what i want now, when i will run php artisan serve it should redirect to http://localhost:8000/en.
Following is the route file:
Route::group( ['prefix' => App::getLocale() ], function()
{
Route::get('/', array('as' => 'home.index', 'uses' => 'HomeController#getIndex'));
});
If I understand your problem properly, You need use code like this:
Route::group( ['prefix' => '{locale}' ], function()
{
Route::get('/', array('as' => 'home.index', 'uses' => 'HomeController#getIndex'));
//Setup locale based on request...
App::setLocale(Request::segment(1));
});
But the better way I can suggest is use locale setup like:
if (in_array(Request::segment(1), ['en', 'fr'])) {
App::setLocale(Request::segment(1));
} else {
// set your default local if request having other then en OR fr
App::setLocale('en');
}
And just call route like:
Route::group( ['prefix' => '{locale}' ], function()
{
Route::get('/', array('as' => 'home.index', 'uses' => 'HomeController#getIndex'));
});
By this code you can setup locale based on route prefix dynamically.

Laravel how to add group prefix parameter to route function

For example, I have defined routes like this:
$locale = Request::segment(1);
Route::group(array('prefix' => $locale), function()
{
Route::get('/about', ['as' => 'about', 'uses' => 'aboutController#index']);
}
I want to generate links for several locales (en, de, es,...). When I try to provide prefix parameter like this
$link = route('about',['prefix' => 'de']);
I got link like this example.com/en/about?prefix=de
How to provide prefix param to got link like this example.com/de/about
You can play around with something like this perhaps.
Route::group(['prefix' => '{locale}'], function () {
Route::get('about', ['as' => 'about', 'uses' => '....']);
});
route('about', 'en'); // http://yoursite/en/about
route('about', 'de'); // http://yoursite/de/about
You can do like this :
Route::group(['prefix'=>'de'],function(){
Route::get('/about', [
'as' => 'about',
'uses' => 'aboutController#index'
]);
});
Now route('about') will give link like this : example.com/de/about
Try this:
$locale = Request::segment(1);
Route::group(array('prefix' => $locale), function()
{
Route::get('/about', ['as' => 'about', 'uses' => 'aboutController#index']);
}
And while providing a link, you can use url helper function instead of route:
$link = url('de/about');
If you want more generic, use this in controller/view:
$link = url($locale.'/about');
where $locale could be en,de,etc
You can simply achieve it like as
Route::group(['prefix' => 'de'], function () {
Route::get('about', ['as' => 'de.about', 'uses' => 'aboutController#index']);
});
And you can use it like as
$link = route('de.about');

Localization and Ajax request Laravel 4

I'm trying to translate views which some of them are loaded via Ajax, so the problem is that even the locale is I get always the text of the default locale, to be clear, this how my files looks :
app/config/app.php :
//...
'languages' => array('fr', 'en'),
'locale' => 'fr',
//...
routes.php
if(!Request::ajax()) {
// Set locale
$locale = Request::segment(1);
if(in_array($locale, Config::get('app.languages'))) {
App::setLocale($locale);
Session::put('locale', $locale);
} else {
$locale = null;
Session::put('locale', $locale);
}
$locale = Session::get('locale') or null;
}
// Group by locale
Route::group(
array( 'prefix' => $locale ), function () {
// Home controller
Route::get('/' . Config::get('app.lcoale'), array( 'uses' => 'HomeController#getIndex', 'as' => '/' ));
//...
The ajax routes are out of the group prefixed by the locale :
Route::group(
array( 'prefix' => 'ajax', 'namespace' => 'Ajax', 'before' => 'ajax' ), function () {
//...
When I check the current locale after sending ajax request Config::get('app.locale'): It show me the correct locale, but the rendered text in the view is of the default locale (fr).
It makes a sense for you ?, Please help.
Thank you
Resolved for me.
Route::filter('ajax', function(){
if(! Request::ajax())
{
App::abort(404);
}
// Set again the locale
if(Session::has('locale'))
App::setLocale(Session::get('locale'));
});

Categories