简介:该语言包专为 SuiteCRM 7.11.18 版本定制,适合已部署该开源 CRM 却受英文界面困扰的企业管理员、二次开发者和集成运维人员使用。通过替换核心语言文件,可将菜单、模块字段、系统提示和常用工作流界面切换为简体中文,有效降低日常操作与培训成本。压缩包共含152个文件,其中148个php文件支撑各模块的后端语言映射,2个tpl模板负责页面结构展示,1个js脚本处理前端动态提示与交互文案,1个html页面作为简短的返回辅助页。整体体积仅454KB,轻量易部署,不会增加明显的系统载入压力。自发布以来,已有1035人下载学习。实际部署后,除覆盖系统原生英文标签外,文件结构遵循 SuiteCRM 语言包规范,便于后续补充行业术语、修正个别翻译或移植至相近小版本,是一套值得收藏的基础汉化素材。
1. 为什么 SuiteCRM 7.11.18 中文语言包值得单独装:界面汉化、数据编码与升级是三条独立战线
SuiteCRM 开源CRM 圈子里有个老问题:官方安装包默认只有英文界面,7.11.18 也不例外。很多团队装完系统才意识到,菜单、字段、状态选项全得靠语言包来换,而不是改几个配置文件就能糊弄过去。这份 2020 年 11 月发布的 zh-CN core 包,把核心模块的界面字符串整体替换成简体中文,比逐模块手工翻译省事得多。它适合正在做 CRM 选型、想给业务团队直接上中文界面的实施者,也适合已经跑英文版、想平滑切换语言的运维人员。下面从 zip 里有什么开始,把安装、切换、验证、升级保护整个链路拆开讲,最后给一个能长期不翻车的维护习惯。
2. 安装前先拆包:版本核对、zip 结构与时序上的三个关键点
很多人下载语言包只看文件名,后缀带着 7.11.18 就以为万能。实际上语言包与核心版本强关联:7.11.x 的语言文件结构一致,但如果你拿 7.10 的包硬配 7.11.18,往往会缺一批新增键,界面出现「一半中文一半英文」的拼接效果。更麻烦的是,有人在不知道包内结构的情况下直接解压,把文件放到了错误的目录层级,结果自然是毫无变化。所以安装前花五分钟拆包、核对版本,是这套流程里性价比最高的动作。
2.1 先确认当前版本:sugar_version.php 与「关于」页兜底
判断版本有两个入口。界面入口是右上角头像里的「关于」弹窗,能直接看到当前核心版本号;命令行入口更直接,看根目录下的版本文件。我一般会这样查:
grep -n "sugar_version" /var/www/suitecrm/sugar_version.php输出类似$sugar_version = '7.11.18';,就说明当前核心是 7.11.18,和这份 zh-CN 包能对上。有些移仓部署的版本文件叫 version.php,同样 grep 一下也能出结果。这里的关键点是:语言包的版本号不一定非要和核心完全一致,但差异越大,缺失键越多,后期要补的翻译量就越大。7.12 或 8.x 改过一部分语言加载逻辑,老包硬塞进去通常不会崩,只是新功能区域的文案会回落成英文,显得界面很割裂。
2.2 用 unzip -l 判断解压方式,避免装错目录
下载回来的 zip 有两种常见内部结构:一种是根目录直接就是 include/、modules/ 这些目录,另一种是第一层套了一个项目文件夹,比如 SuiteCRM-7.11.18/include/。不拆开看就直接 unzip,很容易把文件解到套娃目录里,语言包根本没进 SuiteCRM 根部,后面所有操作都白做。
unzip -l SuiteCRM-7.11.18_SuiteCRM_core_zh-CN.zip | head -20如果输出第一列路径是include/language/zh_cn.lang.php、modules/Accounts/language/zh_cn.lang.php这类,说明解压后应该直接落在 SuiteCRM 根目录。如果第一层带文件夹名,就得先解压到临时目录,再把里面的内容整体移动过去。常见做法是这样:
unzip -o SuiteCRM-7.11.18_SuiteCRM_core_zh-CN.zip -d /var/www/suitecrm/ chown -R www-data:www-data /var/www/suitecrm/include/language chown -R www-data:www-data /var/www/suitecrm/modules-o表示覆盖已存在的同名文件,-d指定解压目标,避免在当前目录散开一地。后面的 chown 是把语言文件属主交给 Web 运行用户,否则后续「快速修复与重建」写缓存时会因为权限不足失败。注意,chown 不是可选项——很多「包解压了但界面毫无变化」的问题,根子就在这里。另外 zip 标题里的 core 分支是有含义的:它只包含 SuiteCRM 标准模块的翻译,第三方扩展和自定义模块不在覆盖范围内,这一点在验收时要提前有心理预期。
提示:如果 unzip 输出里出现
permission denied或skipping字样,先停下解决目录权限,再谈后面所有步骤。
2.3 拷完文件必须重建语言缓存:不重建等于白装
语言文件拷进去只完成了一半。SuiteCRM 启动时会把分散的语言文件解析、合并成缓存,之后界面读取的是缓存而不是原始 PHP 文件。你不重建,它就继续读旧缓存,界面自然还是英文。这一步很多人漏掉,或者走了「清浏览器缓存」的弯路,折腾半天毫无变化。
正确操作是登录管理员账户,进入「管理 → 修复(Repair)→ 快速修复与重建(Quick Repair and Rebuild)」,勾选与重建缓存相关的项后执行。整个过程会跑一遍语言合并、扩展重写和 JavaScript 打包,耗时几十秒到几分钟,取决于服务器配置。执行完再看界面,中文才会真正出现。顺带说明一个常见疑问:为什么不直接改 en_us.lang.php?因为那是系统回退兜底用的英文源文件,改了之后升级会被官方文件覆盖,而且 en_us 里残留中文也会污染英文用户的界面。语言包的正路永远是放独立语言文件,而不是动英文源。
3. 语言生效机制:语言文件、config 与用户偏好三层
理解「为什么我设了默认语言还是英文」之前,得先明白 SuiteCRM 的翻译到底存在哪、加载顺序是什么。这块清楚了,后面所有排错都是顺藤摸瓜,不会变成玄学。
3.1 翻译存在 PHP 数组文件里,不是数据库
SuiteCRM 7.x 的翻译机制是文件驱动:include/language/ 下的 zh_cn.lang.php 保存公共字符串,对应变量 $app_strings 和 $app_list_strings,负责按钮、菜单、通用标签和各类下拉选项;modules/Accounts/language/zh_cn.lang.php 这类路径保存各模块内字符串,对应变量 $mod_strings,负责模块的字段标签、列表标题等。语言包本质上就是一批待覆盖的 PHP 数组文件,而不是往数据库里插记录。
这个机制带来的直接推论是:安装语言包 = 覆盖文件 + 重建缓存,两步缺一不可。同时也解释了为什么第三方模块不会被 core 包覆盖——它不在包内的路径清单里。加载顺序上,核心语言文件先加载,模块语言文件后加载,最后是 custom/ 目录下的覆盖文件。custom 最晚加载,因此同样键名的翻译,最终以 custom 里的值为准。这一条在第 6 章会变成保命技巧,先记住结论:custom 是升级时唯一不会被官方文件替换的区域。
3.2 default_language 全局开关与用户级偏好
全局默认语言写在 config.php 里,键名是 default_language。常见做法是直接查配置确认当前值:
grep -n "default_language" /var/www/suitecrm/config.php如果没设,或者设的是 en_us,手动补上这一行:
// config.php $sugar_config['default_language'] = 'zh_CN';这里有个容易踩的细节:config 里写的是 locale 键 zh_CN,而语言文件名常见的有 zh_cn.lang.php 和 zh_CN.lang.php 两种命名,Linux 服务器上这两种名字是不同文件。判断标准不是文件名长得对不对,而是「管理 → 本地化」页面里能不能列出简体中文。能列出,说明文件被成功加载;列不出,优先查文件名大小写和缓存是否重建,而不是反复改 config 里的值碰运气。
用户级别的偏好在「用户 → 高级 → 区域设置 → 语言」里设置,它的优先级高于全局 default_language。也就是说,就算你把全局默认语言改成 zh_CN,老用户只要个人偏好还是 English,登录后界面就还是英文。批量处理存量用户时,通常让用户自己在个人设置里切换一次,或者在确认备份的前提下谨慎更新偏好数据——动用户表属于数据操作,和装语言包是两码事,别混在一篇流程里做。
3.3 本地化页面看不到简体中文时先查这三处
排查顺序我一般固定成三步,能覆盖绝大多数情况。第一步,确认 include/language/ 下确实有 zh 语言文件,且文件名大小写与包内结构一致,用ls include/language/看一眼就够;第二步,确认已经跑过快速修复与重建,而不是只清了浏览器缓存;第三步,确认 config 里 default_language 的值和语言文件的命名能对上。三步走完,90% 的「中文出不来」都能解决。
剩下 10% 是字符集问题。SuiteCRM 7.x 的正常部署要求数据库连接使用 UTF-8。如果连接层的字符集被改成 latin1 或类似编码,中文会以问号或乱码形式出现,这和翻译文件本身无关,属于环境问题。判断方法很简单:进「管理 → 系统信息」看数据库连接字符集,或直接在数据库客户端执行SHOW VARIABLES LIKE 'character_set_database';,理想结果是 utf8 或 utf8mb4。
4. 常见问题与避坑:中文语言包装不上的五个翻车现场
这一章全是实操里反复踩过的坑,每一条按现象、原因、解决三段写,可以直接对照排查。如果你只打算读一章,读这章就够对付 80% 的故障。
4.1 解压权限不足:文件没落盘,界面自然全英文
现象是 unzip 命令看似执行完,但界面毫无变化,include/language 下也找不到 zh 语言文件。原因多半是 Web 目录归属不是当前操作账号,普通用户没权限写入,解压时文件被静默跳过;还有一种常见变体是用 root 解压后忘了 chown,Web 进程根本没权限读这些文件。
解决方式是先解决目录权限,再重新解压:
sudo chown -R www-data:www-data /var/www/suitecrm unzip -o SuiteCRM-7.11.18_SuiteCRM_core_zh-CN.zip -d /var/www/suitecrm/解压之后用find /var/www/suitecrm -name "*.lang.php" | grep zh确认文件真实存在。文件在磁盘上了,问题就只剩缓存重建,按 2.3 走一遍即可。这个排查顺序很重要:先查文件在不在,再查缓存新不新,不要一上来就怀疑语言包本身有问题。
4.2 Linux 文件名大小写不一致:语言文件加载直接失败
现象是本地化页面找不到简体中文,但 include/language 目录里明明有 zh 相关文件。有些环境里更诡异:核心菜单是中文的,某几个模块却变回英文,加载时好时坏。原因就是 Linux 文件名区分大小写。语言包在 Windows 或 macOS 上解压后再传到 Linux,文件名大小写可能被改动;或者 config 里写 zh_CN,而文件叫 zh_cn.lang.php,加载逻辑找不到目标。
解决方法是先看实际文件名,再决定改谁:
ls include/language/把输出结果和包内结构对比,保持文件名原始大小写,不要顺手改名。改完文件名或配置后,必须重新执行一次快速修复与重建,否则缓存里还是旧的映射关系。这个问题最玄学的地方在于,Windows 服务器上永远不会出现,所以很多在本地测过的人上传到 Linux 就翻车。
4.3 中文变成问号或方块:编码与字符集问题
现象是菜单中文化成功,但内容里的中文显示成 ? 或方块,录入的中文保存后也是乱码。原因有两类:一是语言文件本身被保存成 GBK/GB2312 编码,或者带了 BOM 头;二是数据库连接字符集不是 UTF-8,前端显示时按错误编码解析。
先查文件编码:
file include/language/zh_cn.lang.php如果显示 non-UTF-8 或非 Unicode,做转码。常见做法是备份原文件后用 iconv 转成 UTF-8:
cp include/language/zh_cn.lang.php /tmp/zh_cn.lang.php.bak iconv -f GBK -t UTF-8 /tmp/zh_cn.lang.php.bak > include/language/zh_cn.lang.php转完再确认数据库连接字符集,SHOW VARIABLES LIKE 'character_set_database';。两个点都对齐后,重建缓存再看界面。注意,转码前一定留备份,否则原文件一旦被覆盖且转码参数写错,想恢复都没有后悔药。
4.4 core 包覆盖不了第三方模块,别指望一次性全中文
现象是核心模块全是中文,但某个第三方扩展或自定义模块的列表、字段还是英文。原因很简单:这份包是 core 分支,只覆盖标准模块,第三方扩展的语言文件不在包内清单里,自然无人翻译。这不是安装问题,是包的范围问题。
先查扩展目录下有没有自带语言包:
ls modules/扩展模块名/language/有的话看里面是否带 zh 文件;没有的话,自己在 custom/modules/扩展模块名/language/ 下补一个 zh_cn.lang.php,只写需要汉化的键,具体写法见第 6 章。这里要记住一个原则:别去改核心包里的模块语言文件,否则下次升级又会被官方文件覆盖,等于白干。
4.5 升级后翻译全部丢失:备份与恢复是保命操作
现象是从 7.11.18 升级到 7.11.19 或更高版本后,整个界面退回英文。原因是升级过程会重写 include/language 与模块语言目录,并顺手清掉语言缓存,中文包文件被官方文件替换,翻译自然不在。这属于正常行为,不是升级程序坏了。
所以升级前先备份,这是整个语言包维护里最便宜的保险:
tar czf lang-backup-$(date +%F).tgz include/language modules/*/language升级完成后把备份解回原目录,再跑一次快速修复与重建。但更省心的方案是把平时的手工修正都放 custom 目录,那样升级根本不需要恢复文件,因为官方升级不会动 custom。这个思路在下一章展开。
5. 中文包完整性验证:键对比脚本与模块抽查清单
翻译装完、界面变中文,不等于翻译是完整的。语言包落后于核心版本时,新增键缺失,界面会回落成英文;翻译质量差的包,值还留着英文原文的键也不少。这一章给两个脚本和一张抽查表,把验证从「看着像中文」变成「数得出差距」。
5.1 核心键缺失扫描:对比 en_us 与 zh_cn
核心公共字符串都在 include/language/ 下的语言文件里,以 PHP 数组形式存放。用 PHP 一行脚本对比两个文件的键,就能得出缺失数量:
php -r ' include "/var/www/suitecrm/include/language/en_us.lang.php"; $en = $app_strings; include "/var/www/suitecrm/include/language/zh_cn.lang.php"; $zh = $app_strings; echo "en 键数: " . count($en) . PHP_EOL; echo "zh 键数: " . count($zh) . PHP_EOL; echo "zh 缺失键: " . count(array_diff_key($en, $zh)) . PHP_EOL; 'include 语句会把语言文件里的变量带进当前作用域,所以后面能直接引用 $app_strings。array_diff_key 按键名取差集,统计 zh 比 en 少哪些键。如果脚本报错,先核对文件名大小写是不是 zh_cn.lang.php,这和 4.2 是同一个坑。
注意,缺失键不等于必须补——有些系统内部字符串不面向用户,刻意不翻译也正常。真正需要关注的是这个数字的变化趋势:新版本发布后突然变大,说明新版本新增了一批未覆盖的文案。同理可以对比 $app_list_strings,方法完全一样,把变量名换掉重跑一遍即可。
5.2 漏译扫描:找出值还是英文的键
缺失键之外,还有一种更隐蔽的问题:键存在,但值没翻译,或者翻译得和英文原文一模一样。写一个扫描脚本,把 zh 文件里值与 en 文件完全相同的键列出来:
php -r ' include "/var/www/suitecrm/include/language/en_us.lang.php"; $en = $app_strings; include "/var/www/suitecrm/include/language/zh_cn.lang.php"; $zh = $app_strings; $same = array(); foreach ($en as $k => $v) { if (isset($zh[$k]) && $zh[$k] === $v && strlen($v) > 3) { $same[$k] = $v; } } echo "疑似未翻译: " . count($same) . PHP_EOL; $i = 0; foreach ($same as $k => $v) { if ($i++ >= 10) break; echo $k . " => " . $v . PHP_EOL; } 'strlen($v) > 3是为了过滤单字符、双字符这类容易误报的短值,比如「是」「否」本来就是单字。输出的键里,品牌名、专有名词、人名可以合法保留英文,需要人工抽查判断,不要无脑全改。这个脚本的价值在于把「漏译」从感觉变成数字:第一次跑如果查出几百个疑似键,这个语言包的完成度就要打个问号;如果只有几十个,属于正常范围。
5.3 模块抽查清单与缺失文件定位
核心字符串之外,每个模块有自己的 $mod_strings。抽查不用全查,把业务最常用的几个模块过一遍就够:
| 模块 | 语言文件位置 | 重点检查项 |
|---|---|---|
| Accounts | modules/Accounts/language/zh_cn.lang.php | 行业、客户类型下拉 |
| Contacts | modules/Contacts/language/zh_cn.lang.php | 称呼、姓名格式 |
| Leads | modules/Leads/language/zh_cn.lang.php | 状态、来源下拉 |
| Opportunities | modules/Opportunities/language/zh_cn.lang.php | 销售阶段下拉 |
| Cases | modules/Cases/language/zh_cn.lang.php | 状态、优先级 |
下拉选项属于 app_list_strings 或模块内的 dom 数组,经常出现菜单是中文、下拉列表却是英文的割裂情况。所以抽查时别只看字段名,一定要点开一个下拉框看选项。想快速定位哪些模块缺中文文件,用一段循环判断:
for m in Accounts Contacts Leads Opportunities Cases; do if [ -f "/var/www/suitecrm/modules/$m/language/zh_cn.lang.php" ]; then echo "$m OK" else echo "$m 缺中文语言文件" fi done缺文件时,先确认是不是 4.2 说的大小写问题,再决定补文件还是走 custom 覆盖。这个循环脚本也可以改成全模块扫描,把模块名列表换成ls modules/的循环输出即可。
6. 让语言包活过升级:custom 目录覆盖法与增量维护
官方升级会覆盖 include/language 和模块语言目录,但不会动 custom/。这个目录就是语言包的「后悔药」:所有手工修正和补充都放进去,升级后依然在。
6.1 只放差异键,不放整包
常见误区是把整个 zh_cn.lang.php 复制进 custom。这样不仅浪费内存,新版语言包发布时你反而被旧副本拖住。正确做法是只放需要修正或补充的键,先建目录:
mkdir -p /var/www/suitecrm/custom/include/language /var/www/suitecrm/custom/modules/Leads/language然后写覆盖文件。下面这段是核心公共字符串的修正,$app_strings 管通用标签,$app_list_strings 管下拉选项:
<?php // custom/include/language/zh_cn.lang.php $app_strings["LBL_SEARCH"] = "搜索(修正版)"; $app_list_strings["account_type_dom"]["Analyst"] = "分析师";模块级修正放在对应模块目录下,比如 Leads 模块的字段标签:
<?php // custom/modules/Leads/language/zh_cn.lang.php $mod_strings["LBL_STATUS"] = "跟进状态";改完必须重跑快速修复与重建,custom 里的键才会合并进最终语言缓存。合并按数组覆盖逻辑进行:键名相同以 custom 里的值为准,没写到的键仍然走核心语言包。这样既保留了官方包的完整覆盖,又不会丢失你自己的修正。
6.2 升级后的增量维护流程
升级时我固定走四步:升级前备份 custom 语言目录,升级后跑第 5 章的两个脚本,把新出现的缺失键和疑似漏译键整理进对应 custom 文件,最后重建缓存收尾。备份命令很简单:
tar czf custom-lang-backup.tgz custom/include/language custom/modules如果官方发布了新版中文包,只把新增的键合并进 custom 文件,不要整包覆盖——否则你手工修过的翻译会全部丢失。整套流程的核心思想是:核心语言包负责「跟着版本走」,custom 目录负责「做本地修正」,两者各管一段,互不覆盖。
从那以后,我每次升级都强制走一遍「备份 custom → 差异扫描 → 只合并新增键 → 重建缓存」的流程。这个习惯救过我至少两次,其中一次新版核心新增了 200 多个键,我没有整包覆盖,只把差异补进 custom,第二天界面照常全中文。希望帮到你。
本文还有配套的精品资源,点击获取