Routing with slug and id with dash separated? - laravel

router->get('{slug}-{id}', 'Controller#method');
router->get('{otherSomething}', 'Controller#method2');
this is my routing and first line doesn't work. how to fix it? my software specification does not allow use slash (/) instead dash (-) in first routing.
for router below samples have the same mask
site.com/slug-name-and-sth-100
site.com/other-something

Assuming your other-something doesn't end with number, you can use Regular Expression Constraints , for example you can define route with id like this:
$router->get('{slug}-{id}', 'Controller#method')->where('id','[0-9]+');
and now it should work. However you need to remember to put this route before the route:
$router->get('{otherSomething}', 'Controller#method2');
otherwise it won't work.
EDIT
In case both urls can have same format, you should remove {slug}-{id} route completely and direct all the traffic for {otherSomething} into one method (method2 in your case).
Now you should parse the $otherSomething variable and decide what you should do:
either you decide it's format {slug}-{id} na you can now run service for this
either you will run other service for other cases

Related

Laravel - How do I navigate to a url with a parameter to left of subdirectory

I have to test this Route, but I am not sure how to navigate to it.
Route::get('/{type}/Foo/{page}/{date}', 'FooController#index');
I understand that URLs usually have subdirectories defined before the parameters in the URL.
I have worked with URLs like this example
Route::get('/Foo/{type}', 'FooController#index');
which would have an endpoint that looks like
/Foo?type=bar
Does anybody know how to test a route such as the one above?
Well i think that you need to clear out a bit the difference between route and query parameters.
In your case you are trying to use route parameters which will actually look something like:
/{type}/Foo/{page}/{date} => /myType/Foo/15/12-11-2021
Laravel considers the words inside {} as variables that you can retrieve via request so you can do something like:
$request->type
and laravel will return you the string myType as output.
In your second case that you have tried in the past you are referring to query parameters which are also a part of the $request. Consider it as the "body" of a GET request but i don't mean in any way to convert your post routes to GET :)
The thing with your second url is that:
/Foo/{type} is not similar to /Foo?type=bar
instead it should be like: /Foo/bar
In general query parameters are when you want to send an optional field most of the times in your GET endpoint (for filtering, pagination etc etc) and the route parameters are for mandatory fields that lead to sub-directories for example /Foo/{FooId}/Bar/{BarId}
The thing to remember is that you must be careful about your routes because variables can conflict with other routes.
For example a route looking like this:
Route::get('/foo/{fooId}', [FooController::class, 'getFoo']);
Route::get('/foo/bar', [BarController::class, 'getBar']);
will conflict because laravel will consider bar as the variable of the fooId so your second route can never be accessed.
The solution to this is to order your routes properly like:
Route::get('/foo/bar', [BarController::class, 'getBar']);
Route::get('/foo/{fooId}', [FooController::class, 'getFoo']);
So when you give as a route parameter anything else than bar your will go to your second route and have it working as expected.

How can I have a parameter with slashes in gin url

I want to have a parameter with slashes in the router in gin.
From what I gathered I can do this by adding a wildcard to the URL. For example: /api/v0/files/*addr
But this approach doesn't work if I want to have the addr in the middle of the URL like /api/v0/*addr/files, and it returns this error:
catch-all routes are only allowed at the end of the path.
I was wondering whether there is another way of having it?
Seems that is a limitation of the Gin framework, as seen # https://github.com/gin-gonic/gin/blob/master/tree.go#L322
You could always invert the order and do a rewrite using a proxy and a regexp (i.e. /api/v0/*addr/files to /api/v0/files/*addr) or only accept methods ending with /files inside your handling function, but I'm afraid that is a hardcoded limitation of the Gin framework.

Codeigniter routes don't work correctly

I have two string in routing config.
$route['education/course/(:any)'] = "education/course/$1";
$route['education/course/(:any)/(:num)'] = "education/lection/$1/$2";
But when I went to /education/course/my_course/1, the first rule worked, but the second didn't.
Please help! I'm newbie in CI.
Routes run in the order they are defined. Your second one will never be applied because the (:any) wildcard is capturing, well, anything.
I believe you should be able to switch the order so the most specific is first, followed by the least specific:
$route['education/course/(:any)/(:num)'] = "education/lection/$1/$2";
$route['education/course/(:any)'] = "education/course/$1";
Since both two routes are similar in the first three segments
education / course / (:any)
And since Route.php runs procedural (line by line),
Requesting a page like /education/course/my_course/1 matches the first route pattern (below)
$route['education/course/(:any)'] = "education/course/$1";
And also, requesting a page like /education/course/my_course/1/23 will still matches the first route pattrn, because Route.php only cares if your requested URL link matched the specified route pattern or not, otherwise go check the next route.
So, switching the order of the routes will fix the problem.

Shorten URLs within CodeIgniter

This question has been asked a few times but I can't seem to find a solution that helps me which is why I am trying here.
I have my site setup with the following for URLs I am using CodeIgniter I have a controller called user which loads a user view.
So my URLs are structured as follows:
http://example.com/user/#/username
I want to try and strip out the user controller from the URL to tidy up my URL so they would just read:
http://example.com/#/username
Is this possible I have been looking at route and have tried lots of different options but none have worked?
$route['/'] = "user";
Could anyone offer any solution?
Assuming the '#' in your URLs is a valid function and 'username' is a parameter for that function, then this route should work:
$route['#/(:any)'] = "user/#/$1";
Depending on what usernames are to be routed you may want to change the wildcard. For example, if you only wanted to route numbers as the parameter, you could change (:any) to (:num).
(:num) will match a segment containing only numbers.
(:any) will match a segment containing any character.
You can also use regular expressions to define routing rules, allowing you to further restrict what is routed.

How can I shorten routes in Codeigniter for certain requests?

I have a page that has this category URL website.com/category/view/honda-red-car and I just want it to say http://website.com/honda-red-car no html or php and get rid of the category view in the URL.. this website has been done using the CodeIgniter framework..
also this product view URL website.com/product/details/13/honda-accord-red-car
and I want it to be website.com/honda-accord-red-car PLEASE HELP!!!
I cannot find correct instructions on what I am doing wrong??
In Routes.php you need to create one like so
$route['mycar'] = "controller_name/function_name";
So for your example it would be:
$route['honda-red-car] = "category/view/honda-red-car";
Take a look into the URI Routing part of the user guide.
If you have concrete set of urls that you want to route then by adding rules to the application/config/routes.php you should be able to achieve what you want.
If you want some general solution (any uri segment can be a product/details page) then you might need to add every other url explicitly to the routes.php config file and set up a catch-all rule to route everything else to the right controller/method. Remember to handle 404 urls too!
Examples:
Lets say the /honda-red-car is something special and you want only this one to be redirected internally you write:
$routes['honda-red-car'] = 'product/details/13/honda-accord-red-car';
If you want to generalize everything that starts with the honda- string you do:
$routes['(honda-.*)'] = 'product/details_by_slug/$1'; // imaginary endpoint
These rules are used inside a preg_replace() call passing in the key as the pattern, and the value as the replace string, so the () are for capture groups, $1 for placing the capture part.
Be careful with the patterns, if they are too general they might catch every request coming in, so:
$routes['(.*)'] = 'product/details_by_slug/$1';
While it would certainly work for any car name like suzuki-swift-car too it would catch the ordinary root url, or the product/details/42 request too.
These rules are evaulated top to bottom, so start with specific rules at the top and leave general rules at the end of the file.

Resources