py2htmlblog 使用指南
从安装到写文章、构建、切换主题的完整流程。
1. 环境要求
- Python 3.7+
- (可选)PyQt5 — 用于 GUI 界面:
pip install PyQt5 - (可选)paramiko — 用于 SFTP 发布:
pip install paramiko
2. 初始化站点
python main.py init "我的博客" "https://example.com" "作者名"
这会在 data/ 下创建 info.json、category.json、links.json 三个配置文件,并在 templates/default/ 下复制默认模板。
3. 配置站点
编辑 data/info.json,设置站点基本信息:
{
"site_name": "我的博客",
"tagline": "记录生活与技术",
"description": "一个有趣的个人博客",
"site_url": "https://example.com",
"author": "作者名",
"language": "zh-CN",
"timezone": "Asia/Shanghai",
"template": "default",
"posts_per_page": 10,
"rss_count": 20,
"copyright": "Copyright 2026",
"nav_pages": [
{"title": "首页", "url": "index.html"},
{"title": "归档", "url": "archives.html"}
]
}
详细配置项见:data/info.json 字段说明
4. 管理分类
# 添加分类
python main.py add cat "日志" --slug log
python main.py add cat "技术" --slug tech
python main.py add cat "生活" --slug life
# 查看分类
python main.py list cats
# 删除分类(用 ID)
python main.py del cat 2
5. 写文章
方式一:命令行新建
python main.py new "我的第一篇文章" --cat log --tags "博客,Python"
然后输入文章正文(Markdown),输入 EOF 结束。
或者从文件导入正文:
python main.py new "文章标题" --cat tech --file article.md
方式二:mdblog 批量发布
把写好的 Markdown 文件放到 mdblog/ 目录,文件格式如下:
---
title: 文章标题
category: tech
tags: python,教程
datetime: 2026-07-22 17:30:00
slug: article-slug
---
正文内容(Markdown)...
然后运行:
python main.py publish
系统会自动分配 ID、生成 slug、保存到 data/post/ 并立即构建站点。
方式三:GUI 编辑器
python main.py gui
使用 PyQt 桌面编辑器,支持 Markdown 实时预览、分类管理、文章管理。
文章 frontmatter 完整字段
---
id: 1
title: 域名和空间
datetime: 2014-03-15 09:15:08
slug: yu-ming-he-kong-jian
category: log
tags: 域名, 空间
quotes: 几个域名和空间要到期
nearaid: 2
status: published
---
正文内容...
| 字段 | 必填 | 说明 |
|---|---|---|
id |
否 | 文章 ID(自动分配时不填) |
title |
是 | 文章标题 |
datetime |
否 | 发布时间,默认当前时间 |
slug |
否 | URL 别名,留空自动生成 |
category |
是 | 分类的 slug |
tags |
否 | 标签,逗号分隔 |
quotes |
否 | 引用/摘要 |
nearaid |
否 | 关联文章 ID |
status |
否 | published 或 draft |
6. 构建站点
python main.py build
构建过程:
站点: 我的博客
模板: default
文章: 10 篇
分类: 3 个
友链: 5 个
正在生成首页...
正在生成归档页...
正在生成分类页...
正在生成文章页...
正在生成月度归档页...
正在生成 RSS...
正在生成 sitemap.xml...
构建完成 → wwwroot/
生成的静态文件在 wwwroot/ 目录中,结构如下:
wwwroot/
├── index.html # 首页
├── index_2.html # 第 2 页(如果有多页)
├── archives.html # 归档/关于页
├── rss.xml # RSS 2.0 订阅
├── sitemap.xml # 搜索引擎站点地图
├── css/ # 样式表
├── js/ # 脚本
├── images/ # 图片
└── archives/ # 归档目录
├── cat_log.html # 分类页
├── cat_tech.html
├── 2014/03/entry_1.html # 文章页
├── 03-01-2014_03-31-2014.html # 月度归档
└── ...
7. 切换主题
在 data/info.json 中修改 template 字段:
{
"template": "inove"
}
支持的模板名:default、inove、boxed、clean、georgiablue、gettysburg、lovingrey、macstripe、matrixcode、modernlines、orangepurple、plainblue、plainjane、rusty、slashdotclassic、titaniumgold、tpthin、trendy
主题支持 ZIP 压缩包形式,详见 ZIP 模板说明。
8. 发布站点
py2htmlblog 内置三种发布方式,配置一次之后一键部署。
方式一:FTP 上传
适合虚拟主机(如 Bluehost、HostGator 等)。
在 data/info.json 中添加:
"deploy": {
"method": "ftp",
"ftp": {
"host": "ftp.example.com",
"port": 21,
"user": "username",
"password": "your-password",
"remote_dir": "/public_html/"
}
}
运行:
python main.py deploy
方式二:SFTP 上传
适合 VPS 或云服务器。
"deploy": {
"method": "sftp",
"sftp": {
"host": "123.45.67.89",
"port": 22,
"user": "root",
"key_file": "~/.ssh/id_rsa",
"remote_dir": "/var/www/html/"
}
}
支持密码和密钥两种认证方式。如果使用密钥,设置 key_file 即可,留空 password。
方式三:Git 推送
适合 GitHub Pages、Gitee Pages、Coding Pages 等。
"deploy": {
"method": "git",
"git": {
"remote": "origin",
"branch": "main",
"repo_dir": "D:/my-site-repo",
"commit_message": "Site update"
}
}
repo_dir 是你本地 Git 仓库的路径。发布时系统会:
- 清空仓库目录(保留 .git)
- 复制 wwwroot 文件进去
- 执行
git add -A && git commit && git push
模拟运行
不确定配置是否正确?先模拟运行看看会上传哪些文件:
python main.py deploy --dry-run
9. 其他命令
# 查看站点信息
python main.py info
# 修改站点信息
python main.py set site_name "新名称"
python main.py set posts_per_page 5
# 列出文章
python main.py list posts
# 管理友链
python main.py add link "GitHub" "https://github.com" --desc "代码托管"
python main.py del link 2
python main.py list links
# 删除文章
python main.py del post 5
附录
appendix-infojson
data/info.json 完整字段说明
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
site_name |
string | "My Blog" | 站点名称 |
tagline |
string | "" | 副标题/标语 |
description |
string | "" | 站点描述(meta & RSS) |
site_url |
string | "http://localhost" | 站点 URL |
author |
string | "" | 作者名 |
author_email |
string | "" | 作者邮箱 |
language |
string | "zh-CN" | 语言 |
timezone |
string | "Asia/Shanghai" | 时区 |
template |
string | "default" | 模板名 |
nextpostid |
int | 1 | 下一篇文章 ID |
postsperpage |
int | 10 | 首页每页文章数 |
rss_count |
int | 20 | RSS 条目数 |
copyright |
string | "" | 版权信息 |
comment_code |
string | "" | 评论系统 HTML 代码 |
footer_code |
string | "" | 页脚统计代码 |
nav_pages |
array | [] | 导航页面列表 |
appendix-zip-模板
ZIP 模板使用
模板可以打包为 ZIP 以节省空间。系统加载优先级:目录 > ZIP。
打包命令:
cd templates
zip -r boxed.zip boxed/
ZIP 内部结构:
boxed.zip
├── header.html
├── footer.html
├── index.html
├── entry.html
├── category.html
├── archives.html
├── month_archive.html
├── rss.xml
└── css/
└── style.css
ZIP 首次使用时自动解压到 .workbuddy/template_cache/,后续检测 ZIP 修改时间自动刷新缓存。
appendix-模板语法
模板引擎语法速查
| 语法 | 说明 | 示例 | ||
|---|---|---|---|---|
{{ var }} |
变量替换 | {{ site_name }} |
||
{{ obj.attr }} |
属性访问 | {{ p.title }} |
||
| `{{ var \ | filter }}` | 过滤器 | `{{ p.content_html\ | safe }}` |
{% for x in list %}...{% endfor %} |
循环 | 文章列表循环 | ||
{% if cond %}...{% endif %} |
条件 | 分页判断 | ||
{% include "file.html" %} |
引入子模板 | header/footer |
内置过滤器:safe(不转义 HTML)、escape、date:"%Y-%m-%d"、truncate:100、default:"值"、striptags、upper、lower、length
appendix-convert
ThingamaBlog 模板转换
使用 convertthingamatemplates.py 将 ThingamaBlog 原始模板转换为 py2htmlblog 格式:
python convert_thingama_templates.py
转换规则:
| ThingamaBlog | py2htmlblog | |
|---|---|---|
<$BlogTitle$> |
{{ site_name }} |
|
<$EntryTitle$> |
{{ p.title }} |
|
<$EntryBody$> |
`{{ p.content_html\ | safe }}` |
<$EntryPermalink$> |
{{ siteurl }}/{{ p.entryurl }} |
|
|
{% for p in page_posts %}...{% endfor %} |
|
|
{% for a in archives %}...{% endfor %} |
|
|
{% for c in categories %}...{% endfor %} |