从零创建第一个插件
这一页的目标很简单:让您从零创建一个能被系统识别、能在界面里启用、能在翻译结果里看到效果的插件。
为了让第一次体验更直观,这里不做“只打日志”的示例,而是做一个最小的普通翻译后处理插件:它会在译文末尾追加一个测试标记。
先确认适合的模式和步骤
这个示例选择:
- 步骤:
after_translate - 模式:
standard
原因很简单:
after_translate直接处理普通翻译结果- 改完后您能立刻在译文里看到标记
- 逻辑最短,也最容易验证
注意
after_translate 只适合普通翻译主链。高质量翻译和 AI 校对使用的是 ai_translate,不是 translate。
第一步:创建插件目录
在 Saber Translator 应用根目录下找到:
text
plugins/然后新建一个子目录,例如:
text
plugins/
my_first_plugin/第二步:创建 __init__.py
在 my_first_plugin/ 下创建 __init__.py:
python
from .plugin import MyFirstPlugin这一步的作用很直接:把您的插件类暴露给插件加载器。
第三步:创建 plugin.py
在同一目录下创建 plugin.py,填入下面这份最小可运行代码:
python
import copy
from src.plugins.base import PluginBase
class MyFirstPlugin(PluginBase):
plugin_id = "my_first_plugin"
display_name = "我的第一个插件"
plugin_version = "1.0.0"
plugin_author = "Your Name"
plugin_description = "在普通翻译结果末尾追加测试标记。"
default_enabled = False
supported_steps = ("translate",)
supported_modes = ("standard",)
priority = 100
failure_policy = "continue"
def after_translate(self, context, result):
updated = copy.deepcopy(result)
updated["translated_texts"] = [
f"{text}【插件测试】"
for text in updated.get("translated_texts", [])
]
return updated这段代码做了 3 件事:
- 把插件声明为一个
translate步骤插件 - 只让它在
standard模式下生效 - 在普通翻译结果后追加
【插件测试】
第四步:刷新插件列表
保存文件后:
- 打开 Saber Translator
- 进入翻译页
- 点击设置
- 打开插件管理
- 点击刷新插件
如果结构和代码没有问题,列表中应该能看到:
我的第一个插件
然后把它启用。
第五步:验证是否真的生效
验证方式推荐尽量简单:
- 选择一张图片
- 使用普通翻译模式
- 翻译完成后查看译文
如果插件生效,您应该能看到类似:
text
原本译文……【插件测试】这说明您的插件已经完成了:
- 被系统发现
- 成功加载
- 可以启用
- 正确命中
after_translate - 正确修改了翻译结果
如果没有效果,先检查什么
最常见的问题通常是下面这几类:
插件没有出现在列表里
优先检查:
- 目录名是否正确
- 是否同时存在
__init__.py和plugin.py __init__.py里导出的类名是否和plugin.py一致
插件出现在列表里,但启用后没效果
优先检查:
- 是否真的点击了启用
- 是否使用的是普通翻译模式
supported_steps是否写成了("translate",)supported_modes是否写成了("standard",)
插件报错
优先检查:
after_translate返回的是不是dict或None- 是否误改成了字符串、列表等其他类型
- 是否直接原地修改了不兼容的数据结构
为什么示例里要用 copy.deepcopy
推荐写法不是直接改原对象,而是先复制再改:
python
updated = copy.deepcopy(result)这样做的好处是:
- 更安全
- 更容易排查问题
- 不容易误伤同一批次里后续还要使用的数据
对于大多数插件,尤其是第一次写插件时,建议优先采用这种写法。
下一步怎么学
当您完成这个第一个插件后,建议马上继续看:
因为接下来真正会决定插件质量的,不是“会不会创建文件”,而是:
- 这个步骤到底会给您什么输入
- 您应该修改哪个字段
- 什么模式下才会触发这个 Hook
- 什么情况下应该用
continue,什么情况下应该用fail
如果您不想手写,也可以继续看:
