I am creating a project in Laravel . I want to create a url
like http://www.mywebsite.com/username
so i can show the user profile based on username
so far i have this code
Route::group(array('prefix' => 'user', 'before' => 'admin'), function() {
# USer / Individual
Route::get('/', array('as' => 'user', 'uses' => 'Admin\AdminIndividualController#getindex'));
Route::get('create-user', array('as' => 'create-user', 'uses' => 'Admin\AdminIndividualController#create'));
Route::get('edit-user/{id}', array('as' => 'edit-user', 'uses' => 'Admin\AdminIndividualController#edit'))->where(array('id' => '[0-9]+'));
Route::get('delete-user/{id}', array('as' => 'del_user', 'uses' => 'Admin\AdminIndividualController#destroy'))->where(array('id' => '[0-9]+'));
Route::get('deactivate/{id}', array('as' => 'user_deactive', 'uses' => 'Admin\AdminIndividualController#deactive_user'))->where(array('id' => '[0-9]+'));
Route::get('active/{id}', array('as' => 'user_active', 'uses' => 'Admin\AdminIndividualController#active_user'))->where(array('id' => '[0-9]+'));
Route::post('create-user', array('as' => 'post-user', 'uses' => 'Admin\AdminIndividualController#store'));
Route::post('update-user/{id}', array('as' => 'update-user', 'uses' => 'Admin\AdminIndividualController#update'))->where(array('id' => '[0-9]+'));
# USer [Individual] Skills
Route::get('create-skill', array('as' => 'create-user-skill', 'uses' => 'Admin\AdminIndividualController#create_skill'));
Route::get('delete-skill/{id}', array('as' => 'del_skill', 'uses' => 'Admin\AdminIndividualController#destroy_skill'))->where(array('id' => '[0-9]+'));
Route::post('create-skill', array('as' => 'create-user-skill', 'uses' => 'Admin\AdminIndividualController#store_skill'));
#send email to user
Route::get('send-email/{id}', array('as' => 'create-email-user', 'uses' => 'Admin\AdminIndividualController#create_email'))->where(array('id' => '[0-9]+'));
Route::post('send-email', array('as' => 'send-email-user', 'uses' => 'Admin\AdminIndividualController#send_email'));
});
I couldnt find any way to create routing for that if i create just a simple route it disturbs all my other urls like /logout
After Brainstorming here is what i concluded i have to implement it in order to check if this works or not
Route::filter('user.item', function($route, $request)
{
if ($route->parameter('item')->user_id !== Auth::user()->id)
{
App::abort(404);
}
});
What ill be doing is applying filter to routes to check from database if that username exists or not if it does exist ill fetch the view for profile and show the profile otherwise run the url as it is .Is it possible that way >?
A route that has a dynamic segment in the first place should be put after all the other routes so it only runs when the other routes don't match...
Route::get('foo', ...);
Route::get('bar', ...);
Route::get('{user}', ...);
Note that there is still a problem because a user can't have the name create-user because otherwise he won't see his profile but rather the actual create-user route.
That means if you really want to have the profile URL like that you should validate the username and check for reserved words (which are actually your other routes)
Of course the alternative is to just use something like user/{username}
You are right that such routing will overload all other routes and nothing works.
It is much easier to create url like http://www.mywebsite.com/u/username
If you want to have route /{username} then you can either make all other urls to be made of 2 or more url segments or make ineffective manual magic in the routing.
In manual routing you can see if the username matches any user and if not then perform the logout for example. You also need to keep in mind that someones username can be logout.
Bind your username "key" (in your route) and create a Route Bind.
Route::bind('username',function($value){
return User::where('username',$value)->first();
});
Route::group(array('prefix' => '{username}', 'before' => 'admin'), function() {
# USer / Individual
Route::get('/', array('as' => 'user', 'uses' => 'Admin\AdminIndividualController#getindex'));
Route::get('create-user', array('as' => 'create-user', 'uses' => 'Admin\AdminIndividualController#create'));
Route::get('edit-user/{id}', array('as' => 'edit-user', 'uses' => 'Admin\AdminIndividualController#edit'))->where(array('id' => '[0-9]+'));
Route::get('delete-user/{id}', array('as' => 'del_user', 'uses' => 'Admin\AdminIndividualController#destroy'))->where(array('id' => '[0-9]+'));
Route::get('deactivate/{id}', array('as' => 'user_deactive', 'uses' => 'Admin\AdminIndividualController#deactive_user'))->where(array('id' => '[0-9]+'));
Route::get('active/{id}', array('as' => 'user_active', 'uses' => 'Admin\AdminIndividualController#active_user'))->where(array('id' => '[0-9]+'));
Route::post('create-user', array('as' => 'post-user', 'uses' => 'Admin\AdminIndividualController#store'));
Route::post('update-user/{id}', array('as' => 'update-user', 'uses' => 'Admin\AdminIndividualController#update'))->where(array('id' => '[0-9]+'));
# USer [Individual] Skills
Route::get('create-skill', array('as' => 'create-user-skill', 'uses' => 'Admin\AdminIndividualController#create_skill'));
Route::get('delete-skill/{id}', array('as' => 'del_skill', 'uses' => 'Admin\AdminIndividualController#destroy_skill'))->where(array('id' => '[0-9]+'));
Route::post('create-skill', array('as' => 'create-user-skill', 'uses' => 'Admin\AdminIndividualController#store_skill'));
#send email to user
Route::get('send-email/{id}', array('as' => 'create-email-user', 'uses' => 'Admin\AdminIndividualController#create_email'))->where(array('id' => '[0-9]+'));
Route::post('send-email', array('as' => 'send-email-user', 'uses' => 'Admin\AdminIndividualController#send_email'));
});
If its ok for you to display URL of the user's profile page like this: http://website.com/#username then you can show the user's profile based on his username like this:
in routes.php file
Route::get("#{username}", array(
"as" => "users.show",
"uses" => "UsersController#show",
));
in UsersController.php file
public function show($username)
{
$user = User::where("username", "=", $username)->first();
if (is_null($user))
{
return App::abort(404);
}
return View::make("path/to/view/file")->with("user", $user);
}
and you can create links with that URL http://website.com/#username like this:
{{ $user->username }}
this way you don't need to check for reserved words (which are your other routes) unless you already have a route begins with the symbol #.
Related
I'm using Laravel's route groups to try and stop duplication within my Routes file.
I have one main group, frontend. This has the namespace Frontend and as frontend.
Nested within that group, is another group. This group has the prefix account which appends /account/ to each route. It also has as account..
The routes inside the nested group, I'd expect to be:
frontend.account.home
frontend.account.order.show
frontend.account.order.index
Instead I get:
frontend.account.home
frontend.account.account.order.index
frontend.account.account.order.show
Code:
Route::group(['as' => 'frontend.', 'namespace' => 'Frontend'], function () {
Route::group(['prefix' => 'account', 'as' => 'account.', 'namespace' => 'Account'], function () {
Route::get('home', [
'as' => 'home',
'uses' => 'Home\Controller#get'
]);
Route::resource('order', 'Order\Controller', ['except' => [
'create',
'store',
'update',
'destroy',
'edit',
]]);
});
});
Since your excepting almost every routes from the Route::resource method, why not create 2 single routes for index and show like so:
// in your routes file, within your nested group :
Route::get('order', ['as' => 'order.index', 'uses' => 'Order\Controller#index' ]);
Route::get('order/{id}', ['as' => 'order.show', 'uses' => 'Order\Controller#show' ]);
I have the following route definition in Laravel 5. When I group the routes in the following way, it seems the route admin.proposals.home will not work if I provide "/" as the get path, and will work if something trailing (like home) is provided:
/**
* Routes for system administrators.
*/
Route::group(['prefix' => 'admin', 'middleware' => 'admin'], function()
{
Route::group(['prefix' => 'people'], function()
{
Route::get('/', ['as' => 'admin.people.home', 'uses' => 'PersonController#index']);
Route::get('/profile/{userName}', ['as' => 'admin.person.profile', 'uses' => 'PersonController#view']);
Route::get('/organization/{id}', ['as' => 'admin.people.organization', 'uses' => 'PersonController#indexByOrganization']);
});
Route::group(['prefix' => 'projects'], function()
{
Route::get('/', ['as' => 'admin.projects.home', 'uses' => 'ProjectController#index']);
Route::get('/{projectId}', ['as' => 'admin.project.view', 'uses' => 'ProjectController#view']);
Route::group(['prefix' => 'proposals'], function()
{
//problematic line below
Route::get('/home', ['as' => 'admin.proposals.home', 'uses' => 'ProposalController#index']);
Route::get('/{proposalId}', ['as' => 'admin.proposal.view', 'uses' => 'ProposalController#view']);
});
});
});
Specifically, if I change the line:
Route::get('/home', ['as' => 'admin.proposals.home',
'uses' => 'ProposalController#index'
]);
To:
Route::get('/', ['as' => 'admin.proposals.home',
'uses' => 'ProposalController#index'
]);
I got an error saying:
Trying to get property of non-object (View: ... \views\admin\projects\view.blade.php)
But, the admin.proposals.home route points to the controllers index() method and has nothing to do with the view.blad.php.
Changing the path back to get('/home') works perfectly.
What is it that I'm missing?
It's a Route position order problem.
Since you have the route for the URI admin/projects/ as admin.project.home, and after that admin/projects/{projectId} it takes precedence over the route admin/projects/proposals/
Laravel takes proposals as the projectId.
Route::group(['prefix' => 'projects'], function()
{
Route::group(['prefix' => 'proposals'], function()
{
//problematic line below
Route::get('/', ['as' => 'admin.proposals.home', 'uses' => 'ProposalController#index']);
Route::get('/{proposalId}', ['as' => 'admin.proposal.view', 'uses' => 'ProposalController#view']);
});
Route::get('/', ['as' => 'admin.projects.home', 'uses' => 'ProjectController#index']);
Route::get('/{projectId}', ['as' => 'admin.project.view', 'uses' => 'ProjectController#view']);
});
Try this order and let me know what you get. But purely it's a route order problem.
I have been using laravel for a while now, but I stumbled across an error which I have never encountered before. It is probably me overlooking it, but with the route file given below, the route group with the prefix account gives a blank page. When going to /account/anunregisteredroute it does give a httpnotfoundexception
My routes.php file:
http://pastebin.com/EnnGSm10
By adding a / before the parameter you can solve this issue:
Route::get('/{username}', ['as' => 'account-profile', 'uses' => 'AccountController#getProfile']);
This piece of code worked for me:
Route::group(['prefix' => 'account'], function () {
Route::get('/{username}', ['as' => 'account-profile', 'uses' => function($username){
echo $username;
}]);
Route::get('profile', ['as' => 'account-edit-profile', 'uses' => 'AccountController#getUpdate', 'before' => 'auth']);
Route::post('profile', ['as' => 'account-edit-profile', 'uses' => 'AccountController#postUpdate', 'before' => 'auth|csrf']);
Route::group(['before' => 'guest'], function () {
Route::get('create', ['as' => 'account-create', 'uses' => 'AccountController#getCreate']);
Route::get('signin', ['as' => 'account-signin', 'uses' => 'AccountController#getSignin']);
Route::group(['before' => 'csrf'], function() {
Route::post('create', ['as' => 'account-create', 'uses' => 'AccountController#postCreate']);
Route::post('signin', ['as' => 'account-signin', 'uses' => 'AccountController#postSignin']);
});
});
});
I got the expected output.
I've noticed a bit of a peculiarity in Laravel 4 when using Routes. I have a Route group that looks like this:
// Employers routes
Route::group(array('prefix' => 'employers'), function(
Route::get('/', array('as' => 'employers.index', 'uses' => 'EmployersController#index'));
Route::get('create', array('as' => 'employers.create', 'uses' => 'EmployersController#create'));
Route::post('/', array('as' => 'employers.store', 'uses' => 'EmployersController#store', 'before' => 'csrf'));
Route::get('search', array('as' => 'employers.search', 'uses' => 'EmployersController#search'));
Route::get('{id}', array('as' => 'employers.show', 'uses' => 'EmployersController#show'));
Route::get('{id}/edit', array('as' => 'employers.edit', 'uses' => 'EmployersController#edit'));
Route::patch('{id}/update', array('as' => 'employers.update', 'uses' => 'EmployersController#update', 'before' => 'csrf'));
Route::delete('{id}/destroy', array('as' => 'employers.destroy', 'uses' => 'EmployersController#destroy', 'before' => 'csrf'));
));
I've noticed, however, that when I try and add in a new route I have to add it before the first route to use the {id} wildcard as the first parameter in it's url, otherwise I get a notfoundhttpexception. Is this normal? So for example, this works (adding in the employers.search route:
// Employers routes
Route::group(array('prefix' => 'employers'), function(
Route::get('/', array('as' => 'employers.index', 'uses' => 'EmployersController#index'));
Route::get('create', array('as' => 'employers.create', 'uses' => 'EmployersController#create'));
Route::post('/', array('as' => 'employers.store', 'uses' => 'EmployersController#store', 'before' => 'csrf'));
Route::get('{id}', array('as' => 'employers.show', 'uses' => 'EmployersController#show'));
Route::get('search', array('as' => 'employers.search', 'uses' => 'EmployersController#search'));
}
Results in the route employers.search not being found?
This is expected behavior. Routes are evaluated in a top-down fashion.
{id} is a "catch all" route.
So the route system sees /search - and thinks search is an {id} - so it loads that route. But then it cannot find an id of search - and so it fails.
So keep your "catch all" route at the bottom of the list - and it will work correctly.
Is there a way to make something like this?
Route::group(array('as' => 'admin', 'prefix' => 'admin', 'before' => 'admin'), function()
{
Route::get('/', array('as' => 'home', 'uses' => 'AdminController#index'));
Route::get('users', array('as' => 'users', 'uses' => 'AdminController#users'));
});
The goal is to do not include "admin" in all names and make links for above example like this:
URL::route('admin.home');
URL::route('admin.users');
Above example doesn't work:
Illegal offset type in unset
laravel/bootstrap/compiled.php:5053
Named group with nonamed routes inside works.
Named routes in nonamed group work too.
But not together.
Route::group(['prefix' => 'admin', 'before' => 'adminAuth'], function(){
// If you do not want to repeat 'admin' in all route names,
// define the value here
$r = 'admin';
Route::get('users', ['as' => "{$r}.users", 'uses' => 'AdminController#users']);
Route::get('/', ['as' => "{$r}.root", 'uses' => 'AdminController#index']);
});
In yout views/redirect you can use URL::action('ControllerName#method) and Laravel will know where redirect/point to...