内容多语言

1CMS 内容多语言插件,支持自定义语言、语言前缀路由、栏目与文章多语言内容维护
标识contenti18n
版本号1.1
文件大小1.5MB
发布时间2026-04-25
作者 爱之易
获取
¥199.00
请在您的网站后台-应用商店内购买此应用.

内容多语言

contenti18n 是 1CMS 的真实内容多语言插件,用来维护文章、栏目和前台静态词条的多语言版本,而不是浏览器js整页翻译方案,整页翻译方案可以看这个插件:https://1cms.com/app/AIi18n/

必看的

  • 完美支持大量多语言,自带Edge翻译接口,可免费无限翻译。企业外贸站利器!
  • 支持扩展定制其他翻译平台接口。
  • 默认使用task任务自动触发,建议改为接口触发。否则翻译过程中页面会变卡顿。
  • 如有问题或者想看演示的话:官方群找爱之易或群主

插件优势

  • 真内容多语言:译文是可维护、可复用的业务数据,不是前端临时机翻。
  • 后台闭环:语言管理、翻译范围、工作台、批量任务、词条管理一套打通。
  • 低学习成本:运营可以通过筛选、状态矩阵、行内保存快速完成日常工作。
  • 前后端统一:模板用 T(),JS 用词条包,前台与后台语义一致。
  • 机器翻译可选:支持多种 provider,既能快速起量,也能结合人工精修提质。

适用场景

  • 文章内容需要多语言显示
  • 栏目名称、栏目变量需要多语言维护
  • 前台模板里的固定文案需要统一管理
  • 前台 JS 需要读取多语言词条
  • 需要通过工作台集中查看翻译状态

后台入口

  • 内容多语言 -> 语言管理
  • 内容多语言 -> 翻译范围
  • 内容多语言 -> 翻译工作台
  • 内容多语言 -> 批量任务
  • 内容多语言 -> 词条管理

文章列表、文章编辑页、栏目列表页里也会提供多语言入口,点击后可直接进入高级精修页或工作台。

快速开始

  1. 在后台应用管理中安装并启用 内容多语言。
  2. 进入 内容多语言 -> 语言管理,确认当前站点源文语言相关配置。
  3. 启用需要开放的目标语言。
  4. 进入 内容多语言 -> 翻译范围,勾选允许翻译的文章字段、栏目字段和栏目变量。
  5. 进入 内容多语言 -> 翻译工作台,按模型、类型、语言和状态筛选内容。
  6. 点击语言状态或“高级精修”,进入单篇翻译页保存译文。
  7. 如需前台静态文案,进入 内容多语言 -> 词条管理 维护词条。

5 分钟上手检查清单

按下面顺序做,通常 5 分钟内就能看到前台多语言效果:

  1. 先在语言管理里启用一个目标语言(例如 en)。
  2. 在翻译范围里至少勾选一个文章字段(例如 title)。
  3. 到翻译工作台筛选该语言,进入高级精修保存一条译文。
  4. 前台切到目标语言,验证页面已显示对应译文。
  5. 在模板里加一条 T('demo.hello','你好'),验证词条链路可用。

机器翻译适配器

当前内置支持以下适配器(应用设置 -> 机器翻译 Provider):

  • edge_experimental:Edge 免 API(实验)
  • google_experimental:Google Cloud Translation(官方 API)
  • nllb_local:本地 NLLB(CTranslate2)

Edge 适配器的优势

Edge 适配器在很多项目里是“最快起步”的选择:

  • 免 API Key:开发和演示阶段开箱可用,接入成本低。
  • 配置简单:只需在应用设置里切换 provider,无需额外凭据管理。
  • 语言别名兼容:内置常见语言别名映射,减少 code 差异造成的失败。
  • 适合做初稿:可快速产出机器草稿,再在高级精修页人工校对。

说明:Edge 属于实验 provider,稳定性会受网络环境影响。生产场景建议准备 Google 或本地 NLLB 作为补充方案。

其它适配器怎么选

  • Google Cloud:适合有正式 API 配额、需要稳定 SLA 的线上环境。
  • 本地 NLLB:适合内网或数据不便出网场景,支持本地化部署与自主可控。

可扩展更多适配器

插件已预留 provider 扩展机制,可以继续接更多平台(如 DeepL、OpenAI 兼容网关、企业内部翻译服务):

  1. 新建 machine.provider.xxx.php,并继承 contenti18n_machine_provider_base。
  2. 实现 key()/title()/translate(),按目标平台做 languageCode 映射。
  3. 在 contenti18n.machine.php 的 machineProviderClassMap() 注册新 provider。
  4. 在应用设置中补充需要的配置项(如 endpoint、api_key、超时、代理)。

批量任务与推进方式

内容多语言的批量任务现在统一复用 app/task 的执行链路,contenti18n 自己的页面只负责创建任务和查看状态,不再由页面停留或按钮点击去推进任务。

1. 创建任务

  • 在“翻译工作台”里按当前筛选条件发起批量机器翻译、批量重译或批量改状态
  • 在“批量任务”页里按模式、目标语言创建全站翻译任务

2. 查看状态

  • 翻译工作台会显示最近任务面板,轮询 jobProgress 展示进度、日志和成功/失败数
  • 批量任务页会轮询活跃任务的最新状态
  • 这两个页面都只读,不负责执行任务

3. 真正执行任务

批量任务的实际推进完全交给 task 应用:

  • 如果 task 配置为“自动触发”,则由 task 自己在站点访问时调度执行
  • 如果 task 配置为“接口触发”,则需要定时器、脚本或外部请求持续调用 task 接口地址

4. 接口触发教程(按 1CMS task 官方用法)

