is there a simple way to translate my routes in Laravel 5.4. My translation files located in here:
/resources
/lang
/en
routes.php
/de
routes.php
In my web.php i define my routes like this:
Route::get('/{locale}', function ($locale) {
App::setLocale($locale);
return view('welcome');
});
Route::get('{locale}/contact', 'ContactController#index');
I have found very elaborate solutions or solutions for Laravel 4. I am sure that Laravel has also provided a simple solution. Can someone explain to me the best approach?
Thanks.
we usually do it like this
to get the current language:
$request = request()->segment(1);
$language = null;
if (!empty($request) && in_array($request,config('translatable.locales'))) {
$language = $request;
App::setLocale($language);
} else {
$language = 'nl';
}
routes:
Route::group(['prefix' => $language], function () {
Route::get(trans('routes.newsletter'), array('as' => 'newsletter.index', 'uses' => 'NewsletterController#index'));
I created a file translatable.php in my config folder:
<?php
return [
'locales' => ['en', 'de'],
];
web.php:
$request = request()->segment(1);
$language = null;
if (!empty($request) && in_array($request,config('translatable.locales'))) {
$language = $request;
App::setLocale($language);
} else {
$language = 'de';
}
Route::get('/', function() {
return redirect()->action('WelcomeController#index');
});
Route::group(['prefix' => $language], function () {
/*
Route::get('/', function(){
return View::make('welcome');
});
*/
Route::get('/',
array( 'as' => 'welcome.index',
'uses' => 'WelcomeController#index'));
Route::get(trans('routes.contact'),
array('as' => 'contact.index',
'uses' => 'ContactController#index'));
});
Works fine - Thanks. Is the redirect also the best practice?
Best regards
Related
the controller is returning a blank data/view and I think something is wrong with my routes. if I remove {locale}, the data is retrieved.
Can anyone help with returning the data properly while my routes have {locale} in it? Here are my related code:
Web.php
Route::get('{locale}/projects/{id}/billings', 'ProjectController#showbilling')
->name('showbilling');
Route::post('{locale}/projects/{id}', 'ProjectController#addbilling')
->name('addbilling');
ProjectController.php
public function showbilling($id)
{
$billings = Project::find($id);
$locale = app()->getLocale();
return $billings;
//return view('admin.addbillings', compact('billings'));
}
Edit: Here's my full web.php
web.php
Route::get('/', function() {
return redirect(app()->getLocale());
});
Route::group(['prefix' => '{locale}', 'where' => ['locale' => '[a-zA-Z]{2}'], 'middleware' => 'setlocale'], function () {
Route::get('/', function () {
return view('welcome');
})->name('main');
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
//Customers
Route::get('/customers', 'CustomerController#showcust')->name('customers');
Route::post('/sendcust', 'CustomerController#sendcust')->name('sendcust');
//Items
Route::get('/items', 'ItemController#showitems')->name('items');
Route::post('/senditem', 'ItemController#senditem')->name('senditem');
//Projects
Route::get('/projects', 'ProjectController#showprojects')->name('projects');
Route::post('/sendproj', 'ProjectController#sendproj')->name('sendproj');
//ProjectBillings
Route::get('/projects/{id}/billings', 'ProjectController#showbilling')->name('showbilling');
Route::post('/projects/{id}', 'ProjectController#addbilling')->name('addbilling');
//Invoices
Route::get('/invoices', 'InvoiceController#showinvoice')->name('invoices');
Route::post('/sendinvoitem', 'InvoiceController#sendinvoitem')->name('sendinvoitem');
Route::get('/invoices/{id}/details', 'InvoiceController#showdetails');
Route::post('/updateitem','InvoiceController#updatedetail')->name('updateitem');
Route::get('invoices/{id}/generate', 'InvoiceController#generate');
Route::post('/updatestatus', 'InvoiceController#changestatus')->name('updatestatus');
});
You are passing 2 params in your route but accepting only 1 in the controller. Add locale.
public function showbilling($locale, $id)
Lets assume I have a site with cars: cars.com on Laravel 5.
I want to set up my routes.php so a user could type in a browser ford.cars.com/somethingOrnothing and get to the controller responsible for Ford™ cars (FordController).
Of course I could use something like this code:
Route::group(['middleware' => 'web'], function () {
Route::group(['domain' => 'ford.cars.com'], function(\Illuminate\Routing\Router $router) {
return $router->resource('/', 'FordController');
});
});
But I am not happy about writing and maintaining routes for hundreds of car brands.
I would like to write something like this:
Route::group(['domain' => '{brand}.cars.com'], function(\Illuminate\Routing\Router $router) {
return $router->get('/', function($brand) {
return Route::resource('/', $brand.'Controller');
});
});
So the question is: Is it possible to dynamically set routes for sub-domains and how to achieve this?
upd:
the desirable outcome is to have subdomains that completely repeat controllers structure. Like Route::controller() did (but it is now deprecated)
To emulate Route::controller() behaviour you could do this:
Route::group(['domain' => '{carbrand}.your.domain'], function () {
foreach (['get', 'post'] as $request_method) {
Route::$request_method(
'{action}/{one?}/{two?}/{three?}/{four?}',
function ($carbrand, $action, $one = null, $two = null, $three = null, $four = null) use ($request_method) {
$controller_classname = '\\App\\Http\\Controllers\\' . Str::title($carbrand).'Controller';
$action_name = $request_method . Str::title($action);
if ( ! class_exists($controller_classname) || ! method_exists($controller_classname, $action_name)) {
abort(404);
}
return App::make($controller_classname)->{$action_name}($one, $two, $three, $four);
}
);
}
});
This route group should go after all other routes, as it raises 404 Not found exception.
Probably this is what you need:
Sub-Domain Routing
Route groups may also be used to route wildcard sub-domains.
Sub-domains may be assigned route parameters just like route URIs,
allowing you to capture a portion of the sub-domain for usage in your
route or controller. The sub-domain may be specified using the domain
key on the group attribute array:
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
From:
Laravel 5.2 Documentation
upd.
If you want to call your controller method you can do it like this:
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
$controllerName = $account . 'Controller' //...or any other Controller Name resolving logic goes here
app('App\Http\Controllers\\' . $controllerName)->controllerMethod($id);
});
});
I"m using Laravel framework and I have situation adding routes based on different conditional parameters.
Currently, I'm using this code.
Route::get('/{report?}/{type?}', [
'uses' => 'SomeController#getReport'
])->where(['report' => 'overview', 'type' => 'type1']);
www.example.com/overview/type1 // Working
www.example.com?report=overview&type=type1 // Not working (not verifying the where conditions).
I have another solution to resolve this. Is this a better way?
if (Input::get('report') == 'overview' && Input::get('type') == 'type1') {
Route::get('/', ['uses' => 'SomeController#getReport']);
}
Try this:
if (request()->get('report') == 'overview'
&& request()->get('type') == 'type1') {
Route::get('/', [
'uses' => 'SomeController#getReport'
);
}
Try this. Hope it will work.
Route::get('/{report?}/{type?}', function()
{
if (Input::get('report') == 'overview'
&& Input::get('type') == 'type1') {
// Run controller and method
$app = app();
$controller = $app->make('SomeController');
return $controller->callAction('getReport', $parameters = array());
}
});
I'm trying to handle basic validation of my API calls in the Laravel's routes. Here is what I want to achieve:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', 'PropertiesController#getPropertyByProgressStatus', function () {
//pass variable x = 1 to the controller
});
Route::get('waiting', 'PropertiesController#getPropertyByProgressStatus', function () {
//pass variable x = 2 to the controller
});
});
Long story short, depending on the segment of the URI after api/v1/properties/ I want to pass a different parameter to the controller. Is there a way to do that?
I was able to get it to work with the following route.php file:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 1
]);
Route::get('remodeled', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 1
]);
Route::get('pending', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 3
]);
Route::get('available', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 4
]);
Route::get('unavailable', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 5
]);
});
and the following code in the controller:
public function getPropertyByProgressStatus(\Illuminate\Http\Request $request) {
$action = $request->route()->getAction();
print_r($action);
Pretty much the $action variable is going to let me access the extra parameter that I passed from the route.
I think that you can do it directly in the controller and receiving the value as a parameter of your route:
First you need to specify the name of the parameter in the controller.
Route::group(['prefix' => 'api/v1/properties/'], function ()
{
Route::get('{parameter}', PropertiesController#getPropertyByProgressStatus');
In this way, the getPropertyByProgressStatus method is going to receive this value, so in the controller:
class PropertiesController{
....
public function getPropertyByProgressStatus($parameter)
{
if($parameter === 'purchased')
{
//do what you need
}
elseif($parameter === 'waiting')
{
//Do another stuff
}
....
}
I hope it helps to solve your issue.
Take a view for this courses: Learn Laravel or Create a RESTful API with Laravel
Best wishes.
----------- Edited ---------------
You can redirect to the route that you want:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', function () {
return redirect('/api/v1/properties/purchased/valueToSend');
});
Route::get('waiting', function () {
return redirect('/api/v1/properties/waiting/valueToSend');
});
Route::get('purchased/{valueToSend}', PropertiesController#getPropertyByProgressStatus);
});
Route::get('waiting/{valueToSend}', PropertiesController#getPropertyByProgressStatus);
});
});
The last two routes response to the redirections and send that value to the controller as a parameter, is the most near that I think to do this directly from the routes.
I want to set the localization using subdomains. I've managed to set up subdomain wildcards and it's working fine. However I'd like to set up filters.
For example I was thinking of setting up an array of available countries in the config:
<?php
return array(
'available' => array(
'uk',
'fr',
'de'
)
);
Then in my routes I need a way of filtering a group. For the moment my code is the following without any filters:
<?php
$homeController = 'MembersController#profile';
if ( ! Sentry::check())
{
$homeController = 'HomeController#index';
}
Route::group(['domain' => '{locale}.'.Config::get('app.base_address')], function() use ($homeController)
{
Route::get('/', ['as' => 'home', 'uses' => $homeController]);
Route::post('users/register', ['as' => 'register', 'uses' => 'UsersController#register']);
Route::resource('users', 'UsersController');
});
Does anyone have any ideas for filtering the group?
Also if the subdomain isn't valid how can I redirect to something like uk.domainname.com?
Thank you in advance for any help, it's much appreciated.
you could solve this in your routes with a filter, that will be executed first. it checks then for the available subdomains and if it doesn't find it, it redirects to a default subdomain.
Route::filter('subdomain', function()
{
$subdomain = current(explode('.', Request::url()));
if (!in_array($subdomain, Config::get('app.countries.available'))) {
return Redirect::to(Config::get('app.default_subdomain') . '.' . Config::get('app.base_address'));
}
});
Route::group(['before' => 'subdomain'], function()
{
...
}
In your app/filters.php I would write something like this. You will have a to create a new variable in your config called availableSubdomains with your subdomains array.
<?php
Route::filter('check_subdomain', function()
{
$subdomain = Route::getCurrentRoute()->getParameter('subdomain');
if (!in_array($subdomain, Config::get('app.availableSubdomains')))
return Redirect::home();
});
Then I will add a before filter in your group route in app/routes.php
<?php
Route::group(
['domain' => '{locale}.'.Config::get('app.base_address'),
'before' => 'check_subdomain']
, function() use ($homeController)
{
Route::get('/', ['as' => 'home', 'uses' => $homeController]);
Route::post('users/register', ['as' => 'register', 'uses' => 'UsersController#register']);
Route::resource('users', 'UsersController');
});
Sorry, I haven't tested it.
For subdomains where the language designator is the first part of the subdomain name, like: en.domain.com/section here is what I've used for laravel 5.1
this uses getHost which avoids the problem with http/https showing up first
app\Http\routes.php:
Route::filter('subdomain', function() {
$locale_url = current(explode('.', Request::getHost()));
if (!in_array($locale_url, Config::get('app.countries_available'))) {
return Redirect::to(Config::get('app.default_subdomain') . '.' . Config::get('app.base_address'));
}
App::setLocale($locale_url);
});
it is necessary to add things like:
config/app.php:
'countries_available' => ['en','es'],
to find the variable
finally, to add it to a route
app\Http\routes.php:
Route::group(['before' => 'subdomain'], function()
{
Route::get('/', 'control#func');
...
});