> ## Documentation Index
> Fetch the complete documentation index at: https://dev.marginnote.com.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 最小打包

> 场景模板的包结构与最小配置

<Warning>
  本文由 AI 撰写，暂未经过人工校对，请谨慎参考。
</Warning>

`场景模板` 决定场景界面上模态的划分、工具行的摆放、菜单的条目与浮球的位置。把插件写好之后，还需要一份模板，界面才会出现对应的入口。本文先说明模板包的文件构成，再给出一份装得进去的最小模板。

# 模板包的结构

一个模板包是一个扩展名为 `.mntemplate` 的压缩文件，解开之后是下面这样：

<Tree>
  <Tree.Folder name="起步-0.1.0.mntemplate" defaultOpen>
    <Tree.File name="template.json" />

    <Tree.File name="manifest.json" />

    <Tree.File name="localizations.json" />

    <Tree.Folder name="plugins" defaultOpen>
      <Tree.Folder name="mn.hello" defaultOpen>
        <Tree.File name="mnaddon.json" />

        <Tree.File name="index.html" />

        <Tree.File name="hello.png" />
      </Tree.Folder>
    </Tree.Folder>
  </Tree.Folder>
</Tree>

各文件的分工如下。

* `template.json`：模板配置。界面元素的摆放、偏好的预设值、AI 任务的声明，都写在这份文件里。本文余下部分讲的全是这份文件。
* `manifest.json`：包目录。记录包的目标应用、包含的插件清单与所需的最低宿主版本。
* `localizations.json`：模板名称的多语言取值。
* `plugins/<插件id>/`：模板用到的插件，按插件 id 分目录，原样放进包内。

其中 `template.json` 与 `manifest.json` 是 MN 识别模板所必需的。插件是模板的一部分，界面的按钮与菜单项依赖插件，面板同样依赖插件，因此模板与插件一起分发。

# 最小模板

`template.json` 里只有 `id` 与 `name` 是必填字段：

```json template.json theme={null}
{
  "id": "u-hello",
  "name": "你好世界"
}
```

`manifest.json` 由出包脚本生成，字段含义如下：

```json manifest.json theme={null}
{
  "format": 1,
  "app": "MarginNote",
  "appVersion": "4.5.0",
  "exportedAt": 1700000000,
  "template": {
    "id": "u-hello",
    "name": "你好世界"
  },
  "plugins": [
    {
      "pluginID": "mn.hello",
      "folder": "mn.hello",
      "version": "0.1.0",
      "title": "你好世界"
    }
  ]
}
```

* `format`：包格式的版本号。
* `app` 与 `appVersion`：目标应用与所需的最低宿主版本。
* `template`：模板的 `id` 与 `name`，需与 `template.json` 一致。
* `plugins`：包内插件的清单。`pluginID` 与 `folder` 取插件的 `addonid`，`version` 与 `title` 取 `mnaddon.json` 中的同名字段。

`localizations.json` 按界面语言给出模板名称：

```json localizations.json theme={null}
{
  "zh-Hans": {
    "你好世界": "你好世界"
  },
  "en": {
    "你好世界": "Hello World"
  }
}
```

<Note>
  模板界面上的文字（例如模态名称、笔与摘录工具的名称）按界面语言取值。取不到对应语言时回落到英文。
</Note>

# 打包与导入

把上例中的文件按目录结构放进一个文件夹，压缩为 zip，再把扩展名改成 `.mntemplate`，便得到一个模板包。

导入步骤：点击设置右侧三个点，选择插件，导入。导入之后模板出现在场景模板菜单的 `我的场景模板` 一组里。带插件的包会一并安装插件，安装前逐个列出处理方式：本机没有的新安装，包内版本更新的替换本机的，同版本或本机更新的跳过。

<Note>
  未认证的插件需要在设置里允许之后才能安装。插件装不上时，模板虽然导入了也无法使用。
</Note>

# 名册语义

模板的每一个位置都是名册：写了就以写的为准，留空表示不接管，即宿主保持现状。

这一条决定了模板的写法。留空表示宿主保持现状，不表示清空。想让某一行比默认更少，必须把要保留的显式列出来。

因此不要先抄一份别人的模板再改。抄写会把对方的语义整包继承下来，而且看不出来。仓库里的起步模板曾经从一份复习模板整份复制，于是其中一直带着复习模板用的标签前缀、一颗摘题按钮，以及一条要求插件写入特定字段的复习规则；而起步插件一个字段都不写，那条规则永远匹配不上。

每一篇后续文章都会重申这条规则，因为它决定了所有字段的读法。

<Warning>
  模板里的字段名或代号写错时，宿主不会报错，而是静默忽略该条目。表现为那颗按钮没有出现。排查办法见[校验与排错](/zh/template-validate)。
</Warning>

# 身份字段

除 `id` 与 `name` 之外，`template.json` 顶层还有几个字段控制模板本身：

| 字段 | 类型 | 说明 |
| - | - | - |
| `id` | `String` | 模板的唯一标识。 |
| `name` | `String` | 模板在界面上的名称。 |
| `schema` | `Int?` | 配置格式的版本号。留空表示不接管。 |
| `minAppVersion` | `String?` | 所需的最低 MarginNote 版本。留空表示不挑宿主。 |
| `base` | `String?` | 这份模板分叉自哪一份内置模板。由用户在编辑器中复制产生，手写时无需填写。 |

`schema` 与 `minAppVersion` 配合构成两道闸：`schema` 是粗闸，只在配置格式整体换代时才动；`minAppVersion` 是细闸，模板用到某一版之后才有的宿主能力时声明它，导入时挡下。文件导入同样会检查，不限于从模板库安装。

# 样例与模板库

模板可以附带一份样例，让拿到模板的人打开即见效果。相关字段如下：

| 字段 | 类型 | 说明 |
| - | - | - |
| `sample` | `Sample?` | 随模板分发的样例。 |
| `gallery` | `GallerySource?` | 该模板来自模板库的记录。 |

`Sample` 的字段：

| 字段 | 类型 | 说明 |
| - | - | - |
| `title` | `String` | 样例的标题。 |
| `summary` | `String?` | 样例的简介。 |
| `file` | `String` | 样例学习集文件的位置。 |
| `topicIds` | `[String]?` | 样例包含的学习集标识。 |
| `sizeBytes` | `Int?` | 样例文件的字节数。 |
| `language` | `String?` | 样例内容的语言。 |

`GallerySource` 的字段：

| 字段 | 类型 | 说明 |
| - | - | - |
| `id` | `String` | 模板库中的标识。 |
| `version` | `String` | 模板库中的版本号。 |

<Warning>
  样例中的全部卡片与文档会随模板分发，拿到模板的人都能读到。添加样例之前需要确认内容可以公开。
</Warning>

# 递进的四级样本

仓库的 `sdk/output/tools/starter/template/` 目录下有四份模板，每份只比上一份多一个概念。级与级之间的差异即为课程：

| 文件 | 新增内容 | 对应文章 |
| - | - | - |
| `0-minimal.json` | 无。只有 `id` 与 `name`。 | 本文 |
| `1-bottom.json` | `bottom`，接管底部工具条 | [工具与模式](/zh/template-bottom) |
| `2-plugin.json` | `plugins`、`pluginConfigs`、`addon.` 代号 | [接入插件](/zh/template-plugins) |
| `3-full.json` | `aiTasks`，声明 AI 任务 | [AI 任务](/zh/template-ai) |

装上 `0-minimal.json` 之后，界面看起来与默认状态一致。这属于正常现象，因为这份模板没有接管任何位置。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.