本地化 SharePoint 框架客户端 Web 部件

可以通过将 SharePoint Framework 客户端 Web 部件进行不同语言的本地化(使其适用于世界各地的 SharePoint 用户)来扩大其吸引力。 在本文中,你将将 Web 部件本地化为荷兰 (荷兰) 区域设置,并验证本地化值是否正确显示。

注意

执行本文中的步骤前,请务必先设置 SharePoint 客户端 Web 部件开发环境

准备项目

新建项目

  1. 为项目新建文件夹。

    md react-localization
    
  2. 转到项目文件夹。

    cd react-localization
    
  3. 在项目文件夹中,运行 SharePoint 框架 Yeoman 生成器,为新的 SharePoint 框架项目搭建基架。

    yo @microsoft/sharepoint
    
  4. 出现提示时,输入以下值:

    • 解决方案名称是什么? react-localization
    • 要创建哪种类型的客户端组件? WebPart
    • Web 部件名称是什么? 问候语
    • 你想要使用哪个模板? React
  5. 基架搭建完成后,运行以下命令,锁定项目依赖项的版本:

    npm shrinkwrap
    
  6. 在代码编辑器中,打开项目文件夹。 本文的步骤和屏幕截图中使用 Visual Studio Code,但你可以使用你喜欢的任何编辑器。

在 Visual Studio Code 中打开 SharePoint 框架项目

替换默认代码

  1. 在代码编辑器中,打开 ./src/webparts/greeting/GreetingWebPart.ts 文件,并将 IGreetingWebPartProps 接口的定义更新为以下代码:

    export interface IGreetingWebPartProps {
      greeting: string;
    }
    
  2. 在同一文件中,将 GreetingWebPart 类更改为:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
    
      public render(): void {
        const element: React.ReactElement<IGreetingProps > = React.createElement(
          Greeting,
          {
            greeting: this.properties.greeting
          }
        );
    
        ReactDom.render(element, this.domElement);
      }
    
      protected get dataVersion(): Version {
        return Version.parse('1.0');
      }
    
      protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
        return {
          pages: [
            {
              header: {
                description: strings.PropertyPaneDescription
              },
              groups: [
                {
                  groupName: strings.DisplayGroupName,
                  groupFields: [
                    PropertyPaneTextField('greeting', {
                      label: strings.GreetingFieldLabel
                    })
                  ]
                }
              ]
            }
          ]
        };
      }
    }
    
  3. 更新主 React 组件,方法是打开 ./src/webparts/greeting/components/Greeting.tsx 文件并将其代码更改为:

    import * as React from 'react';
    import styles from './Greeting.module.scss';
    import { IGreetingProps } from './IGreetingProps';
    import { escape } from '@microsoft/sp-lodash-subset';
    
    export default class Greeting extends React.Component<IGreetingProps, {}> {
      public render(): JSX.Element {
        return (
          <div className={styles.greeting}>
            <div className={styles.container}>
              <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>
                <div className="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
                  <span className='ms-font-xl ms-fontColor-white'>
                    Welcome to SharePoint!
                  </span>
                  <p className='ms-font-l ms-fontColor-white'>
                    Customize SharePoint experiences using web parts.
                  </p>
                  <p className='ms-font-l ms-fontColor-white'>
                    {escape(this.props.greeting)}
                  </p>
                  <a href="https://aka.ms/spfx" className={styles.button}>
                    <span className={styles.label}>Learn more</span>
                  </a>
                </div>
              </div>
            </div>
          </div>
        );
      }
    }
    
  4. 更新主 React 组件接口,方法是打开 ./src/webparts/greeting/components/IGreetingProps.tsx 文件并将其代码更改为:

    import { IGreetingWebPartProps } from '../GreetingWebPart';
    
    export interface IGreetingProps extends IGreetingWebPartProps {
    }
    
  5. 更新本地化 TypeScript 类型定义文件,方法是打开 ./src/webparts/greeting/loc/mystrings.d.ts 文件并将其代码更改为:

    declare interface IGreetingWebPartStrings {
      PropertyPaneDescription: string;
      DisplayGroupName: string;
      GreetingFieldLabel: string;
    }
    
    declare module 'GreetingWebPartStrings' {
      const strings: IGreetingWebPartStrings;
      export = strings;
    }
    
  6. 更新美国英语区域设置文件,方法是打开 ./src/webparts/greeting/loc/en-us.js 文件并将其代码更改为:

    define([], function() {
      return {
        "PropertyPaneDescription": "Greeting web part configuration",
        "DisplayGroupName": "Display",
        "GreetingFieldLabel": "Greeting to show in the web part"
      }
    });
    
  7. 在 Web 部件清单中,更新 greeting 属性的默认值,方法是打开 ./src/webparts/greeting/GreetingWebPart.manifest.json 文件并将 properties 部分更改为:

    {
      // ...
      "preconfiguredEntries": [{
        "groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Advanced
        "group": { "default": "Advanced" },
        "title": { "default": "Greeting" },
        "description": { "default": "Greets the user" },
        "officeFabricIconFontName": "Page",
        "properties": {
          "greeting": "Hello"
        }
      }]
    }
    
  8. 通过运行以下命令确认已正确应用所有更改:

    gulp serve
    
  9. 在 SharePoint 工作台中,向页面添加 Web 部件,并打开其配置。

    向页面添加了 Greeting Web 部件,其属性窗格已打开

