在Laravel中如何在相同的slug上显示不同的内容?

huangapple go评论78阅读模式
英文:

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

问题

我想在我的Laravel应用程序中在相同的slug上显示不同的内容。

以下代码适用于帖子和页面,如果slug与页面/帖子的slug匹配,它将加载内容。

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方法:

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);
}

但是,如果我使用 laravel-modules 包创建一个新模块,例如Product,那么Modules\Product\Routes\web.php 中的默认路由如下所示:

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

但 localhost/product 链接会因为我的 ContentController 的show方法逻辑而引发404错误...我如何实现如果slug与页面/帖子的slug不匹配,就使用默认逻辑?

我不想将页面和帖子分开,如 localhost/pages/xy 或 localhost/posts/xy。

英文:

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

答案1

得分: 0

使用Laravel Fallback 路由(仅适用于8.0或更高版本)

在路由文件中:

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

在控制器中:

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'));
    }

    // 如果不匹配,则返回404。
    abort(404);
}

如果在方法中使用Request参数,您可以使用$request->query()

英文:

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.

huangapple
  • 本文由 发表于 2023年6月5日 01:17:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76401565.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定