Files
laralog/routes/web.php
T
goukiandCursor ae47447062
Build and Deploy / verify (push) Successful in 40s
Build and Deploy / deploy (push) Successful in 36s
feat: restore sablog browse modes and clean imported HTML
Keep the public site readable after import (nbsp, highlighter, wrapping code, compact pager) and finish the admin extras already in this tree: sticky levels, preview, page cache, and live llms.txt.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 21:33:02 +00:00

180 lines
9.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
use App\Blog\Controllers\ArchiveController;
use App\Blog\Controllers\AuthController;
use App\Blog\Controllers\CategoryController;
use App\Blog\Controllers\CommentController;
use App\Blog\Controllers\FeedController;
use App\Blog\Controllers\HomeController;
use App\Blog\Controllers\LegacyController;
use App\Blog\Controllers\LinkController;
use App\Blog\Controllers\LlmsController;
use App\Blog\Controllers\PostController;
use App\Blog\Controllers\SearchController;
use App\Blog\Controllers\TagController;
use App\Blog\Controllers\ThemeAssetController;
use App\Models\Category;
use App\Models\Post;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| 前台规范路由(canonical 带 .shtml 后缀,无后缀版本 301 兼容)
|--------------------------------------------------------------------------
*/
// 首页:兼容老式 /?action=xxx 查询串(301)
Route::get('/', function () {
if (request()->filled('action')) {
return app(LegacyController::class)->resolveAction(request());
}
return app(HomeController::class)->index();
})->name('home');
// sablog 首页分页格式:/index-{page}.shtml
Route::get('/index-{page}.shtml', function (string $page) {
Paginator::currentPageResolver(fn () => max(1, (int) $page));
return app(HomeController::class)->index();
})->whereNumber('page');
Route::get('/posts/{slug}.md', [LlmsController::class, 'postMarkdown'])
->where('slug', '[^/]+')
->name('geo.post.markdown');
Route::get('/posts/{slug}.shtml', function (string $slug) {
$post = Post::query()->where('slug', $slug)->orWhere('id', (int) $slug)->first();
return $post ? redirect()->route('posts.show', $post->id, 301) : abort(404);
})->where('slug', '[^/]+');
Route::get('/posts/{slug}', function (string $slug) {
$post = Post::query()->where('slug', $slug)->orWhere('id', (int) $slug)->first();
return $post ? redirect()->route('posts.show', $post->id, 301) : abort(404);
})->where('slug', '[^/]+');
// 文章正典:与 sablog 完全一致 /show-{id}.shtml(评论分页 /show-{id}-{page}.shtml)
Route::get('/show-{id}.shtml', [PostController::class, 'show'])->whereNumber('id')->name('posts.show');
Route::get('/show-{id}-{page}.shtml', [PostController::class, 'show'])->whereNumber('id')->whereNumber('page');
Route::post('/posts/{post}/comments', [CommentController::class, 'store'])->name('comments.store');
// 浏览量统计(独立端点,避开整页缓存,保证实时)
Route::get('/track-view/{post}', fn (Post $post) => response($post->increment('views') ? '' : '', 204))->name('track-view');
Route::get('/category/{slug}.shtml', function (string $slug) {
$category = Category::query()->where('slug', $slug)->orWhere('id', (int) $slug)->first();
return $category ? redirect()->route('category.show', $category->id, 301) : abort(404);
})->where('slug', '[^/]+');
Route::get('/category/{slug}', function (string $slug) {
$category = Category::query()->where('slug', $slug)->orWhere('id', (int) $slug)->first();
return $category ? redirect()->route('category.show', $category->id, 301) : abort(404);
})->where('slug', '[^/]+');
// 分类正典:/category-{cid}.shtml(分页 /category-{cid}-{page}.shtml)
Route::get('/category-{cid}.shtml', [CategoryController::class, 'show'])->whereNumber('cid')->name('category.show');
Route::get('/category-{cid}-{page}.shtml', [CategoryController::class, 'show'])->whereNumber('cid')->whereNumber('page');
Route::get('/archives.shtml', [ArchiveController::class, 'index'])->name('archives');
Route::get('/archives', fn () => redirect()->route('archives', [], 301));
Route::get('/archives/{year}/{month}.shtml', fn (string $year, string $month) => redirect()->route('archives.month', $year.$month, 301))
->where(['year' => '\d{4}', 'month' => '\d{2}']);
Route::get('/archives/{year}/{month}', fn (string $year, string $month) => redirect()->route('archives.month', $year.$month, 301))
->where(['year' => '\d{4}', 'month' => '\d{2}']);
// 按月归档正典:/archives-{YYYYMM}.shtml(分页 /archives-{YYYYMM}-{page}.shtml)
Route::get('/archives-{date}.shtml', [ArchiveController::class, 'month'])->where('date', '\d{6}')->name('archives.month');
Route::get('/archives-{date}-{page}.shtml', [ArchiveController::class, 'month'])->where(['date' => '\d{6}', 'page' => '\d+']);
// 标签正典:/tag/{name}(sablog 原版);列表 /tagslist.shtml
Route::get('/tagslist.shtml', [TagController::class, 'index'])->name('tags');
Route::get('/tagslist-{page}.shtml', [TagController::class, 'index'])->whereNumber('page');
Route::get('/tag/{name}', [TagController::class, 'show'])->name('tags.show');
Route::get('/tags.shtml', fn () => redirect()->route('tags', [], 301));
Route::get('/tags', fn () => redirect()->route('tags', [], 301));
Route::get('/tags/{slug}.shtml', fn (string $slug) => redirect()->route('tags.show', $slug, 301))->where('slug', '[^/]+');
Route::get('/tags/{slug}', fn (string $slug) => redirect()->route('tags.show', $slug, 301))->where('slug', '[^/]+');
Route::get('/search.shtml', [SearchController::class, 'index'])->name('search');
Route::get('/search', fn () => redirect()->route('search', [], 301));
Route::get('/search-{page}.shtml', [SearchController::class, 'index'])->whereNumber('page');
Route::get('/links.shtml', [LinkController::class, 'index'])->name('links');
Route::get('/links', fn () => redirect()->route('links', [], 301));
Route::get('/comments.shtml', [CommentController::class, 'index'])->name('comments');
Route::get('/comments', fn () => redirect()->route('comments', [], 301));
Route::get('/comments-{page}.shtml', [CommentController::class, 'index'])->whereNumber('page');
Route::get('/login.shtml', [AuthController::class, 'showLogin'])->name('login');
Route::get('/login', fn () => redirect()->route('login', [], 301));
Route::post('/login.shtml', [AuthController::class, 'login'])->middleware('throttle:6,1');
Route::post('/login', [AuthController::class, 'login'])->middleware('throttle:6,1');
Route::post('/logout.shtml', [AuthController::class, 'logout'])->name('logout');
Route::post('/logout', [AuthController::class, 'logout']);
Route::get('/register.shtml', [AuthController::class, 'showRegister'])->name('register');
Route::get('/register', fn () => redirect()->route('register', [], 301));
Route::post('/register.shtml', [AuthController::class, 'register'])->middleware('throttle:6,1');
Route::post('/register', [AuthController::class, 'register'])->middleware('throttle:6,1');
Route::get('/profile.shtml', [AuthController::class, 'profile'])->middleware('auth')->name('profile');
Route::get('/profile', fn () => redirect()->route('profile', [], 301))->middleware('auth');
/*
|--------------------------------------------------------------------------
| 稳定路径:RSS / Sitemap / Robots / llms.txt
|--------------------------------------------------------------------------
*/
Route::get('/rss.xml', [FeedController::class, 'rss'])->name('feed.rss');
Route::get('/rss.php', [FeedController::class, 'rss']);
Route::get('/sitemap.xml', [FeedController::class, 'sitemap'])->name('feed.sitemap');
Route::get('/robots.txt', [FeedController::class, 'robots'])->name('robots');
Route::get('/llms.txt', [LlmsController::class, 'index'])->name('feed.llms');
/*
|--------------------------------------------------------------------------
| 主题资产(开发模式直接流式返回;生产可用 theme:publish 后由 Web 服务器托管)
|--------------------------------------------------------------------------
*/
Route::get('/themes/{theme}/assets/{path}', [ThemeAssetController::class, 'show'])
->where('path', '.*')
->name('theme.assets');
/*
|--------------------------------------------------------------------------
| sablog 老 URL 兼容(301)
|--------------------------------------------------------------------------
*/
Route::get('/show-{id}-{page}.html', [LegacyController::class, 'showRewritten'])
->where(['id' => '\d+', 'page' => '\d+']);
Route::get('/show-{id}.html', [LegacyController::class, 'showRewritten'])->where('id', '\d+');
Route::get('/category-{cid}-{page}.html', [LegacyController::class, 'categoryRewritten'])
->where(['cid' => '\d+', 'page' => '\d+']);
Route::get('/category-{cid}.html', [LegacyController::class, 'categoryRewritten'])->where('cid', '\d+');
Route::get('/archives-{date}-{page}.html', [LegacyController::class, 'archivesRewritten'])
->where(['date' => '\d+', 'page' => '\d+']);
Route::get('/archives-{date}.html', [LegacyController::class, 'archivesRewritten'])->where('date', '\d+');
Route::get('/tagslist-{page}.html', fn () => redirect()->route('tags', [], 301))->where('page', '\d+');
Route::get('/tagslist.html', fn () => redirect()->route('tags', [], 301));
Route::get('/comments-{page}.html', fn () => redirect()->route('comments', [], 301))->where('page', '\d+');
Route::get('/search-{page}.html', fn () => redirect()->route('search', [], 301))->where('page', '\d+');
Route::get('/reg.shtml', fn () => redirect()->route('register', [], 301));
// /tag/{name} 已是正典路由(tags.show),不再需要 LegacyController 中转
Route::get('/index.php', fn () => app(LegacyController::class)->resolveAction(request()));
// 旧 PHP 入口
Route::get('/sitemap.php', fn () => redirect()->route('feed.sitemap', [], 301));
Route::get('/attachment.php', [LegacyController::class, 'attachment']);
Route::post('/post.php', [LegacyController::class, 'postAction']);
Route::get('/tburl.php', fn () => abort(410, 'trackback 已废弃'));
Route::get('/trackback.php', fn () => abort(410, 'trackback 已废弃'));