本地化 Web 部件清单

每个 SharePoint 框架客户端 Web 部件均包含代码和清单。 清单提供有关 Web 部件的信息,如 Web 部件的标题、说明和图标。 向页面添加 Web 部件时,将向用户显示来自 Web 部件清单的信息。

用户使用此信息来确定该 Web 部件是否是他们正在寻找的部件。 如果希望用户使用你的 Web 部件,请务必提供能够正确反映 Web 部件的功能的标题和说明。 如果你的 Web 部件用于非英语网站,本地化其元数据可以进一步提升用户体验。

Web 部件清单中定义的某些属性(如标题或说明)支持指定本地化的值。 有关支持本地化的所有 Web 部件清单属性的完整列表,请参阅使用预配置项简化添加 Web 部件的步骤

支持本地化的属性类型是 ILocalizedString。 每个本地化的字符串必须为其他区域设置指定至少一个默认值和可选值。

为标题、说明和组名添加本地化值

  1. 在代码编辑器中,打开 ./src/webparts/greeting/GreetingWebPart.manifest.json 文件。
  2. preconfiguredEntries 数组中,为标题说明属性添加荷兰语(荷兰)翻译,方法是将代码更改为:
{
  // ...
  "preconfiguredEntries": [{
    "groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Advanced
    "group": { "default": "Advanced", "nl-NL": "Anders" },
    "title": { "default": "Greeting", "nl-NL": "Begroeting" },
    "description": { "default": "Greets the user", "nl-NL": "Begroet de gebruiker" },
    "officeFabricIconFontName": "Page",
    "properties": {
      "greeting": "Hello"
    }
  }]
}

重要

应注意区域设置的正确拼写。 第一部分必须用小写字母,而最后一部分必须为大写(“nl-NL”)。

  1. 运行以下命令,验证项目是否正常运行:

    gulp serve
    

注意

遗憾的是,SharePoint 工作台暂不支持预览 Web 部件清单中的本地化值。 它始终使用默认翻译。

本地化 Web 部件属性窗格

使用 Web 部件时,用户经常需要对其进行配置,以满足他们的特定需求。 为不同的配置设置提供说明性标签提高了 Web 部件的可用性,并减少了来自用户的帮助配置 Web 部件的支持请求数。

Web 部件属性窗格由各部分组成。 每个部分都有一个标头和一个或多个控件,供用户配置 Web 部件。 其中的每个控件都包含说明其用途的标签。

默认情况下,Web 部件从 JavaScript 资源文件加载字符串标签。 如果已使用完全信任的解决方案构建了经典 Web 部件,它们将类似于 .resx 资源文件。 不需要使用这些资源文件,并且可以直接在代码中包含字符串。 但是,强烈建议使用资源文件。 如果你以后需要翻译 Web 部件,那么现在这一点小小的额外成本将超出你今后提取所有标签需完成的工作量。

Web 部件使用的本地化文件存储在 ./src/webparts/greeting/loc 文件夹中。

SharePoint Framework 客户端 Web 部件使用的本地化文件在 Visual Studio Code 中突出显示。

loc 文件夹包含 TypeScript 类型定义文件(./src/webpart/greeting/loc/mystrings.d.ts),该文件通知 TypeScript 在本地化文件中包含的不同字符串。 使用来自该文件的信息,你的代码编辑器可以在你使用代码中的字符串时为你提供 IntelliSense。 此外,在构建你的项目时,TypeScript 可以验证你未引用尚未定义的字符串。

Visual Studio Code 中的本地化字符串的 IntelliSense

对于你的 Web 部件支持的每个区域设置,都有一个包含翻译字符串的纯文本 JavaScript 文件(而非 TypeScript),该文件以区域设置的小写字母命名(例如 en-us.js)。

使用新的 SharePoint 框架项目搭建的标准本地化文件

