Laravel: Creating route resource for sub directory - laravel

I am new to laravel and creating a spare parts maintenance app.
I created a route resource for spare parts using :
Route::resource('/parts' , 'SparePartsController');
This works fine.
Later I wanted to also create another route resource for spare parts categories. So I created the controller and used:
Route::resource('/parts/categories' , 'SpCategoriesController');
But this second resource wont work. When i go to www.myapp.com/parts/categories , I get a blank page. Any idea whats wrong?

Try to group the routes with a prefix for example:
Route::group(['prefix' => 'parts'], function(){
Route::get('/', 'SparePartsController');
Route::get('/categories', 'SpCategoriesController');
});
This will route all traffic from /parts to the SparePartsController and /parts/categories will call the SpCategoriesController
Look at the documentation for more information:
https://laravel.com/docs/5.3/routing#route-groups
If you want to call a specific function of the Controller just write:
Route::get('/', 'SparePartsController#functionName')

The SpCategoriesController resource route won't work because SparePartsController resource route is taking precedence over it.
To fix that, place your routes in this order:
Route::resource('/parts/categories' , 'SpCategoriesController');
Route::resource('/parts' , 'SparePartsController')
Ref: https://laravel.com/docs/5.3/controllers#restful-supplementing-resource-controllers

Related

Laravel using of resource

I'm new to Laravel and I'm working around with it.
I have a folder in views called 'cp'. in cp folder I can add/remove new slider through index.blade.php and also add new products through product.blade.php. I want to update my products too but when I submit the form It goes to the wrong route ( blog.dev/product/6 ).
I also attached 4 screenshots that shows the pages.
Could you please help me with that.
This is web.php:
Route::get('/','PagesController#index');
Route::get('درباره-ما', 'PagesController#about');
Route::get('تماس-با-ما', 'PagesController#contact');
Route::get('غذای-سگ', 'PagesController#dogs');
Route::get('/cp/product', 'ProductController#product');
Route::get('/cp/product/{id}/edit/', 'ProductController#edit');
Route::resource('product','ProductController');
Route::resource('cp', 'PostsController');
Auth::routes();
screenshot1: https://cdn.pbrd.co/images/GSFDbPj.jpg
screenshot2: https://cdn.pbrd.co/images/GSFDNRq.jpg
screenshot3: https://cdn.pbrd.co/images/GSFEi1a.jpg
screenshot4: https://cdn.pbrd.co/images/GSFCI6F.jpg
Laravel read the route from the top and stop at the first match, so put the more restrictive route at the top
Try something like this : (unfortunately I can't check the non-latin alaphabet, maybe you can also comment them if you still have issue - just to be sure it's not a cause too)
Route::get('/','PagesController#index');
Route::get('درباره-ما', 'PagesController#about');
Route::get('تماس-با-ما', 'PagesController#contact');
Route::get('غذای-سگ', 'PagesController#dogs');
Route::get('/cp/product/{id}/edit/', 'ProductController#edit');
Route::get('/cp/product', 'ProductController#product');
Route::resource('product','ProductController');
Route::resource('cp', 'PostsController');
Auth::routes();
Can you tell me if it's working ?
update method available only PUT|PATCH method
change your request url
/product/6?_method=PUT
now you can use POST method for update

laravel routing based on convention

