feat: Markdown 正文自动 TOC(锚点+折叠目录)+ 社交账号扩充国内平台(B站/小红书/抖音/视频号/公众号/其他)+ 侧边栏社交展示 + JSON-LD sameAs 全平台聚合 + 首页 h1(SEO 语义)
This commit is contained in:
@@ -32,9 +32,14 @@ class PostController extends Controller
|
|||||||
->orderBy('created_at', (int) blog_setting('comment_order', 1) === 1 ? 'asc' : 'desc')
|
->orderBy('created_at', (int) blog_setting('comment_order', 1) === 1 ? 'asc' : 'desc')
|
||||||
->paginate(20);
|
->paginate(20);
|
||||||
|
|
||||||
$contentHtml = $this->renderer->render($post);
|
$rendered = $this->renderer->renderWithToc($post);
|
||||||
|
|
||||||
return theme_view('show', compact('post', 'comments', 'contentHtml'));
|
return theme_view('show', [
|
||||||
|
'post' => $post,
|
||||||
|
'comments' => $comments,
|
||||||
|
'contentHtml' => $rendered['html'],
|
||||||
|
'toc' => $rendered['toc'],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ensureReadable(Post $post): void
|
private function ensureReadable(Post $post): void
|
||||||
|
|||||||
@@ -46,6 +46,43 @@ class PostContentRenderer
|
|||||||
return app(\App\Blog\Support\PluginManager::class)->applyFilters('post.rendered', $html, $post);
|
return app(\App\Blog\Support\PluginManager::class)->applyFilters('post.rendered', $html, $post);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染并提取目录(TOC)。
|
||||||
|
*
|
||||||
|
* @return array{html: string, toc: array<int, array{id: string, text: string, level: int}>}
|
||||||
|
*/
|
||||||
|
public function renderWithToc(Post $post): array
|
||||||
|
{
|
||||||
|
$html = $this->render($post);
|
||||||
|
|
||||||
|
$toc = [];
|
||||||
|
$index = 0;
|
||||||
|
|
||||||
|
$html = preg_replace_callback(
|
||||||
|
'/<h([2-6])([^>]*)>(.*?)<\/h\1>/is',
|
||||||
|
function (array $m) use (&$toc, &$index): string {
|
||||||
|
$level = (int) $m[1];
|
||||||
|
$attrs = $m[2];
|
||||||
|
$text = trim(strip_tags($m[3]));
|
||||||
|
$id = 'toc-'.(++$index);
|
||||||
|
|
||||||
|
$toc[] = ['id' => $id, 'text' => $text, 'level' => $level];
|
||||||
|
|
||||||
|
// 已存在 id 则保留原 id,否则注入锚点
|
||||||
|
if (preg_match('/id="([^"]+)"/', $attrs, $idMatch)) {
|
||||||
|
$toc[array_key_last($toc)]['id'] = $idMatch[1];
|
||||||
|
|
||||||
|
return $m[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<h'.$level.$attrs.' id="'.$id.'">'.$m[3].'</h'.$level.'>';
|
||||||
|
},
|
||||||
|
$html
|
||||||
|
);
|
||||||
|
|
||||||
|
return ['html' => $html, 'toc' => $toc];
|
||||||
|
}
|
||||||
|
|
||||||
public function toHtml(string $markdown): string
|
public function toHtml(string $markdown): string
|
||||||
{
|
{
|
||||||
return $this->converter->convert($markdown)->getContent();
|
return $this->converter->convert($markdown)->getContent();
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Blog\Support;
|
||||||
|
|
||||||
|
use App\Models\Setting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 社交账号聚合:后台「社交账号」Tab 配置 -> 前端展示 + SEO sameAs。
|
||||||
|
*/
|
||||||
|
class SocialLinks
|
||||||
|
{
|
||||||
|
public const PLATFORMS = [
|
||||||
|
'social_weibo' => '微博',
|
||||||
|
'social_zhihu' => '知乎',
|
||||||
|
'social_bilibili' => '哔哩哔哩',
|
||||||
|
'social_xiaohongshu' => '小红书',
|
||||||
|
'social_douyin' => '抖音',
|
||||||
|
'social_wechat_channel' => '视频号',
|
||||||
|
'social_wechat_public' => '微信公众号',
|
||||||
|
'social_github' => 'GitHub',
|
||||||
|
'social_twitter' => 'Twitter / X',
|
||||||
|
'social_facebook' => 'Facebook',
|
||||||
|
'social_email' => '邮箱',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全部社交账号:['platform' => 平台名, 'value' => URL/名称, 'url' => 是否为外链]。
|
||||||
|
*/
|
||||||
|
public static function all(): array
|
||||||
|
{
|
||||||
|
$items = [];
|
||||||
|
|
||||||
|
foreach (self::PLATFORMS as $key => $platform) {
|
||||||
|
$value = trim((string) Setting::get($key, ''));
|
||||||
|
if ($value === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$items[] = [
|
||||||
|
'platform' => $platform,
|
||||||
|
'value' => $value,
|
||||||
|
'url' => filter_var($value, FILTER_VALIDATE_URL) ? $value : null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他平台(KeyValue)
|
||||||
|
$other = Setting::get('social_other', []);
|
||||||
|
$other = is_array($other) ? $other : (json_decode((string) $other, true) ?: []);
|
||||||
|
foreach ($other as $platform => $value) {
|
||||||
|
if (trim((string) $value) === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$items[] = [
|
||||||
|
'platform' => (string) $platform,
|
||||||
|
'value' => (string) $value,
|
||||||
|
'url' => filter_var((string) $value, FILTER_VALIDATE_URL) ? (string) $value : null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可进 JSON-LD sameAs 的 URL 列表。
|
||||||
|
*/
|
||||||
|
public static function sameAs(): array
|
||||||
|
{
|
||||||
|
return array_values(array_unique(array_filter(array_map(
|
||||||
|
fn (array $item) => $item['url'],
|
||||||
|
self::all()
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,6 +62,8 @@ class SidebarComposer
|
|||||||
];
|
];
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
$view->with('socialLinks', \App\Blog\Support\SocialLinks::all());
|
||||||
|
|
||||||
$view->with('siteName', blog_setting('site_name', config('blog.name')));
|
$view->with('siteName', blog_setting('site_name', config('blog.name')));
|
||||||
$view->with('siteDescription', blog_setting('site_description', config('blog.description')));
|
$view->with('siteDescription', blog_setting('site_description', config('blog.description')));
|
||||||
$view->with('siteIcp', blog_setting('site_icp', config('blog.icp')));
|
$view->with('siteIcp', blog_setting('site_icp', config('blog.icp')));
|
||||||
|
|||||||
@@ -72,7 +72,13 @@ class BlogSettings extends Page
|
|||||||
'social_twitter' => Setting::get('social_twitter', ''),
|
'social_twitter' => Setting::get('social_twitter', ''),
|
||||||
'social_facebook' => Setting::get('social_facebook', ''),
|
'social_facebook' => Setting::get('social_facebook', ''),
|
||||||
'social_zhihu' => Setting::get('social_zhihu', ''),
|
'social_zhihu' => Setting::get('social_zhihu', ''),
|
||||||
|
'social_bilibili' => Setting::get('social_bilibili', ''),
|
||||||
|
'social_xiaohongshu' => Setting::get('social_xiaohongshu', ''),
|
||||||
|
'social_douyin' => Setting::get('social_douyin', ''),
|
||||||
|
'social_wechat_channel' => Setting::get('social_wechat_channel', ''),
|
||||||
|
'social_wechat_public' => Setting::get('social_wechat_public', ''),
|
||||||
'social_email' => Setting::get('social_email', ''),
|
'social_email' => Setting::get('social_email', ''),
|
||||||
|
'social_other' => Setting::get('social_other', []),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,11 +138,21 @@ class BlogSettings extends Page
|
|||||||
->columns(2)
|
->columns(2)
|
||||||
->schema([
|
->schema([
|
||||||
TextInput::make('social_weibo')->label('微博')->url()->placeholder('https://weibo.com/xxx'),
|
TextInput::make('social_weibo')->label('微博')->url()->placeholder('https://weibo.com/xxx'),
|
||||||
|
TextInput::make('social_zhihu')->label('知乎')->url()->placeholder('https://zhihu.com/people/xxx'),
|
||||||
|
TextInput::make('social_bilibili')->label('哔哩哔哩')->url()->placeholder('https://space.bilibili.com/xxx'),
|
||||||
|
TextInput::make('social_xiaohongshu')->label('小红书')->url()->placeholder('https://xiaohongshu.com/user/profile/xxx'),
|
||||||
|
TextInput::make('social_douyin')->label('抖音')->url()->placeholder('https://www.douyin.com/user/xxx'),
|
||||||
|
TextInput::make('social_wechat_channel')->label('视频号')->url()->placeholder('https://channels.weixin.qq.com/xxx'),
|
||||||
|
TextInput::make('social_wechat_public')->label('微信公众号')->placeholder('公众号名称 / 微信号(无外链时用于展示)'),
|
||||||
TextInput::make('social_github')->label('GitHub')->url()->placeholder('https://github.com/xxx'),
|
TextInput::make('social_github')->label('GitHub')->url()->placeholder('https://github.com/xxx'),
|
||||||
TextInput::make('social_twitter')->label('Twitter / X')->url()->placeholder('https://x.com/xxx'),
|
TextInput::make('social_twitter')->label('Twitter / X')->url()->placeholder('https://x.com/xxx'),
|
||||||
TextInput::make('social_facebook')->label('Facebook')->url()->placeholder('https://facebook.com/xxx'),
|
TextInput::make('social_facebook')->label('Facebook')->url()->placeholder('https://facebook.com/xxx'),
|
||||||
TextInput::make('social_zhihu')->label('知乎')->url()->placeholder('https://zhihu.com/people/xxx'),
|
|
||||||
TextInput::make('social_email')->label('邮箱')->email()->placeholder('contact@example.com'),
|
TextInput::make('social_email')->label('邮箱')->email()->placeholder('contact@example.com'),
|
||||||
|
\Filament\Forms\Components\KeyValue::make('social_other')
|
||||||
|
->label('其他平台')
|
||||||
|
->keyLabel('平台名')
|
||||||
|
->valueLabel('链接 / 名称')
|
||||||
|
->columnSpanFull(),
|
||||||
]),
|
]),
|
||||||
Tab::make('维护')
|
Tab::make('维护')
|
||||||
->schema([
|
->schema([
|
||||||
|
|||||||
@@ -137,6 +137,14 @@ themes/{name}/
|
|||||||
|
|
||||||
主题 CSS 需自带 `@media (max-width: 768px)` 断点:容器改全宽、两栏改单栏、导航换行。内置 sablog / modern 已实现,新主题请参照。
|
主题 CSS 需自带 `@media (max-width: 768px)` 断点:容器改全宽、两栏改单栏、导航换行。内置 sablog / modern 已实现,新主题请参照。
|
||||||
|
|
||||||
|
## TOC 目录
|
||||||
|
|
||||||
|
文章页自动为 Markdown 正文提取目录(h2-h6 生成锚点 + 折叠目录块)。主题需在 show 视图接收 `$toc` 变量并按 `.toc` / `.toc-level-N` 类样式化,或自行实现。
|
||||||
|
|
||||||
|
## 社交账号
|
||||||
|
|
||||||
|
后台「博客设置 → 社交账号」配置微博/知乎/B站/小红书/抖音/视频号/公众号/GitHub/X/Facebook/邮箱 + 自定义其他平台。数据经 `$socialLinks` 共享给所有前台视图(侧边栏可展示),URL 类账号同时输出到 JSON-LD `sameAs`。
|
||||||
|
|
||||||
## 打包与安装
|
## 打包与安装
|
||||||
|
|
||||||
- 目录打成 ZIP(根目录含 theme.json),后台「主题管理」上传安装,或远程市场安装
|
- 目录打成 ZIP(根目录含 theme.json),后台「主题管理」上传安装,或远程市场安装
|
||||||
|
|||||||
@@ -101,19 +101,11 @@ class SeoMiddleware
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 后台配置的社交账号 -> schema sameAs(Facebook / GitHub / Twitter 等平台识别)。
|
* 后台配置的社交账号 -> schema sameAs(微博/公众号/抖音/小红书/GitHub 等全平台)。
|
||||||
*/
|
*/
|
||||||
private function socialLinks(): array
|
private function socialLinks(): array
|
||||||
{
|
{
|
||||||
$links = [];
|
return \App\Blog\Support\SocialLinks::sameAs();
|
||||||
|
|
||||||
foreach (['social_weibo', 'social_github', 'social_twitter', 'social_facebook', 'social_zhihu'] as $key) {
|
|
||||||
if ($url = blog_setting($key, '')) {
|
|
||||||
$links[] = $url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_values(array_unique($links));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ogTags(Request $request, array $data): string
|
private function ogTags(Request $request, array $data): string
|
||||||
|
|||||||
@@ -139,3 +139,17 @@ a:hover { color: #1a4fa8; }
|
|||||||
|
|
||||||
.site-footer { background: #fff; border-top: 1px solid #e5e7eb; padding: 20px 0; margin-top: 24px; text-align: center; font-size: 13px; color: #888; }
|
.site-footer { background: #fff; border-top: 1px solid #e5e7eb; padding: 20px 0; margin-top: 24px; text-align: center; font-size: 13px; color: #888; }
|
||||||
.powered { margin-top: 4px; }
|
.powered { margin-top: 4px; }
|
||||||
|
|
||||||
|
/* TOC */
|
||||||
|
.toc { background: #f8f9fa; border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px 16px; margin: 0 0 18px; font-size: 14px; }
|
||||||
|
.toc summary { cursor: pointer; font-weight: 600; margin-bottom: 6px; }
|
||||||
|
.toc-list { list-style: none; }
|
||||||
|
.toc-list li { padding: 2px 0; }
|
||||||
|
.toc-list a { color: #555; }
|
||||||
|
.toc-list a:hover { color: #2d6cdf; }
|
||||||
|
.toc-level-2 { padding-left: 0; }
|
||||||
|
.toc-level-3 { padding-left: 14px; }
|
||||||
|
.toc-level-4, .toc-level-5, .toc-level-6 { padding-left: 28px; }
|
||||||
|
|
||||||
|
/* 屏幕阅读器专用(SEO h1 隐藏) */
|
||||||
|
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@include('partials.header')
|
@include('partials.header')
|
||||||
<div class="container main-layout">
|
<div class="container main-layout">
|
||||||
<main class="content">
|
<main class="content">
|
||||||
|
<h1 class="sr-only">{{ $siteName }}</h1>
|
||||||
@if(session('success'))
|
@if(session('success'))
|
||||||
<div class="alert alert-success">{{ session('success') }}</div>
|
<div class="alert alert-success">{{ session('success') }}</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -62,6 +62,19 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="widget">
|
||||||
|
<h3>社交账号</h3>
|
||||||
|
<ul class="social-links">
|
||||||
|
@foreach($socialLinks as $social)
|
||||||
|
@if($social['url'])
|
||||||
|
<li><a href="{{ $social['url'] }}" target="_blank" rel="noopener nofollow">{{ $social['platform'] }}</a></li>
|
||||||
|
@else
|
||||||
|
<li>{{ $social['platform'] }}:{{ $social['value'] }}</li>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="widget">
|
<section class="widget">
|
||||||
<h3 class="widget-title">站点统计</h3>
|
<h3 class="widget-title">站点统计</h3>
|
||||||
<ul class="widget-list">
|
<ul class="widget-list">
|
||||||
|
|||||||
@@ -16,6 +16,20 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
<article class="post-full">
|
<article class="post-full">
|
||||||
|
@if(! empty($toc))
|
||||||
|
<nav class="toc" aria-label="文章目录">
|
||||||
|
<details open>
|
||||||
|
<summary>目录</summary>
|
||||||
|
<ol class="toc-list">
|
||||||
|
@foreach($toc as $item)
|
||||||
|
<li class="toc-level-{{ $item['level'] }}">
|
||||||
|
<a href="#{{ $item['id'] }}">{{ $item['text'] }}</a>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ol>
|
||||||
|
</details>
|
||||||
|
</nav>
|
||||||
|
@endif
|
||||||
@if($cover = $post->getFirstMedia('cover'))
|
@if($cover = $post->getFirstMedia('cover'))
|
||||||
<div class="post-cover">
|
<div class="post-cover">
|
||||||
<img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}">
|
<img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}">
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake-jpg
|
||||||
@@ -158,3 +158,15 @@ a:hover { opacity: 0.8; }
|
|||||||
.pagination-links { gap: 6px; }
|
.pagination-links { gap: 6px; }
|
||||||
.pagination-links a, .pagination-links .current, .pagination-links .disabled { padding: 5px 10px; }
|
.pagination-links a, .pagination-links .current, .pagination-links .disabled { padding: 5px 10px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TOC */
|
||||||
|
.toc { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 14px 18px; margin: 0 0 18px; font-size: 14px; }
|
||||||
|
.toc summary { cursor: pointer; font-weight: 600; margin-bottom: 6px; }
|
||||||
|
.toc-list { list-style: none; }
|
||||||
|
.toc-list li { padding: 3px 0; }
|
||||||
|
.toc-list a { color: var(--muted); }
|
||||||
|
.toc-list a:hover { color: var(--accent); }
|
||||||
|
.toc-level-3 { padding-left: 14px; }
|
||||||
|
.toc-level-4, .toc-level-5, .toc-level-6 { padding-left: 28px; }
|
||||||
|
|
||||||
|
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
||||||
|
|||||||
@@ -134,3 +134,13 @@ a:hover { color: #f60; text-decoration: underline; }
|
|||||||
.post-full .post-title { font-size: 22px; }
|
.post-full .post-title { font-size: 22px; }
|
||||||
.archive-posts { margin-left: 10px; }
|
.archive-posts { margin-left: 10px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TOC */
|
||||||
|
.toc { background: #f7f9fb; border: 1px solid #d8dfe6; padding: 10px 14px; margin: 0 0 14px; font-size: 13px; }
|
||||||
|
.toc summary { cursor: pointer; font-weight: bold; margin-bottom: 4px; }
|
||||||
|
.toc-list { list-style: none; }
|
||||||
|
.toc-list li { padding: 2px 0; }
|
||||||
|
.toc-level-3 { padding-left: 14px; }
|
||||||
|
.toc-level-4, .toc-level-5, .toc-level-6 { padding-left: 28px; }
|
||||||
|
|
||||||
|
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@include('partials.header')
|
@include('partials.header')
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<main id="content">
|
<main id="content">
|
||||||
|
<h1 class="sr-only">{{ $siteName }}</h1>
|
||||||
@if(session('success'))
|
@if(session('success'))
|
||||||
<div class="alert alert-success">{{ session('success') }}</div>
|
<div class="alert alert-success">{{ session('success') }}</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -62,6 +62,19 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="widget">
|
||||||
|
<h3>社交账号</h3>
|
||||||
|
<ul class="social-links">
|
||||||
|
@foreach($socialLinks as $social)
|
||||||
|
@if($social['url'])
|
||||||
|
<li><a href="{{ $social['url'] }}" target="_blank" rel="noopener nofollow">{{ $social['platform'] }}</a></li>
|
||||||
|
@else
|
||||||
|
<li>{{ $social['platform'] }}:{{ $social['value'] }}</li>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="widget">
|
<section class="widget">
|
||||||
<h3>统计</h3>
|
<h3>统计</h3>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -16,6 +16,20 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
<article class="post-full">
|
<article class="post-full">
|
||||||
|
@if(! empty($toc))
|
||||||
|
<nav class="toc" aria-label="文章目录">
|
||||||
|
<details open>
|
||||||
|
<summary>目录</summary>
|
||||||
|
<ol class="toc-list">
|
||||||
|
@foreach($toc as $item)
|
||||||
|
<li class="toc-level-{{ $item['level'] }}">
|
||||||
|
<a href="#{{ $item['id'] }}">{{ $item['text'] }}</a>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ol>
|
||||||
|
</details>
|
||||||
|
</nav>
|
||||||
|
@endif
|
||||||
@if($cover = $post->getFirstMedia('cover'))
|
@if($cover = $post->getFirstMedia('cover'))
|
||||||
<div class="post-cover"><img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}"></div>
|
<div class="post-cover"><img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}"></div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
Reference in New Issue
Block a user