Namespacing controllers within routes file - laravel

I have created a package which uses controllers from a certain namespace
Route::get('login', 'Full\Name\Space\Login\LoginController#method');
Route::get('other', 'Full\Name\Space\Other\OtherController#method');
Is there a 'Laravel' way to define the namespace once at the top of the routes file so I can shorten these controller paths? Something like
use 'Full\Name\Space';
Route::get('login', 'Login\LoginController#method');
Route::get('other', 'Other\OtherController#method');

Ofcourse you can:
Route::group(['namespace'=>'foo/1/2'],function(){
Route::get('specify_your_route', 'BarController#index')
});
Route will stay as "specify_your_route", but instead of \Base\Controller\Namespace\BarController router will use \foo\1\2\BarController

Related

Generate routes from controllers' (resources) functions

It has been a while I began to think if it's possible to create functions (resources) in Laravel Controller, and then use some kind of command to generate Routes automatically.
For example, with -r command we generate basic controller resources. Is there any way to generate routes automatically even with external libraries to look in the route/web file like this;
Route::get('/index', 'ProductController#index')->name('product.index');
Route::get('/edit', 'ProductController#edit')->name('product.edit');
Route::get('/create', 'ProductController#create')->name('product.create');
Route::get('/show', 'ProductController#show')->name('product.show');
Route::get('/store', 'ProductController#store')->name('product.store');
Route::get('/update', 'ProductController#update')->name('product.update');
Route::get('/destroy', 'ProductController#destroy')->name('product.destroy');
Thank you.

Laravel: Creating route resource for sub directory

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

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

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