Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/build-data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build Navigation Data

on:
push:
branches:
- master
- main
paths:
- 'content/sites/**'
- 'content/categories.json'
workflow_dispatch:

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Build navigation data
run: node scripts/build-data.js

- name: Check for changes
id: changes
run: |
git add data/sites.json
if git diff --cached --quiet; then
echo "changed=false" >> $GITHUB_OUTPUT
echo "No changes to data/sites.json"
else
echo "changed=true" >> $GITHUB_OUTPUT
echo "Changes detected in data/sites.json"
fi

- name: Commit changes
if: steps.changes.outputs.changed == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git commit -m "chore: auto-rebuild data/sites.json [skip ci]"
git push
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# WorkBuddy
.workbuddy/

# Python cache
__pycache__/
*.pyc

# Temp files
*.tmp
._*
180 changes: 180 additions & 0 deletions DECAP_CMS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Decap CMS 后台管理指南

本项目已集成 [Decap CMS](https://decapcms.org/)(原 Netlify CMS),提供可视化的后台管理界面,无需修改代码即可管理导航网站内容。

---

## 目录结构

```
.
├── admin/ # Decap CMS 后台
│ ├── index.html # CMS 入口页面
│ └── config.yml # CMS 配置文件
├── content/ # CMS 管理的内容文件
│ ├── sites/ # 每个网址一个 JSON 文件
│ │ ├── dribbble.json
│ │ ├── behance.json
│ │ └── ...
│ └── categories.json # 分类结构配置
├── data/ # 前端使用的合并数据(自动生成)
│ ├── sites.json # 中文版导航数据
│ └── sites_en.json # 英文版导航数据
├── scripts/
│ └── build-data.js # 数据合并脚本
├── .github/workflows/
│ └── build-data.yml # GitHub Actions 自动构建
├── assets/
│ └── js/
│ └── nav-render.js # 前端数据渲染引擎
├── cn/index.html # 中文首页(数据驱动)
└── en/index.html # 英文首页(数据驱动)
```

## 数据流程

```
CMS 后台编辑 → content/sites/*.json → GitHub Actions → data/sites.json → 前页面动态渲染
```

1. 在 `/admin/` 后台新增/编辑/删除网址条目
2. CMS 将每个条目保存为 `content/sites/` 下的独立 JSON 文件
3. GitHub Actions 自动将所有 JSON 合并为 `data/sites.json`
4. 前端页面通过 `nav-render.js` 加载 `data/sites.json` 并动态渲染

## 访问后台

部署后,访问以下地址进入 CMS 后台:

```
https://你的域名/admin/
```

首次访问需要通过 GitHub OAuth 登录认证。

## 认证配置

Decap CMS 需要OAuth认证才能连接 GitHub 仓库。以下是三种可选方案:

### 方案一:Netlify OAuth(推荐,最简单)

即使你的网站部署在 GitHub Pages 上,也可以使用 Netlify 作为 OAuth 提供商。

1. 注册 [Netlify](https://app.netlify.com/) 账号
2. 点击 "New site from Git",选择你的 GitHub 仓库 `imhardcore/nav`
3. 部署设置可以保持默认(不需要实际部署,只需要关联仓库)
4. 进入站点设置 → Site details,记下你的站点 URL
5. 进入 Site settings → Domain management,确保有一个域名
6. `admin/config.yml` 中的配置已经是 Netlify OAuth 模式:
```yaml
backend:
name: github
repo: imhardcore/nav
branch: master
base_url: https://api.netlify.com
auth_endpoint: auth
```

### 方案二:Git Gateway(适用于 Netlify 部署)

如果你将网站部署在 Netlify 上(而非 GitHub Pages),可以使用更简单的 Git Gateway:

1. 在 Netlify 站点设置中开启 Identity 服务
2. 启用 Git Gateway
3. 修改 `admin/config.yml`:
```yaml
backend:
name: git-gateway
branch: master
```
4. 取消 `admin/index.html` 中 Netlify Identity Widget 的注释

### 方案三:自建 OAuth 代理

如果你不想使用 Netlify,可以自建 OAuth 代理:

1. 参考 [Decap CMS OAuth 文档](https://decapcms.org/docs/github-backend/) 创建 GitHub OAuth App
2. 部署一个 OAuth 代理服务(如使用 Cloudflare Workers、Vercel 等)
3. 修改 `admin/config.yml`:
```yaml
backend:
name: github
repo: imhardcore/nav
branch: master
base_url: https://你的代理地址
auth_endpoint: api/auth
```

## 使用方法

### 添加新网址

1. 进入 CMS 后台 → 「网址导航」
2. 点击「添加网址」
3. 填写信息:
- **名称**:网站名称(如 Dribbble)
- **网址**:完整 URL(如 https://dribbble.com/)
- **描述**:网站简介
- **Logo**:上传或选择网站 Logo 图片
- **分类**:选择所属分类
- **排序**:数字越小越靠前
4. 点击「保存」即可发布

### 编辑网址

1. 在列表中点击要编辑的网址
2. 修改内容后保存

### 删除网址

1. 在列表中找到要删除的网址
2. 点击删除按钮

### 管理分类

1. 进入 CMS 后台 → 「分类管理」
2. 可以添加、编辑、删除分类
3. 支持父子层级关系(父级分组 + 子分类)

## 本地开发

### 运行本地 CMS 服务器

```bash
# 安装 decap-server
npx decap-server

# 在项目根目录启动一个静态服务器
npx http-server -p 8080
```

然后访问 `http://localhost:8080/admin/` 即可使用本地 CMS。

`admin/config.yml` 中已配置 `local_backend: true`,在本地运行时会自动连接本地代理。

### 手动构建数据文件

如果需要在本地测试数据合并:

```bash
node scripts/build-data.js
```

这会将 `content/sites/` 下的所有 JSON 文件合并为 `data/sites.json`。

## 启用编辑工作流(可选)

如果需要审核流程(草稿 → 审核 → 发布),取消 `admin/config.yml` 中的注释:

```yaml
publish_mode: editorial_workflow
```

启用后,CMS 中的内容需要经过审核才能发布到主分支。

## 注意事项

- `data/sites.json` 是自动生成的文件,请勿手动编辑
- `cn/index_original.html` 和 `en/index_original.html` 是原始版本的备份
- Logo 图片尺寸建议为 120×120px,存放在 `assets/images/logos/` 目录
- GitHub Actions 工作流在 `content/sites/` 或 `content/categories.json` 变更时自动触发
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ Docker部署版本:https://hub.docker.com/r/arvon2014/webstack-laravel
#### 方法13. 基于 Golang 开发的后台系统🔥 Webstack-Go (感谢[@ch3nnn](https://github.com/ch3nnn)提供)
开源地址: https://github.com/ch3nnn/webstack-go

#### 方法14. 自己写后台系统
#### 方法14. 使用 Decap CMS 管理后台(本项目内置)
本项目已集成 Decap CMS(原 Netlify CMS),提供可视化后台管理界面。访问 `/admin/` 即可管理所有网址内容,无需修改代码。详见 [DECAP_CMS.md](./DECAP_CMS.md)。

#### 方法15. 自己写后台系统
可以按照自己的喜好和框架搭建后台系统,也可以参考我设计好的后台框架自行搭建。本站设计开发过程在我的博客文章有详细讲到[《webstack \| viggo》](http://blog.viggoz.com/2018/01/03/2018-01-03-webstack/)。静态源码(半成品):[https://github.com/WebStackPage/webstack-Admin](https://github.com/WebStackPage/webstack-Admin)

如果你有更好的解决方案,并且能够开源供大家使用,可以在本项目提Issus,或者直接通过我个人网站中的联系方式联系我。
Expand Down
127 changes: 127 additions & 0 deletions admin/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Decap CMS Configuration
# 文档: https://decapcms.org/docs/configuration/

# 本地开发模式 (运行 npx decap-server 后可在 localhost 访问 /admin/)
local_backend: true

# ─── 后端配置 ───
# 方式一: GitHub OAuth (适用于 GitHub Pages 部署)
# 需要配置 OAuth Provider, 详见 README 说明
backend:
name: github
repo: imhardcore/nav
branch: master
base_url: https://api.netlify.com
auth_endpoint: auth

# 方式二: Git Gateway (适用于 Netlify 部署)
# 取消下方注释并注释掉上方 backend 配置即可使用
# backend:
# name: git-gateway
# branch: master

# ─── 媒体配置 ───
# 上传的 Logo 图片存储位置
media_folder: "assets/images/logos"
# 浏览器访问图片的 URL 前缀
public_folder: "/assets/images/logos"

# ─── 发布模式 (可选) ───
# 取消下行注释可启用编辑工作流 (草稿 → 审核 → 发布)
# publish_mode: editorial_workflow

# ─── 站点配置 ───
site_url: https://imhardcore.github.io/nav

# ─── 内容集合 ───
collections:
# ===== 网址导航条目 =====
- name: "sites"
label: "🌐 网址导航"
label_singular: "网址"
description: "管理导航网站中的所有网址条目"
folder: "content/sites"
create: true
delete: true
format: "json"
extension: "json"
slug: "{{slug}}"
summary: "{{name}} — {{category}}"
sortable_fields: ['name', 'category', 'order']
view_filters:
- label: "常用推荐"
field: category
pattern: "常用推荐"
- label: "社区资讯"
field: category
pattern: "社区资讯"
- label: "灵感采集"
field: category
pattern: "发现产品"
- label: "素材资源"
field: category
pattern: "图标素材"
fields:
- { label: "名称", name: "name", widget: "string", hint: "网站名称,如 Dribbble" }
- { label: "网址", name: "url", widget: "string", hint: "完整 URL,如 https://dribbble.com/" }
- { label: "描述", name: "description", widget: "text", hint: "网站简介" }
- { label: "Logo", name: "logo", widget: "image", required: false, hint: "上传或选择网站 Logo 图片" }
- label: "分类"
name: "category"
widget: "select"
hint: "选择该网址所属分类"
options:
- { label: "常用推荐", value: "常用推荐" }
- { label: "社区资讯", value: "社区资讯" }
- { label: "灵感采集 → 发现产品", value: "发现产品" }
- { label: "灵感采集 → 界面灵感", value: "界面灵感" }
- { label: "灵感采集 → 网页灵感", value: "网页灵感" }
- { label: "素材资源 → 图标素材", value: "图标素材" }
- { label: "素材资源 → LOGO设计", value: "LOGO设计" }
- { label: "素材资源 → 平面素材", value: "平面素材" }
- { label: "素材资源 → UI资源", value: "UI资源" }
- { label: "素材资源 → Sketch资源", value: "Sketch资源" }
- { label: "素材资源 → 字体资源", value: "字体资源" }
- { label: "素材资源 → Mockup", value: "Mockup" }
- { label: "素材资源 → 摄影图库", value: "摄影图库" }
- { label: "素材资源 → PPT资源", value: "PPT资源" }
- { label: "常用工具 → 图形创意", value: "图形创意" }
- { label: "常用工具 → 界面设计", value: "界面设计" }
- { label: "常用工具 → 交互动效", value: "交互动效" }
- { label: "常用工具 → 在线配色", value: "在线配色" }
- { label: "常用工具 → 在线工具", value: "在线工具" }
- { label: "常用工具 → Chrome插件", value: "Chrome插件" }
- { label: "学习教程 → 设计规范", value: "设计规范" }
- { label: "学习教程 → 视频教程", value: "视频教程" }
- { label: "学习教程 → 设计文章", value: "设计文章" }
- { label: "学习教程 → 设计电台", value: "设计电台" }
- { label: "学习教程 → 交互设计", value: "交互设计" }
- { label: "UED团队", value: "UED团队" }
- { label: "排序", name: "order", widget: "number", default: 100, hint: "数字越小越靠前", value_type: "int" }

# ===== 分类管理 =====
- name: "categories"
label: "📁 分类管理"
description: "管理导航网站的分类结构"
files:
- file: "content/categories.json"
label: "分类配置"
name: "categories"
format: "json"
fields:
- label: "分类列表"
name: "categories"
widget: "list"
hint: "所有分类及其层级关系"
fields:
- { label: "分类名称", name: "name", widget: "string" }
- { label: "父级分组", name: "parent", widget: "string", required: false, hint: "如属于某个父级分组则填写,如 灵感采集、素材资源等" }
- { label: "图标", name: "icon", widget: "string", required: false, hint: "Linecons 图标类名,如 linecons-star" }
- { label: "排序", name: "order", widget: "number", value_type: "int" }
- label: "父级分组"
name: "parent_groups"
widget: "list"
hint: "包含子分类的父级分组"
fields:
- { label: "分组名称", name: "name", widget: "string" }
- { label: "图标", name: "icon", widget: "string" }
Loading