重要

需额外注意的一点是,应确认 TypeScript 类型定义文件中用于本地化的所有指定的键在所有本地化 JavaScript 文件中都有翻译。

SharePoint 框架使用的默认区域设置是 en-US。 如果某个网站所使用的区域设置并不支持你的 Web 部件,则 SharePoint 框架将 en-US 作为默认区域设置。

可以通过使用你的首选语言的翻译创建名为 default.js 的区域设置文件来重写此行为。 尽管名称 default.js 不遵循区域设置命名约定,它向 SharePoint 框架构建过程发出信号,以将该特定区域设置文件用作后备区域设置(而非标准美国英语区域设置)。

为 Web 部件属性窗格字符串添加本地化值

  1. ./src/webparts/greetings/loc 文件夹中,创建名为 nl-nl.js 的新文件,并输入以下代码:

    define([], function() {
      return {
        "PropertyPaneDescription": "Instellingen van het begroeting webonderdeel",
        "DisplayGroupName": "Weergave",
        "GreetingFieldLabel": "Begroeting die in het webonderdeel getoond wordt"
      }
    });
    
  2. 验证 TypeScript 类型定义文件中用于本地化的键与美国英语和荷兰语(荷兰)的区域设置文件的内容相匹配。

    本地化 TypeScript 类型定义文件和美国英语以及荷兰语(荷兰)的区域设置文件在 Visual Studio Code 中并排打开

验证本地化 Web 部件属性窗格字符串

使用 SharePoint 工作台的托管版本或开发人员租户上的团队网站对 Web 部件进行测试时,spPageContextInfo.currentUICultureName 属性表示的上下文网站的区域设置将用作默认区域设置。

使用本地 SharePoint 工作台测试 Web 部件时,SharePoint 框架默认使用 en-US 区域设置来显示 Web 部件属性窗格字符串。 有两种方法可以对 Web 部件支持的其他区域设置的值进行测试。

使用命令行参数指定要测试的区域设置

另一种指定本地 SharePoint 工作台所使用的区域设置的方法是将其指定为 gulp 任务的参数。

  • 通过运行以下命令,启动 SharePoint 工作台:

    gulp serve --locale=nl-nl
    

    当打开 Web 部件的配置时,将看到所有属性窗格字符串以荷兰语(荷兰)显示,而不以默认的美国英语显示。

    Web 部件属性窗格字符串以荷兰语(荷兰)显示

本地化 Web 部件内容

与本地化 Web 部件属性窗格字符串的方法相同,应在 Web 部件正文中本地化由其显示的所有字符串。 可以使用与本地化 Web 部件属性窗格字符串所使用的相同方法。 对于要本地化的每个字符串,在本地化 TypeScript 定义文件中添加键,然后将字符串翻译为相应区域设置 JavaScript 文件中的每个受支持的区域设置。

全球化 Web 部件字符串

通过搭建基架的 SharePoint 框架项目提供的默认 Web 部件将其字符串嵌入在代码中。 在本地化这些字符串前,需要参考本地化字符串将其替换。 此过程通常称为全球化国际化(或简称为 i18n)。

  1. 在代码编辑器中,打开 ./src/webparts/greeting/components/Greetings.tsx 文件。

  2. 在文件顶部,直接在最后一个 import 语句后添加对本地化字符串的引用:

    import * as strings from 'GreetingWebPartStrings';
    
  3. 然后,使用以下代码替换 Greeting 类的内容:

    // ...
    export default class Greeting extends React.Component<IGreetingProps, {}> {
      public render(): JSX.Element {
        return (
          <div className={styles.greeting}>
            <div className={styles.container}>
              <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>
                <div className="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
                  <span className='ms-font-xl ms-fontColor-white'>
                    Welcome to SharePoint!
                  </span>
                  <p className='ms-font-l ms-fontColor-white'>
                    Customize SharePoint experiences using web parts.
                  </p>
                  <p className='ms-font-l ms-fontColor-white'>
                    {escape(this.props.greeting)}
                  </p>
                  <a href="https://aka.ms/spfx" className={styles.button}>
                    <span className={styles.label}>{strings.LearnMoreButtonLabel}</span>
                  </a>
                </div>
              </div>
            </div>
          </div>
        );
      }
    }
    

将新的字符串添加到本地化 TypeScript 类型定义文件

使用引用替换字符串后,下一步是将该字符串添加到 Web 部件所使用的本地化文件。

  • 在代码编辑器中,打开 ./src/webparts/greetings/loc/mystrings.d.ts 文件,并将其代码更改为:

    declare interface IGreetingWebPartStrings {
      PropertyPaneDescription: string;
      DisplayGroupName: string;
      GreetingFieldLabel: string;
      LearnMoreButtonLabel: string;
    }
    
    declare module 'greetingStrings' {
      const strings: IGreetingWebPartStrings;
      export = strings;
    }
    
    

