SharePoint Framework のクライアント側 Web パーツをローカライズする

世界中の SharePoint ユーザーによって話されているさまざまな言語にローカライズすれば、SharePoint Framework のクライアント側の Web パーツを広くアピールできます。 この記事では、Web パーツをオランダ語 (オランダ) ロケールにローカライズし、ローカライズされた値が正しく表示されていることを確認します。

プロジェクトを準備する

新規プロジェクトを作成する

  1. プロジェクト用の新しいフォルダーを作成します。

    md react-localization
    
  2. プロジェクト フォルダーに移動します。

    cd react-localization
    
  3. プロジェクト フォルダーで SharePoint Framework Yeoman ジェネレーターを実行し、新しい SharePoint Framework プロジェクトをスキャホールディングします。

    yo @microsoft/sharepoint
    
  4. ダイアログ ボックスが表示されたら、次の値を入力します。

    • ソリューション名は何ですか? react-localization
    • どの種類のクライアント側コンポーネントを作成しますか? WebPart
    • Web パーツ名は何ですか? あいさつ
    • どのテンプレートを使用しますか? React
  5. スキャフォールディングが完了したら、次のコマンドを実行して、プロジェクトの依存関係のバージョンをロック ダウンします。

    npm shrinkwrap
    
  6. コード エディターでプロジェクト フォルダーを開きます。 この記事の手順とスクリーンショットでは Visual Studio Code を使用していますが、お好きなエディターをどれでも使用できます。

Visual Studio Code で開いた SharePoint Framework のプロジェクト

既定のコードを置き換える

  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 パーツをページに追加し、その構成を開きます。

    プロパティ ウィンドウが開かれているページに追加された案内応答 Web パーツ

Web パーツのマニフェストをローカライズする

SharePoint Framework のクライアント側の Web パーツはすべて、コードとマニフェストで構成されています。 マニフェストは、タイトル、説明、アイコンなどの Web パーツに関する情報を提供します。 Web パーツをページに追加すると、Web パーツのマニフェストからの情報がユーザーに表示されます。

この情報を使用して、ユーザーは自分が探しているものがその Web パーツかどうか判断します。 Web パーツを使用してもらうには、Web パーツの機能を正しく反映したタイトルと説明を入力する必要があります。 英語以外のサイトで Web パーツを使用する場合、そのメタデータをローカライズすれば、ユーザー エクスペリエンスはさらに向上します。

タイトルや説明など、Web パーツのマニフェストで定義されている一部のプロパティには、ローカライズされた値を指定することができます。 ローカライズをサポートしている Web パーツのマニフェスト プロパティの完全な一覧については、「事前構成済みのエントリを使用して Web パーツの追加を簡略化する」を参照してください。

ローカライズをサポートするプロパティの型は ILocalizedString です。 ローカライズされる各文字列では、少なくとも既定値を指定しなければならず、必要に応じてその他のロケールの値を指定します。

