Tailwind Logo

sxastarter サンプルを多言語サイトで利用できるように調整する - その1 Navigation (後編)

XM CloudHeadless SXA

公開日: 2024-09-13

前回は Navigation コンポーネントで表示をする URL に関して、ロケールを入れた URL を利用してリンクを張る手順を紹介しました。実は多言語でデータを持っているときのナビゲーションに関して、もう少し課題を見ていきます。

各言語ごとのメニューとして

アイテムが常にすべての言語に対してデータを持っていない場合、Sitecore にデータを問い合わせをした場合、以下のような動作をします。

  • 日本語のみのアイテムの場合、Display name としてアイテムの Standard Value となる $name が返ってくる
  • 英語のみのアイテムの場合、そのアイテムの Display name が返ってくる

まずベースとして、英語と日本語のデータが設定されているツリーを用意します。

xmcaddlanguage03.png

これに対して、英語のみのアイテム、日本語のみのアイテムを用意します。以下が英語のみのアイテムです。

xmcaddlanguage04.png

続いて Global Menu 3 の下に日本語のみのアイテムを用意します。

xmcaddlanguage05.png

この状態で Navigation コンポーネントを配置するとどのような表示になるでしょうか?まず英語で表示をさせると以下のようになります。

xmcaddlanguage06.png

続いて日本語に切り替えてると、以下のようになります。

xmcaddlanguage07.png

Postman を利用してデータの確認

今回は Postman を利用してデータがどのように返ってきているのかを確認します。今回は Home アイテムの ID を利用して、そのアイテムの2つ下のアイテムを取得していきます。

GraphQL
query Item {
    item(language: "en", path: "{819432C0-EFF5-4D0D-82E4-50CD4782F948}") {
        displayName
        id
        name
        path
        rendered
        version
        children(hasLayout: true) {
            total
            results {
                displayName
                hasChildren
                id
                name
                path
                rendered
                version
                children(hasLayout: true) {
                    total
                    results {
                        displayName
                        hasChildren
                        id
                        name
                        path
                        rendered
                        version
                    }
                }
            }
        }
    }
}

上記の問い合わせは英語のコンテンツを取得するようにしています。例えば、Sub Menu 1-1 のアイテムの場合、以下のような結果が返ってきています。

JSON
{
   "Id": "376ed8b8-5e97-4390-8d1f-319fb4671a3e",
    "Styles": [
        "level2",
        "item0",
        "odd",
        "first"
    ],
    "Href": "/Global-Menu-1/Sub-Menu-1-1",
    "Querystring": "",
    "NavigationTitle": {
        "value": "Sub Menu 1-1",
        "editable": "Sub Menu 1-1"
    }
}

これに対して、Japanese Menu に関しては英語で問い合わせをすると以下のデータが返ってきます。

JSON
{
   "Id": "c1b7a744-b502-4b7a-81d6-f668cc4ad640",
    "Styles": [
        "level2",
        "item0",
        "odd",
        "first",
        "last"
    ],
    "Href": "/Global-Menu-3/Japanese-Menu",
    "Querystring": "",
    "NavigationTitle": {
        "value": "$name",
        "editable": "$name"
    }
}

アイテムとして持っていない状況ですが、アイテムの Standard Value として定義されている $name が返ってくる形となっています。このため、日本語のみのアイテムに対して、英語のナビゲーションには $name のメニューが表示される形です。

今度は ja-JP に切り替えてデータを取得してみます。

JSON
{
    "Id": "7b4cc476-bdec-4313-980f-13aa693df651",
    "Styles": [
        "level1",
        "item3",
        "even",
        "last"
    ],
    "Href": "/English-Menu",
    "Querystring": "",
    "DisplayName": "English Menu"
}

アイテムの英語の情報を取得する形となっています。これにより日本語のメニューでは English Menu が表示されるようになっています。

解決方法

Navigation コンポーネントのコードを確認しにいくと、アイテムの名前を取得するための関数が以下のように定義されています。

TypeScript
const getNavigationText = function (props: NavigationProps): JSX.Element | string {
  let text;

  if (props.fields.NavigationTitle) {
    text = <Text field={props.fields.NavigationTitle} />;
  } else if (props.fields.Title) {
    text = <Text field={props.fields.Title} />;
  } else {
    text = props.fields.DisplayName;
  }

  return text;
};

このコードは、アイテムの text として NavigationTitle があればその値を、ページの Title があればその項目を、それ以外は DisplayName を表示するようにしています。これにより設定が不足している場合でもアイテムがメニューに表示されるようになります。

今回は NavigationTile が有効であれば表示する、ただし NavigationTitle に値が含まれていない、もしくは $name になっている場合は表示しない、という形に書き換えます。

この処理は NavigationList の関数で、return の前に以下の行を追加してください。

TypeScript
  if (!props.fields.NavigationTitle) {
    return null;
  }

  if (props.fields.NavigationTitle.value === '$name') {
    return null;
  }

結果として、まず英語のメニューに対して $name が表示されないようになりました。

xmcaddlanguage08.png

続いて日本語の表示の時に English Menu が表示されない形となりました。

xmcaddlanguage09.png

まとめ

標準の Navigation コンポーネントを変更して、言語として持っている NavigationTitle があるときのみ表示するように書き換えました。これにより、コンテンツのツリーとして英語のみ、日本語のみという形でアイテムを持ってそれぞれメニューを自動的に表示することが可能となります。

関連タグ