OpenMetadata二次开发之前端汉化

目录

  1. 配置默认语言为中文
  2. 服务配置模块汉化
  3. 右侧描述汉化
  4. 结果展示
    在这里插入图片描述

1. 配置默认语言为中文

修改i18nextUtil中的fallbackLng值,改为’zh-CN’

路径:OpenMetadata/openmetadata-ui/src/main/resources/ui/src/utils/i18next/i18nextUtil.ts

......
// Returns i18next options
export const getInitOptions = (): InitOptions => {
  return {
    supportedLngs: Object.values(SupportedLocales),
    resources: {
      'en-US': { translation: enUS },
      'fr-FR': { translation: frFR },
      'zh-CN': { translation: zhCN },
      'ja-JP': { translation: jaJP },
      'pt-BR': { translation: ptBR },
      'pt-PT': { translation: ptPT },
      'es-ES': { translation: esES },
      'gl-ES': { translation: glES },
      'ru-RU': { translation: ruRU },
      'de-DE': { translation: deDe },
      'he-HE': { translation: heHE },
      'nl-NL': { translation: nlNL },
      'pr-PR': { translation: prPR },
      'th-TH': { translation: thTH },
      'mr-IN': { translation: mrIN },
      'ko-KR': { translation: koKR },
    },
    fallbackLng: ['zh-CN'],
    detection: {
      order: ['querystring', 'cookie', 'navigator'],
      caches: ['cookie'], // cache user language on
    },
    interpolation: {
      escapeValue: false, // XSS safety provided by React
    },
    missingKeyHandler: (_lngs, _ns, key) =>
      // eslint-disable-next-line no-console
      console.error(`i18next: key not found "${key}"`),
    saveMissing: true, // Required for missing key handler
  };
};
};

2. 服务配置模块汉化

2.1 字段提取与翻译

在locale下面新建一个zh-cn.json,将需要汉化的字段提取出来,分别写在zh-cn.json和en-us.json内,比如服务配置主要分布在OpenMetadata-main/openmetadata-spec/src/main/resources/json/schema/entity/services/connections下,例如

路径:OpenMetadata/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json

en-us.json
zh-cn.json

字段提取可以手动,也可以脚本提取,分享一个脚本json_title_extractor.js,在命令行运行
node json_title_extractor.js

不同页面需要更改目标目录地址targetDir

// json_title_extractor.js
const fs = require('fs');
const path = require('path');

****************第一种***************
// 定义目标目录
const targetDir = path.join(__dirname, 'openmetadata-spec', 'src', 'main', 'resources', 'json', 'schema', 'entity', 'services', 'connections', 'database');

// 读取目录下的所有文件
fs.readdir(targetDir, (err, files) => {
    if (err) {
        console.error('读取目录时出错:', err);
        return;
    }

    // 过滤出所有的 JSON 文件
    const jsonFiles = files.filter(file => path.extname(file) === '.json');

    const allTitles = {};

    // 遍历每个 JSON 文件
    jsonFiles.forEach(file => {
        const filePath = path.join(targetDir, file);
        try {
            // 读取文件内容
            const data = fs.readFileSync(filePath, 'utf8');
            const jsonData = JSON.parse(data);

            // 递归查找所有的 title 字段
            function findTitles(obj) {
                if (typeof obj === 'object' && obj!== null) {
                    if (obj.hasOwnProperty('title')) {
                        const title = obj.title;
                        allTitles[title] = title;
                    }
                    for (const key in obj) {
                        findTitles(obj[key]);
                    }
                }
            }

            findTitles(jsonData);
        } catch (error) {
            console.error(`处理文件 ${file} 时出错:`, error);
        }
    });

    // 格式化输出结果,为键和值添加双引号
    const formattedOutput = Object.entries(allTitles).map(([key, value]) => {
        return `"${key}": "${value}"`;
    }).join(',\n');

    console.log(formattedOutput);
});


