建立笔记方法
可以的,我们可以给你做一个简易版“后台 /admin” 页面:
以后你:
- 打开
https://huanyuheng.com/admin/- 在网页里写标题 + 正文
- 点「发布」 👉 网页用 GitHub API 直接把文章提交到
huanyuheng.github.io仓库的_posts里,相当于自动 Git commit。
完全静态,不需要服务器,PAT 只存在你自己的浏览器里。
我一步步给你配好(建议边看边做):
第 0 步:准备 GitHub Token(只你自己知道)
- 进 GitHub → 右上角头像 → Settings
- 左侧最下面 Developer settings → Personal access tokens → Tokens (classic)
-
New token
- Note 随便写:
blog-admin - 选择权限:勾 repo(整组勾上就行)
- Note 随便写:
- 生成后复制那串 token(很长的一串)。
这串 token 相当于你手里的钥匙:不要给别人看,不要在公共电脑上用。
第 1 步:新建后台页面 admin.html
在你的仓库根目录新建一个文件:admin.html
内容直接复制下面这段(OWNER/REPO 我已经给你写好了):
---
layout: page
title: 后台发布
permalink: /admin/
---
<div class="page admin-page">
<h1>发布新文章</h1>
<p style="color:#6b7280;font-size:14px;">
第一次使用先在下面输入你的 GitHub Token,点击“保存 Token(只保存在本机)”。
之后就可以直接在网页里写文章,一键同步到仓库的 <code>_posts</code>。
</p>
<div style="margin:16px 0;padding:12px 14px;border-radius:10px;background:#f9fafb;border:1px solid #e5e7eb;">
<label style="font-size:14px;color:#374151;">GitHub Token</label><br>
<input id="token-input" type="password" style="margin-top:6px;width:100%;max-width:420px;padding:8px 10px;border-radius:8px;border:1px solid #d1d5db;">
<button id="save-token" style="margin-left:8px;padding:8px 14px;border-radius:999px;border:none;background:#2563eb;color:#fff;font-size:14px;cursor:pointer;">
保存 Token(只保存在本机)
</button>
<span id="token-status" style="margin-left:8px;font-size:13px;color:#16a34a;"></span>
</div>
<hr style="margin:18px 0 20px 0;border:none;border-top:1px solid #e5e7eb;">
<form id="post-form">
<div style="margin-bottom:12px;">
<label>标题(title)</label><br>
<input id="post-title" type="text" required
style="margin-top:4px;width:100%;max-width:420px;padding:8px 10px;border-radius:8px;border:1px solid #d1d5db;">
</div>
<div style="margin-bottom:12px;">
<label>日期(YYYY-MM-DD)</label><br>
<input id="post-date" type="text"
style="margin-top:4px;width:160px;padding:8px 10px;border-radius:8px;border:1px solid #d1d5db;">
</div>
<div style="margin-bottom:12px;">
<label>文件名中的 slug(可空,例如 my-first-post)</label><br>
<input id="post-slug" type="text"
style="margin-top:4px;width:100%;max-width:420px;padding:8px 10px;border-radius:8px;border:1px solid #d1d5db;">
<div style="font-size:12px;color:#6b7280;margin-top:2px;">
最终文件名会是:<code>YYYY-MM-DD-slug.md</code>,不写就自动用时间戳。
</div>
</div>
<div style="margin-bottom:12px;">
<label>标签(tags,用英文逗号分隔,可选)</label><br>
<input id="post-tags" type="text"
placeholder="gamma-ray, metasurface"
style="margin-top:4px;width:100%;max-width:420px;padding:8px 10px;border-radius:8px;border:1px solid #d1d5db;">
</div>
<div style="margin-bottom:12px;">
<label>正文内容(支持 Markdown)</label><br>
<textarea id="post-body" rows="18"
style="margin-top:4px;width:100%;max-width:100%;padding:10px 12px;border-radius:10px;border:1px solid #d1d5db;font-family:monospace,Consolas,Menlo;"></textarea>
</div>
<button type="submit"
style="padding:10px 24px;border-radius:999px;border:none;background:#16a34a;color:#fff;font-size:15px;font-weight:600;cursor:pointer;">
🚀 发布到 GitHub
</button>
<span id="post-status" style="margin-left:10px;font-size:14px;color:#6b7280;"></span>
</form>
</div>
<script>
// ===== 基本配置 =====
const OWNER = "huanyuheng";
const REPO = "huanyuheng.github.io";
const BRANCH = "main"; // 如果以后不是 main,可以改这里
const TOKEN_KEY = "blog_admin_token";
function getToken() {
return localStorage.getItem(TOKEN_KEY) || "";
}
function setToken(token) {
localStorage.setItem(TOKEN_KEY, token);
}
// 初始化:如果本地已有 token,给个提示
const tokenInput = document.getElementById("token-input");
const tokenStatus = document.getElementById("token-status");
if (getToken()) {
tokenStatus.textContent = "已在本机保存 Token";
}
document.getElementById("save-token").onclick = function () {
const t = tokenInput.value.trim();
if (!t) {
alert("请先粘贴 GitHub Token");
return;
}
setToken(t);
tokenStatus.style.color = "#16a34a";
tokenStatus.textContent = "Token 已保存(仅本机浏览器)";
tokenInput.value = "";
};
// 默认日期:今天
const dateInput = document.getElementById("post-date");
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, "0");
const dd = String(today.getDate()).padStart(2, "0");
dateInput.value = `${yyyy}-${mm}-${dd}`;
// 表单提交:调用 GitHub API 创建 _posts 里的文件
document.getElementById("post-form").addEventListener("submit", async function (e) {
e.preventDefault();
const token = getToken();
if (!token) {
alert("请先在上面保存 GitHub Token。");
return;
}
const title = document.getElementById("post-title").value.trim();
const date = document.getElementById("post-date").value.trim();
let slug = document.getElementById("post-slug").value.trim();
const tagsStr = document.getElementById("post-tags").value.trim();
const body = document.getElementById("post-body").value;
if (!title || !date || !body) {
alert("标题 / 日期 / 正文是必填的。");
return;
}
// 生成 slug
if (!slug) {
slug = "post-" + Date.now();
}
const filename = `${date}-${slug}.md`;
const path = `_posts/${filename}`;
// tags: 用逗号分隔
let tagsYaml = "";
if (tagsStr) {
const arr = tagsStr.split(",").map(s => s.trim()).filter(Boolean);
if (arr.length > 0) {
tagsYaml = "tags: [" + arr.join(", ") + "]\n";
}
}
// 生成 Jekyll front-matter
const now = new Date();
const hh = String(now.getHours()).padStart(2, "0");
const mi = String(now.getMinutes()).padStart(2, "0");
const ss = String(now.getSeconds()).padStart(2, "0");
const dateTime = `${date} ${hh}:${mi}:${ss} +0800`;
const frontMatter =
`---
layout: post
title: ${JSON.stringify(title).slice(1,-1)}
date: ${dateTime}
${tagsYaml}---
`;
const fullContent = frontMatter + "\n" + body + "\n";
const b64 = btoa(unescape(encodeURIComponent(fullContent)));
const statusSpan = document.getElementById("post-status");
statusSpan.style.color = "#6b7280";
statusSpan.textContent = "正在提交到 GitHub…";
try {
const res = await fetch(`https://api.github.com/repos/${OWNER}/${REPO}/contents/${encodeURIComponent(path)}`, {
method: "PUT",
headers: {
"Authorization": "token " + token,
"Accept": "application/vnd.github+json"
},
body: JSON.stringify({
message: `Add post ${filename}`,
content: b64,
branch: BRANCH
})
});
const data = await res.json();
if (res.status === 201 || res.status === 200) {
statusSpan.style.color = "#16a34a";
statusSpan.textContent = "发布成功!GitHub Pages 正在重新构建。";
console.log("GitHub 返回:", data);
} else {
console.error("GitHub error:", data);
statusSpan.style.color = "#dc2626";
statusSpan.textContent = "提交失败,打开控制台查看错误信息。";
alert("提交失败:" + (data.message || res.status));
}
} catch (err) {
console.error(err);
statusSpan.style.color = "#dc2626";
statusSpan.textContent = "网络或其它错误。";
alert("网络或其它错误,请稍后再试。");
}
});
</script>
说明:
- Token 用
localStorage存在你自己的浏览器里,不会写进仓库;- 页面会直接调用 GitHub API,把文章作为新文件推到
_posts/;- 文件名自动按
YYYY-MM-DD-slug.md格式生成,Jekyll 能正常识别。
第 2 步:GitHub Pages 自动构建
你一保存 admin.html 之后,GitHub 会自动构建。
构建成功后访问:
https://huanyuheng.com/admin/
就能看到这个后台页面。
第一次使用:
- 把刚才生成的 GitHub Token 粘贴到最上面的输入框 → 点「保存 Token」
- 填标题 / 日期 / slug / tags / 正文 → 点「发布到 GitHub」
- 等几十秒,博客首页就会出现新文章。
使用注意(安全相关)
- 这个后台只给你自己用,网址不要乱发;
- Token 有仓库写权限,不要在公共电脑、网吧等地方保存 Token;
- 如果哪天 Token 泄露或电脑换了,去 GitHub 把这个 Token revoke 掉,再重新生成一个新的。
如果你愿意,下一步我还能帮你:
- 做一个「文章列表」+「编辑已有文章」功能;
- 让后台的 UI 和现在的博客风格更统一(复用你的卡片样式);
- 把这个过程再写一篇详细教程文章发到你的博客里 😄。