Gatsby 比 Hexo 更像一个通用框架,关于博客的工具真是全靠社区衬托。Nlvi 迁移遇到了标签云和分类等各种问题,还有一个多语言问题…
找了一圈插件,i18n 大多数方案都是「一个站点同时多语言」,这对一个博客来说没必要啊(相对来说我博文是不是也得写个几份…),想了一圈好像也没必要上react-intl
,直接手作一个吧 —— 按照**「好看的皮囊千篇一律」**写一个
但是主题毕竟是要开源的,所以如果有好兄弟萌觉得 i18n 处理不行,自行替换成 gatsby-plugin-i18n
或者 react-intl
就可以了
Context
直接从 react 分出 createContext
方法,直接用
import { createContext } from 'react'
const langContext = createContext({} as ContextInterface)
// 创建上下文后输出 Provider 和 Consumer 还是要的
export const Provider = langContext.Provider
export const Consumer = langContext.Consumer
// ps: 其实 Consumer 用不上...
生成翻译
hexo 版 nlvi 已经有语言文件,所以直接拿过来放到lang
文件夹下,然后每个文件通过 yaml2json 转成json
,简单一点就不上 yaml 了
大概思路就是:
- 设定是通过主题的
options
传入lang
属性,然后lang
写到siteMetadata
中 - 由
layout
读取语言,传入翻译生成文本,传入Provider
- 使用的地方使用
formatMessage
去接
所以也就是接地气且极其简化啥都不考虑保证数据存在版的react-intl
。方法可以这么写
export const genTranslate = (lang: string) => {
const _message = require(`@/lang/${lang}.json`)
if (!_message) {
throw Error(`${lang} language json was not found.`)
}
const formatMessage = ({ id, defaultMsg }: FormatMessageType): string =>
// _get 来自 lodash
_get(_message, id) || defaultMsg || ''
const formatter = () => ({ formatMessage, _message })
return formatter()
}
使用翻译
直接用 useContext
去接,2020年该跟风用 hooks 了(大雾
export const useIntl = (): ContextInterface => useContext(langContext)
所以这么写的话,只要在 layout
下的组件都可以用这个方式拿到翻译
const { formatMessage: t } = useIntl()
这样一来其实跟使用 react-intl
是差不多的,就算日后要改也应该不用动业务代码
所以刚刚那句话还差一半来着?另一半应该是**「糜烂的灵魂(?)凑合对付」**!