refactor(routes): canonical URLs now match sablog format exactly
Build and Deploy / verify (push) Successful in 1m6s
Build and Deploy / deploy (push) Successful in 41s

- /show-{id}.shtml (comments page: /show-{id}-{page}.shtml)
- /category-{cid}.shtml / /category-{cid}-{page}.shtml
- /archives-{YYYYMM}.shtml / /archives-{YYYYMM}-{page}.shtml
- /tag/{name}, /tagslist.shtml, /index-{page}.shtml
- slug 时代的 /posts/{slug} 等旧格式全部 301 到 sablog 格式
This commit is contained in:
2026-09-09 21:21:07 +00:00
parent f6a9a8ea50
commit f5987e7cc2
22 changed files with 113 additions and 70 deletions
@@ -75,13 +75,13 @@ class SeoMiddleware
'@context' => 'https://schema.org',
'@type' => 'BlogPosting',
'headline' => $post->title,
'url' => route('posts.show', $post->slug ?: $post->id),
'url' => route('posts.show', $post->id),
'datePublished' => $post->published_at?->toIso8601String(),
'dateModified' => $post->updated_at?->toIso8601String(),
'author' => ['@type' => 'Person', 'name' => $post->author?->name ?? $siteName] + ($sameAs ? ['sameAs' => $sameAs] : []),
'publisher' => ['@type' => 'Organization', 'name' => $siteName, 'url' => url('/')] + ($sameAs ? ['sameAs' => $sameAs] : []),
'description' => Str::limit(strip_tags($post->excerpt_or_fallback), 200),
'mainEntityOfPage' => route('posts.show', $post->slug ?: $post->id),
'mainEntityOfPage' => route('posts.show', $post->id),
];
if ($cover = $post->getFirstMedia('cover')) {
@@ -105,7 +105,7 @@ class SeoMiddleware
'@type' => 'BreadcrumbList',
'itemListElement' => [
['@type' => 'ListItem', 'position' => 1, 'name' => $siteName, 'item' => url('/')],
['@type' => 'ListItem', 'position' => 2, 'name' => $category->name, 'item' => route('category.show', $category->slug ?: $category->id)],
['@type' => 'ListItem', 'position' => 2, 'name' => $category->name, 'item' => route('category.show', $category->id)],
],
];
}
@@ -30,7 +30,7 @@ class SeoController
$lines[] = '';
foreach ($posts as $post) {
$lines[] = '- ['.$post->title.']('.route('posts.show', $post->slug ?: $post->id).') — '.Str::limit(strip_tags($post->excerpt_or_fallback), 120);
$lines[] = '- ['.$post->title.']('.route('posts.show', $post->id).') — '.Str::limit(strip_tags($post->excerpt_or_fallback), 120);
}
return response(implode("\n", $lines)."\n")
@@ -81,7 +81,7 @@ class MembershipController
// 已能读付费内容(会员 / 作者 / 已解锁):直接查看文章,避免重复支付。
// 注意:付费块文章的整篇是公开的,不能用 canReadPost 判断(否则永远"已有权限")
if ($this->service->canReadPaidContent($user, $post)) {
return redirect()->route('posts.show', $post->slug ?? $post->id);
return redirect()->route('posts.show', $post->id);
}
// 单篇付费解锁:创建一笔定向支付