DDL 焦虑症患者的自救:我给博客加了个 CFP

DDL 焦虑症患者的自救:我给博客加了个 CFP

搞学术的都知道,错过一个顶会 deadline 意味着什么——再等一年。

之前一直用 aideadlin.es 查会议截止日期,UI 挺好看,但有个致命问题:数据更新不及时。打开一看,2025 年的会议还挂在上面,2026 年的反而没几条。对于需要精确规划投稿的人来说,这不太能接受。

所以,我决定给自己的博客加一个会议追踪页面。

🎯 需求分析

在动手之前,我先明确了几个核心需求:

  1. 数据要新:必须有 2025-2026 年的会议
  2. 领域覆盖:AI、数据库、软件工程、网络安全、系统、图形学、HCI
  3. 筛选能力:按领域、按时间(30/60/90天内)
  4. 极简风格:与博客整体黑白调性一致
  5. 纯前端:不需要后端,静态托管即可

📊 数据源选型

最初尝试直接爬 aideadlin.es 的数据,发现它用的是一个 JSON 文件,但确实很久没更新了。

后来找到了 ccfddl/ccf-deadlines —— 这是一个由中国学术社区维护的开源项目,专门追踪 CCF 推荐会议的截止日期。优势明显:

  • ✅ 活跃维护:几乎每天都有更新
  • ✅ 结构清晰:按领域分类的 YAML 文件
  • ✅ 信息完整:包含 CCF 等级、会议地点、多个截止日期
  • ✅ 覆盖广:10 个领域,数百个会议

数据结构长这样:

- title: NeurIPS
  description: Conference on Neural Information Processing Systems
  sub: ML
  rank:
    ccf: A
  dblp: neurips
  confs:
    - year: 2026
      id: neurips26
      link: https://neurips.cc/
      timeline:
        - abstract_deadline: '2026-05-11 23:59:59'
          deadline: '2026-05-18 23:59:59'
      timezone: UTC-12
      date: December 7-13, 2026
      place: San Diego, CA, USA

完美契合我的需求。

🏗️ 技术实现

整体架构

Zola 静态站点
├── content/cfp/_index.md     # 页面入口
├── templates/cfp.html        # 页面模板
├── static/js/cfp.js          # 核心逻辑(~500行)
└── static/css/cfp.css        # 样式

核心思路:Zola 生成静态 HTML 壳,JavaScript 运行时从 GitHub 拉取数据渲染。

数据获取流程

// 1. 获取各领域的 YAML 文件列表
const categories = ['AI', 'DB', 'NW', 'SC', 'SE', 'DS', 'CT', 'CG', 'HI', 'MX'];

async function fetchCategoryConferences(category) {
    // 通过 GitHub API 获取目录下所有 YAML 文件
    const apiUrl = `https://api.github.com/repos/ccfddl/ccf-deadlines/contents/conference/${category}`;
    const files = await fetch(apiUrl).then(r => r.json());
    
    // 并行获取所有 YAML 文件内容
    const conferences = await Promise.all(
        files.filter(f => f.name.endsWith('.yml'))
             .map(f => fetchAndParseYaml(f.download_url))
    );
    return conferences.flat();
}

截止日期解析

ccfddl 的时间格式比较灵活,需要处理多种情况:

function parseDeadline(timeline, timezone) {
    // 优先使用 abstract_deadline,没有则用 deadline
    const deadlineStr = timeline.abstract_deadline || timeline.deadline;
    
    // 处理时区(如 UTC-12 表示 AoE - Anywhere on Earth)
    const date = new Date(deadlineStr);
    if (timezone === 'UTC-12') {
        date.setHours(date.getHours() + 12); // 转换为本地时间
    }
    return date;
}

本地缓存

为了减少 API 调用,实现了 6 小时缓存:

const CACHE_KEY = 'cfp_conferences_cache';
const CACHE_DURATION = 6 * 60 * 60 * 1000; // 6 hours

function getCachedData() {
    const cached = localStorage.getItem(CACHE_KEY);
    if (cached) {
        const { data, timestamp } = JSON.parse(cached);
        if (Date.now() - timestamp < CACHE_DURATION) {
            return data;
        }
    }
    return null;
}

🎨 UI 设计迭代

第一版:太花哨

最初照着 aideadlin.es 的风格做了个"Premium Academic Design"——渐变背景、大色块倒计时、hover 阴影...

结果一看效果,和博客的黑白极简风格完全不搭,用户反馈"辣眼睛"。

第二版:Editorial Minimalism

推倒重来,遵循几个原则:

  1. 无色块:背景透明,只用边框和文字颜色区分
  2. Typography-first:倒计时不再是大色块,而是纯粹的数字
  3. 胶囊徽章:CCF 等级和领域标签用空心胶囊样式

核心 CSS:

/* 卡片 - 简约边框 + 细左侧条 */
.cfp-card {
    background: #fff;
    border: 1px solid #e8e8ef;
    border-radius: 8px;
    position: relative;
}

.cfp-card::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: #8b8ba7;
    border-radius: 3px 0 0 3px;
}

/* 倒计时 - 纯 typography,颜色表达紧急程度 */
.countdown-value {
    font-family: 'SF Mono', monospace;
    font-size: 1.75rem;
    font-weight: 700;
    color: #1a1a2e;
}

.urgency-critical .countdown-value { color: #dc3545; }
.urgency-warning .countdown-value { color: #fd7e14; }

/* 徽章 - 空心胶囊 */
.cfp-card-rank {
    padding: 3px 10px;
    background: transparent;
    border: 1.5px solid;
    border-radius: 50px;
    font-size: 0.65rem;
    font-weight: 600;
}

响应式布局

根据屏幕宽度自适应列数:

屏幕宽度列数
< 640px1 列
640-1023px2 列
1024-1279px3 列
≥ 1280px4 列
@media (min-width: 1280px) {
    .cfp-grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

📱 最终效果

访问 polly.wang/cfp 可以看到:

  • 🔍 搜索:按会议名称、描述、地点搜索
  • 📂 领域筛选:AI / Database / Software / Network / Security / Graphics / HCI / Systems
  • ⏰ 时间筛选:30天内 / 60天内 / 90天内 / 全部
  • 🏷️ CCF 等级:A / B / C / N 用不同颜色的胶囊徽章标识
  • 📍 会议信息:日期、地点、官网链接、CFP 链接

💡 经验总结

  1. 数据源选择很重要:与其自己维护,不如找一个活跃的社区项目
  2. 设计要服务于内容:极简不是目的,让用户快速获取信息才是
  3. 纯前端方案的好处:无需服务器,静态托管即可,维护成本为零
  4. 缓存是必需的:GitHub API 有频率限制,本地缓存既省流量又提升体验

下次再也不用担心错过 NeurIPS 的 deadline 了。😎

Comments