为新字符串添加本地化值

最后一步是为 Web 部件支持的所有区域设置中的新字符串提供本地化版本。

  1. 在代码编辑器中,打开 ./src/webparts/greeting/loc/en-us.js 文件,并将其代码更改为:

    define([], function() {
      return {
        "PropertyPaneDescription": "Greeting web part configuration",
        "DisplayGroupName": "Display",
        "GreetingFieldLabel": "Greeting to show in the web part",
        "LearnMoreButtonLabel": "Learn more"
      }
    });
    
  2. 打开 ./src/webparts/greeting/loc/nl-nl.js 文件,并将其代码更改为:

    define([], function() {
      return {
        "PropertyPaneDescription": "Instellingen van het begroeting webonderdeel",
        "DisplayGroupName": "Weergave",
        "GreetingFieldLabel": "Begroeting die in het webonderdeel getoond wordt",
        "LearnMoreButtonLabel": "Meer informatie"
      }
    });
    
  3. 通过运行以下命令确认正确显示所翻译的字符串:

    gulp serve --locale=nl-nl
    

    “了解更多”按钮的标签以荷兰语(荷兰)显示(而非默认的美国英语)

使用伪区域设置改进全球化和本地化 Web 部件

在构建 Web 部件时使用本地化具有明显的好处,但也是开发人员很容易忽视的方法。 对其他区域设置的翻译通常在项目完成后进行,而测试人员很难验证是否所有代码都能正确支持不同的区域设置。

不同区域设置中的相同单词具有不同的长度。 例如,对于同一句子,从英语翻译成德语要比翻译成荷兰语长 35%。 在所有翻译未在前端显示时,开发人员和设计人员很难确保用户界面能够正确容纳更长的字符串。

有些语言使用标准 ASCII 字符集以外的特殊字符。 如果设计人员使用非标准字体,则有可能该字体不能正确支持某些特殊字符。

在项目后期才发现所有这些相关问题可能会导致交付期延迟以及高额的修复成本。 SharePoint Framework 允许开发人员使用伪区域设置在构建 Web 部件时解决这些问题。

提示

什么是伪区域设置? 伪区域设置是旨在测试软件是否正确支持本地化过程的不同方面的区域设置,例如是否支持特殊字符串、从右到左的语言或在用户界面中容纳更长的字符串。

添加基本伪区域设置

  1. ./src/webparts/greeting/loc 文件夹中,添加名为 qps-ploc.js 的新文件,并粘贴以下代码:

    define([], function() {
      return {
        "PropertyPaneDescription": "[!!! Gřèèƭïñϱ ωèβ ƥářƭ çôñƒïϱúřáƭïôñ ℓôřè₥ ïƥƨú !!!]",
        "DisplayGroupName": "[!!! Ðïƨƥℓᥠℓ !!!]",
        "GreetingFieldLabel": "[!!! Gřèèƭïñϱ ƭô ƨλôω ïñ ƭλè ωèβ ƥářƭ ℓôřè₥ ïƥƨú !!!]",
        "LearnMoreButtonLabel": "[!!! £èářñ ₥ôřè ℓôř !!!]"
      }
    });
    

    提示

    可以在 Pseudolocalize! 中将美国英语字符串转换为对应的基本伪区域设置。 通过将生成的字符串的长度增加 35%,应能模拟翻译为更长区域设置(如德语或荷兰语)的字符串的长度。 此外,通过使用括号和感叹号将翻译括起来,可以更轻松地查看是否在屏幕上显示了整个字符串。

  2. 通过运行以下命令,使用基本伪区域设置测试项目:

    gulp serve --locale=qps-ploc
    

    向页面添加 Web 部件后,可以快速看到,在 Web 部件正文中有两个字符串尚未国际化,并仍以美国英语显示,而不是以基本伪区域设置显示。

    尽管使用基本伪区域设置进行了测试,在 Web 部件正文中仍有两个字符串以美国英语显示。

  3. 打开 Web 部件属性窗格,并确认所有字符串及其特殊字符均正确显示,并正确适合可用空间。

    使用基本伪区域设置测试本地工作台中的 Web 部件时打开 Web 部件属性窗格

本地化 Web 部件设置值

SharePoint 支持多语言用户界面 (MUI),其中网站管理员可以为用户界面启用多种语言。 用户访问网站时,将使用基于用户首选项的首选语言自动显示其用户界面。

