Xiuno BBS 重构记录贴(十)多语言系统文档
贰先生 2小时前

Xiuno BBS 多语言系统文档

目录

  1. 架构概述
  2. 文件结构
  3. 核心 API
  4. 插件开发
  5. 模板开发
  6. 语言切换机制
  7. 后台多语言
  8. 安装程序多语言
  9. 同步检测工具
  10. API 多语言支持
  11. 翻译协作流程

1. 架构概述

Xiuno BBS 采用关联数组方式实现多语言,核心是 PHP 原生的 return array() 结构。

设计原则

  • 零依赖:无需第三方库,PHP 原生支持
  • 模块化拆分:按功能模块将语言包拆分为多个子文件,便于维护
  • 插件友好:通过 hook 机制允许插件扩展语言包
  • 用户级切换:支持前台用户选择语言偏好,存储于 Cookie
  • 自动检测:首次访问时根据浏览器 Accept-Language 自动选择语言

语言列表

代码 语言 目录
zh-cn 简体中文 lang/zh-cn/
zh-tw 繁体中文 lang/zh-tw/
en-us English lang/en-us/
ru-ru Русский lang/ru-ru/
th-th lang/th-th/

2. 文件结构

lang/
├── zh-cn/
│   ├── bbs.php              ← 前台语言统一入口(include 子模块)
│   ├── bbs_common.php       ← 通用词汇(登录、提交、删除等)
│   ├── bbs_user.php         ← 用户相关(注册、个人资料等)
│   ├── bbs_thread.php       ← 帖子相关(发表、回复、收藏等)
│   ├── bbs_forum.php        ← 版块相关
│   ├── bbs_search.php       ← 搜索相关
│   ├── bbs_theme.php        ← 主题/外观相关
│   ├── bbs_social.php       ← 社交相关(关注、通知、动态等)
│   ├── bbs_friendlink.php   ← 友情链接
│   ├── bbs_misc.php         ← 其他杂项
│   ├── bbs_admin.php        ← 后台管理
│   └── bbs_install.php       ← 安装程序
├── zh-tw/
│   └── ...                  ← 同上结构
├── en-us/
│   └── ...
├── ru-ru/
│   └── ...
└── th-th/
    └── ...

bbs.php 入口文件

<?php
$lang = array();

$_lang_dir = APP_PATH . "lang/{$conf['lang']}";

// 按模块 include 子文件
$lang += include _include("$_lang_dir/bbs_common.php");
$lang += include _include("$_lang_dir/bbs_user.php");
$lang += include _include("$_lang_dir/bbs_thread.php");
// ... 其他模块

// hook lang_zh_cn_bbs.php    ← 插件语言注入点
// 编译时,插件的 hook 文件内容会追加到这里

return $lang;

注意:必须使用 _include() 而非 include,确保:

  1. 子模块文件也被 Xiuno 编译到 tmp/ 目录
  2. 插件 hook 能正确注入

模块划分建议

文件 内容 示例 key
bbs_common.php 通用操作 login, logout, submit, delete, success, error
bbs_user.php 用户功能 register, user_center, edit_profile, change_password
bbs_thread.php 帖子功能 create_thread, reply, digest, top
bbs_forum.php 版块功能 forum, category, sub_forum
bbs_search.php 搜索功能 search, search_result, no_result
bbs_theme.php 主题功能 theme_settings, light_mode, dark_mode
bbs_social.php 社交功能 follow, followers, my_feed, notification
bbs_friendlink.php 友情链接 friend_link, link_name, link_url
bbs_misc.php 其他杂项 no_data, loading, confirm_action

3. 核心 API

3.1 lang() 函数

/**
 * 获取翻译文本
 * @param string $key    语言 key
 * @param array  $arr    可选,替换变量
 * @return string        翻译后的文本
 */
