Laravel custom Route - laravel

Hi I want to use routes like this for a page
Route::get('{slug?}-{newsSlug?}-{id?}', array('as' => 'subpages', 'uses' => 'HomeController#subpages' ));
It does not work like this
Route::get('{slug?}/{newsSlug?}/{id?}', array('as' => 'subpages', 'uses' => 'HomeController#subpages' ));
This way the other pages do not work naturally.
Could you suggest me a solution about this.

Where you define a route like this
Route::get('{slug?}-{newsSlug?}-{id?}'...)
without a constant, it means it will cover most cases of routing, which is why other pages do not work.
For them to work, you need to put that code at the end of your routes file, so that other routes will have precedence.

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.

Multiple routes for the same controller function

I need to have 2 routes managed by the same controller function.
Instead of creating to different rules, I would like to create 1 rule.
So instead of something like this:
Route::get('/', ['uses' => 'MyController#index']);
Route::get('dashboard', ['uses' => 'MyController#index']);
I want to use 1 rule. I found out this multiple routes in single Route::get() call Laravel 4 but that code not works for me.
This is what I tried without success:
// THEY BOTH DO NOT WORK
Route::get('/{name}', ['uses' => 'MyController#index'])->where('name', 'dashboard|');
Route::get('/{name}', ['uses' => 'MyController#index'])->where('name', '(dashboard)?');
With these rules, if I go to / route I get 404 error.
If I go to dashboard route it works.
Making name a optional route parameter should work:
Route::get('/{name?}', ['uses' => 'MyController#index'])->where('name', 'dashboard');
Not sure why you are using uses, the shorter version would be:
Route::get('/{name?}', 'MyController#index')->where('name', 'dashboard');

Laravel 5.4 route simplification

I've been trying to find some documentation on how to accomplish the following, but it seems like maybe I'm not using the correct search terms.
I would like to implement some simplified routes in Laravel 5.4 by omitting the route name from the path – for example:
/{page} instead of /pages/{page}
/profile instead of /users/{user}/edit
/{exam}/{question} (or even /exams/{exam}/{question}) instead of /exams/{exam}/questions/{question}
Example of current routes
Route::resource('exams.questions', 'ExamQuestionController', ['only' => ['show']]);
// exams/{exam}/question/{question}
I know how to do this with route closures and one-off routes (e.g.: Route::get...) but is there a way to do this using Route::resource?
In rails the above could be accomplished with:
resources :exams, path: '', only: [:index, :show] do
resources :question, path: '', only: [:show]
end
// /:exam_id/:id
While I haven't yet found a way to accomplish my test cases using strictly Route::resource, here is what I implemented to accomplish what I was trying to do:
// For: `/{exam}/{question}`
Route::group(['as' => 'exams.', 'prefix' => '{exam}'], function() {
Route::get('{question}', [
'as' => 'question.show',
'uses' => 'QuestionController#show'
]);
});
// For: `/exams/{exam}/{question}`
Route::group(['as' => 'exams.', 'prefix' => 'exams/{exam}'], function() {
Route::get('{question}', [
'as' => 'question.show',
'uses' => 'QuestionController#show'
]);
});
// For: `/profile`
Route::get('profile', function() {
$controller = resolve('App\Http\Controllers\UserController');
return $controller->callAction('edit', $user = [ Auth::user() ]);
})->middleware('auth')->name('users.edit');
// For: `/{page}`
// --------------
// Note that the above `/profile` route must come before
// this route if using both methods as this route
// will capture `/profile` as a `{page}` otherwise
Route::get('{page}', [
'as' => 'page.show',
'uses' => 'PageController#show'
]);
No, you cannot and should not be trying to do this with Route::resource.
The whole purpose of Route::resource is that it creates the routes in a specific way that matches the common "RESTful Routing" pattern.
There is nothing wrong with wanting simpler routes (no one is forcing you to use RESTful routing), but you will need to make them yourself with Route::get, etc. as you already know.
From the documentation (not exactly your case, but related to it - showing that Route::resource is not meant to be super-configurable):
Supplementing Resource Controllers
If you need to add additional routes to a resource controller beyond the default set of resource routes, you should define those routes before your call to Route::resource; otherwise, the routes defined by the resource method may unintentionally take precedence over your supplemental routes:
Route::get('photos/popular', 'PhotoController#method');
Route::resource('photos', 'PhotoController');