在多语言网站上使用的 Web 部件应自动检测当前使用的语言,并以该语言显示其内容。 SharePoint 框架通过自动加载与当前所使用的语言对应的资源文件来简化此过程。 此外,使用 SharePoint 工作台的托管版本测试 SharePoint 框架 Web 部件时,工作台也会自动使用用户首选的语言。

通过 Web 部件属性配置的值并不存储在资源文件中。 在默认情况下,配置的值按原样使用,这可能导致不一致性,例如,当用户的首选语言为荷兰语时,系统仍以英语问候用户。

尽管将工作台设置为使用荷兰语(荷兰),系统仍以美国英语显示问候消息

通过使用由 SharePoint 框架提供的构建基块,可以扩展你的 Web 部件,以支持使用多种语言存储 Web 部件配置值。 对于每种受支持的语言,属性窗格均显示单独的文本字段,其中用户可以为该属性输入翻译的值。

在 Web 部件属性窗格中呈现多个文本字段,以允许翻译 Web 部件值

注意

用于测试本文中的 Web 部件的 SharePoint 网站是启用了美国英语、荷兰语和德语的多语言网站。 有关在 SharePoint 网站中启用其他语言的详细信息,请参阅选择想要为网站的用户界面使用的语言

添加 SharePoint Online 支持的语言列表

在多语言 SharePoint 网站上启用的语言列表以区域设置标识符 (LCID) 数组的形式返回,例如,美国英语为 1033

但是,当前使用的语言会返回为字符串,例如,美国英语为 en-US。 由于 JavaScript 不具备将 LCID 编号转换为区域设置名称的本机方式,反之亦然,因此必须亲自执行。

  1. 在代码编辑器中,打开 ./src/webparts/greeting/GreetingWebPart.ts 文件。

  2. 使用以下代码在现有的 GreetingWebPart 中添加名为 locales 的新类变量:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      private locales = {
        1025: 'ar-SA',
        1026: 'bg-BG',
        1027: 'ca-ES',
        1028: 'zh-TW',
        1029: 'cs-CZ',
        1030: 'da-DK',
        1031: 'de-DE',
        1032: 'el-GR',
        1033: 'en-US',
        1035: 'fi-FI',
        1036: 'fr-FR',
        1037: 'he-IL',
        1038: 'hu-HU',
        1040: 'it-IT',
        1041: 'ja-JP',
        1042: 'ko-KR',
        1043: 'nl-NL',
        1044: 'nb-NO',
        1045: 'pl-PL',
        1046: 'pt-BR',
        1048: 'ro-RO',
        1049: 'ru-RU',
        1050: 'hr-HR',
        1051: 'sk-SK',
        1053: 'sv-SE',
        1054: 'th-TH',
        1055: 'tr-TR',
        1057: 'id-ID',
        1058: 'uk-UA',
        1060: 'sl-SI',
        1061: 'et-EE',
        1062: 'lv-LV',
        1063: 'lt-LT',
        1066: 'vi-VN',
        1068: 'az-Latn-AZ',
        1069: 'eu-ES',
        1071: 'mk-MK',
        1081: 'hi-IN',
        1086: 'ms-MY',
        1087: 'kk-KZ',
        1106: 'cy-GB',
        1110: 'gl-ES',
        1164: 'prs-AF',
        2052: 'zh-CN',
        2070: 'pt-PT',
        2108: 'ga-IE',
        3082: 'es-ES',
        5146: 'bs-Latn-BA',
        9242: 'sr-Latn-RS',
        10266: 'sr-Cyrl-RS',
      };
    
      // ...
    }
    

    locales 变量列出 SharePoint Online 支持的所有语言。

  3. 添加两种类方法,以便从区域设置名称获取 LCID,并从 LCID 获取区域设置名称:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
    
      private getLocaleId(localeName: string): number {
        const pos: number = (Object as any).values(this.locales).indexOf(localeName);
        if (pos > -1) {
          return parseInt(Object.keys(this.locales)[pos]);
        }
        else {
          return 0;
        }
      }
    
      private getLocaleName(localeId: number): string {
        const pos: number = Object.keys(this.locales).indexOf(localeId.toString());
        if (pos > -1) {
          return (Object as any).values(this.locales)[pos];
        }
        else {
          return '';
        }
      }
    }
    

删除标准 Greeting Web 部件属性

