美文网首页
scratch 国际化

scratch 国际化

作者: hanxianshe_9530 | 来源:发表于2019-11-01 13:01 被阅读0次

scratch语言配置文件

语言配置文件所在路径:scratch-gui\src\reducers\local.js。

import {addLocaleData} from 'react-intl';

import {localeData} from 'scratch-l10n';
import editorMessages from 'scratch-l10n/locales/editor-msgs';
import {isRtl} from 'scratch-l10n';

addLocaleData(localeData);

const UPDATE_LOCALES = 'scratch-gui/locales/UPDATE_LOCALES';
const SELECT_LOCALE = 'scratch-gui/locales/SELECT_LOCALE';

const initialState = {
    isRtl: false,
    locale: 'en',
    messagesByLocale: editorMessages,
    messages: editorMessages.en
};
...

语言源文件

文件所在文件夹: scratch-gui\node_modules\scratch-l10n

image.png

blocks是block块的翻译文件。
extensions是扩展的翻译文件。
interface 是gui界面的翻译文件。
pain-editor是造型页面的翻译文件。

一、语言文件的使用

  1. 引入react-intl

src\containers\gui.jsx是我们遇到的第一个用到多语言的地方

import {defineMessages, injectIntl, intlShape} from 'react-intl';
  1. defineMessages

defineMessages中,id相当于一个key,将来在scratch-l10导出的多语言文件中查找,defaultMessage表示默认显示,如果id没有对应的值,就显示默认的。description表示属性描述。

const messages = defineMessages({
    defaultProjectTitle: {
        id: 'gui.gui.defaultProjectTitle',
        description: 'Default title for project',
        defaultMessage: 'Scratch Project'
    }
});
  1. 在组件中注入 injectIntl
const ConnectedGUI = injectIntl(connect(
    mapStateToProps,
    mapDispatchToProps,
)(GUI));

二、通过 LocalizationHOC 高阶组件为GUI提供本地化状态

react-int包还需要用 <IntlProvider />包裹在组件的最外层,scratch-gui中通过LocalizationHOC高阶组件来封装

const WrappedGui = compose(
    // 提供本地化状态的高阶组件。
    LocalizationHOC, 
    // 提供封装组件错误边界的高阶组件,传入一个string类型的action,用于GA跟踪错误标签
    ErrorBoundaryHOC('Top Level App'), 
    // 加载字体高阶组件
    FontLoaderHOC, 
    // 从URL查询字符串获取参数并初始化redux状态的高阶组件
    QueryParserHOC, 
    // 提供通过id加载项目的行为的高阶组件。如果没有id,则加载默认的项目。
    ProjectFetcherHOC, 
    // 提供项目保存功能的高阶组件
    ProjectSaverHOC, 
    // 监听VM事件的高阶组件
    vmListenerHOC, 
    // 发送VM事件的高阶组件
    vmManagerHOC, 
    // 连接云服务器的高阶组件
    cloudManagerHOC 
)(ConnectedGUI);

LocalizationHOC组件:

import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';

import ConnectedIntlProvider from './connected-intl-provider.jsx';

/*
 * Higher Order Component to provide localiztion state. Creates a nested IntlProvider
 * to handle Gui intl context. The component accepts an onSetLanguage callback that is
 * called when the locale chagnes.
 * @param {React.Component} WrappedComponent - component to provide state for
 * @returns {React.Component} component with intl state provided from redux
 */
// 提供本地化状态的高阶组件。
//创建一个嵌套的IntlProvider来处理Gui intl上下文。
//组件接受一个onSetLanguage回调函数,该函数在语言环境chagnes时调用。
const LocalizationHOC = function (WrappedComponent) {
    class LocalizationWrapper extends React.Component {
        componentDidUpdate (prevProps) {
            if (prevProps.locale !== this.props.locale) {
                this.props.onSetLanguage(this.props.locale);
            }
        }
        render () {
            const {
                locale, // eslint-disable-line no-unused-vars
                onSetLanguage, // eslint-disable-line no-unused-vars
                ...componentProps
            } = this.props;
            return (
                <ConnectedIntlProvider>
                    <WrappedComponent {...componentProps} />
                </ConnectedIntlProvider>
            );
        }
    }
    LocalizationWrapper.propTypes = {
        locale: PropTypes.string,
        onSetLanguage: PropTypes.func
    };

    LocalizationWrapper.defaultProps = {
        onSetLanguage: () => {}
    };

    const mapStateToProps = state => ({
        locale: state.locales.locale
    });

    const mapDispatchToProps = () => ({});

    return connect(
        mapStateToProps,
        mapDispatchToProps
    )(LocalizationWrapper);
};

export default LocalizationHOC;

三、添加 localedata

定义在“src\reducers\locales.js”:

import {addLocaleData} from 'react-intl';

import {localeData} from 'scratch-l10n';
// 国际化只取中英文
import editorMessages from '../locales/editor-msgs';
// import editorMessages from 'scratch-l10n/locales/editor-msgs';
import {isRtl} from 'scratch-l10n';

addLocaleData(localeData);

const UPDATE_LOCALES = 'scratch-gui/locales/UPDATE_LOCALES';
const SELECT_LOCALE = 'scratch-gui/locales/SELECT_LOCALE';

const initialState = {
    isRtl: false,
    locale: 'en',
    messagesByLocale: editorMessages,
    messages: editorMessages.en
};
...

这里我们可以看到 scratch-l10n的多语言文件由node-modlue包的scratch-l10n/locales/editor-msgs.js文件导出

四、应用 FormattedMessage 来格式化多语言

 setReduxTitle (newTitle) {
        if (newTitle === null || typeof newTitle === 'undefined') {
            this.props.onUpdateReduxProjectTitle(
                this.props.intl.formatMessage(messages.defaultProjectTitle)
            );
        } else {
            this.props.onUpdateReduxProjectTitle(newTitle);
        }
    }

这里是gui组件挂载完成后 ,componentDidMount()生命周期函数调用:

  componentDidMount () {
        setIsScratchDesktop(this.props.isScratchDesktop);
        this.setReduxTitle(this.props.projectTitle);
        this.props.onStorageInit(storage);
    }

我们可以看到挂载完成后,设置项目标题,并保存到redux中,在这里用到了多语言
this.props.intl.formatMessage(messages.defaultProjectTitle)。在第一步injectIntl注入到组件后,组件的prop上就有了一个intl对象,然后formatMessage来应用。

作者:LiviSun
链接:https://www.jianshu.com/p/c97b88ca7631
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章

网友评论

      本文标题:scratch 国际化

      本文链接:https://www.haomeiwen.com/subject/apyfbctx.html