function lang($key, $arr = array()) {
    global $_SERVER;
    $text = isset($_SERVER['lang'][$key]) ? $_SERVER['lang'][$key] : $key;
    if (!empty($arr)) {
        $search = $replace = array();
        foreach ($arr as $k => $v) {
            $search[] = '{' . $k . '}';
            $replace[] = $v;
        }
        $text = str_replace($search, $replace, $text);
    }
    return $text;
}

3.2 使用示例

基本用法

echo lang('login');              // 输出:登录 / Login / 登入

变量替换

// 语言文件中的定义
'welcome' => '欢迎 {username},您有 {count} 条新消息',

// 调用
echo lang('welcome', array('username' => '张三', 'count' => 5));
// 输出:欢迎 张三,您有 5 条新消息

HTML 内容翻译

// 语言文件中
'terms' => '我已阅读并同意<a href="/terms">服务条款</a>',

// 调用
echo lang('terms');
// 输出:我已阅读并同意<a href="/terms">服务条款</a>

3.3 key 命名规范

// 推荐:下划线分隔,小写
'user_register_success' => '注册成功'
'thread_create_success' => '发帖成功'
'confirm_delete' => '确定要删除吗?'

// 不推荐:驼峰命名、混合大小写
'userRegisterSuccess'   // ❌
'THREAD_CREATE_SUCCESS' // ❌

4. 插件开发

4.1 插件语言文件位置

插件在 hook/ 目录下放置语言文件:

plugin/my_plugin/
├── hook/
│   ├── lang_zh_cn_bbs.php    ← 中文翻译
│   ├── lang_en_us_bbs.php    ← 英文翻译
│   ├── lang_zh_tw_bbs.php    ← 繁体翻译
│   ├── lang_ru_ru_bbs.php    ← 俄语翻译
│   └── lang_th_th_bbs.php    ← 泰语翻译
└── ...

4.2 插件语言文件格式

<?php
// hook/lang_zh_cn_bbs.php
return array(
    // 建议使用插件名前缀避免冲突
    'my_plugin_title' => '我的插件',
    'my_plugin_enable' => '启用插件',
    'my_plugin_disable' => '禁用插件',
    'my_plugin_config' => '插件设置',
    'my_plugin_settings_saved' => '设置已保存',
);

4.3 在模板中使用插件语言

<?php echo lang('my_plugin_title'); ?>

4.4 后台管理语言

如果插件有后台设置页面,需要创建后台语言文件:

plugin/my_plugin/
├── hook/
│   ├── lang_zh_cn_bbs.php
│   ├── lang_en_us_bbs.php
│   └── ...
└── hook/admin/
    ├── lang_zh_cn_bbs_admin.php    ← 后台中文
    └── lang_en_us_bbs_admin.php    ← 后台英文
<?php
// hook/admin/lang_zh_cn_bbs_admin.php
return array(
    'my_plugin_admin_title' => '我的插件管理',
    'my_plugin_admin_settings' => '插件设置',
);

后台语言会在加载 bbs_admin.php 时通过 hook 注入。

4.5 插件语言 key 前缀建议

为避免与核心或其他插件冲突,建议:

// 推荐:插件名_功能
'haya_favorite_add' => '收藏'
'haya_favorite_remove' => '取消收藏'

// 推荐:插件名_模块_功能
'sitemap_admin_generate' => '生成站点地图'
'sitemap_admin_settings' => '地图设置'

5. 模板开发

5.1 正确使用 lang()

HTML 模板中

<h1><?php echo lang('user_center'); ?></h1>
<button class="btn btn-primary"><?php echo lang('submit'); ?></button>

JavaScript 中(通过 data 属性)

<button class="btn btn-danger" onclick="confirmDelete('<?php echo lang('confirm_delete'); ?>')">
    <?php echo lang('delete'); ?>
</button>

JavaScript 中(通过 DOM 注入)

// 在 JS 文件中
var deleteConfirmText = document.getElementById('delete-btn').dataset.confirm;
<button id="delete-btn" class="btn btn-danger" data-confirm="<?php echo lang('confirm_delete'); ?>">
    <?php echo lang('delete'); ?>