最初,Greeting Web 部件定义了 Greeting 属性,用户可以在其中指定要在屏幕上显示的问候语。 若要将 Web 部件调整为支持多语言 SharePoint 网站,需要存储多个值(每种语言存储一个)。 由于无法预知将在网站上启用哪种语言,可以在运行时动态生成 Web 部件属性,而不是使用一个静态的 Web 部件属性。

  1. 在代码编辑器中,打开 ./src/webparts/greeting/GreetingWebPart.manifest.json 文件。

  2. properties 属性中删除 greeting 属性:

    {
      // ...
    
      "preconfiguredEntries": [{
        "groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Advanced
        "group": { "default": "Advanced", "nl-NL": "Anders" },
        "title": { "default": "Greeting", "nl-NL": "Begroeting" },
        "description": { "default": "Greets the user", "nl-NL": "Begroet de gebruiker" },
        "officeFabricIconFontName": "Page",
        "properties": {
        }
      }]
    }
    
  3. 打开 ./src/webparts/greeting/GreetingWebPart.ts 文件。

  4. IGreetingWebPartProps 接口定义中删除 greeting 属性:

    export interface IGreetingWebPartProps {
    }
    
  5. 因为主 React 组件应显示问候语,打开 ./src/webparts/greeting/components/IGreetingProps.ts 文件,并将 IGreetingProps 接口更改为:

    export interface IGreetingProps {
      greeting: string;
    }
    

    通过此修改,可以将 Web 部件中显示的问候语传递到 React 组件。

为所有已启用的语言显示属性窗格文本字段。

最初,通过使用 Web 部件配置,用户可以配置一条欢迎消息。 Web 部件使用户可以配置单个值,该值对所有用户显示,不论他们使用何种首选语言。 通过检索当前网站上启用的语言列表,可以动态显示文本字段以允许用户为网站上启用的所有语言提供翻译。

加载有关当前网站上已启用语言的信息

第一步是加载当前网站上已启用的所有语言的信息。

  1. 在代码编辑器中,打开 ./src/webparts/greeting/GreetingWebPart.ts 文件。

  2. 添加名为的 supportedLanguageIds 的新类变量:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
      private supportedLanguageIds: number[];
      // ...
    }
    

    由于我们将在 SharePoint 中查询数据,因此,使用 SharePoint Http 客户端进行操作。

  3. 添加 GreetingWebPart 上方的以下导入内容。

    import {
      SPHttpClient,
      SPHttpClientResponse
    } from '@microsoft/sp-http';
    
  4. GreetingWebPart 类中,添加一个名为 getSupportedLanguageIds 的新方法:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
    
      private getSupportedLanguageIds(): Promise<number[]> {
        return new Promise<number[]>((resolve: (supportedLanguageIds: number[]) => void, reject: (error: any) => void): void => {
          if (this.supportedLanguageIds) {
            resolve(this.supportedLanguageIds);
            return;
          }
    
          this.context.spHttpClient.get(this.context.pageContext.web.absoluteUrl + '/_api/web?$select=SupportedUILanguageIds', SPHttpClient.configurations.v1)
          .then((response: SPHttpClientResponse): Promise<{ SupportedUILanguageIds: number[] }> => {
            return response.json();
          }).then((siteInfo: { SupportedUILanguageIds: number[] }): void => {
            this.supportedLanguageIds = siteInfo.SupportedUILanguageIds;
            resolve(siteInfo.SupportedUILanguageIds);
          }, (error: any): void => {
            reject(error);
          });
        });
      }
    }
    

当前网站上已启用的语言列表只能加载一次。 如果尚未加载有关语言的信息,则方法使用标准 SharePoint 框架 HTTP 客户端调用 SharePoint REST API 并检索当前网站上已启用的语言的信息。

动态呈现所有语言的文本字段

