166 lines
7.1 KiB
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'; ?>
|