no one?
One app multiple view routes (and domains assigned to it)
Hi, I'm going to build an application thats using multiple domains. Each domain has its own views, but its all the same application.
- Api gets json
- site1 gets his views
- site2 gets other views
I've tried this setup in my routes.php:
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::auth();
//**********************
//********Home**********
//**********************
Route::get('home', 'HomeController@index');
Route::get('api', 'HomeController@index');
Route::get('site1', 'HomeController@index');
Route::get('site2', 'HomeController@index');
//**********************
//*******Product********
//**********************
//
// API
//
Route::get('product', 'HomeController@index'); //returns login or welcome text
Route::get('api/product', 'ProductController@index'); // returns all products as json
Route::get('api/product/{id}', function ($id) { // returns given product as json
$product = \App\Product::with('category','supplier')->find($id);
return response(view('product',array('product'=>$product)),200, ['Content-Type' => 'application/json']);
});
//
// SITE1
//
Route::get('site1/product', function () { // returns all products as view, styled as site1
$products = \App\Product::all();
return response(view('site1/products',array('products'=>$products)),200);
});
Route::get('site1/product/{id}', function ($id) { // returns given product as view, styled as site1
$product = \App\Product::with('category','supplier')->find($id);
return response(view('site1/product',array('product'=>$product)),200);
});
//
// SITE2
//
Route::get('site2/product', function () { // returns all products as view, styled as site2
$products = \App\Product::all();
return response(view('site2/products',array('products'=>$products)),200);
});
Route::get('site2/product/{id}', function ($id) { // returns given product as view, styled as site2
$product = \App\Product::with('category','supplier')->find($id);
return response(view('site2/product',array('product'=>$product)),200);
});
//**********************
//*******Category*******
//**********************
//
// API
//
Route::get('category', 'HomeController@index'); //returns login or welcome text
Route::get('api/category', 'ProductController@index'); // returns all categories as json
Route::get('api/category/{id}', function ($id) { // returns given category as json
$category = \App\Category::with('product')->find($id);
return response(view('category',array('category'=>$category)),200, ['Content-Type' => 'application/json']);
});
//
// SITE1
//
Route::get('site1/category', function ($id) { // returns all categories as view, styled as site1
$categories = \App\Category::all();
return response(view('site1/categories',array('categories'=>$categories)),200);
});
Route::get('site1/category/{id}', function ($id) { // returns given category as view, styled as site1
$product = \App\Category::with('product')->find($id);
return response(view('site1/category',array('category'=>$category)),200);
});
//
// SITE2
//
Route::get('site2/category', function ($id) { // returns all categories as view, styled as site2
$categories = \App\Category::all();
return response(view('site2/categories',array('categories'=>$categories)),200);
});
Route::get('site1/category/{id}', function ($id) { // returns given category as view, styled as site2
$product = \App\Category::with('product')->find($id);
return response(view('site2/category',array('category'=>$category)),200);
});
//**********************
//*******Supplier*******
//**********************
//
// API
//
Route::get('supplier', 'HomeController@index'); //returns login or welcome text
Route::get('api/supplier', 'ProductController@index'); // returns all suppliers as json
Route::get('api/supplier/{id}', function ($id) { // returns given supplier as json
$supplier = \App\Supplier::with('product')->find($id);
return response(view('supplier',array('supplier'=>$supplier)),200, ['Content-Type' => 'application/json']);
});
//
// SITE1
//
Route::get('site1/supplier', function ($id) { // returns all suppliers as view, styled as site1
$suppliers = \App\Supplier::all();
return response(view('site1/suppliers',array('suppliers'=>$suppliers)),200);
});
Route::get('site1/supplier/{id}', function ($id) { // returns given supplier as view, styled as site1
$product = \App\Supplier::with('product')->find($id);
return response(view('site1/supplier',array('supplier'=>$supplier)),200);
});
//
// SITE2
//
Route::get('site2/supplier', function ($id) { // returns all suppliers as view, styled as site2
$suppliers = \App\Supplier::all();
return response(view('site2/suppliers',array('suppliers'=>$suppliers)),200);
});
Route::get('site1/supplier/{id}', function ($id) { // returns given supplier as view, styled as site2
$product = \App\Supplier::with('product')->find($id);
return response(view('site2/supplier',array('supplier'=>$supplier)),200);
});
It works, but:
- I think it can be done better / simpler
- How can i connect domains to an in app route like /site1 in apache via htacces or httpd/vhost?
If that's not possible, maybe its better to create a middleware for it to regognise the way its requested and not duplicating the routes for each site?
Bart
PS: The answer of @thefuzzy0ne looks like a better way than mine. I'm still thinking about the other way's of @dylanh too and let all the possible way's to do it pass my thoughts, but for now this one is the real answer on my initial question ;)
=============================================================
thefuzzy0ne — 15 hours ago
Or better yet: (Still untested):
function viewForDomain($view, $data = [], $mergeData = [])
{
$domain = str_replace('.', '_', url());
return view($domain.'.'.$view, $data, $mergeData);
}
Now you don't have to specify the domain at all, the function will use it automatically. You can still use the standard view() helper when you just want a normal view.
=============================================================
edit from Bart:
i made it working with this one as helper (multiple ways to make helpers, google for that) and added a fallback, so you can make base views and overrule them per domain:
<?php
function viewForDomain($view, $data = [], $mergeData = [])
{
$domain = str_replace('.', '_', str_replace('http://', '', url('/')));
if (view()->exists($domain.'.'.$view)) {
return view($domain.'.'.$view, $data, $mergeData);
}
else{
return view('base.'.$view, $data, $mergeData);
}
}
?>
If it's really just the same data with different presentation, I think my idea should work fine. Then your routes.php will look something like this (I tried to optimise it a little, but I'm sure it can be optimised a bit more):
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::auth();
Route::get('home', 'HomeController@index');
Route::get('api', 'HomeController@index');
/***********************
* Product *
***********************/
Route::group(['prefix' => '/product'], function() {
Route::get('/', function () { // returns all products as view
$products = \App\Product::all();
return viewForDomain('products', ['products'=>$products]);
});
Route::get('/{id}', function ($id) { // returns given product as view
$product = \App\Product::with('category','supplier')->find($id);
return viewForDomain('product', ['product'=>$product]);
});
})
/******************
* API *
******************/
Route::group(['prefix' => '/api'], function() {
Route::get('/category', 'ProductController@index'); // returns all categories as json
Route::get('/category/{id}', function ($id) { // returns given category as json
$category = \App\Category::with('product')->find($id);
return response()->json($category);
});
Route::get('/supplier', 'ProductController@index'); // returns all suppliers as json
Route::get('/supplier/{id}', function ($id) { // returns given supplier as json
$supplier = \App\Supplier::with('product')->find($id);
return response()->json($supplier);
});
Route::get('/product', 'ProductController@index'); // returns all products as json
Route::get('/product/{id}', function ($id) { // returns given product as json
$product = \App\Product::with('category', 'supplier')->find($id);
return response()->json($product);
});
})
/***********************
* Category *
***********************/
Route::group(['prefix' => '/category'], function() {
Route::get('/', function () { // returns all categories as view
$categories = \App\Category::all();
return viewForDomain('categories', ['categories'=>$categories]);
});
Route::get('/{id}', function ($id) { // returns given category as view
$product = \App\Category::with('product')->find($id);
return viewForDomain('category', ['category' => $category]);
});
});
/***********************
* Supplier *
**********************/
Route::group(['prefix' => '/supplier'], function() {
Route::get('/', function () { // returns all suppliers as view
$suppliers = \App\Supplier::all();
return viewForDomain('suppliers', ['suppliers'=>$suppliers]);
});
Route::get('/{id}', function ($id) { // returns given supplier as view
$supplier = \App\Supplier::with('product')->find($id);
return viewForDomain('supplier', ['supplier'=>$supplier]);
});
});
I've not tested it, but hopefully you get the idea. Now, to add a new site, you just need to add the corresponding views. You won't need to touch the routes unless you add a new URI.
Note, there's no more mention of site1, site2 or whatever. I'm sure you could apply this same technique to your API too.
Please or to participate in this conversation.