自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

多語言設(shè)計,你學(xué)會了嗎?

開發(fā) 前端
對于主數(shù)據(jù)來說,需要在不同的語言區(qū)域保持一致,因此需要為每條數(shù)據(jù)創(chuàng)建翻譯拓展表,以冗余表的方式處理。

多語言設(shè)計是國際化系統(tǒng)設(shè)計的第一步,也是最基本的內(nèi)容。很多時候,我們會認為多語言設(shè)計非常簡單。對于靜態(tài)資源來說確實如此,通過加載一個語言包即可,但是對于一些動態(tài)內(nèi)容而言卻不太一樣。

這些動態(tài)內(nèi)容可能是消息通知、服務(wù)器生成的導(dǎo)出內(nèi)容等。這里我整理了一個完整的清單,用來指導(dǎo)多語言的方案設(shè)計:

  • 前端文案。例如菜單、表單提示信息等。
  • 錯誤信息。表單驗證或者服務(wù)器報錯信息的提示。
  • 導(dǎo)出文件。導(dǎo)出 Excel 或者 PDF 文件,往往為后端生成。
  • 郵件和消息通知。為用戶發(fā)送通知時,也需要使用對應(yīng)語言的模板文件。
  • 主數(shù)據(jù)。例如在電商系統(tǒng)中,管理員需要為支持的語言都添加一份商品數(shù)據(jù)、商品分類等。
  • 業(yè)務(wù)增量數(shù)據(jù)。在業(yè)務(wù)增量數(shù)據(jù)中,為了搜索和存檔的目的,有時候需要將一些主數(shù)據(jù)持久化下來用于搜索或者查看,例如訂單中,需要持久化對應(yīng)的商品數(shù)據(jù)。

下面我們逐個討論。

多語言的基本概念

在開始進入詳細的內(nèi)容之前,先了解幾個基本的概念。

語言編碼

在國際標(biāo)準(zhǔn)化組織 ISO 的 639-1 標(biāo)準(zhǔn)中,每個語言都被分配了一個特定的編碼。例如中文的編碼為“zh”,英文的編碼為“en”。除了基本的語言標(biāo)準(zhǔn)外,不同地區(qū)使用的語言還需要細分,因此拓展了使用地區(qū)的編碼,最終的編碼由兩部分組成,由中橫線連接。

如果需要表達中國大陸使用的語言,可以使用 “zh-cn”編碼,如果需要表達中國臺灣的語言,可以使用 “zh-tw”。通常來說,中國大陸和新加坡使用簡體中文,中國香港、中國臺灣使用繁體中文。

對于英文來說,英國、美國等地區(qū)的英文使用習(xí)慣不同,在必要時也可以提供不同的語言包。

本位語言

在多幣種設(shè)計中會介紹一個本位貨幣的概念,在多語言中也會有一個本位語言的概念。

本位語言是指在系統(tǒng)設(shè)計中的通用語言,通常都會使用英語作為本位語言。本位語言作為其它語言包缺失的情況下的默認語言,也可以作為其它語言包的 key。

在動態(tài)數(shù)據(jù)處理中,默認情況下使用本位語言,在需要翻譯的場景使用翻譯拓展表。這樣就避免了到處使用 name_en,name_zh 等和語言相關(guān)的字段。

I18N 框架

I18N是“Internationalization(國際化)”的縮寫,其中數(shù)字18代表首字母I和末字母N之間的字母數(shù)。多語言是國際化中最重要的一部分之一,在很多時候,I18N 框架往往就被當(dāng)做多語言框架。

I18N 能力在主流的編程框架中都有提供。在 JavaScript 項目中,i18next 框架提供了一整套 I18N 特性,包括多語言翻譯、數(shù)據(jù)格式化等內(nèi)容,對于 Node.js 項目 i18next 也可以在服務(wù)端發(fā)生作用。

而對于服務(wù)器端由于前后端分離的發(fā)展,相對來說就弱的多。Spring Boot 提供了一個 MessageSource 功能,配合 Java 的 Locale 對象,可以實現(xiàn)翻譯用戶消息的能力。