タイトル、説明、グループ名のローカライズされた値を追加する

  1. コード エディターで、./src/webparts/greeting/GreetingWebPart.manifest.json ファイルを開きます。
  2. preconfiguredEntries 配列で、コードを次のように変更し、titledescriptiongroup プロパティの翻訳をオランダ語 (オランダ) で追加します。
{
  // ...
  "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 パーツのプロパティ ウィンドウは、複数のセクションで構成されます。 各セクションには 1 つのヘッダーと、ユーザーが Web パーツを構成するための 1 つ以上のコントロールが含まれます。 これらの各コントロールには、その目的を説明するラベルが含まれています。

既定では、Web パーツは、JavaScript リソース ファイルから文字列ラベルを読み込みます。 完全信頼ソリューションを使用して従来の Web パーツを構築した場合、これらは .resx リソース ファイルに類似したものになります。 これらのリソース ファイルを必ず使用する必要はなく、コードに文字列を直接含めることもできます。 しかし、リソース ファイルを使用することを強くお勧めします。 それに伴う若干のオーバーヘッドは、後で Web パーツを翻訳しなければならなくなった場合に必要になる、すべてのラベルを後から抽出する労力を補って余りあります。

Web パーツで使用されるローカライズ ファイルは、./src/webparts/greeting/loc フォルダーに格納されています。

SharePoint Framework のクライアント側の Web パーツで使用されるローカライズ ファイルが Visual Studio Code で強調表示されている

loc フォルダーには、ローカライズされたファイルに含まれるさまざまな文字列を TypeScript に通知する TypeScript 型定義ファイル (./src/webpart/greeting/loc/mystrings.d.ts) が含まれます。 このファイルの情報を使用することにより、コード内の文字列を処理するときにコード エディターで IntelliSense を使用できます。 さらに、TypeScript は、プロジェクトのビルド中に、定義されていない文字列が参照されていないか検証できます。

Visual Studio Code においてローカライズされた文字列に対応する IntelliSense

Web パーツでサポートされているロケールごとに、翻訳済みの文字列が入ったプレーン JavaScript ファイル (TypeScript ではありません) もあります。これには、ロケールに基づく小文字の名前が付いています (例: en-us.js)。

新しい SharePoint Framework プロジェクトでスキャフォールディングされた標準ローカライズ ファイル

重要

ローカライズ用の TypeScript 型定義ファイルで指定されているすべてのキーが、すべてのローカライズ JavaScript ファイルで翻訳されていることを特に注意深く確認する必要があります。

SharePoint Framework で使用される既定のロケールは、en-us (英語) です。 Web パーツでサポートされていないロケールのサイトで Web パーツが使用される場合、SharePoint Framework は、既定のロケールとして 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 Framework は既定で en-US ロケールを使用して、Web パーツのプロパティ ウィンドウの文字列を表示します。 Web パーツでサポートされているその他のロケールからの値をテストする方法は 2 種類あります。

コマンド ライン引数を使用してテストするロケールを指定する

ローカルの SharePoint ワークベンチで使用するロケールを指定する別の方法は、それを gulp タスクの引数として指定することです。

  • 次のコマンドを実行して SharePoint ワークベンチを起動します。

    gulp serve --locale=nl-nl
    

    Web パーツの構成を開くと、すべてのプロパティ ウィンドウの文字列が既定の英語 (米国) ではなくオランダ語 (オランダ) で表示されます。

    オランダ語 (オランダ) で表示される Web パーツ プロパティ ウィンドウの文字列

Web パーツのコンテンツをローカライズする

Web パーツのプロパティ ウィンドウの文字列をローカライズするのと同じ方法で、Web パーツの本体に表示されるすべての文字列をローカライズする必要があります。 Web パーツのプロパティ ウィンドウの文字列をローカライズするときに使用するのと同じアプローチを使用することができます。 ローカライズする文字列ごとに、ローカライズ TypeScript 定義ファイルにキーを追加してから、サポートされているロケールの JavaScript ファイルでその文字列を対応するロケールに翻訳します。

Web パーツの文字列をグローバル化する

スキャフォールディングされる SharePoint Framework プロジェクトで提供される既定の 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 パーツの本文に国際化されていない 2 つの文字列があり、基本の擬似ロケールではなく英語 (米国) のまま表示されていることにすぐ気付くはずです。

    基本の擬似ロケールを使用してテストしているにもかかわらず、Web パーツの本体で 2 つの文字列が英語 (米国) で表示される

  3. Web パーツのプロパティ ウィンドウを開いて、すべての文字列と特殊文字が正しく表示されていること、およびそれらが使用可能なスペースに正しく収まっていることを確認します。

    基本の擬似ロケールを使用してローカル ワークベンチで Web パーツをテストすると、Web パーツのプロパティ ウィンドウが開きます

Web パーツの設定値をローカライズする

SharePoint は、サイトの管理者がユーザー インターフェイス用に複数の言語を有効にするための多言語ユーザー インターフェイス (MUI) をサポートしています。 ユーザーがサイトを訪問すると、ユーザー設定に基づいて UI が優先言語で自動的に表示されます。

多言語のサイトで使用されている Web パーツは、現在使用されている言語を自動的に検出し、その内容をその言語で表示します。 SharePoint Framework は、現在使用されている言語に対応するリソース ファイルを自動的に読み込むことによってこのプロセスを簡略化します。 さらに、ホストされたバージョンの SharePoint ワークベンチを使用して SharePoint Framework の Web パーツをテストする場合も、ワークベンチはユーザーの優先言語を自動的に使用します。

Web パーツ プロパティで構成された値はリソース ファイルに格納されません。 既定では、構成済みの値はそのまま使用されるため、ユーザーの優先言語がオランダ語であっても、ユーザーへの案内応答が英語で表示されるといった矛盾が生じる場合があります。

オランダ語 (オランダ) を使用するようにワークベンチが設定されているにもかかわらず、案内応答メッセージが英語 (米国) で表示される

SharePoint Framework で提供される構成要素を使用すると、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 からロケール名を取得したりできるように 2 つのクラス メソッドを追加します。

    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 プロパティが定義されており、ユーザーは画面に表示される案内応答を指定することができました。 多言語の SharePoint サイトをサポートするように Web パーツを適合させるには、複数の値、つまり言語ごとに 1 つの値を格納する必要があります。 サイトで有効にされる言語は事前にはわからないため、1 つの静的な 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 つの値を設定できました。 現在のサイトで有効になっている言語の一覧を取得すれば、サイトで有効になっているすべての言語の翻訳をユーザーが指定するためのテキスト フィールドを動的に表示できます。

現在のサイトで有効になっている言語に関する情報を読み込む

最初の手順は、現在のサイトで有効になっているすべての言語に関する情報を読み込むことです。

  1. コード エディターで、./src/webparts/greeting/GreetingWebPart.ts ファイルを開きます。

  2. supportedLanguageIds という名前の新しいクラス変数を追加します。

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

    SharePoint 内のデータを照会するため、この操作に SharePoint HTTP クライアントを使用します。

  3. GreetingWebPart の直前に次の import を追加します。

    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);
          });
        });
      }
    }
    

