本来做导航的,想着如果是文章也能同时在首页分开显示就好了而不是都显示在一起,在首页因为公用一个分类导致文章也会进入导航的分类里面,这样显示的就不太好,下面的方式是通过js渲染的方法判断是导航还是文章然后对应的写进不同的区域,即同个分类包含两种模式显示,这样导航模式下分类全部显示导航的,文章区域全部显示文章的。
// 文章自定义字段
function themeFields($layout) {
$url = new Typecho_Widget_Helper_Form_Element_Textarea('url', NULL, '', _t('跳转链接'), _t('请输入跳转URL,建议不用以 / 结尾。'));
$layout->addItem($url);
// 将单选框(Radio)改为下拉选择框(Select)
$mode = new Typecho_Widget_Helper_Form_Element_Select(
'mode',
array(
'navigation' => '导航模式',
'article' => '文章模式',
),
'navigation', // 默认选中项(字符串形式)
'显示方式',
'介绍:选择一种显示方式(导航模式、文章模式或网站关闭页面)'
);
$layout->addItem($mode);
}
<?php
// 1. 获取所有分类(保留原始顺序)
$categories = array();
$categoryWidget = $this->widget('Widget_Metas_Category_List');
if ($categoryWidget->have()) {
while ($categoryWidget->next()) {
$categories[] = array(
'id' => $categoryWidget->mid,
'name' => $categoryWidget->name,
'permalink' => $categoryWidget->permalink
);
}
}
// 2. 获取所有文章
$posts = array();
$postWidget = $this->widget('Widget_Contents_Post_Recent', array(
'order' => 'created',
'desc' => true,
'pageSize' => 9999
));
if ($postWidget->have()) {
while ($postWidget->next()) {
$posts[] = array(
'cid' => $postWidget->cid,
'title' => $postWidget->title,
'permalink' => $postWidget->permalink,
'url' => $postWidget->fields->url,
'date' => $postWidget->date->format('Y-m-d H:i:s'),
'excerpt' => $postWidget->excerpt,
'mode' => trim($postWidget->fields->mode),
'categories' => $postWidget->categories
);
}
}
// 3. 准备供JavaScript使用的数据(保留分类原始顺序)
$jsonData = json_encode(array(
'categories' => $categories,
'posts' => $posts
));
?>
<div class="container">
<!-- 导航模式区域 -->
<section class="navigation-section">
<h2 class="section-title">导航链接</h2>
<div id="navigation-container"></div>
<p class="empty-message navigation-empty" style="display: none;">暂无导航链接</p>
</section>
<!-- 文章模式区域 -->
<section class="article-section">
<h2 class="section-title">最新文章</h2>
<div id="article-container"></div>
<p class="empty-message article-empty" style="display: none;">暂无文章内容</p>
</section>
</div>
<script>
// 解析从PHP传递的数据
const data = <?php echo $jsonData; ?>;
// 组织数据:按分类和模式整理(保留分类原始顺序)
const organizedData = {};
// 初始化所有分类(按原始顺序)
data.categories.forEach(category => {
organizedData[category.id] = {
...category,
navigationPosts: [],
articlePosts: []
};
});
// 按模式分配文章到对应分类
data.posts.forEach(post => {
const mode = post.mode || 'article'; // 默认文章模式
if (post.categories && post.categories.length) {
post.categories.forEach(cat => {
const catId = cat.mid;
// 如果分类不存在(可能是未在后台创建的分类),添加它
if (!organizedData[catId]) {
organizedData[catId] = {
id: catId,
name: cat.name,
permalink: cat.permalink,
navigationPosts: [],
articlePosts: []
};
// 添加到分类数组末尾
data.categories.push(organizedData[catId]);
}
// 根据模式添加到对应数组
if (mode === 'navigation') {
organizedData[catId].navigationPosts.push(post);
} else {
organizedData[catId].articlePosts.push(post);
}
});
}
});
// 渲染导航区域(按原始分类顺序)
function renderNavigation() {
const container = document.getElementById('navigation-container');
const emptyMsg = document.querySelector('.navigation-empty');
let hasAnyContent = false;
container.innerHTML = '';
// 按原始顺序遍历所有分类
data.categories.forEach(category => {
const catData = organizedData[category.id];
const hasContent = catData.navigationPosts.length > 0;
if (hasContent) {
hasAnyContent = true;
}
// 创建分类容器(即使没有内容也创建,可根据需求调整)
const categoryDiv = document.createElement('div');
categoryDiv.className = `navigation-category ${hasContent ? '' : 'empty-category'}`;
// 分类标题
categoryDiv.innerHTML = `
<h3 class="category-title">
<a href="${catData.permalink}">${catData.name}</a>
</h3>
<div class="navigation-list">
${hasContent ? catData.navigationPosts.map(post => {
const jumpUrl = post.url || post.permalink;
const target = jumpUrl !== post.permalink ? 'target="_blank"' : '';
return `
<div class="navigation-item">
<a href="${jumpUrl}" class="nav-link" ${target}>
${post.title}
</a>
</div>
`;
}).join('') : '<p class="category-empty">该分类下暂无导航链接</p>'}
</div>
`;
container.appendChild(categoryDiv);
});
// 控制整体空状态显示
container.style.display = hasAnyContent ? 'block' : 'none';
emptyMsg.style.display = hasAnyContent ? 'none' : 'block';
}
// 渲染文章区域(按原始分类顺序)
function renderArticles() {
const container = document.getElementById('article-container');
const emptyMsg = document.querySelector('.article-empty');
let hasAnyContent = false;
container.innerHTML = '';
// 按原始顺序遍历所有分类
data.categories.forEach(category => {
const catData = organizedData[category.id];
const hasContent = catData.articlePosts.length > 0;
if (hasContent) {
hasAnyContent = true;
}
// 创建分类容器(即使没有内容也创建)
const categoryDiv = document.createElement('div');
categoryDiv.className = `article-category ${hasContent ? '' : 'empty-category'}`;
// 分类内容
categoryDiv.innerHTML = `
<h3 class="category-title">
<a href="${catData.permalink}">${catData.name}</a>
</h3>
<div class="article-list">
${hasContent ? catData.articlePosts.map(post => `
<article class="article-item">
<h3 class="article-title">
<a href="${post.permalink}">${post.title}</a>
</h3>
<div class="article-meta">
<time datetime="${new Date(post.date).toISOString()}">${post.date}</time>
</div>
<div class="article-content">
${post.excerpt}
</div>
<a href="${post.permalink}" class="read-more">阅读全文 →</a>
</article>
`).join('') : '<p class="category-empty">该分类下暂无文章</p>'}
</div>
`;
container.appendChild(categoryDiv);
});
// 控制整体空状态显示
container.style.display = hasAnyContent ? 'block' : 'none';
emptyMsg.style.display = hasAnyContent ? 'none' : 'block';
}
// 页面加载完成后渲染内容
document.addEventListener('DOMContentLoaded', () => {
renderNavigation();
renderArticles();
});
</script>
这样的做法实现了在首页是按照自定义分类的不会受限于分类显示,如本身有大量文章配置此功能需要全部执行一遍更新,因为已发布的文章缺少mode字段值导致的。新发布的文章会正确保存mode字段(导航 / 文章模式),而旧文章可能没有这个字段,导致 JavaScript 无法正确识别其模式从而不显示,仅供测试,记录一下
© 版权声明
本站网络名称:
五七网络
本站永久网址:
https://www.wuqiz.com
网站侵权说明:
本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系七叔删除处理。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
THE END
暂无评论内容