識別和傳遞用戶語言標(biāo)識

通常來說,多語言的系統(tǒng)會根據(jù)優(yōu)先級識別語言:

  • 用戶賬戶的用戶設(shè)置。
  • 用戶登錄后會話中的語言信息。
  • 用戶瀏覽器或者 App 的語言設(shè)置。
  • 操作系統(tǒng)語言設(shè)置。

當(dāng)用戶安裝瀏覽器時,瀏覽器安裝程序通常會自動選擇與操作系統(tǒng)相同的語言作為默認語言。我們可以通過 JavaScript 的 navigator.language 屬性拿到當(dāng)前用戶的語言。如果是應(yīng)用系統(tǒng)本身的語言,可以在登錄后調(diào)用 API 獲取用戶的語言設(shè)置。

識別到語言信息后,需要在前后端傳遞語言信息,通常的做法有:

  • 使用 Header 傳遞,通過寫入 HTTP Header 的 Accept-Language 字段。
  • 使用 Query 傳遞,在 URL 參數(shù)上增加語言標(biāo)識。

在實踐中,可以將識別到的用戶語言信息放到瀏覽器 localStorage 或者 App 的本地配置中,然后通過 Header 或者 Query 傳遞。另外也可以將語言信息放入用戶 Session 或 Token 中,不過用戶在修改語言配置后需要刷新 Session 或者重新頒發(fā) Token。

除此之外,還有一些不常用的語言標(biāo)識設(shè)置方式:

  • cookie
  • sessionStorage/localStorage
  • navigator (這個對象也可以寫入)
  • htmlTag,例如 <html lang=“LANGUAGE” .>
  • URL path
  • 子域名

為了識別復(fù)雜的語言標(biāo)識場景,i18next 還提供了一個 i18next-browser-languageDetector 工具,快速識別當(dāng)前用戶的語言標(biāo)識。

前端的多語言

在前端開啟多語言有一個經(jīng)驗需要留意。我們需要為每個語言定義一個語言包,語言包往往由 key value 構(gòu)成,在一些項目中,有些開發(fā)者會使用一個簡短的英文字符串作為 key,并給英文也設(shè)置了一個語言包。這種實踐會造成兩個壞處,首先是需要額外定義一個英文語言包,另外當(dāng)需要排錯時,搜索關(guān)鍵詞會變得有一點麻煩。所以,通常來說,我們會直接使用英語作為語言包的 key,這樣可以減少很多工作量。

這里以 react-i18next 開啟 React 項目中的多語言設(shè)置。

導(dǎo)入 react-i18next i18next 兩個庫。

npm install react-i18next i18next –save

編寫下面初始化代碼,并確保被 React 入口文件導(dǎo)入。

import i18n from "i18next";
import { initReactI18next } from "react-i18next";


const resources = {
  zh: {
    translation: {
      "Welcome to React": "歡迎使用 React"
    }
  }
};


i18n
  .use(initReactI18next)
  .init({
    resources,
    lng: "zh"
  });


export default i18n;

在組件中使用翻譯:

import React from 'react';
import { useTranslation } from 'react-i18next';


function MyComponent () {
  const { t, i18n } = useTranslation();
  return <h1>{t('Welcome to React')}</h1>
}

react-i18next 還提供了其它形式的翻譯方式,例如組件之類的,總之來說使用 t 函數(shù)翻譯文本是最簡單的一種形式,也便于搜索和排錯。

后端服務(wù)的多語言

除了前端的多語言外,后端避免不了需要使用語言標(biāo)識和翻譯能力, 不過應(yīng)該盡量避免在后端服務(wù)使用 I18N 相關(guān)特性。例如,對于錯誤信息來說,盡量通過錯誤碼將錯誤信息放到前端,而不是由后端加工。

對于導(dǎo)出、上下游系統(tǒng)等場景后端,后端服務(wù)的多語言無法避免,這里以 Spring Boot 為例,演示基本的 I18N 實現(xiàn)。

在 Spring Boot 項目中可以添加下面配置。

@Configuration
public class InternationalizationConfig {