接口触发是 task 官方推荐的稳定触发方式:通过定时脚本持续请求 task 接口,及时性更高,也不会拖慢前台页面访问。

使用步骤:

  1. 进入 task 应用设置,把触发方式切换为“接口触发”。
  2. 在 task 应用设置中复制“接口网址”(接口前缀)。
  3. 按运行环境选择官方脚本:
    • Windows 本地测试:使用 app/task/task_curl.bat
    • Linux 服务端:使用 app/task/task_curl.sh
    • 宝塔计划任务:使用 app/task/task_bt.sh
  4. 将脚本内的接口网址改成你在 task 设置里复制的地址后启动脚本,让它持续触发任务。

前台模板用法

推荐直接使用全局 helper:

{T('sidebar.hot_articles','推荐文章')}

说明:

  • 第一个参数是词条 Key
  • 第二个参数是当前语言没有译文时的兜底文案
  • 如果你已经在词条管理里维护过该 Key,前台会自动按当前语言输出对应译文

模板调用示例

<div class="title">{T('sidebar.hot_articles','推荐文章')}</div>
<span>{T('nav.current_position','当前位置')}:</span>

前台切换器自定义

如果你不想使用系统内置的右下角语言切换器,而是希望自己控制布局、样式和插入位置,推荐按下面方式接入。

1. 先关闭内置切换器

进入:内容多语言 -> 语言管理,把“前台切换器”关闭。

这样插件就不会再自动往 </body> 前输出默认切换器 HTML。

2. 在模板里读取切换器数据

插件已经提供了前台语言列表数据 helper:

  • C('contenti18n:langs'):返回当前页面可切换的语言数组
  • C('contenti18n:url','en'):返回当前页面在指定语言下的 URL

C('contenti18n:langs') 返回的每一项包含:

  • code:语言代码,例如 zh-cnen
  • name:语言名称,例如 简体中文English
  • prefix:URL 前缀,例如 enjp
  • current:当前语言时为 1,否则为 0
  • url:当前页面切到该语言后的链接

3. 自己写模板和样式

下面是一个最直接的自定义示例:

<style>
.site-lang-nav{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.site-lang-nav a{display:inline-flex;align-items:center;justify-content:center;min-width:88px;padding:8px 14px;border:1px solid #d9dfe7;border-radius:999px;color:#4a5560;text-decoration:none;background:#fff;transition:.2s}
.site-lang-nav a:hover{border-color:#1e9fff;color:#1e9fff}
.site-lang-nav a.is-current{background:#1e9fff;border-color:#1e9fff;color:#fff}
</style>
{php}
$langs=C('contenti18n:langs');
{/php}
{if count($langs)}
<div class="site-lang-nav">
    {loop $langs as $item}
    <a href="{$item.url}" class="{if $item.current}is-current{/if}"> <i data-icon="{$item.icon}"></i> {$item.name}</a>
    {/loop}
</div>
{/if}

这段代码的特点是:

  • 样式和结构完全由你自己控制
  • 可以放在页头、导航条、页脚、侧边栏等任何位置
  • 高亮状态直接用 current 判断
  • 链接不需要自己拼,直接使用 url
  • 需要icon的话,需要配合iconify插件,安装后 <i data-icon="{$item.icon}"></i> 这种写法,直接生效

4. 只取单个语言链接

如果你只想单独输出某一个语言入口,也可以直接这样写:

{php}
$en_url=C('contenti18n:url','en');
$jp_url=C('contenti18n:url','jp');
{/php}
<a href="{$en_url}">English</a>
<a href="{$jp_url}">日本語</a>

适合放在页头工具栏、移动端菜单或你自己的下拉框组件里。

5. 建议

  • 自定义切换器时,优先使用 contenti18n:langs 返回的数据,不要自己手工拼语言前缀
  • 如果站点启用了“默认语言不带前缀”,url 会自动处理默认语言和非默认语言的链接差异
  • 如果你的模板已经有自己的导航体系,建议把语言切换器并进现有导航,不要再保留系统内置浮动按钮

前台 JS 用法

如果前台 JS 需要多语言词条,可以先在模板里输出一组词条:

<script>
window.CONTENT_SNIPPETS={contenti18n:pack('common','search','dialog')};
</script>

然后在 JS 里按 Key 读取:

JS 中的读取示例

(function (win) {
    var i18n = win.CONTENT_SNIPPETS || {};
    var t = function (key, fallback) {
        return typeof i18n[key] !== "undefined" && i18n[key] !== "" ? i18n[key] : fallback || key;
    };

    function showEmpty() {
        layer.msg(t("search.empty", "暂无搜索结果"));
    }

    function confirmDelete(title) {
        layer.confirm(t("dialog.delete_confirm", "确定删除“{0}”吗?", [title]));
    }

    win.searchPage = {
        showEmpty: showEmpty,
        confirmDelete: confirmDelete,
    };
})(window);

说明:

  • contenti18n:pack(...) 会按分组输出 JSON
  • 只有在词条管理里开启“允许 JS 输出”的词条,才会进入这个包
  • 建议按业务分组管理词条,例如 commonsearchdialog

词条管理建议

  • Key 建议带业务前缀,例如 sidebar.hot_articles
  • 分组建议按模板块或 JS 模块划分,例如 sidebar
  • 词条的“文案”字段是默认语言源文
  • 需要给前台 JS 使用的词条,开启“允许 JS 输出”

使用说明

  • 源语言内容仍然保存在原始文章表和栏目表中
  • 译文通过高级精修页单独维护
  • 工作台和批量任务页适合批量查看状态、创建任务和集中跳转,任务推进统一由 task 应用负责
  • 机器翻译适合初稿生成,建议校对后再发布