現在のサイトで有効になっている言語の一覧は、1 回だけ読み込む必要があります。 言語に関する情報がまだ読み込まれていない場合、メソッドは標準の SharePoint Framework の HTTP クライアントを使用して SharePoint REST API を呼び出し、現在のサイトで有効になっている言語に関する情報を取得します。

すべての言語用のテキスト フィールドを動的に表示する

現在のサイトで有効になっている言語に関する情報を取得できたら、案内応答メッセージの翻訳済みの値をユーザーが指定できるように、これらの各言語でテキスト フィールドを表示します。

  1. コード エディターで、./src/webparts/greeting/GreetingWebPart.ts ファイルを開きます。

  2. greetingFields という名前の新しいクラス変数を GreetingWebPart クラスに追加します。

    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 ゲッターを変更し、新たに追加された 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 Framework はローカライズ ファイルを異なる方法で処理します。 デバッグ ビルドとリリース ビルドで生成されたファイルの相違点の一部を次に示します。

デバッグ ビルドのローカライズ ファイル

SharePoint Framework プロジェクトをデバッグ モードでビルドする場合、生成された Web パーツのマニフェストには既定のロケールに関する情報のみが含まれます。 デバッグ モードでは、SharePoint Framework は、既定の 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 フレームワーク プロジェクトをリリース モードでビルドする場合、生成された Web パーツのマニフェストには使用可能なすべてのロケールに関する情報が含まれます。 また、各ロケールのリソースは、別々のファイルに格納されます。 これらのリソース ファイルは、Web パーツのマニフェストおよび Web パーツのバンドルとともに ./temp/deploy フォルダーにコピーされます。

重要

リリース ビルドでは、リソース ファイルは ./dist フォルダーではなく、./temp/deploy フォルダーだけにコピーされます。 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 Framework はコンテキスト サイトからの情報を使用して、対応するロケールのリソース ファイルを自動的に読み込みます。 一致するリソース ファイルが見つからない場合、SharePoint Framework は defaultPath プロパティで指定されたファイルを読み込みます。

SharePoint Framework は、リソース ファイルを分けることにより、サイトで使用されるロケールと一致する最小限の量のデータだけをページに読み込みます。

関連項目