前言
之前在WordPress上面使用了今日热榜,据说可以有助于SEO,于是就想着在solitude主题上也添加这个页面
效果

教程
在网站的source文件夹中新建一个hot文件夹,并在其中新建一个index.md文件,将如下代码放到里面
---
title: 今日热榜
date: 2025-08-04 00:00:00
type: "hot"
comment: false
---
<div id="hot-container">
<div class="hot-header">
<h1>今日热榜</h1>
<p>实时获取各大平台热门内容</p>
</div>
<div class="hot-grid" id="hot-grid">
<!-- 热榜卡片将通过JavaScript动态加载 -->
<div class="hot-card">
<div class="hot-card-header">
<h3 class="hot-card-title">微博</h3>
</div>
<div class="hot-card-content">
<div class="hot-card-loading">
<div class="hot-card-loading-spinner"></div>
<div class="hot-card-loading-text">正在加载数据...</div>
</div>
</div>
</div>
<div class="hot-card">
<div class="hot-card-header">
<h3 class="hot-card-title">知乎</h3>
</div>
<div class="hot-card-content">
<div class="hot-card-loading">
<div class="hot-card-loading-spinner"></div>
<div class="hot-card-loading-text">正在加载数据...</div>
</div>
</div>
</div>
<div class="hot-card">
<div class="hot-card-header">
<h3 class="hot-card-title">百度</h3>
</div>
<div class="hot-card-content">
<div class="hot-card-loading">
<div class="hot-card-loading-spinner"></div>
<div class="hot-card-loading-text">正在加载数据...</div>
</div>
</div>
</div>
<div class="hot-card">
<div class="hot-card-header">
<h3 class="hot-card-title">今日头条</h3>
</div>
<div class="hot-card-content">
<div class="hot-card-loading">
<div class="hot-card-loading-spinner"></div>
<div class="hot-card-loading-text">正在加载数据...</div>
</div>
</div>
</div>
</div>
</div>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #f5f5f5;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
}
/* 深色主题 */
[data-theme="dark"] body {
background-color: #1a1a1a;
color: #e0e0e0;
}
[data-theme="dark"] .hot-header h1 {
color: #ffffff;
}
[data-theme="dark"] .hot-header p {
color: #b0b0b0;
}
[data-theme="dark"] .hot-card {
background: #2d2d2d;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}
[data-theme="dark"] .hot-card:hover {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}
[data-theme="dark"] .hot-card-header {
background: #2d2d2d;
border-bottom: 1px solid #404040;
}
[data-theme="dark"] .hot-card-title h3 {
color: #e0e0e0;
}
[data-theme="dark"] .hot-item:hover {
background-color: #3a3a3a;
}
[data-theme="dark"] .hot-item-content a {
color: #e0e0e0;
border-bottom: none !important;
}
[data-theme="dark"] .hot-item-content a:hover {
color: #667eea;
border-bottom: none !important;
}
[data-theme="dark"] .hot-item-meta {
color: #b0b0b0;
}
[data-theme="dark"] .hot-card-loading {
color: #b0b0b0;
}
[data-theme="dark"] .hot-card-loading-text {
color: #b0b0b0;
}
[data-theme="dark"] .error-message {
color: #b0b0b0;
}
[data-theme="dark"] .hot-card-content::-webkit-scrollbar-track {
background: #3a3a3a;
}
[data-theme="dark"] .hot-card-content::-webkit-scrollbar-thumb {
background: #666;
}
[data-theme="dark"] .hot-card-content::-webkit-scrollbar-thumb:hover {
background: #888;
}
#hot-container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
.hot-header {
text-align: center;
margin-bottom: 30px;
}
.hot-header h1 {
font-size: 28px;
font-weight: 600;
color: #2c3e50;
margin: 0;
}
.hot-header p {
text-align: center;
margin: 8px 0 0 0;
color: #666;
font-size: 14px;
}
.hot-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.hot-card {
background: #ffffff;
border-radius: 12px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
height: 400px;
display: flex;
flex-direction: column;
overflow: hidden;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.hot-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
}
.hot-card-header {
padding: 10px 12px;
background: #ffffff;
border-bottom: 1px solid #e9ecef;
}
.hot-card-title {
margin: 0.3rem 0 !important;
}
.hot-card-title h3 {
margin: 0;
font-size: 15px;
font-weight: 600;
color: #2c3e50;
}
.hot-card-content {
flex: 1;
overflow-y: auto;
padding: 0;
}
.hot-card-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: #666;
}
.hot-card-loading-spinner {
width: 32px;
height: 32px;
border: 3px solid #f0f0f0;
border-radius: 50%;
border-top-color: #667eea;
animation: spin 1s linear infinite;
margin-bottom: 12px;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.hot-card-loading-text {
font-size: 14px;
color: #666;
}
.hot-list {
list-style: none;
padding: 0;
margin: 0;
}
.hot-item {
display: flex;
padding: 12px 20px;
transition: background-color 0.2s ease;
}
.hot-item:hover {
background-color: #f8f9fa;
}
.hot-item-index {
width: 24px;
height: 24px;
line-height: 24px;
text-align: center;
background: #e9ecef;
color: #495057;
margin-right: 12px;
font-weight: 600;
border-radius: 6px;
flex-shrink: 0;
font-size: 12px;
}
.hot-item:nth-child(1) .hot-item-index {
background: #ff4757;
color: white;
}
.hot-item:nth-child(2) .hot-item-index {
background: #ffa502;
color: white;
}
.hot-item:nth-child(3) .hot-item-index {
background: #ff6348;
color: white;
}
.hot-item:nth-child(4) .hot-item-index {
background: #3742fa;
color: white;
}
.hot-item:nth-child(5) .hot-item-index {
background: #2ed573;
color: white;
}
.hot-item-content {
flex: 1;
display: flex;
flex-direction: column;
}
.hot-item-content a {
color: #2c3e50;
font-size: 14px;
line-height: 1.5;
text-decoration: none;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
margin-bottom: 6px;
font-weight: 500;
border-bottom: none !important;
}
.hot-item-content a:hover {
color: #667eea;
border-bottom: none !important;
}
.hot-item-meta {
color: #6c757d;
font-size: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.alert {
padding: 16px;
margin: 16px;
border-radius: 8px;
border: 1px solid transparent;
}
.alert-danger {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
}
.error-message {
text-align: center;
padding: 20px;
color: #666;
}
.error-message h3 {
margin-bottom: 8px;
color: #dc3545;
}
.refresh-btn {
background: #667eea;
color: white;
border: none;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
margin-top: 8px;
}
.refresh-btn:hover {
background: #5a6fd8;
}
.hot-card-content::-webkit-scrollbar {
width: 6px;
}
.hot-card-content::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
.hot-card-content::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
}
.hot-card-content::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
@media (max-width: 1200px) {
.hot-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 900px) {
.hot-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 600px) {
#hot-container {
padding: 15px;
}
.hot-grid {
grid-template-columns: 1fr;
gap: 15px;
}
.hot-card {
height: 350px;
}
.hot-header h1 {
font-size: 24px;
}
.hot-item {
padding: 10px 16px;
}
.hot-item-content a {
font-size: 13px;
margin-bottom: 4px;
}
.hot-item-meta {
font-size: 11px;
gap: 6px;
}
}
</style>
<script>
// 立即执行,不等待DOMContentLoaded
(function() {
// 等待DOM加载完成
function initWhenReady() {
const hotGrid = document.getElementById('hot-grid');
if (!hotGrid) {
// 如果元素还没准备好,稍后再试
setTimeout(initWhenReady, 10);
return;
}
// 平台图标映射 - 已移除所有图标
const platformIcons = {};
// 创建热榜卡片
function createHotCard(platformName) {
const card = document.createElement('div');
card.className = 'hot-card';
card.innerHTML = `
<div class="hot-card-header">
<h3 class="hot-card-title">${platformName}</h3>
</div>
<div class="hot-card-content">
<div class="hot-card-loading">
<div class="hot-card-loading-spinner"></div>
<div class="hot-card-loading-text">正在加载数据...</div>
</div>
</div>
`;
return card;
}
// 渲染热榜项目
function renderHotItems(container, items) {
container.innerHTML = '';
items.forEach((item, index) => {
const hotItem = document.createElement('div');
hotItem.className = 'hot-item';
const indexClass = index < 3 ? 'top-3' : '';
const hotValue = item.hot ? `🔥 ${item.hot}` : '';
hotItem.innerHTML = `
<div class="hot-item-index ${indexClass}">${index + 1}</div>
<div class="hot-item-content">
<div class="hot-item-title">
<a href="${item.url}" target="_blank" rel="noopener noreferrer">
${item.title}
</a>
</div>
<div class="hot-item-meta">
${hotValue ? `<span class="hot-item-hot">${hotValue}</span>` : ''}
<span class="hot-item-time">${item.timestamp ? new Date(item.timestamp).toLocaleString() : ''}</span>
</div>
</div>
`;
container.appendChild(hotItem);
});
}
// 获取平台列表
async function fetchPlatforms() {
try {
const response = await fetch('https://api.pearktrue.cn/api/dailyhot/');
const data = await response.json();
if (data.code === 200 && data.data && data.data.platforms) {
return data.data.platforms;
}
throw new Error('获取平台列表失败');
} catch (error) {
console.error('获取平台列表失败:', error);
return null;
}
}
// 获取指定平台的热榜数据
async function fetchPlatformData(platformName) {
try {
const response = await fetch(`https://api.pearktrue.cn/api/dailyhot/?title=${encodeURIComponent(platformName)}`);
const data = await response.json();
if (data.code === 200 && data.data) {
return {
items: data.data.slice(0, 20), // 只显示前20条
updateTime: data.updateTime
};
}
throw new Error('获取热榜数据失败');
} catch (error) {
console.error(`获取${platformName}热榜失败:`, error);
return null;
}
}
// 初始化热榜页面
function initHotPage() {
// 屏蔽的平台列表
const blacklistPlatforms = [
'数字尾巴',
'极客公园',
'果壳',
'崩坏3',
'爱范儿',
'简书',
'米游社 · 崩坏3',
'NGA',
'什么值得买',
'崩坏:星穹铁道',
'微信读书',
'游研社'
];
// 完整平台列表
const allPlatforms = [
"36氪","51CTO","吾爱破解","AcFun","百度","哔哩哔哩","酷安","CSDN","数字尾巴","豆瓣讨论","豆瓣电影","抖音","极客公园","原神","果壳","HelloGitHub","历史上的今天","崩坏3","虎扑","虎嗅","爱范儿","IT之家「喜加一」","IT之家","简书","稀土掘金","英雄联盟","米游社 · 崩坏3","网易新闻","水木社区","NGA","腾讯新闻","新浪新闻","新浪网","什么值得买","少数派","崩坏:星穹铁道","澎湃新闻","百度贴吧","今日头条","中央气象台","微博","微信读书","游研社"
];
// 过滤掉屏蔽的平台
const defaultPlatforms = allPlatforms.filter(platform => !blacklistPlatforms.includes(platform));
// 清空现有内容
hotGrid.innerHTML = '';
// 立即创建所有卡片(显示加载状态)
defaultPlatforms.forEach((platformName, index) => {
const card = createHotCard(platformName);
hotGrid.appendChild(card);
// 异步获取该平台的数据
fetchPlatformData(platformName).then(data => {
const contentContainer = card.querySelector('.hot-card-content');
if (data && data.items && data.items.length > 0) {
renderHotItems(contentContainer, data.items);
} else {
contentContainer.innerHTML = `
<div class="error-message">
<h3>暂无数据</h3>
<p>${platformName}暂无热榜数据</p>
</div>
`;
}
}).catch(error => {
const contentContainer = card.querySelector('.hot-card-content');
contentContainer.innerHTML = `
<div class="error-message">
<h3>加载失败</h3>
<p>无法获取${platformName}热榜数据</p>
<button class="refresh-btn" onclick="location.reload()">重新加载</button>
</div>
`;
});
});
// 异步获取平台列表(后台执行,不影响页面显示)
fetchPlatforms().then(platforms => {
if (platforms && platforms.length > 0) {
// 过滤掉屏蔽的平台
const filteredPlatforms = platforms.filter(platform =>
!blacklistPlatforms.includes(platform)
);
// 如果获取到新的平台列表,可以选择更新显示
// 这里暂时保持默认平台列表,避免频繁刷新
console.log('获取到平台列表:', filteredPlatforms);
}
}).catch(error => {
console.error('获取平台列表失败:', error);
});
}
// 启动热榜页面
initHotPage();
}
// 立即开始初始化
initWhenReady();
})();
</script>
我在里面屏蔽了一些平台,这些平台要么不常见,要么更新缓慢。
最后就是到需要的地方添加页面地址了,比如我就是放到了导航栏的关于中。
在_config.solitude.yml文件中找到menu,将今日热榜: /hot/ || fas fa-fire添加到了里面。
结语
最后感谢PearAPI提供的API服务