    @Bean
    public MessageSource messageSource() {
        // 定義多語言資源位置
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        // 設(shè)置資源目錄
        messageSource.setBasename("messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }


    @Bean
    public LocaleResolver localeResolver() {
        // 設(shè)置應(yīng)用如何讀取語言標(biāo)識,這里使用了 HTTP 頭信息識別語言標(biāo)識
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(Locale.ENGLISH);
        return localeResolver;
    }
}

創(chuàng)建在 resources 目錄下默認語言包: messages.properties。

greeting=Hello

創(chuàng)建一個中文語言包(記得修改 IDE 的文件編碼格式,包括 properties 文件的編碼):

greeting=你好

這樣就可以在后端拿到 Locale 對象并進行翻譯了:

@GetMapping("/greeting")
public String getGreeting(Locale locale) {
    return messageSource.getMessage("greeting", null, locale);
}

通過傳入合適的語言標(biāo)識就能獲得相應(yīng)的翻譯信息了。

curl -H "Accept-Language: zh" http://localhost:8080/greeting

拿到合適的 Locale 對象,在后端處理錯誤提示、通知、郵件、導(dǎo)出都可以完成。為 HTTP Client 編寫一個 Interceptor 自動附加 Header 信息,可以把當(dāng)前請求的語言標(biāo)識傳遞到下游服務(wù)中,解決上下文傳遞的問題。

動態(tài)數(shù)據(jù)的多語言設(shè)計

動態(tài)的數(shù)據(jù)也需要翻譯,這里分兩種情況:

  • 主數(shù)據(jù)或者基本數(shù)據(jù),例如商品、品牌、品類等。
  • 業(yè)務(wù)增量數(shù)據(jù),或者快照數(shù)據(jù),例如訂單、預(yù)約、工單等。

這兩類數(shù)據(jù)在國際化的項目中需要分開處理。

對于主數(shù)據(jù)來說,需要在不同的語言區(qū)域保持一致,因此需要為每條數(shù)據(jù)創(chuàng)建翻譯拓展表,以冗余表的方式處理。例如,對于 brand 表中有 name 字段,brand 表本身使用前面介紹的本位語,name 字段使用英語。然后拓展一張 brand_locale 表,表中放置需要翻譯的字段,并增加一個 lang 字段。

對于業(yè)務(wù)增量數(shù)據(jù)來說,如果按照主數(shù)據(jù)的處理方式,會導(dǎo)致數(shù)據(jù)量非常大,通常來說我們通過冗余字段,或不冗余的方式處理。例如,訂單表中產(chǎn)品名稱可以增加一個字段,其中一個字段存儲用戶下單時所用的語言(本地語言),另外一個字段存儲本位語言。這樣的好處是滿足本地用戶查詢、總部人員管理相關(guān)數(shù)據(jù),并提供足夠好的搜索性能。

參考資料

責(zé)任編輯:武曉燕 來源: DDD和微服務(wù)
相關(guān)推薦

2024-03-06 08:28:16

設(shè)計模式Java

2024-03-05 10:09:16

restfulHTTPAPI

2022-11-11 08:29:24

C語言中文字符代碼

2023-01-10 08:43:15

定義DDD架構(gòu)

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-07-26 13:11:21

ChatGPT平臺工具

2024-01-19 08:25:38

死鎖Java通信

2024-01-02 12:05:26

Java并發(fā)編程

2023-08-01 12:51:18

WebGPT機器學(xué)習(xí)模型

2024-09-09 09:00:12

架構(gòu)設(shè)計算法

2024-05-06 00:00:00

InnoDBView隔離

2024-08-06 09:47:57

2022-07-08 09:27:48

CSSIFC模型

2023-01-30 09:01:54

圖表指南圖形化

2024-07-31 08:39:45

Git命令暫存區(qū)

2023-12-12 08:02:10

2023-10-10 11:04:11

Rust難點內(nèi)存

2022-07-13 08:16:49

RocketMQRPC日志

2023-01-31 08:02:18

2023-05-05 06:54:07

MySQL數(shù)據(jù)查詢
點贊
收藏

51CTO技術(shù)棧公眾號