一、为什么要改主题代码?
我用 BeaconNav 搭了一个导航站,平时放各种链接。唯独“推特关注列表”这个分类比较特殊——它不是网站链接卡片,而是一个表格。如果也用卡片展示,信息密度太低,需要反复切换,浏览起来极不方便。
所以核心需求只有两条:
在指定页面直接开一个完整的表格面板。
一键更新:如果有表格变动,我不应该去手动敲代码修改,而是用Excel格式转换,粘贴数据到文章。
二、修改 index.php
2.1 关键修改点
原主题代码在导航标签<ul class="nav nav-tabs">之后,直接就是卡片循环<div class="nav-list row">。
所以干脆在它们之间插入了条件判断分支。
代码片段 1:条件判断 + 自定义面板输出
<!-- 自定义面板 -->
<?php
// 智能识别指定的分类(菜单)关键词,支持大小写模糊匹配
$catName = strtolower($this->category);
if ($this->is('category', 'x-twitter') ||
strpos($catName, '推特') !== false ||
strpos($catName, '关注列表') !== false ||
strpos($catName, 'follow') !== false) :
?>
<div class="x-custom-block mt-3 text-white">
<div class="x-custom-wrapper">
<?php if ($this->have()) : ?>
<?php while ($this->next()) : ?>
<?php
// 直接查数据库取文章正文(text 字段)
$db = Typecho_Db::get();
$postData = $db->fetchRow($db->select('text')->from('table.contents')->where('cid = ?', $this->cid));
$rawHtml = $postData['text'];
// 去掉 Typecho 自动加的 Markdown 标记
if (strpos($rawHtml, '<!--markdown-->') === 0) {
$rawHtml = substr($rawHtml, 15);
}
// 解码实体,直接输出 HTML
echo htmlspecialchars_decode($rawHtml);
?>
<?php endwhile; ?>
<?php else : ?>
<div class="text-center opacity-50"><?php _e('暂无列表数据,请先在后台发布一篇该分类下的文章。'); ?></div>
<?php endif; ?>
</div>
</div>
<?php else : ?>
<!-- 原卡片列表(不变) -->
<div class="nav-list row">
...
</div>
<?php endif; ?>代码解释
第 4~7 行:只要当前分类缩略名是
x-twitter,或分类缩略名包含“推特/关注列表/follow”(不区分大小写),就触发自定义面板。第 11~16 行:遍历该分类下的文章。从数据库
table.contents表中读取text字段(即文章正文)。第 18~19 行:因为文章是用 Markdown 写的,Typecho 会在内容前加上
<!--markdown-->,必须截掉,否则会显示在页面上。第 21 行:
htmlspecialchars_decode把<之类的实体转回<,这样表格 HTML 才能被浏览器解析。
代码片段 2:配套的 CSS(让面板好看且能滚动)
<style>
.x-custom-block {
display: block !important;
width: 100% !important;
margin-top: 0 !important;
}
.x-custom-wrapper {
background: rgba(255, 255, 255, 0.12) !important;
backdrop-filter: blur(10px) !important; /* 毛玻璃效果 */
-webkit-backdrop-filter: blur(10px) !important;
border: 1px solid rgba(255, 255, 255, 0.15) !important;
border-radius: 12px !important;
padding: 24px !important;
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.25) !important;
/* 关键:限制高度,长表格内部滚动 */
max-height: 65vh !important;
overflow-y: auto !important;
}
/* 表格样式 */
.x-table {
width: 100% !important;
border-collapse: collapse !important;
color: #fff !important;
}
.x-table th {
background: #70ad47 !important; /* 表头绿色高亮 */
color: #ffffff !important;
font-weight: 600 !important;
}
.x-table tr:hover {
background: rgba(255, 255, 255, 0.08) !important;
}
.x-link-btn {
background: rgba(255, 255, 255, 0.18) !important;
color: #fff !important;
padding: 5px 12px !important;
border-radius: 6px !important;
text-decoration: none !important;
}
/* 美化滚动条 */
.x-custom-wrapper::-webkit-scrollbar { width: 6px; }
.x-custom-wrapper::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 4px; }
</style>三、表格转换工具
分类下的内容来自文章正文,但我不能每次更新关注列表都手写标签来更新吧?太反人类了。所以我写了一个独立的HTML工具,放在网站根目录,用来把文本表格转成方便复制的 HTML 代码。
3.1 核心逻辑代码片段(JS 解析部分)
function generateHTML() {
const textVal = document.getElementById('rawText').value.trim();
if (!textVal) return alert('好歹说点什么啊喂!');
// 获取当前(或手动冻结的)时间
let finalTime = document.getElementById('updateTime').innerText.trim();
if (finalTime.length > 16) finalTime = finalTime.substring(0, 16);
const lines = textVal.split('\n').map(line => line.trim()).filter(line => line !== '');
// 智能分割:支持 Tab、竖线 |、或多个连续空格
function splitLine(str) {
return str.split(/\t|\|| {2,}/).map(item => item.trim()).filter(item => item !== '');
}
const headerCols = splitLine(lines[0]); // 首行作表头
let html = `<div class="x-table-container"><table class="x-table"><thead><tr>`;
headerCols.forEach(h => { html += `<th>${h}</th>`; });
html += `</tr></thead><tbody>`;
for (let i = 1; i < lines.length; i++) {
let cols = splitLine(lines[i]);
if (cols.length === 0) continue;
while (cols.length < headerCols.length) cols.push(''); // 补全空位
html += `<tr>`;
cols.forEach((cell, index) => {
if (index === 0) {
html += `<td><strong>${cell}</strong></td>`; // 第一列加粗
} else if (cell.startsWith('http://') || cell.startsWith('https://')) {
html += `<td><a class="x-link-btn" href="${cell}" target="_blank">直达网页</a></td>`;
} else {
html += `<td>${cell}</td>`;
}
});
html += `</tr>`;
}
html += `</tbody></table></div>`;
// 去掉所有换行符,压缩成一行,防止 Markdown 捣乱
document.getElementById('outputHtml').value = html.replace(/\r?\n|\r/g, "");
document.getElementById('resultBox').style.display = 'block';
document.getElementById('outputHtml').select();
}3.2 这个工具还帮我做了什么?
时间戳管理:自动显示当前时区时间,支持手动“冻结/修改”,方便自定义数据更新时间。
时区切换:下拉菜单支持全球主流的24时区,以适配不同的工作环境。
智能链接识别:只要单元格里是
http://或https://开头的,就会变成方形按钮,简约美观且便携。
四、列表维护流程
以后想更新“关注列表”,只需三步:
整理数据:先在 Excel 里把数据整理好,连带首行复制出来。
打开工具:访问
/tools.html或点击右上角的更新数据,粘贴表格内容,确认更新时间,点击生成文章格式代码,复制输出的代码。更新文章:在Typecho后台找到该分类下的关注列表文章,全选粘贴替换掉旧文章代码,发布。
五、注意事项
特殊分类只发一篇文章:如果发多篇文章,
while ($this->next())会循环输出多次,页面会叠好几层面板。关闭 Markdown 解析:工具生成的已经是纯 HTML。如果你后台有Markdown插件,记得在模板里用
substr去掉<!--markdown-->标记,或者禁用 Markdown的插件。分隔符建议用 Tab:肉眼对不齐的空格容易导致分割错位,Excel默认Tab分隔最稳。
样式前缀:所有自定义 CSS 都加了
x-前缀,这样不会和主题原有样式冲突。
评论