tp/public/themes/template3/blog-details.php

166 lines
7.1 KiB
PHP

<?php
// 支持 Index@articleDetail 注入 $pageTitle 等;直接访问 /blog-details 时用默认文案
$pageTitle = (isset($pageTitle) && $pageTitle !== '') ? $pageTitle : '新闻中心详情 - Nova';
$pageDescription = (isset($pageDescription) && $pageDescription !== '') ? $pageDescription : 'Nova Bootstrap Template 的新闻中心详情页面';
$pageKeywords = (isset($pageKeywords) && $pageKeywords !== '') ? $pageKeywords : 'blog, details, nova';
$article = (isset($article) && is_array($article)) ? $article : [];
$hasArticle = !empty($article['id']);
// 面包屑第三段:文章分类名(与控制器注入的 $articleCategoryName 一致)
$cateName = (isset($articleCategoryName) && (string) $articleCategoryName !== '') ? (string) $articleCategoryName : '未分类';
require_once __DIR__ . '/header.php';
?>
<!-- Page Title -->
<div class="page-title dark-background" data-aos="fade" style="background-image: url(<?php echo $baseUrl; ?>/themes/template3/assets/img/blog-page-title-bg.jpg);">
<div class="container">
<h1><?php echo $hasArticle ? htmlspecialchars($article['title'] ?? '博客详情') : '博客详情'; ?></h1>
<nav class="breadcrumbs">
<ol>
<li><a href="<?php echo htmlspecialchars($baseUrl); ?>/">主页</a></li>
<li><a href="<?php echo htmlspecialchars($baseUrl . '/blog'); ?>">新闻中心</a></li>
<li class="current"><?php echo htmlspecialchars($cateName); ?></li>
</ol>
</nav>
</div>
</div><!-- End Page Title -->
<div class="container">
<div class="row">
<div class="col-lg-12">
<!-- Blog Details Section -->
<section id="blog-details" class="blog-details section">
<div class="container">
<article class="article">
<?php if ($hasArticle): ?>
<?php
$detailTitle = $article['title'] ?? '无标题';
$detailAuthor = $article['author'] ?? '';
$publishRaw = $article['publish_date'] ?? ($article['create_time'] ?? '');
$publishTs = ($publishRaw !== '') ? strtotime((string) $publishRaw) : false;
$publishDateAttr = ($publishTs !== false) ? date('c', $publishTs) : '';
$publishDateText = ($publishTs !== false) ? date('Y年m月d日', $publishTs) : '';
$views = (int) ($article['views'] ?? 0);
$coverSrc = !empty($articleCoverUrl)
? $articleCoverUrl
: ($baseUrl . '/themes/template3/assets/img/blog/blog-1.jpg');
?>
<h2 class="title"><?php echo htmlspecialchars($detailTitle); ?></h2>
<div class="meta-top">
<ul>
<li class="d-flex align-items-center"><i class="bi bi-person"></i> <span><?php echo htmlspecialchars($detailAuthor !== '' ? $detailAuthor : '—'); ?></span></li>
<li class="d-flex align-items-center"><i class="bi bi-clock"></i> <?php if ($publishDateText !== ''): ?><time datetime="<?php echo htmlspecialchars($publishDateAttr); ?>"><?php echo htmlspecialchars($publishDateText); ?></time><?php else: ?><span>—</span><?php endif; ?></li>
<li class="d-flex align-items-center"><i class="bi bi-eye"></i> <span id="article-views-count">阅读 <?php echo $views; ?></span></li>
</ul>
</div><!-- End meta top -->
<div class="content article-body">
<?php echo $article['content'] ?? ''; ?>
</div><!-- End post content -->
<div class="meta-bottom">
<i class="bi bi-folder"></i>
<ul class="cats">
<li><span><?php echo htmlspecialchars($cateName); ?></span></li>
</ul>
</div><!-- End meta bottom -->
<?php else: ?>
<p class="text-center py-5">暂无文章数据,请从<a href="<?php echo htmlspecialchars($baseUrl . '/blog'); ?>">新闻列表</a>进入详情。</p>
<?php endif; ?>
</article>
</div>
</section><!-- /Blog Details Section -->
</div>
</div>
</div>
</main>
<?php if ($hasArticle): ?>
<script>
(function () {
var id = <?php echo (int) ($article['id'] ?? 0); ?>;
if (!id) return;
var url = <?php echo json_encode(rtrim($baseUrl, '/') . '/articleViews/', JSON_UNESCAPED_SLASHES); ?> + id;
var el = document.getElementById('article-views-count');
fetch(url, { method: 'POST', credentials: 'same-origin', headers: { 'Accept': 'application/json' } })
.then(function (r) { return r.json(); })
.then(function (res) {
if (res && res.code === 200 && res.data && typeof res.data.views !== 'undefined' && el) {
el.textContent = '阅读 ' + res.data.views;
}
})
.catch(function () { /* 静默失败,保留服务端渲染的阅读量 */ });
})();
</script>
<script>
(function () {
var root = document.querySelector('.blog-details .content.article-body');
if (!root) return;
root.querySelectorAll('pre').forEach(function (pre) {
if (pre.closest('.article-code-block')) return;
var wrap = document.createElement('div');
wrap.className = 'article-code-block';
pre.parentNode.insertBefore(wrap, pre);
wrap.appendChild(pre);
var btn = document.createElement('button');
btn.type = 'button';
btn.className = 'article-code-copy';
btn.setAttribute('aria-label', '复制代码');
btn.textContent = '复制';
wrap.insertBefore(btn, pre);
btn.addEventListener('click', function () {
var text = (pre.innerText !== undefined ? pre.innerText : pre.textContent) || '';
function showDone() {
btn.textContent = '已复制';
btn.classList.add('is-done');
clearTimeout(btn._copyReset);
btn._copyReset = setTimeout(function () {
btn.textContent = '复制';
btn.classList.remove('is-done');
}, 2000);
}
function showFail() {
btn.textContent = '复制失败';
clearTimeout(btn._copyReset);
btn._copyReset = setTimeout(function () { btn.textContent = '复制'; }, 2000);
}
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
navigator.clipboard.writeText(text).then(showDone).catch(function () {
fallbackCopy();
});
} else {
fallbackCopy();
}
function fallbackCopy() {
var ta = document.createElement('textarea');
ta.value = text;
ta.setAttribute('readonly', '');
ta.style.position = 'fixed';
ta.style.left = '-9999px';
document.body.appendChild(ta);
ta.select();
try {
if (document.execCommand('copy')) showDone();
else showFail();
} catch (e) {
showFail();
}
document.body.removeChild(ta);
}
});
});
})();
</script>
<?php endif; ?>
<?php require_once __DIR__ . '/footer.php'; ?>