</button>

5.2 避免硬编码中文

❌ 错误示例

<span>帖子</span>
<button>删除</button>
<a href="/user">个人中心</a>

✅ 正确示例

<span><?php echo lang('thread'); ?></span>
<button><?php echo lang('delete'); ?></button>
<a href="<?php echo url('user'); ?>"><?php echo lang('user_center'); ?></a>

5.3 动态内容的翻译

对于运行时生成的文本,需要在语言包中添加对应的 key:

// 语言文件
'upload_success' => '上传成功'
'upload_failed' => '上传失败,错误码:{error_code}'

// PHP 代码
if ($uploadSuccess) {
    message(0, lang('upload_success'));
} else {
    message(-1, lang('upload_failed', array('error_code' => $errorCode)));
}

6. 语言切换机制

6.1 前台语言切换流程

用户选择语言 → 设置 Cookie → 刷新页面 → 检测 Cookie → 加载对应语言包

语言检测优先级

  1. Cookie 中的用户偏好(最高)
  2. 浏览器 Accept-Language
  3. 站点默认语言(conf.php 中的 lang 配置)

相关代码位置

  • 入口:index.inc.php 中的 detect_user_lang()
  • 切换路由:route/lang.php
  • 前台导航:view/htm/header_nav.inc.htm 中的语言下拉菜单

6.2 Cookie 设置

// route/lang.php
$lang_code = param(1) . '-' . param(2);  //'en-us'
setcookie('lang', $lang_code, time() + 86400 * 365, '/');

6.3 URL 路由切换

前台语言切换通过 URL 路由实现:

?lang-zh-cn.htm  → 切换到简体中文
?lang-en-us.htm  → 切换到 English

注意:URL 中使用 - 分隔语言代码,如 en-us,不要使用 en_us

6.4 后台语言处理

后台使用独立的语言包 bbs_admin.php,不受前台语言切换影响。

后台管理员可以在后台导航栏单独切换后台显示语言,设置同样保存在 Cookie 中。


7. 后台多语言

7.1 后台语言文件

// lang/zh-cn/bbs_admin.php
return array(
    // 后台特有的翻译
    'admin_dashboard' => '仪表盘',
    'admin_settings' => '站点设置',
    'admin_user_manage' => '用户管理',
    // ...
);

7.2 后台模板中使用

<?php echo lang('admin_dashboard'); ?>

7.3 后台语言与前台语言的关系

方面 后台语言 前台语言
文件 bbs_admin.php bbs.php 及子模块
语言 key 前缀 admin_ 无特定前缀
切换影响 仅后台 仅前台
插件 hook hook/lang_*_bbs_admin.php hook/lang_*_bbs.php

8. 安装程序多语言

8.1 安装语言文件

// lang/zh-cn/bbs_install.php
return array(
    'install_welcome' => '欢迎使用 Xiuno BBS 安装向导',
    'install_database' => '数据库配置',
    'install_admin_account' => '创始人账号',
    'install_complete' => '安装完成',
    // ...
);

8.2 安装程序加载语言

// install/index.php
$_lang = include APP_PATH . "lang/{$conf['lang']}/bbs_install.php";

8.3 安装时语言选择

安装程序通常需要先让用户选择语言,然后再加载对应语言包。


9. 同步检测工具

9.1 工具位置

tools/lang_sync_check.php

9.2 功能

  • 检测各语言包的 key 数量是否一致
  • 列出缺失的 key
  • 生成缺失 key 的模板供翻译

9.3 使用方法

php tools/lang_sync_check.php

9.4 输出示例

=== 语言包同步检测 ===
基准语言:zh-cn (410 keys)

en-us: 367 keys, 缺失 43 个 key
  - missing_key_1
  - missing_key_2
  ...

zh-tw: 310 keys, 缺失 100 个 key
  - missing_key_1
  ...