现在,可以检索当前网站上已启用的语言的信息,将为每种语言显示文本字段,以便用户可以为问候语消息指定已翻译值。

  1. 在代码编辑器中,打开 ./src/webparts/greeting/GreetingWebPart.ts 文件。

  2. GreetingWebPart 类添加名为 greetingFields 的新类变量:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
      private greetingFields: IPropertyPaneField<any>[] = [];
      // ...
    }
    
  3. @microsoft/sp-webpart-base 包的 import 语句更改为:

    import {
      BaseClientSideWebPart,
      IPropertyPaneConfiguration,
      PropertyPaneTextField,
      IPropertyPaneField
    } from '@microsoft/sp-webpart-base';
    
  4. 更改 propertyPaneSettings Getter,以便从新添加的 greetingFields 类变量获取文本字段的列表:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
    
        protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
        return {
          pages: [
            {
              header: {
                description: strings.PropertyPaneDescription
              },
              groups: [
                {
                  groupName: strings.GreetingGroupName,
                  groupFields: this.greetingFields
                }
              ]
            }
          ]
        };
      }
    
      // ...
    }
    

    如果网站启用了多种语言,Web 部件将为用户呈现多个字段,以输入问候消息。 若要更清楚地表明这些字段归属在一起,可以将它们放入单独的组。

  5. 在代码编辑器中打开 ./src/webparts/greeting/loc/mystrings.d.ts 文件,并将其代码更改为:

    declare interface IGreetingWebPartStrings {
      PropertyPaneDescription: string;
      GreetingGroupName: string;
      LearnMoreButtonLabel: string;
    }
    
    declare module 'GreetingWebPartStrings' {
      const strings: IGreetingWebPartStrings;
      export = strings;
    }
    
  6. 更新以下资源文件,以便为 GreetingGroupName 字符串提供值。

    ./src/webparts/greeting/loc/en-us.js

    define([], function() {
      return {
        "PropertyPaneDescription": "Greeting web part configuration",
        "GreetingGroupName": "Greeting to show in the web part",
        "LearnMoreButtonLabel": "Learn more"
      }
    });
    

    ./src/webparts/greeting/loc/nl-nl.js

    define([], function() {
      return {
        "PropertyPaneDescription": "Instellingen van het begroeting webonderdeel",
        "GreetingGroupName": "Begroeting die in het webonderdeel getoond wordt",
        "LearnMoreButtonLabel": "Meer informatie"
      }
    });
    

    ./src/webparts/greeting/loc/qps-ploc.js

    define([], function() {
      return {
        "PropertyPaneDescription": "[!!! Gřèèƭïñϱ ωèβ ƥářƭ çôñƒïϱúřáƭïôñ ℓôřè₥ ïƥƨú !!!]",
        "GreetingGroupName": "[!!! Gřèèƭïñϱ ƭô ƨλôω ïñ ƭλè ωèβ ƥářƭ ℓôřè₥ ïƥƨú !!!]",
        "LearnMoreButtonLabel": "[!!! £èářñ ₥ôřè ℓôř !!!]"
      }
    });
    
  7. ./src/webparts/greeting/GreetingWebPart.ts 文件中,通过使用以下代码重写 onPropertyPaneConfigurationStart 方法:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
      protected onPropertyPaneConfigurationStart(): void {
        this.context.statusRenderer.displayLoadingIndicator(this.domElement, 'languages');
    
        this.getSupportedLanguageIds()
          .then((supportedLanguageIds: number[]): void => {
            this.greetingFields = [];
            supportedLanguageIds.forEach(localeId => {
              this.greetingFields.push(PropertyPaneTextField(`greeting_${localeId}`, {
                label: this.getLocaleName(localeId)
              }));
            });
    
            this.context.propertyPane.refresh();
            this.context.statusRenderer.clearLoadingIndicator(this.domElement);
            this.render();
          });
      }
    }
    

    当用户打开 Web 部件属性窗格时,方法将加载当前网站上已启用的语言的相关信息。 由于加载此信息可能需要一些时间,方法将显示一个加载标记,用于向用户传递其状态。

    加载已启用的语言的相关信息后,方法将创建一个新的属性窗格文本字段,该字段链接到名为 greeting__lcid_ 的动态 Web 部件属性,例如,美国英语为 greeting_1033

    对所有已启用的语言的文本字段进行构建后,方法通过调用 IPropertyPaneAccessor.refresh 方法来刷新属性窗格。

    最后,方法清除 Web 部件加载标记,并重新呈现 Web 部件正文。

    在 Web 部件属性窗格中显示所有已启用语言的文本字段

显示用户首选语言的问候语

最初,Web 部件对所有用户显示同一问候语,无论是何种首选语言都是如此。 现在,Web 部件存储了欢迎消息的不同翻译,它会使用由当前用户设置的首选语言显示问候语。

  1. ./src/webparts/greeting/GreetingWebPart.ts 文件中,将 Web 部件的 render 方法更改为:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
    
      public render(): void {
        const element: React.ReactElement<IGreetingProps> = React.createElement(Greeting, {
          greeting: this.getGreeting()
        });
    
        ReactDom.render(element, this.domElement);
      }
    }
    
  2. GreetingWebPart 中,添加一个名为 getGreeting 的新方法:

    export default class GreetingWebPart extends BaseClientSideWebPart<IGreetingWebPartProps> {
      // ...
    
      private getGreeting(): string {
        let localeId: number = this.getLocaleId(this.context.pageContext.cultureInfo.currentUICultureName);
        if (localeId === 0) {
          localeId = 1033;
        }
    
        return this.properties[`greeting_${localeId}`];
      }
    
      // ...
    }
    

    该方法获取当前使用的语言,并将其转换为区域设置 ID。 然后,它返回翻译为该语言的 greeting 属性的值。

