
Wekan 批量修改全部用户语言设置基于 mongosh 的 profile.language 实战指南【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan导读本文以 Wekan 官方文档 Change-Language.md 为核心讲解如何用 MongoDB Shellmongosh一次性修改所有用户的语言偏好profile.language例如将英文日期格式统一切换为DD/MM/YYen-GB。文中会结合仓库源码剖析语言字段的存储结构、客户端语言解析逻辑与 e2e 测试证据帮助你理解改数据库与界面语言生效之间的完整链路并掌握批量语言迁移的落地操作。背景Wekan 用户语言存在哪里Wekan基于 Meteor 的开源看板把每个用户的语言偏好存放在 MongoDBusers集合的profile.language字段中。这个字段在用户模型中有着明确的 schema 定义见 models/users.jsprofile.language: { /** * language of the user */ type: String, optional: true, },在代码层面几乎所有需要读取用户语言的逻辑都经由Users.getLanguage()获取它做了兜底回退见 models/users.jsgetLanguage() { const profile this.profile || {}; return profile.language || en; },也就是说未设置语言或写入非法语言代码的用户最终都会回退到英文en。这也是批量修改语言前需要理解的第一条规则——直接写库不会报错但写入的语言代码必须能被 TAPi18nMeteor 的 i18n 包识别否则界面不会按预期切换。官方方案用 mongosh 批量修改所有用户语言原文档给出的核心场景是管理员希望强制所有用户包括新注册、尚未设置语言或语言偏好不正确的用户统一使用某一种语言。做法是绕过 Web 界面直接用 MongoDB Shell 对users集合执行一次updateMany。准备 mongoshWekan 的 Snap 版本自带私有 MongoDB 实例监听在本地127.0.0.1:27019注意不是默认的 27017。执行批量更新前需要先安装mongoshMongoDB Shell——它不再随 MongoDB 服务端捆绑需单独从 MongoDB 官方下载页获取命令行二进制。提示Wekan 其他部署形态如 Docker、源码运行的数据库地址、端口以实际环境的MONGO_URL配置为准本文命令基于 Snap 候选版的默认端口 27019。创建 language.sh 脚本将下面的内容保存为language.sh完整继承自 Change-Language.mdmongosh --quiet \ --host 127.0.0.1 \ --port 27019 \ --eval use wekan \ --eval db.users.updateMany({}, { $set: {profile.language: en-GB }});逐条参数解读参数作用--quiet抑制启动横幅与多余提示只输出命令结果--host 127.0.0.1连接本机 MongoDB--port 27019Snap 版 Wekan 的私有 MongoDB 端口--eval use wekan切换到wekan数据库--eval db.users.updateMany({}, {...})对users集合全量更新{}为匹配所有文档$set将profile.language写为en-GB示例中将语言设置为en-GB英式英语官方文档特别说明这是为了把英文日期格式切换为DD/MM/YY。赋予执行权限并运行chmod x language.sh然后执行$ ./language.sh { acknowledged: true, insertedId: null, matchedCount: 20, modifiedCount: 5, upsertedCount: 0 }读懂返回结果上面是文档中一个真实运行场景的返回当时共 20 个用户其中 5 个新用户的语言尚未正确设置。MongoDB 返回的UpdateResult各项含义如下acknowledged: true写入已被数据库确认matchedCount: 20匹配到了 20 个文档全部用户modifiedCount: 5实际发生修改的只有 5 个——其余 15 个用户的profile.language本来就已经是en-GB或已是同一值$set写入相同值时 MongoDB 不会重复写入upsertedCount: 0updateMany不执行 upsert因此恒为 0insertedId: null非插入操作故为null。理解modifiedCount的含义很重要它统计的是值真正被改变的文档数而不是被扫描到的文档数。因此第二次运行同样的脚本modifiedCount会变成 0这是幂等更新idempotent的正常表现可用于反复修复语言配置而不产生副作用。语言如何影响日期格式从 en-GB 说起为什么文档要把语言设置为en-GB而不是en因为 Wekan 中日期格式既受profile.dateFormat显式控制也会跟随语言区域变化。用户模型里日期格式的默认值定义在 models/users.jsgetDateFormat() { const profile this.profile || {}; return profile.dateFormat || YYYY-MM-DD; },即默认日期格式为YYYY-MM-DD但不同的语言/区域设置以及可选的profile.dateFormat、profile.calendarSystem字段会共同决定界面中日期的呈现。e2e 测试 44-calendar-date-display.e2e.js 正是通过组合写入profile.language、profile.calendarSystem、profile.dateFormat来验证日历与日期展示行为——例如测试中分别将语言设为en、ar阿拉伯语同时验证 RTL 日期布局与lv拉脱维亚语逐一断言日期显示是否符合预期。这说明改语言与日期格式变化在 Wekan 中是强关联的一组配置。语言字段的服务端校验链路在 Web 界面内切换语言时走的是Users.setLanguage()方法见 server/models/users.jsasync setLanguage(language) { check(language, String); if (!this.userId) throw new Meteor.Error(not-logged-in, User must be logged in); const TAPi18n getTAPi18n(); if (!TAPi18n.isLanguageSupported(language)) { throw new Meteor.Error(invalid-language, Language is not supported); } await Users.updateAsync(this.userId, { $set: { profile.language: language } }); },注意这条校验链路服务端会先用TAPi18n.isLanguageSupported(language)校验语言代码是否受支持不支持的代码会直接抛出invalid-language错误。而本文的 mongosh 方案是直接写库绕过了这层校验——所以批量执行前务必确认目标语言代码与imports/i18n/data/目录下的语言文件名一致例如en-GB、zh-CN、ja等否则用户界面会回退到getLanguage()的默认值en。此外还有一条隐性的语言传播规则当有用户被邀请加入看板时如果邀请者已设置语言新用户会继承邀请者的profile.language相关逻辑见 server/models/users.js。这解释了为什么新用户语言没设对是一种常见的初始状态也说明批量脚本可以作为团队 onboarding 后的统一修正手段。客户端如何决定界面语言浏览器设置文档中提到的 Language browser settings对应 Wekan issue #4518 的讨论指向客户端语言解析逻辑。仓库实现位于 client/lib/i18n.js其优先级顺序为当前登录用户的profile.language最优先持久化的用户偏好navigator.languages[0]浏览器首选语言列表第一项navigator.language浏览器语言navigator.userLanguageIE 等旧浏览器的语言属性。选出的候选语言会做逐步剥离子标签的降级匹配例如zh-Hans-CN→zh-Hans→zh-Hans命中即停zh-Hant-TW→zh-Hant裸的zh会经别名映射到zh-Hans同时TAPi18n.isLanguageSupported不区分大小写因此zh-hant、JA-JP等写法也能命中。再配合 client/components/boards/boardsList.js当用户访问看板列表页时客户端会读取当前用户的profile.language并调用TAPi18n.setLanguage(userLanguage)应用界面语言。由此可以总结出完整生效链路mongosh updateMany写库 → users.profile.language 更新 → 用户刷新/重新登录后客户端读取 profile → TAPi18n.setLanguage(language) 应用语言包 → 界面文案与日期格式按新语言渲染需要特别指出直接改数据库不会让已登录用户立刻看到变化。客户端在启动时读取语言client/lib/i18n.js 中的Meteor.startupTracker.autorun逻辑因此批量修改后用户需要刷新页面或重新登录才能让新语言生效。语言代码来源与翻译维护Wekan 的界面翻译以 imports/i18n/data/en.i18n.json 为英文源文件其中包含language: Language、date-format: Date Format等关键条目其他语言通过 Transifex 平台协作翻译。批量脚本中使用的语言代码必须与这些语言文件对应完整的翻译工作流新语言接入、新文案同步、发布前拉取见 docs/Features/Translations/Translations.md。在 e2e 测试中也能看到同样的直接写库手法如 18-rtl-layout.e2e.js 通过db.updateOne(users, { _id: userId }, { $set: { profile.language: lang } })设置语言以验证从右到左布局19-accessibility.e2e.js 分别设置zh-CN与ja验证不同语言下的无障碍属性。这些测试证明了profile.language字段是驱动 Wekan 多语言与 RTL 布局的单一事实来源single source of truth。实战要点与注意事项汇总确认数据库连接参数Snap 版默认127.0.0.1:27019其他部署方式请以实际MONGO_URL为准切勿在未确认端口的情况下执行。语言代码必须合法直接写库绕过TAPi18n.isLanguageSupported校验写入不存在的语言代码会导致界面回退英文。幂等可重跑updateMany$set可安全重复执行modifiedCount为 0 即代表所有用户语言已一致。生效时机客户端在启动时读取语言用户需刷新页面或重新登录对长期在线的用户可考虑配合登录令牌失效机制。区分用户偏好与全局策略setLanguage每次只改单个用户而 mongosh 脚本是全局强制策略如果希望尊重用户个人选择应谨慎使用批量覆盖。结合其他 profile 字段如需同时统一日期格式或日历系统可在同一$set中追加profile.dateFormat、profile.calendarSystem字段参见 44-calendar-date-display.e2e.js 的用法。通过上述步骤管理员可以在几分钟内完成整个 Wekan 实例的语言统一无论是修正新用户的默认语言、强制切换日期格式还是为多语言团队做全局基线配置都能安全、可重复地落地。【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考