I'm trying to setup a simple routing system based on convention.
My app will have this structure
Http
--Controllers
----Admin
------User.php
----Books
------Add.php
----etc...
I want to be able to add new Folders and controllers without adding routes manually to the web.php file.
For example I want the route to respond to /Admin/User URL with User.php controller.
I'm trying something like this, but I don't understand how to write the internal router...
Route::any('/{module}/{action?}', function($module, $action = 'index') {
Route::get('*',$module.'\'.$action.'#index' );
});
It seems that Rout:get('*'... never matches.
PS the controller namespace is correct and I reloaded with composer.
The controller works if called harcoded.
I tried also to escape '\'
$r=$module.'\\'.$action.'\\'.$action.'Ctl#index';
Route::get('/',$r );
But no result. The route is intercepted but nothing i served
It seems I came up with this
Route::get('/{module}/{action}', function($module,$action) {
return App::make('\App\Http\Controllers\\'
.$module.'\\'.$action)->callAction('index', []);
});
Any other better way?

Subfolder routing in laravel 5

I am having trouble routing with controllers in subfolders. I have tried the solution proposed in Laravel Controller Subfolder routing, but I can't get it to work.
Folder structure
HTTP
Controllers
Admin
AdminControllers
User
UserControllers
BaseController
Admincontrollers are defined in the 'App\HTTP\Controllers\Admin' namespace
Routes file
Route::group(['middleware'=> 'admin','prefix' => 'admin'], function() {
Route::get('home', 'AdminHomeController#index');
Route::get('home', 'Admin\AdminHomeController#index');
Route::resource('events', 'AdminEventController');
Route::resource('events', 'Admin\AdminEventController');
Route::get('myevents', 'AdminEventController#myevents');
Route::get('myevents', 'Admin\AdminEventController#myevents');
Route::resource('groups', 'AdminGroupController');
Route::resource('users', 'AdminUserController');
});
This does seem weird, but it is the only way to keep it working right now.
If I delete
Route::get('myevents', 'Admin\AdminEventController#myevents');
//errormessage Class App\Http\Controllers\AdminEventController does not exist
If I delete
Route::get('myevents', 'AdminEventController#myevents');
//errormessage Action App\Http\Controllers\AdminEventController#myevents not defined.
If I put the controllers in the controller namespace (not the admin one)
I still get
//errormessage Class App\Http\Controllers\AdminEventController does not exist
When the only route added is
Route::resource('events', 'AdminEventController');
The problem were the calls in the views:
changing
<td>{!!Html::linkAction('AdminEventController#show', $event->name, $event->slug)!!}</td>
to
<td>{!!Html::linkAction('Admin\AdminEventController#show', $event->name, $event->slug)!!}</td>
fixed it.
The Laravel 5 solution in Laravel Controller Subfolder routing is correct. The problem was not in the routes file or controllers.
Yes If your application gets bigger like this, it makes sense to structure Controllers with sub-folders. But it takes a little more effort than just moving the files here and there. Let me explain the structure.
For example, we want to have a sub-folder app/Http/Controllers/Admin and then inside of it we have our AdminController.php, that’s fine. What we need to do inside of the file itself:
Correct namespace – specify the inner folder:
namespace App\Http\Controllers\Admin;
Use Controller – from your inner-namespace Laravel won’t “understand” extends Controller, so you need to add this:
use App\Http\Controllers\Controller;
Routes – specify full path
This wouldn’t work anymore:
Route::get('admin', 'AdminController#index');
This is the correct way:
Route::get('admin', 'Admin\AdminController#index');
And that’s it – now you can use your controller from sub-folder.
Reference (Tested):
http://laraveldaily.com/moving-controllers-to-sub-folders-in-a-correct-way/
By: Povilas Korop

Laravel routing group for muliple domains with wildcards, how to handle domain suffixes?

I have 3 domains which, on my local server, take the format:
mydomainfirst.local
mydomainsecond.local
mydomainthird.local
In my routes.php file, I have the following:
Route::group(array('domain' => '{domain}.{suffix}'), function() {
Route::get('/', 'Primary#initialize');
});
The idea is to take the $domain variable in my controller and extract the first/second/third part from it, which works fine. However, now my site is online, this routing file no longer works and throws a Http-not-found exception. After a while, I have figured that the problem is that the domains have now taken the format mydomainfirst.co.uk. Because there are now 2 parts to the domain suffix, it seems I need to do this:
Route::group(array('domain' => '{domain}.{a}.{b}'), function() {
Route::get('/', 'Primary#initialize');
});
To get it to work. Which is stupid. How can I tell it to just accept any suffix? Is there an 'anything' wildcard I can use?
I have tried a few things like this answer but it doesn't work with route groups.
EDIT: It seems the Enhanced Router package would at least enable me to add a where clause to the route group, but does it solve the problem of how to set a wildcard that will match an indeterminate number of segments? I need something like:
{domain}.{anything}
That will match both:
mydomainfirst.local AND mydomainfirst.co.uk
?
Ok let me first say that the code of this package actually looks good and should work. Even if you can't get it running by installing you could take the files and use the code with your own service provider etc.
But there's also a kind of quick and dirty solution. (Actually the package does it pretty similar, but it looks a lot nicer ;))
First, here's how you can do it for one route:
Route::group(array('domain' => '{domain}.{tld}'), function(){
Route::get('/', 'Primary#initialize')->where('tld', '.*');
});
So the where condition for the route group actually gets set on the individual route.
Of course you don't want to do this for every route inside that group so you can use a simple foreach loop:
Route::group(array('domain' => '{domain}.{tld}'), function($group){
Route::get('/', 'Primary#initialize');
foreach($group->getRoutes() as $route){
$route->where('tld', '.*');
}
});
Note: The loop needs to come after all routes. Otherwise they won't registered and therefore not returned with getRoutes()

How to set view file path in laravel?

I have a directory structure for laravel app like this:
app/
admin/
controllers/
views/ -> for admin views
...
views/ -> for frontend views
How can I set the view path for controllers in admin? I don't want to use View::addLocation or View::addNamespace because I might have the same view file name for admin and frontend, and don't want to add a namespace for every View::make('namespace::view.file').
I see in http://laravel.com/api/4.2/Illuminate/View/View.html there is a setPath method, but how do I call it? View::setPath raised undefined method error.
You have two ways to accomplish your goal. First, let's have a look at app/config/view.php. That's where the path(s) for view loading are defined.
This is the default:
'paths' => array(__DIR__.'/../views'),
Method 1: Load both directories
You can easily add the admin directory to the array
'paths' => array(
__DIR__.'/../views',
__DIR__.'/../admin/views
),
Now the big disadvantage of this: view names have to be unique. Otherwise the view in the path specified first will be taken.
Since you don't want to use a view namespace I suppose you don't want a syntax like admin.viewname either. You'll probably like method 2 more ;)
Method 2: Change the view page at runtime
Every Laravel config can be changed at runtime using the Config::set method.
Config::set('view.paths', array(__DIR__.'/../admin/views'));
Apparently setting the config won't change anything because it is loaded when the application bootstraps and ignored afterwards.
To change the path at runtime you have to create a new instance of the FileViewFinder.
Here's how that looks like:
$finder = new \Illuminate\View\FileViewFinder(app()['files'], array(app_path().'/admin/views'));
View::setFinder($finder);
Method 3: Use addLocation but without default path
You could also remove the default path in app/config/view.php
'paths' => array(),
And then use View::addLocation in any case (frontend and admin)
View::addLocation(app_path().'/views');
View::addLocation(app_path().'/admin/views');
In the latest version 6 i am doing it this ways:
View::getFinder()
->setPaths([
base_path('themes/frontend/views'),
base_path('themes/admin/views')]
)
In Laravel 5.5, other solutions did not work. In boot method of a service provider
View::getFinder()->prependLocation(
resource_path('views') . '/theme'
);
try it like this
View::addNamespace('admin', app_path() . '/admin/views');
Route::group(['prefix' => 'admin'], function() {
Route::get('/', function() {
return view('admin::index');
});
});

Resources