前言

之前在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服务