*********************第二种**********************
//或者直接复制绝对地址文件地址
const targetFile = ' *****/OpenMetadata/openmetadata-ui/src/main/resources/ui/src/jsons/connectionSchemas/connections/serviceConnection.json';
try {
    // 读取文件内容
    const data = fs.readFileSync(targetFile, 'utf8');
    const jsonData = JSON.parse(data);

    const allTitles = {};

    // 递归查找所有的 title 字段
    function findTitles(obj) {
        if (typeof obj === 'object' && obj!== null) {
            if (obj.hasOwnProperty('title')) {
                const title = obj.title;
                // 转换为小写和短中划线格式
                const kebabCaseKey = title
                    .replace(/([a-z0-9])([A-Z])/g, '$1-$2') // 处理驼峰命名
                    .replace(/[\s_]+/g, '-') // 替换空格和下划线
                    .toLowerCase();
                allTitles[kebabCaseKey] = title;
            }
            for (const key in obj) {
                findTitles(obj[key]);
            }
        }
    }

    findTitles(jsonData);

    // 格式化输出结果
    const formattedOutput = Object.entries(allTitles).map(([key, value]) => {
        return `"${key}": "${value}"`;
    }).join(',\n');

    console.log(formattedOutput);
} catch (error) {
    console.error(`处理文件时出错:`, error);
}

需要注意zh-cn.json的字段需要和en-us.json字段同步,不然会被程序自动删除

2.2 Form表单title渲染适配

在ConnectionConfigForm.tsx中,配置Form的国际化配置。声明一个函数translateSchemaTitles,将title进行多语言翻译,FormBuilder中schema调用translateSchemaTitles(connSch.schema, t)

路径:OpenMetadata/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/ServiceConfig/ConnectionConfigForm.tsx

    type Schema = Record<string, any>;
    // 将 title 转为进行多语言翻译
    const translateSchemaTitles = (
      schema: Schema,
      t: (key: string) => string
    ): Schema => {
      if (typeof schema !== 'object' || schema === null) {
        return schema;
      }
      if (Array.isArray(schema)) {
        return schema.map((item) => translateSchemaTitles(item, t));
      }
      const translated: Schema = { ...schema };
      for (const key in translated) {
        if (Object.prototype.hasOwnProperty.call(translated, key)) {
          if (key === 'title') {
            translated[key] = t(translated[key] as string) || translated[key];
          } else if (key === 'properties' || key === 'definitions') {
            const properties = translated[key];
            for (const propKey in properties) {
              if (Object.prototype.hasOwnProperty.call(properties, propKey)) {
                properties[propKey] = translateSchemaTitles(
                  properties[propKey],
                  t
                );
              }
            }
            translated[key] = properties;
          } else if (key === 'items' || key === 'additionalProperties') {
            translated[key] = translateSchemaTitles(translated[key], t);
          } else if (['allOf', 'anyOf', 'oneOf', 'not'].includes(key)) {
            translated[key] = translateSchemaTitles(translated[key], t);
          }
        }
      }

      return translated;
    };

 return (
      <FormBuilder
        cancelText={cancelText}
        formData={validConfig}
        okText={okText}
        ref={formRef}
        schema={translateSchemaTitles(connSch.schema, t)}
        serviceCategory={serviceCategory}
        status={status}
        uiSchema={connSch.uiSchema}
        validator={validator}
        onCancel={onCancel}
        onFocus={onFocus}
        onSubmit={handleSave}>
        ......

3. 右侧描述汉化

新建一个zh-CN文件夹,复制en-US中问内容,将文件中的title进行汉化

路径:OpenMetadata/openmetadata-ui/src/main/resources/ui/public/locales/zh-CN/Database
在这里插入图片描述

![目录结构](https://i-blog.csdnimg.cn/direct/5286c0c622aa40638cb2fb6f74d8244c.png

4. 结果显示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值