WEB網站國際化的一種解決方案

場景

這裏簡單用一個詳情頁面開始咱們的國際化講解 html

國際化頁面佈局.png
這個 場景中,logo須要國際化,tab以及麪包屑的文字須要國際化,詳情須要國際化,動態詳情以及動態詳情中的文字須要國際化。 通過總結,國際化數據會有四種類型

  • 後臺管理配置的動態數據
  • 服務端渲染的靜態的文字
  • js渲染的靜態文字
  • 靜態的圖片

後臺管理配置的動態數據

場景圖中詳情數據是經過一個後臺管理系統管理,數據經過語言隔離的方式管理,接口設計大體以下 語言管理vue

建立語種 [POST] /m/languages
更新語種 [PUT] /m/languages/{id}
查詢語種 [GET] /c/languages/{id}
查詢語種列表 [GET] /c/languages?$offset=偏移量&$limit=數量&$count=true&state=1
複製代碼

數據管理java

建立文章 [POST] /m/languages/{language_id}/articles
更新文章 [PUT] /m/languages/articles/{article_id}
刪除文章 [DELETE] /m/languages/articles/{article_id}
查詢文章 [GET] /c/languages/articles/{article_id}
查詢文章列表 [GET]/c/languages/{language_id}/articles?$offset=偏移量&$limit=數量&$count=true
複製代碼

服務端渲染的靜態的文字

如場景圖中麪包屑,好比麪包屑文字首頁->詳情, 像這種固定的文字不適合在後臺管理由運維人員配置。用文件統一存儲這些國際化的文件比較合適。這裏採用SpringMVC自帶的國際化解決方案。 配置ResourceBundleMessageSourcegit

@Configuration
public class I18nConfig {
    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("i18n");
        messageSource.setUseCodeAsDefaultMessage(true);
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}
複製代碼

基於Cookie的國際化實現github

@Bean
 public CookieLocaleResolver localeResolver() {
   CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
   cookieLocaleResolver.setCookieName("lang");
   return cookieLocaleResolver;
 }
複製代碼

SpringMVC國際化的的resolver有不少,用法也不少樣,能夠參考這篇博客,這裏就不造輪子了(^▽^)json

國際化語言攔截器bash

@Component
public class I18nInterceptor extends HandlerInterceptorAdapter {
    public static final String DEFAULT_PARAM_NAME = "lang";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {

        String newLocale = request.getParameter(DEFAULT_PARAM_NAME);
        if (newLocale != null) {
            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
            if (localeResolver == null) {
                throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
            }
            localeResolver.setLocale(request, response, StringUtils.parseLocaleString(newLocale));
        }
        // Proceed in any case.
        return true;
    }
}
複製代碼

這裏攔截器顯示多語言路由的實現是經過改變參數來實現語言切換cookie

http://i18n.example.com?lang=en
http://i18n.example.com?lang=cn
複製代碼

費些功夫經過改寫這個攔截器的實現以及路由的設計,能夠把國際化的路由改寫成這樣子框架

http://i18n.example.com/en
http://i18n.example.com/cn
複製代碼

在resources中配置配置國際化語言文件運維

i18n.properties    默認
i18n_en.properties 英文
i18n_cn.properties 中文
複製代碼

添加el表達式

public static String i18n(String key) {
  RequestContext requestContext = new RequestContext(SpringUtil.getRequest());
  return requestContext.getMessage(key);
}
在tld配置
<function>
    <description>國際化</description>
    <name>i18n</name>
    <function-class>com.example.utils.ElFuncUtil
    </function-class>
    <function-signature>java.lang.String i18n(java.lang.String))</function-signature>
    <example>${elf:i18n(key)}</example>
  </function>
複製代碼

使用

<span>${elf:i18n("詳情")}</span>
複製代碼

很遺憾,Spring自帶的國際化方案有一個缺陷:配置文件是內置在項目代碼中的,沒法剝離到後臺統一管理,這樣子若是新增一種語言,就必須動到項目代碼。 有能力的同窗能夠嘗試改寫ResourceBundleMessageSource,能支持讀取遠端的配置文件,這樣就完美了。

js渲染的靜態的文字

場景圖中動態推薦部分是用js渲染出來的,其中會出現所有等一些靜態的文本。這些文本也須要國際化。我在項目中使用如今最受歡迎的js框架vue。 配合使用(vue-i18n)[http://kazupon.github.io/vue-i18n/en/started.html]進行國際化。 引入vue-i18n

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import messages from './message.json'
import { langCode } from '../lang'

Vue.use(VueI18n)

export default new VueI18n({
  locale: langCode,
  messages
})
複製代碼

message.json

"cn": {
  "所有": "所有"
},
"en": {
  "所有": "All"
}
複製代碼

使用

vueI18n.t('所有')
// 或者,在template模板中
<p>{{ $t("所有") }}</p>
複製代碼

靜態的圖片

場景圖中的logo根據不一樣語言也須要不一樣,這樣的圖片須要直接其訪問其圖片路徑,咱們約定圖片的訪問路徑規則。

<img src="/images/logo_${lang}.svg" onerror='this.src="${ctx}/images/logo_en.svg"'/>
複製代碼

抽取配置的自動化腳本

國際化的文本處於各個代碼文件中,手動拷貝到配置文件是一件效率至關底下且容易出錯的事情。故寫個自動化腳本溜起來。

結語

隨着咱國家的國力不斷強盛,國際影響力不斷擴大。會有更多更好的產品走向世界,國際化已經成爲勢不可擋的趨勢。

相關文章
相關標籤/搜索