How to combine these two routes? - laravel

I have these two routes:
Route::post('/post',
array(
'uses' => 'PostController#newPost'
)
);
Route::post('/post/picture',
array(
'uses' => 'PostController#newPost'
)
);
In the actual controller, I differentiate between the two parameters (since they use the same controller), but how can I combine the two routes above?

Give the following a try
Route::post('/post/{picture?}',
array(
'uses' => 'PostController#newPost'
)
);
Wrapping picture in the {} brackets treats that URL segment as a parameter. Using a ? at the end of the parameter treats it as optional. One caveat: This will also catch things like
/post/some-other-thing
If you're concerned about catching the other items, give the following a try
Route::post('/post/{myvar?}',
array(
'uses' => 'PostController#newPost'
)
)->where('myvar','picture');;
The second parameter to the where method can be any PCRE regular expression.

Related

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: POST and GET routes with same name scrambling link_to_route

I got these routes:
Route::get('prefix/list/{page?}/{size?}', ['as' => 'prefix.list', 'uses' => 'MyController#getList']);
Route::post('prefix/list', ['as' => 'prefix.list', 'uses' => 'MyController#postList']);
When I call link_to_route() like so:
{{ link_to_route('prefix.list', $page, ['page' => $page, 'size' => $size]) }}
It creates this link:
http://my.site/prefix/list?page=5&size=12
But when I remove the post route, it renders correctly this:
http://my.site/prefix/list/5/12
I don't want to change the name of the routes because my system depends on them being the same. How can I solve this?
You could try just changing the order of the routes in your routes file, so that the get one comes last and overrides the post for the purposes of link_to_route().

Optional route parameter that must equal a string

I need to show the exact same page/data for two differents paths (/ and /index). How can I create a route that satisfies this rule?
I tried the following, but the optional parameter allows for any word (like /hello, /world, or /anything), whereas I just want / or /index:
Route::get('/{trending?}', array('as' => 'index', function()
{
// some code
});
You can add a regular expression for route parameters, in your case that would look like this:
Route::get('/{trending?}', array('as' => 'index', function()
{
// some code
}))->where('trending', 'index');
However if you have a controller anyways (and you probably should) then I'd just add two routes:
Route::get('/', ['as' => 'index', 'uses' => 'SomeController#index']);
Route::get('index', 'SomeController#index');

How to display two dynamic names within one url using laravel

The following code:
{{url('/'.$subjecttype->name)}}
is the name 'garden' wrapped up in a url. This gives me localhost/garden with obviously garden as the dynamic name. With my routes setup like so:
Route::get('/{subject}/', array( 'as' => 'subject', 'uses' =>
'SubjectController#getsubject'));
The question is how would I setup two dynamic names within one route? For example
localhost/garden/12
so i would want my route to look something like this
Route::get('/{subject}/{id}/', array( 'as' => 'subjectid', 'uses' => 'SubjectController#getsubjectid'));
but more importantly what would it look like in my view? so that I have the of my garden header wrapped up in a url that looks like this:
'gardening tips for beginners' which is {{$subjecttype->title}}
below is my very poor attempt at what i want but i hope you get the picture.
{{url('/$subjecttype->name/$subjecttype->id/'.$subjecttype->title)}}
Thanks
For your route:
Route::get(
'/{subject}/{id}/',
array(
'as' => 'subjectid',
'uses' => 'SubjectController#getsubjectid'
)
);
you can generate the URL with the following code:
$url = URL::route(
'subjectid',
array(
'subject' => $subjecttype->name,
'id' => $subjecttype->id
)
);
or, if you prefer to use the helper functions:
$url = route(
'subjectid',
array(
'subject' => $subjecttype->name,
'id' => $subjecttype->id
)
);
That's going to give you a URL like http://example.com/subjectname/42. If you want to add another parameter like the title at the end of the URL, you'll need to add another parameter to your route definition. If you don't you're going to get 404 errors because no route will match the URL.
For the second part of my question using the 'gardening tips for beginners' example:
gardening tips for beginners

Resources