Adin
Adin

Reputation: 33

How to show different contents on the same slug in laravel?

I want to show different contents on the same slug in my laravel app.

The following works like a charm with the posts and pages, so if the slug matches a page/post slug, it'll load the content.

routes/web.php:

/// ADMIN ROUTES
Route::middleware(['web', 'auth'])->prefix('admin')->group(function () {
    Route::get('/', [AdminController::class, 'index'])->name('admin');
    Route::resource('roles', RoleController::class);
    Route::resource('pages', BackendPageController::class);
    Route::resource('permissions', PermissionController::class);
    Route::resource('posts', BackendPostController::class);
    Route::resource('users', UserController::class);
    Route::resource('packages', PackageController::class);

    Route::delete('/users', [UserController::class, 'deleteAll'])->name('users.delete');
    Route::delete('/pages', [BackendPageController::class, 'delete'])->name('pages.delete');
    
    Route::prefix('modules')->group(function () {
        Route::get('/', [ModuleController::class, 'index'])->name('modules.index');
        Route::get('/enable/{moduleName}', [ModuleController::class, 'enable'])->name('modules.enable');
        Route::get('/disable/{moduleName}', [ModuleController::class, 'disable'])->name('modules.disable');
    });
});


/// FRONTEND ROUTES
Route::middleware('web')->group(function () {
    Route::get('/', [ContentController::class, 'homePage']);
    Route::get('/{slug}', [ContentController::class, 'show'])->where('slug', '^[a-z0-9-]+$');
});

app\\Http\\Controllers\\ContentController.php show method:

public function show($slug)
    {
        $page = Page::where('slug', $slug)->first();
        $post = Post::where('slug', $slug)->first();

        if ($page) {
            return view('frontend.pages.show', compact('page'));
        }

        if ($post) {
            return view('frontend.posts.show', compact('post'));
        }
        
        abort(404);
      
    }

But I want to use the laravel-modules package and if I create a new module for ex.: Product then the default route in the Modules\Product\Routes\web.php is:

Route::prefix('product')->group(function() {
    Route::get('/', 'ShopController@index');
});

But the localhost/product link throws a 404 error because of my ContentController show method logic... how can I achieve that if the slug doesn't match with the page/post slug then use the default logic?

I don't want to seperate the pages and the posts like localhost/pages/xy or localhost/posts/xy

Upvotes: 2

Views: 136

Answers (1)

Abdulla Nilam
Abdulla Nilam

Reputation: 38642

Use Laravel Fallback Routes (8.0 or higher only)

In route file

Route::fallback([ContentController::class, 'fallback']);

In Controller

public function fallback($slug)
{
    $page = Page::where('slug', $slug)->first();
    $post = Post::where('slug', $slug)->first();

    if ($page) {
        return view('frontend.pages.show', compact('page'));
    }

    if ($post) {
        return view('frontend.posts.show', compact('post'));
    }

    // If unmatch, then 404.
    abort(404);
}

You can use $request->query() if you use Request params in the method.

Upvotes: 0

Related Questions