不同版本类型中的本地化

根据所选的版本模式,SharePoint 框架处理本地化文件的方式有所不同。 以下是在调试版本和在发布版本中所生成的文件之间的一些差异。

调试版本中的本地化文件

在调试模式下构建 SharePoint 框架项目时,在生成的 Web 部件清单中仅包含有关默认区域设置的信息。 在调试模式下,SharePoint 框架使用默认 en-US 区域设置或在项目配置中指定的区域设置,或使用命令行中的 locale 参数。

具有已翻译字符串的资源文件并不包含在输出 dist 文件夹中。 相反,它们通过使用生成的 Web 部件清单中的路径从中间 lib 文件夹的运行时进行加载。

通过查看在调试构建期间生成的 Web 部件清单中 GreetingWebPartStrings 模块的信息,可以看到,尽管 Web 部件支持不同的区域设置(en-US、nl-NL 和 qps-ploc),存储在中间位置的 en-US 资源文件的路径已被分配为本地化模块的默认路径。

{
  "id": "edbc4e31-6085-4ffa-85f4-eeffcb0ea2d4",
  "alias": "GreetingWebPart",
  "componentType": "WebPart",
  "version": "0.0.1",
  "manifestVersion": 2,
  // ...
  "loaderConfig": {
    "entryModuleId": "greeting-web-part",
    "internalModuleBaseUrls": [
      "https://localhost:4321/"
    ],
    "scriptResources": {
      "greeting-web-part": {
        "type": "path",
        "path": "dist/greeting-web-part.js"
      },
      "GreetingWebPartStrings": {
        "defaultPath": "lib/webparts/greeting/loc/en-us.js",
        "type": "localizedPath",
        "paths": {
          "en-US": "lib/webparts/greeting/loc/en-us.js",
          "nl-NL": "lib/webparts/greeting/loc/nl-nl.js",
          "qps-ploc": "lib/webparts/greeting/loc/qps-ploc.js"
        }
      },
      // ...
    }
  }
}

发布版本中的本地化文件

在发布模式下构建 SharePoint Framework 项目时,在生成的 Web 部件清单中包含所有可用的区域设置的信息。 此外,每个区域设置的资源都存储在单独的文件中。 这些资源文件随 Web 部件清单和 Web 部件捆绑包一起复制到 ./temp/deploy 文件夹。

重要

在发布版本中,资源文件仅复制到 ./temp/deploy 文件夹,而不复制到 ./dist 文件夹。 在将 Web 部件部署到生产环境时,应始终使用来自 ./temp/deploy 文件夹的文件,以确保部署 Web 部件所需的所有文件。

在发布版本中检查生成的最新 Web 部件清单时,现在可以看到 GreetingWebPartStrings 模块包含所有受支持的区域设置的引用。

{
  "id": "edbc4e31-6085-4ffa-85f4-eeffcb0ea2d4",
  "alias": "GreetingWebPart",
  "componentType": "WebPart",
  "version": "0.0.1",
  "manifestVersion": 2,
  // ...
  "loaderConfig": {
    "entryModuleId": "greeting-web-part",
    "internalModuleBaseUrls": [
      "https://cdn.contoso.com/"
    ],
    "scriptResources": {
      "greeting-web-part": {
        "type": "path",
        "path": "greeting-web-part_159d9eb591c6716cae6d0ff15b78a19a.js"
      },
      "GreetingWebPartStrings": {
        "defaultPath": "react-localization-greetingwebpartstrings_en-us_b5e89eba6e8d819bf1647b3ab505dae5.js",
        "type": "localizedPath",
        "paths": {
          "en-US": "react-localization-greetingwebpartstrings_en-us_b5e89eba6e8d819bf1647b3ab505dae5.js",
          "nl-NL": "react-localization-greetingwebpartstrings_nl-nl_d6e80ff75385975e7737774e0802641e.js",
          "qps-ploc": "react-localization-greetingwebpartstrings_qps-ploc_effe5ee4af9cadee91bbf84327eb7308.js"
        }
      },
      // ...
    }
  }
}

在页面上加载 Web 部件时,SharePoint 框架使用来自上下文网站的信息自动为相应的区域设置加载资源文件。 如果找不到匹配的资源文件,SharePoint 框架将加载 defaultPath 属性中指定的文件。

通过将资源文件分离,SharePoint 框架将页面上加载的数据量最小化为与网站上所使用的相匹配的区域设置的数据量。

另请参阅