代码改动: - SEO-02 产品页标题品牌重复:Product::seoTitle() 去掉品牌后缀,由视图统一追加 $siteName - SEO-05/Geo-03 结构化数据:布局增 WebSite+SearchAction;产品页 Product+BreadcrumbList;文章页 Article+BreadcrumbList(含作者/发布日期) - SEO-06 hreflang 自引用(zh-CN/x-default) - SEC-02 新增 public/.well-known/security.txt - GEO-05 新增 public/llms.txt 记录文档(供未来开发者接手): - CHANGELOG.md:版本与变更日志 - docs/SECURITY_SEO_REMEDIATION.md:逐项状态总表 + 改动位置 + 上线 curl 自检清单 (SEC-01/REL-01~03/PHY-01~04 等需 Tailwind 构建或云端操作项标记为待办,未自动改以免破坏站点)
90 lines
4.7 KiB
PHP
90 lines
4.7 KiB
PHP
@extends('layouts.app')
|
||
|
||
@php $siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司'); @endphp
|
||
@section('title', $article->seoTitle() . ' - ' . $siteName)
|
||
@section('description', $article->seoDescription())
|
||
|
||
@section('content')
|
||
<section class="px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
|
||
<div class="mx-auto max-w-3xl">
|
||
<nav class="mb-6 flex items-center gap-1.5 text-sm text-muted">
|
||
<a href="{{ url('/') }}" class="hover:text-primary">首页</a>
|
||
<span>/</span>
|
||
<a href="{{ route('articles.index') }}" class="hover:text-primary">技术文章</a>
|
||
<span>/</span>
|
||
<span class="text-fg">{{ $article->title }}</span>
|
||
</nav>
|
||
|
||
@if ($article->template === 'feature' && $article->cover)
|
||
<div class="mb-6 overflow-hidden rounded-lg border border-line">
|
||
<img src="{{ $article->cover }}" alt="{{ $article->title }}" class="max-h-96 w-full object-cover">
|
||
</div>
|
||
@endif
|
||
|
||
<article class="rounded-lg border border-line bg-surface p-6 shadow-soft sm:p-8">
|
||
<h1 class="text-2xl font-bold tracking-tight text-fg sm:text-3xl">{{ $article->title }}</h1>
|
||
<p class="mt-3 text-sm text-muted">
|
||
{{ $article->published_at?->format('Y-m-d') }} · {{ $article->author ?: '云创芯' }}
|
||
@if ($article->template === 'tech') <span class="ml-2 rounded bg-primary-soft px-2 py-0.5 text-xs font-medium text-primary">技术文档</span> @endif
|
||
@if ($article->template === 'feature') <span class="ml-2 rounded bg-primary-soft px-2 py-0.5 text-xs font-medium text-primary">专题报道</span> @endif
|
||
</p>
|
||
@if ($article->category)
|
||
<p class="mt-2 text-sm text-muted">分类:{{ $article->category->name }}</p>
|
||
@endif
|
||
@if ($article->template === 'feature' && $article->summary)
|
||
<p class="lead mt-5 text-base text-muted">{{ $article->summary }}</p>
|
||
@elseif ($article->summary)
|
||
<p class="mt-5 text-base text-muted">{{ $article->summary }}</p>
|
||
@endif
|
||
@if ($article->body)
|
||
<div class="prose mt-6 text-fg">
|
||
{{-- 旧文(纯文本)用 nl2br 换行,新文(Quill HTML)安全渲染(已过 Purifier) --}}
|
||
@if (preg_match('/<[a-z][a-z0-9]*[\s>]/i', $article->body))
|
||
{!! $article->body !!}
|
||
@else
|
||
{!! nl2br(e($article->body)) !!}
|
||
@endif
|
||
</div>
|
||
@endif
|
||
</article>
|
||
|
||
@php
|
||
// 结构化数据:Article + BreadcrumbList(审计 SEO-05 / GEO-03 作者与发布信号)
|
||
$logoUrl = '/images/logo-dark.png';
|
||
$articleSchema = [
|
||
'@context' => 'https://schema.org',
|
||
'@type' => 'Article',
|
||
'headline' => $article->title,
|
||
'description' => $article->seoDescription(),
|
||
'author' => ['@type' => 'Organization', 'name' => $siteName],
|
||
'publisher' => [
|
||
'@type' => 'Organization',
|
||
'name' => $siteName,
|
||
'logo' => ['@type' => 'ImageObject', 'url' => asset($logoUrl)],
|
||
],
|
||
'datePublished' => $article->published_at?->toIso8601String(),
|
||
'dateModified' => $article->updated_at?->toIso8601String(),
|
||
'mainEntityOfPage' => ['@type' => 'WebPage', '@id' => url()->current()],
|
||
];
|
||
$breadcrumbSchema = [
|
||
'@context' => 'https://schema.org',
|
||
'@type' => 'BreadcrumbList',
|
||
'itemListElement' => [
|
||
['@type' => 'ListItem', 'position' => 1, 'name' => '首页', 'item' => url('/')],
|
||
['@type' => 'ListItem', 'position' => 2, 'name' => '技术文章', 'item' => route('articles.index')],
|
||
['@type' => 'ListItem', 'position' => 3, 'name' => $article->title, 'item' => url()->current()],
|
||
],
|
||
];
|
||
@endphp
|
||
<script type="application/ld+json">{!! json_encode($articleSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG) !!}</script>
|
||
<script type="application/ld+json">{!! json_encode($breadcrumbSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG) !!}</script>
|
||
|
||
<div class="mt-6">
|
||
<a href="{{ route('articles.index') }}" class="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover">
|
||
<x-icon name="arrow" :size="16" class="rotate-180" /> 返回文章列表
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
@endsection
|