Build menu through Route::group in Laravel 5 - laravel

I have 2 Route::group and each one has a couple of routes. For example:
Route::group(['prefix'=>'/guest', 'middleware'=>'guest'], function()
{
Route::get('login', ['as' => 'Login to the site', 'uses' => 'WelcomeController#login']);
Route::get('register', ['as' => 'Register', 'uses' => 'WelcomeController#register']);
Route::get('restore', ['as' => 'Restore the password', 'uses' => 'WelcomeController#restore']);
});
Route::group(['prefix'=>'/admin', 'middleware'=>'auth', function()
{
Route::get('/dashboard', ['as' => 'Home Page', 'uses' => 'AdminController#users']);
Route::get('/users', ['as' => 'Users', 'uses' => 'AdminController#users']);
});
So, I would like automatically to build a menu using the current prefix of Route::group. If user is authenticated Laravel should display the menu list like this:
<li>Home Page</li>
<li>Users</li>
but if user is just guest, in this case my menu should be like this:
<li>Login to the site</li>
<li>Register</li>
If you look through the second guest menu, you will see that menu for Restoring password was missed. Yes, I would like sometimes do not display some menus.
Basically, I have a 2 questions:
Find the routes which belong to the current Route group and build a
menu.
Don't display any routes in menu, adding some option to them.

Route groups are transient and their only use is to allow the router to populate in bulk the specific attributes (prefixes, namespaces, etc) of the routes that are in them.
When you register a group, the attributes you pass to it are added to the routes that are defined inside the group, then the group is deleted. So the group exists within the router only while the Route::group method is being executed.
All that means that you can't get any group information, in your route closure or controller method in order to get the routes inside.
Since you say that you have 3 types of users, then you should probably have a way to get the user type of the authenticated user, with something like Auth::user()->type (which would return one of these values admin, instructor, student). Also, you should be able to use Auth::guest() to determine if a user is not logged in.
So you can just do the following to handle menu generation (the code below assumes that the $user variable contains the model from Auth::user()):
<ul>
#if (Auth::guest())
<li>Login to the site</li>
<li>Register</li>
#else
#if ($user->type == 'admin')
<li>Home Page</li>
<li>Users</li>
...
#elseif ($user->type == 'instructor')
<li>Home Page</li>
<li>Students</li>
...
#elseif ($user->type == 'student')
<li>Home Page</li>
<li>Lessons</li>
...
#endif
#endif
</ul>

I added "#" in alias for some routes which I want to hide.
Route::group(['prefix'=>'/guest', 'middleware'=>'guest'], function()
{
Route::get('login', ['as' => 'Login to the site', 'uses' => 'WelcomeController#login']);
Route::get('register', ['as' => 'Register', 'uses' => 'WelcomeController#register']);
Route::get('restore', ['as' => 'Restore the password#hide', 'uses' => 'WelcomeController#restore']);
});
Then in view I added this code:
foreach( Route::getRoutes() as $route){
$data = explode('#', $route->getName());
if(Route::getCurrentRoute()->getPrefix() == $route->getPrefix() && #$data[1] == "" ){
echo '<li>'.$data[0].'</li>';
}
}
Now, I successfully displayed all routers of current route::group and hide some routes adding # to the alias. In example it is Restore the password#hide

Related

Laravel route gets wrong controller

I'm building project with Laravel and Vue and i want my categories and tags urls to be like that:
domain.com/some-tag
domain.com/some-category
My web.php:
Route::get('/', ['uses' => '\App\Http\Controllers\IndexController#index']);
Route::get('/{category}', ['as' => 'category', 'uses' => '\App\Http\Controllers\CategoryController#index']);
Route::get('/{tag}', ['as' => 'tag', 'uses' => '\App\Http\Controllers\TagController#index']);
Route::get('/{category}/{article}', ['as' => 'category.article', 'uses' => '\App\Http\Controllers\ArticleController#index']);
I'm getting 404 error on my tags links and i know its because router matches "category" first and uses CategoryController.
What should I do? I don't want to make them unique by adding something like domain.com/tags/tag-name
I've tried to use named routes for my vue component (with Ziggy-js lib) so my link looks like
<a class="tags-block__link" :href="route('tag', {tag: tag.slug}).url()" v-for="tag in tags" :key="tag.id">
But it doesn't help
Why it should not be mixing?
You define Route::get('/{category}' and Route::get('/{tag}'. So if you open /1 in your browser it will always run the first route it is able to find that matches the pattern. So it is always running CategoryController#index yes?
Your routes should be:
Route::get('/category/{category}', ['as' => 'category', 'uses' => '\App\Http\Controllers\CategoryController#index']);
Route::get('/tag/{tag}', ['as' => 'tag', 'uses' => '\App\Http\Controllers\TagController#index']);
Read more at https://laravel.com/docs/7.x/routing
The remaining route should do fine, cause you define it last.

What does 'as' method do in Laravel

In the example from the tutorial, it shows up.
Route::group([
'prefix' => 'admin',
'as' => 'admin.'
], function () {}
Can someone tells me what 'as' does? Also, is the dot next to the 'admin' neccessary?
Thank you.
Let's say, for example, that you have this route:
Route::get('admin', [
'as' => 'admin', 'uses' => 'AdminController#index'
]);
By using as you assign custom name to your route. So now, Laravel will allow you to reference said route by using:
$route = route('admin');
So you don't have to build the URL manually over and over again in your code. You don't really need . notation if you only want to call your route admin. If you want a more detailed name of your route, lets say for ex. admin product route, then you use the . notation, like this:
Route::get('admin/product', [
'as' => 'admin.product', 'uses' => 'AdminController#showProduct'
]);
So now, you will be able to call this route by the assigned name:
$route = route('admin.product');
Update:
The previous answer I provided is valid for a single routes. For the route groups, the procedure is very similar. In the route groups you need the . notation when you add a custom name, since you will be referencing another route after that . notation. This will allow you to set a common route name prefix for all routes within the group. So by your example, lets say you have a dashboard route inside your admin route group:
Route::group(['as' => 'admin.'], function () {
Route::get('dashboard', ['as' => 'dashboard', function () {
//Some logic
}]);
});
Now, you will be able to call the dashboard route like this:
$route = route(admin.dashboard);
You can read more about this in Laravel official documentation.
you may specify an as keyword in the route group attribute array, allowing you to set a common route name prefix for all routes within the group.
For Example
Route::group(['as' => 'admin::'], function () {
// Route named "admin::"
});
UseRoute Name like {{route(admin::)}} or route('admin::')
you can use an 'as' as a named route. if you do not prefix your route name in group route than you may add custom route name like this.
Route::group(['prefix' => 'admin', 'middleware' => ['auth', 'roles'], 'roles' => ['2']], function () {
Route::post('/changeProfile', ['uses' => 'UserController#changeProfile',
'as' => 'changeProfile']);
});

Routes are not working properly

When the user accesses "http://proj.test/" instead of getting the homepage I get:
Sorry, the page you are looking for could not be found.
But if the user accesses "http://proj.test/home" it works.
Also when the user accesses "http://proj.test/conference/create" instead of appear the page with the form to create a conference it appears:
View [app] not found. (View: /Users/johnw/projects/proj/resources/views/conferences/create.blade.php)
Do you know where can be the issue? Should be something about the links or routes but I don't know where is the issue.
Links that I'm using
<a class="logo" href="{{route('home')}}">Homepage</a>
Create Conference
Login
Logout
Register
Routes:
Route::group(['prefix' => '', 'middleware' => 'auth'], function(){
Route::post('/conference/store', [
'uses' => 'ConferenceController#store',
'as' => 'conference.store'
]);
Route::get('/conference/create', [
'uses' => 'ConferenceController#create',
'as' => 'conference.create'
]);
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
When the user accesses "http://proj.test/" instead of getting the homepage I get:
Sorry, the page you are looking for could not be found.
You have not defined any route for this URL
You can do
...
Route::get('/', 'HomeController#index');
Route::get('/home', 'HomeController#index')->name('home');
...
Very simple answer - you need a Route::get('/', ...) route.
Add this to your Routes instead:
Route::group(['middleware' => ['guest']], function(){
Route::get('/', 'WelcomeController#index');
// WelcomeController is my own example, yours will differ...
});
This way it'll check to see if there's an auth or not and will redirect accordingly.

How to check domain in laravel for some routes?

I need check domain for some routes. Then after check, I need redirect domain https://two.com to https://one.com with middleware in laravel.
For example:
Routes:
Route::get('/', ['as' => 'index', 'uses' => 'IndexController#index']);
Route::get('termsAndCondition', ['as' => 'termsAndCondition', 'uses' => 'IndexController#termsAndCondition']);
Route::get('aboutUs', ['as' => 'aboutUs', 'uses' => 'IndexController#aboutUs']);
Route::get('privacy', ['as' => 'privacy', 'uses' => 'IndexController#privacy']);
I need check aboutUs and privacy for domain name.
If domain name is https://two.com/aboutUs or https://two.com/privacy redirect to https://one.com/aboutUs or https://one.com/privacy.
I need check with middleware.
Thanks.
You can do something like this in a middleware:
if (request()->getHttpHost() === 'two.com' && in_array(request()->path(), ['aboutUs', 'privacy'])) {
return redirect('https://one.com/' . request()->path());
}
you can check url segments using segment() helper something like:
if(Request::segment(1)==='aboutus')
{
return redirect(route('your other route');
}
if(Request::segment(1)==='privacy')
{
return redirect(route('your other route');
}
You can add that check in your middleware, segment() expects an integer param like in case above 1 will check first wildcard after domain name.

laravel 5.2 make dashboard for admin

I am new in laravel 5.2. I want to make dashboard for admin but i do not understand how to make it. I did copy all controller files in admin folder and also copied view folder in admin folder.
I did try some code which is mention below:-
Route::group(array('namespace'=>'Admin'), function()
{
Route::get('/admin', array('as' => 'admin', 'uses' => 'UserController#index'));
Route::get('/admin/register', array('as' => 'register', 'uses' => 'UserController#register'));
Route::get('/admin/login', array('as' => 'login', 'uses' => 'UserController#login'));
});
but now I want to show all controller files under admin like:-
localhost:8000/admin/users
If you want to use all route of admin on localhost:8000/admin.
You should use route group and add prefix on it, like that
Route::group(['prefix' => 'admin/'], function () {
Route::get('users', function () {
// Matches The "/admin/users" URL
});
Route::get('login', function () {
// Matches The "/admin/login" URL
});
.......
});
Read more at this doc https://laravel.com/docs/5.2/routing#route-groups
I hope this could help you.

Resources