主题与插件
主题是一个 zip 包,在后台「外观 → 主题」里上传即切换。不需要构建,不需要编译,改模板点一下「重新加载」就生效。
一个主题长什么样
<主题名>/
├── theme.yaml # 元信息:name / label / version / author / license / requireLumo
├── settings.yaml # 设置项声明(可选),与站点设置同一套表单 Schema
├── templates/ # layouts/ 与 partials/
├── static/ # 静态资源,经 /theme-assets/<主题名>/ 访问
└── screenshot.png # 可选
theme.yaml 里的 license 字段如实填写,后台会把它展示给站长看:
license: MIT # 开源主题
license: AGPL-3.0-or-later # 想让衍生版也保持开源
license: LicenseRef-Proprietary # 闭源商业主题
上传时按 zip 安全解压规则处理(拒绝路径穿越、符号链接与超限条目),装到 data/themes/ 下。
必需模板只有四个
templates/index.html 首页
templates/post.html 文章页
templates/page.html 独立页面
templates/404.html 未找到
缺一个会整页回退到内置主题,而不是报错或渲染空白。 这是刻意的:半成品主题不该让站点露出破绽,而「这个页面我不会做」是主题作者最正常的处境。
另有十一个可选模板:分类、标签、归档、搜索、作者,以及登录、注册、找回密码、重置密码、账户页、我的收藏。同样逐个回退。
模板约定是 Hugo 那一套,但落在 html/template 上——Go 的模板系统没有继承,只有「定义块 + 调用块」,所以由页面模板调用骨架、骨架回调 main:
{{ template "layouts/base.html" . }}
{{ define "main" }}
...正文...
{{ end }}
模板能拿到什么
每个路由有固定的上下文:.Site、.Post、.Posts、.Pagination、.Theme.Settings、.Categories、.Tags 等。只读数据一律走 Finder 函数,模板里不加工 HTML:
{{ .Find.Posts.Recent 5 }}
{{ .Find.Categories.Tree }}
{{ .Find.Menus.Get "primary" }}
除了文章正文 .Post.Content,任何用户可控的值都直接输出,绝不 safeHTML。 正文之外的字段(标题、昵称、评论、菜单名)全部是纯文本,在模板里给它们套 HTML 就是把注入面交给访客。
还有两条硬要求:
- 不依赖任何 CDN。 字体与脚本都自托管,主题必须能离线跑。内置主题「墨」把思源宋体按需分包带在包里,就是这个意思。
- 关键表单用原生 POST。 登录、注册、找回密码、重置密码、账户页关掉 JavaScript 也必须可用。
主题设置
主题可以带一份 settings.yaml 声明自己的设置项,后台用与站点设置完全相同的表单引擎渲染——JSON Schema 子集加 x-widget,支持条件显隐、重复条目与拖动排序。站长学会一套界面就够了。
分组的名字是存储键,改一个名字等于把站长填过的值丢掉,所以只增不改。
内置主题「墨」
仓库自带的默认主题 ink 是每个主题的回退目标。启动时会从二进制里解压一份到 data/themes/ink,此后以磁盘那份为准:改模板即时生效,可以「重新加载」,可以点「恢复出厂」,但不能删除。
它同时也是主题作者最好的参考实现——照着它的模板结构写自己的主题是可以的,学习写法不是复制作品。
自由的边界
Lumo 本体是 AGPL-3.0,而 AGPL 的传染性会让「主题算不算衍生作品」说不清楚,没人敢拿它做商业产品。所以项目附带了插件与主题接口例外条款:
仅通过 Lumo 的插件接口或主题接口与 Lumo 交互的独立作品,不因该交互本身而被视为本程序的衍生作品。你可以以你选择的任何条款开发、分发和销售它,包括专有条款。
一句话:你写的主题归你,可以闭源,可以定价出售,不用分给作者一分钱。 这份例外不可撤销,已经发布的版本永远带着它。
三条红线:
- 不能复制或改编 Lumo 的源码。 例外保护的是「通过接口调用」,不是「把代码抄进来」。
- 不能基于内置主题「墨」二次开发后闭源出售。 它是 Lumo 的一部分,以 AGPL-3.0-or-later 授权,改它是衍生作品,必须同样以 AGPL 开源。想做闭源商业主题,请从零写。
- 不能用 Lumo 的名字和标识暗示官方出品。 命名规则是
Aurora for Lumo可以,Lumo Aurora不可以。
插件
插件是 zip 包加一份清单与设置声明,后台安装、启停。第一期是纯声明式的,不执行任何代码——没有钩子回调,没有沙箱,没有 WASM。
之所以先做这一期:声明式插件能覆盖「加一段统计脚本」「挂一个友链页」「注入自定义 meta」这类需求,而它的安全模型简单到可以一句话讲完。WASM 运行时会在后面几期接上,插件接口的形状已经按那个方向留好了。
主题市场
计划中的运作方式:
- 作者自主定价,平台按成交额抽成,比例在市场开放前公布
- 作者保留全部版权,上架不要求转让任何权利,也不要求独家
- 上架需要通过基础审核:包结构合规、不含恶意代码、不侵犯第三方权利
- 随时可以下架,已售出的授权不受影响
主题市场是这个项目唯一的盈利方式,它和「程序本体免费」是配套的:作者靠作品赚钱,作者不靠限制使用者赚钱。
付费主题需要防止随意复制,但这里有个必须说白的技术事实:Lumo 核心是 AGPL 的,任何人都能 fork 掉核心里的校验代码。 所以授权校验不会做成「核心校验、主题信任核心」的形态,那种设计只挡君子。实际方案是校验逻辑跟着付费主题自己走,核心只提供中立的能力接口,不判断某个主题是否合法。
因此免费主题和开源主题不会被任何授权机制拖累,核心里不会出现「检查你有没有买」这类代码。
有疑问
授权、市场、命名的问题直接发邮件到 xzji_studio@qq.com。技术问题走 GitHub Issue,参与 Lumo 本体开发见参与贡献。
评论
还没有评论,来说两句。