Laravel routing hide path - laravel

I have a route like this
http://localhost:8000/produk/slug-product
I want to my url like this, remove produk in url
http://localhost:8000/slug-product
What should I do ?

Do not use .htaccess to handle this. Define route for slugs without any segment at the end of the routes list in your app:
Route::get('{slug}', 'FrontController#getBySlug');
So, all requests which are not related to any of the routes, will go to the getBySlug method:
public function getBySlug($slug)
{
$data = Model::findBySlug($slug);
....
}

Related

Add username as prefix in route URI in Laravel 9

I am building an application where users are registered and want to be redirected to their individual dashboard like this .
http://localhost/project/{username}/dashboard,
Now, its happening like
localhost/project/vendors/dashboard (here all users are accessing same URL)
but I want to make it like :
http://localhost/project/{username1}/dashboard, http://localhost/project/{username2}/dashboard
Googled lot but none of them are explained well and working.
Please assist with complete flow.
I want to declare the value of {username} globally and use it in route as prefix.
I dont want to use it before each name route. will use it as prefix and group with all vendors routes
I have made this, and its working as
localhost/project/vendors/dashboard
Route::prefix('vendors')->group(function () { Route::middleware(['auth:vendor'])->group(function () { Route::get('/dashboard', [VendorController::class, 'dashboard'])->name('vendor.dashboard'); });
});
You can specify route parameters in brackets like so {parameter}, change your code into this.
Route::get('project/{username}/dashboard', [UserDashboardController::class, 'dashboard'])
->name('user.dashboard');
In your controller you could access it like this.
class UserDashboardController
{
public function dashboard(string $username)
{
User::where('username', $username)->firstOrFail();
// something else
}
}
Seems like in your routes your are mixing vendor prefix logic in with something that in your specifications of what your urls should look like does not match. Which i think is making up some of the confusion on this case.
You can use route prefix like this
Route::prefix('{username}')->group(function () {
Route::middleware(['auth'])->group(function () {
Route::get('/dashboard', [UserController::class, 'dashboard'])->name('user.dashboard');
});
});

Disabling the calling of the two routes

For my project, I need to have dynamic routes, because {slug} in URL can point to multiple resources.
/shoes - poinst to category
/black-slippers - points to product
Beside the wildcard route, I have also a few (50) static routes (all defined before wildcard route in routes/web.php)
But now, when is called static route, the wildcard route is performed also, e.g.:
Route::get('/profile', [\App\Http\Controllers\Frontend\UserProfileController::class, 'show'])->name('profile.show');
Route::get('{address}', [\App\Http\Controllers\Core\WebaddressController::class, 'resolveAddress'])->where('address', '.*');
In the browser is displayed Profile page (correctly), but in SQL Queries I see, that the query which is called in WebaddressController#resolveAddress is performed also.
If I comment wildcard Route, the query disappears.
What can I do to not perform wildcard route? Thanks
Please do not suggest changing the route style, I cant, this is the requested form.
You can exclude some keywords from the wildcard route with regex in the where statement:
Route::get(
'{address}',
[\App\Http\Controllers\Core\WebaddressController::class, 'resolveAddress']
)
->where('address', '^(?!profile|other-static-route)$');
The list of keywords doesn't have to be hardcoded. You could create a list yourself, or parse keywords from the routes you defined, like this:
use Illuminate\Support\Str;
$keywords = collect(Route::getRoutes())
->map(function ($route) {
return Str::afterLast($route->uri(), '/');
})
->filter(function ($keyword) {
return !Str::endsWith($keyword, '}');
})
->implode('|');
Add them to the where statement like this:
->where('address', '^(?!' . $keywords . ')$');
I am not sure is that a best practice, but you can make a custom middleware for:
Route::get('{address}', [\App\Http\Controllers\Core\WebaddressController::class, 'resolveAddress'])->where('address', '.*')
->middleware('is_slug_route');
And in your handle method of freshly created middleware you can check is provided url an actual slug.
public function handle($request, Closure $next) {
$possibleSlug = $request->getPathInfo();
if (Address::where('slug',$possibleSlug)->exists()) {
return $next($request);
}
}
Something like that

Laravel - Route has a forward slash

here is the URL i want to access an articel in Laravel.
http://mysite.test/art-entertainment-articles/poetry-articles/guide-praising-comments-1.html
now article_slug is "/art-entertainment-articles/poetry-articles/guide-praising-comments-1.html".
i made a route like this.
Route::get('/{any:.*}', 'ArticlesController#article');
but it is showing error 404 not found. now i want to get article by matching slug like this.
$article = Article::where('article_slug', '=', $article_slug)->first();
what should i write in route? it breaks at slashes and count not read the method.
You are probably better off using the fallback function like so
Route::fallback(function () {
//
});
This will catch all routes that are not defined above it. Then you can add the logic to hit your controller and figure out the article you require from the url.

How to set a route parameter default value from request url in laravel

I have this routing settings:
Route::prefix('admin/{storeId}')->group(function ($storeId) {
Route::get('/', 'DashboardController#index');
Route::get('/products', 'ProductsController#index');
Route::get('/orders', 'OrdersController#index');
});
so if I am generating a url using the 'action' helper, then I don't have to provide the storeId explictly.
{{ action('DashboardController#index') }}
I want storeId to be set automatically from the request URL if provided.
maybe something like this.
Route::prefix('admin/{storeId}')->group(function ($storeId) {
Route::get('/', 'DashboardController#index');
Route::get('/products', 'ProductsController#index');
Route::get('/orders', 'OrdersController#index');
})->defaults('storeId', $request->storeId);
The docs mention default parameter though in regards to the route helper (should work with all the url generating helpers):
"So, you may use the URL::defaults method to define a default value for this parameter that will always be applied during the current request. You may wish to call this method from a route middleware so that you have access to the current request"
"Once the default value for the ... parameter has been set, you are no longer required to pass its value when generating URLs via the route helper."
Laravel 5.6 Docs - Url Generation - Default Values
In my Laravel 9 project I am doing it like this:
web.php
Route::get('/world', [NewsController::class, 'section'])->defaults('category', "world");
NewsController.php
public function section($category){}
Laravel works exactly in the way you described.
You can access storeId in your controller method
class DashboardController extends Controller {
public function index($storeId) {
dd($storeId);
}
}
http://localhost/admin/20 will print "20"

Laravel passing all routes for a particular domain to a controller

Working on a Laravel 4.2 project. What I am trying to accomplish is pass every URI pattern to a controller that I can then go to the database and see if I need to redirect this URL (I know I can do this simple in PHP and do not need to go through Laravel, but just trying to use this as a learning experience.)
So what I have at the moment is this:
Route::group(array('domain' => 'sub.domain.com'), function()
{
Route::get('?', 'RedirectController#index');
});
I am routing any subdomain which I deem as a "redirect subdomain" ... The ? is where I am having the problem. From what I have read you should be able to use "*" for anything but that does not seem to be working. Anyone have a clue how to pass any URL to a controller?
And on top of that I would ideally like to pass the FULL URL so i can easily just check the DB and redirect so:
$url = URL::full();
Try this:
Route::group(array('domain' => 'sub.domain.com'), function()
{
Route::get('{path}', 'RedirectController#index')
->where('path', '.*');
});
And your controller will reseive the path as first argument
public function index($path){
// ...
}
In case you're wondering, the where is needed because without it {path} will only match the path until the first /. This way all characters, even /, are allowed as route parameter

Resources