my routing is not working proper in laravel

Here are my two routes mentioned in http/routes.php
Route::get('/{buy_type}-property/{type}-in-{city}/{location}/project/{projname}/{section}', 'APP\DetectHookController#detectProjectcase4')->where('projname', '[A-Za-z0-9_\-A-Za-z0-9_\-]+')->where('location','[A-Za-z0-9_\-A-Za-z0-9_\-]+')->where('section', '[A-Za-z0-9_\-A-Za-z0-9_\-]+');
And second one is
Route::get('/{buy_type}-property/{type}-in-{city}/{location}/project/{clustername}/{projname}', array( 'as' => 'project-with-cluster', 'uses' => 'APP\DetectHookController#detectProjectcase2'))->where('projname', '[A-Za-z0-9_\-A-Za-z0-9_\-]+')->where('location','[A-Za-z0-9_\-A-Za-z0-9_\-]+');
I want conditional routes based on the {section} parameter in first route.
The second one doesn't get call when it is supposed to be called as both routes are having same parameters. Can someone suggest me as I am helpless for almost a week.
You can re-structure your route as:
Route::get('/{buy_type}-property/{type}-in-{city}/{location}/project/{projname}/cluster/{clustername}', array( 'as' => 'project-with-cluster', 'uses' => 'APP\DetectHookController#detectProjectcase2'))->where('projname', '[A-Za-z0-9_\-A-Za-z0-9_\-]+')->where('location','[A-Za-z0-9_\-A-Za-z0-9_\-]+');

Laravel Routes Artisan

When I run artisan routes in laravel 4
auth/login/{v1}/{v2}/{v3}/{v4}/{v5}
Is this normal or is there something wrong. My routes work just wondering if there might be a bug or something. Below are my routes for auth. I'm using restful routes for auth.
Route::controller('auth','AuthController');
Route::get('AuthController/login', array('as' => 'login', 'uses' => 'AuthController#login'));
Route::get('auth/logout', array('as' => 'logout', 'uses' => 'auth#logout'));
Route::post('auth/login', array('uses' => 'auth#login'));
This is expected. When you register controllers with Route::controller() the controller inspector adds the URI wildcards. Consider the following example:
Route::controller('user', 'UserController');
You might then have a method like this on your UserController:
public function getProfile($username)
{
$user = User::where('username', $username)->first();
return View::make('profile')->with('user', $user);
}
You could then hit that method by going to localhost/yourapp/user/profile/jason
In a nut shell it allows you to pass extra parameters to a method. To me this is a very old school way of doing it, as it looks nicer like localhost/yourapp/user/jason/profile and in this case you'd need to use a route to map to the controller method.
I suggest you 2 improvements:
1 - keep a standard with URIs
You don't need Route::controller in this case. In order to mantain all routes with the same structure I would do:
Route::group( array('prefix'=>'auth,function(){ //make all auth routes starting by auth
Route::get('getLogin', array('as' => 'getLogin', 'uses' => 'AuthController#getLogin'));
Route::get('getLogin', array('as' => 'logout', 'uses' => 'AuthController#logout'));
Route::post('postLogin', array('as' => 'postLogin', 'uses' => 'AuthController#postLogin'));
});
It is not necessary to use group but if you app grows could be better. Without group code will be:
Route::get('auth/getLogin', array('as' => 'getLogin', 'uses' => 'AuthController#getLogin'));
Route::get('auth/getLogin', array('as' => 'logout', 'uses' => 'AuthController#logout'));
Route::post('auth/postLogin', array('as' => 'postLogin', 'uses' => 'AuthController#postLogin'));
2 - Protect your post routes
For every post and put request we've to prevent CSRF attacks like this:
Route::post('postLogin',array('before' => 'csrf','uses'=>AuthController#postLogin) );

Resources