前回の LinkList の動作を応用して、今回はパンくずリストのコンポーネントを作ってみたいと思います。
空のコンポーネントを作成する
まずは空っぽのコンポーネントを作成したいと思います。ウィザードを利用すると簡単に初期設定を作成することができます。
上記のページと異なる手順として、
- コンポーネント名を Breadcrumb
- コンポーネントのファイルは src\components\Navigation\Breadcrumb.tsx
- Other properties は設定しない
- Open Properties after Add の項目は No
- Datasource Template は削除する(テンプレートのアイテムも不要です)
これで準備は出来ました。
GraphQL を準備する
前回はアイテムの1つ下にあるリンクリスト一覧を取得する形でしたが、今回は該当するアイテムから遡ってナビゲーションタイトルを取得したいと思います。実際のクエリは以下の通りです。
fragment breadcrumbFields on Item {
field(name: "NavigationTitle") {
... on TextField {
value
}
}
url {
path
}
}
query BreadcrumbQuery($contextItem: String!, $language: String!) {
# Assume the item id is available on the page
item(path: $contextItem, language: $language) {
ancestors(
hasLayout: true
includeTemplateIDs: "B4283FEF-AE4E-4992-82E7-33B170C7A7DE"
) {
...breadcrumbFields
}
}
}
includeTemplateIDs の GUID は、Page テンプレートのアイテム ID を指定しています。
これに対して、以下の Query Variables を指定します。
{
"contextItem": "74010881-DF60-4FB0-973A-C109959E2E9B",
"language": "en"
}
この contextItem の項目は、そのアイテムの ID を指定するようにします。結果として、以下の Json データを取得することができます。
{
"data": {
"item": {
"ancestors": [
{
"field": {
"value": "Resource"
},
"url": {
"path": "/resource"
}
},
{
"field": {
"value": "Home"
},
"url": {
"path": "/"
}
}
]
}
}
}
該当するアイテムから Home までのアイテムの Navigation Title と Path を取得することができました。このクエリを GraphQL にコピーします。
コンポーネントのコードを変更する
今回はパンくずリストとして動作するかどうか、コードを入れて確認をしていきたいと思います。まず、返ってくる Json のデータを扱うことができるように Interface を定義してしまいます。
interface Ancestor {
field: {
value: string;
};
url: {
path: string;
};
}
interface Fields {
data: {
item: {
ancestors: Ancestor[];
};
};
}
続いて関数の呼び出し部分を書き換えます。
type BreadcrumbProps = {
params: { [key: string]: string };
fields: Fields;
};
export const Default = (props: BreadcrumbProps): JSX.Element => {
これで Json Rendering のアイテムに定義した GraphQL のデータに合わせて動くようになりました。また、コンポーネントが正しく動いているかを確認するために、以下のコードを追加します。
import { useSitecoreContext } from '@sitecore-jss/sitecore-jss-nextjs';
最後に、上記ですでに BreadcrumbProps を利用して呼び出す Default の中身の動作を以下のように書き換えます。
export const Default = (props: BreadcrumbProps): JSX.Element => {
const data = props.fields?.data;
const { sitecoreContext } = useSitecoreContext();
if (data.item.ancestors.length > 0) {
return (
<div className="component-content">
<div>Item OK </div>
<div>id: {sitecoreContext.itemId}</div>
</div>
);
}
return (
<div className="component-content">
<div>No Item </div>
<div>id: {sitecoreContext.itemId}</div>
</div>
);
};
これで準備が整いました。データを取得していれば Item OK の文字と、そのページの Sitecore のアイテムのアイテム ID が表示されるはずです。
アイテム ID を参照すると、正しく値を取得していることがわかります。
データの取得ができていることを確認できました。取得できているデータを一覧として表示するための関数を準備します。
function generateBreadcrumbList(ancestors: Ancestor[]): JSX.Element {
// Iterate through ancestors and generate li elementss
const ancestorListItems = ancestors.map((ancestor: Ancestor, index: number) => {
return (
<li key={index}>
<a href={ancestor.url.path}>{ancestor.field.value}</a>
</li>
);
});
// Wrap the list items with ul tags and return the JSX element
return <ul>{ancestorListItems}</ul>;
}
これを呼び出すように書き換えます。
if (data) {
return <div className="component-content">{generateBreadcrumbList(data.item.ancestors)}</div>;
}
以下のように作成することができました。
パンくずリストとしては、順番が逆の方が良いので、以下のように関数を書き換えます。
function generateBreadcrumbList(ancestors: Ancestor[]): JSX.Element {
const reversedAncestors = ancestors.reverse();
const ancestorListItems = reversedAncestors.map((ancestor: Ancestor, index: number) => {
結果、以下のように表示されました。
スタイルを適用できるようにする
出来上がったコンポーネントに対して Style の設定ができるように、以下のようにコードを追加します。
export const Default = (props: BreadcrumbProps): JSX.Element => {
const data = props.fields?.data;
const styles = `component breadcrumb ${props.params.styles}`.trimEnd();
const id = props.params.RenderingIdentifier;
const { sitecoreContext } = useSitecoreContext();
if (data) {
return <div className="component-content">{generateBreadcrumbList(data.item.ancestors)}</div>;
}
return (
<div className={styles} id={id ? id : undefined}>
<div className="component-content">
<div>No Item </div>
<div>id: {sitecoreContext.itemId}</div>
</div>
</div>
);
};
これで、パンくずリストを処理したい時には、breadcrumb を指定することで、スタイルシートの処理を追加できるようになりました。また、styles で CMS 側で持っているスタイルのデータを取得することもできました。
まとめ
今回は長くなりましたが、Next.js で作成するパンくずリストのサンプルを作成してみました。実際には GraphQL で対象となるデータを取得、それをコンポーネント側に渡して、取得して処理をする、という形になります。