10. API 多语言支持

10.1 RESTful API 多语言策略

API 返回的数据通常不需要翻译,但错误消息需要支持多语言。

10.2 错误消息多语言

方式一:API 返回错误码,客户端翻译

// API 返回
return json(['code' => 1001, 'message' => lang('user_not_login')]);

客户端根据错误码和当前语言显示对应的消息。

方式二:API 接受语言参数,返回翻译后的消息

// API 入口
$apiLang = param('lang', $conf['lang']);

// 加载对应语言包
$_lang = include APP_PATH . "lang/{$apiLang}/bbs.php";

10.3 API 语言包

如果 API 需要独立的语言处理,可以创建 bbs_api.php

// lang/zh-cn/bbs_api.php
return array(
    'api_success' => '操作成功',
    'api_failed' => '操作失败',
    'api_invalid_params' => '参数错误',
    'api unauthorized' => '未授权',
    // ...
);

11. 翻译协作流程

11.1 添加新语言 key 的流程

  1. 在 zh-cn/bbs.php 及子模块中添加新 key

    // bbs_thread.php
    'thread_pin' => '置顶',
    
  2. 在所有其他语言包中添加对应翻译

    // en-us/bbs_thread.php
    'thread_pin' => 'Pin Topic',
    
  3. 运行同步检测工具确认无遗漏

11.2 翻译质量检查

  • [ ] 语法正确,无拼写错误
  • [ ] 语气一致(正式/口语)
  • [ ] 占位符 {placeholder} 保持一致
  • [ ] HTML 标签正确闭合
  • [ ] 复数形式处理(如有)

11.3 翻译注意事项

变量占位符

// ❌ 错误:占位符顺序不一致
'zh' => '{name} 赞了 {user} 的帖子'
'en' => '{user} liked {name}\'s post'

// ✅ 正确:占位符顺序一致
'zh' => '{name} 赞了 {user} 的帖子'
'en' => '{user} liked {name}\'s post'

HTML 内容

// ❌ 错误:HTML 标签不匹配
'zh' => '<strong>重要</strong> 请阅读'
'en' => '<strong>Important</strong> Please read'

// HTML 属性可能需要翻译
'search_placeholder' => '搜索...'
'en' => 'Search...'

复数形式

// PHP 原生不支持复数,需要手动处理
$msg = $count == 1 
    ? lang('x_posts_single', ['count' => $count])
    : lang('x_posts_plural', ['count' => $count]);

11.4 维护建议

  1. 定期同步:每次添加新 key 后,同步到所有语言包
  2. 使用工具tools/lang_sync_check.php 检测遗漏
  3. 翻译协作:考虑使用 PO 文件 + Poedit 或 Crowdin/Transifex 平台
  4. 测试验证:切换到非中文语言,测试所有页面文本

附录

A. 语言相关常量

常量 说明
$conf['lang'] 当前站点默认语言
$_SERVER['lang'] 当前会话语言数组
$_COOKIE['lang'] 用户语言偏好 Cookie

B. 相关文件位置

文件 位置 说明
语言入口 lang/{locale}/bbs.php 前台语言主文件
后台语言 lang/{locale}/bbs_admin.php 后台语言
安装语言 lang/{locale}/bbs_install.php 安装程序语言
切换路由 route/lang.php 语言切换处理
前台入口 index.inc.php 语言检测逻辑
检测工具 tools/lang_sync_check.php 同步检测脚本

C. key 命名参考表

模块 key 前缀 示例
用户 user_ user_register, user_login, user_profile
帖子 thread_ / post_ thread_create, thread_delete, post_edit
版块 forum_ forum_create, forum_update
消息 message_ / notify_ message_send, notify_new
设置 setting_ setting_save, setting_reset
错误 error_ error_not_found, error_permission
成功 success_ success_create, success_update

文档版本:1.0 最后更新:2026-06-01

最新回复 (0)
全部楼主
返回