DEV Community

tackme
tackme

Posted on • Updated on

Sitecore JSSで簡単なページを作ってみる

Sitecore JSSのコードファースト開発で簡単なページを作成する方法を、チュートリアル形式で紹介します。

前提知識

この記事は以下の知識を前提に書いています。極力シンプルに書いているので、そこまで詳しくなくても問題ありません。

  • Sitecoreの開発に関する知識
  • React.jsに関する知識

作成するページ

articleTitleフィールドとarticleContentフィールドを持つArcitlePageテンプレートのページを、/articleに作成します。

  • URL: /article
  • Template: ArticlePage
    • Fields: articleTitle, articleContent

アクセスすると、articleTitlearticleContentフィールドを表示するだけのシンプルなページです。

プロジェクトの準備

まずはSitecore JSSをインストールし、Reactのサンプルプロジェクトをセットアップしましょう。公式ドキュメントの以下のページでセットアップ方法が解説されています。

またSitecore Japanの公式YouTubeチャンネルに解説動画があるので、こちらを参考にしてもOKです。

ページテンプレートを定義する

まずはArticle Pageテンプレートを定義します。

ページテンプレートは/sitecore/definitions/routesフォルダに定義します。

デフォルトではroutesフォルダは存在しないので、自分で作成しましょう。

作成したroutesフォルダにArticlePage.sitecore.jsを追加します。

import {
  CommonFieldTypes,
  SitecoreIcon
} from "@sitecore-jss/sitecore-jss-manifest";

export default function (manifest) {
  manifest.addRouteType({
    name: "ArticlePage",             // テンプレート名
    displayName: "Article Page",     // テンプレートの表示名
    icon: SitecoreIcon.DocumentText, // テンプレートのアイコン
    fields: [
      {
        name: "articleTitle",                  // フィールド名
        displayName: "Article Title",          // フィールドの表示名
        type: CommonFieldTypes.SingleLineText, // フィールドタイプ
        standardValue: "$name"                 // デフォルト値
      },
      {
        name: "articleContent",
        displayName: "Article Content",
        type: CommonFieldTypes.RichText,
      }
    ]
  });
}
Enter fullscreen mode Exit fullscreen mode

manifest.addRouteType関数で、ArticlePageテンプレートを定義しています。ここで定義したテンプレートは、デプロイ時にSitecore上に自動で生成されます。

生成されるテンプレートはApp Routeテンプレートを継承しており、pageTitleフィールドを持っています。

ページアイテムを定義する

次に先程作成したテンプレートで、ページアイテムを定義します。

ページアイテムは/data/routesフォルダにYAML形式で定義します。

ページのURLはフォルダ構造で決まります。

例えば/products/cameraというURLのページを作成するには、以下のようなフォルダ構造にします。

  • routes/
    • products/
      • camera/
        • en.yml

各フォルダ直下にある<言語名>.ymlというファイルで、そのページアイテムの定義をしています。多言語対応させたい場合は、このファイルをコピーしてファイル名を別の言語に変更しましょう。
日本語に対応するには、Sitecore JSSでウェブサイトのデフォルト言語を日本語にするを参考にしてください。

今回は/articleにページを作成するので、routes/article/en.ymlに定義を記述します。中身は以下の例を参考にしてください。

# アイテム名
name: article
# アイテムの表示名
displayName: Article
# テンプレート(先程定義したもの)
template: ArticlePage
# 各フィールドの値
fields:
  articleTitle: My first JSS page
  articleContent: |
    <div>
      <p>This is my first JSS page.</p>
    </div>
Enter fullscreen mode Exit fullscreen mode

これで、ArticlePageテンプレートのアイテムを/articleに作成することができました。こちらもSitecoreへのデプロイ時に対応するパスにアイテムが作成されます。

フィールドを表示するコンポーネントを作成する

テンプレート、アイテムの作成ができたので、次はそのフィールドを表示するコンポーネントを作成します。
JSSのコンポーネントはSitecoreレンダリングとほぼ同義です。コンポーネントを作成してデプロイすると、Sitecore上にアイテム(レンダリング/データソーステンプレート)が生成されます。

レンダリングではなく純粋なReactコンポーネントも存在しますが、今回は割愛します。

コンポーネントを作成するには、コンソール上でjss scaffold ArticlePageContentを実行してください。

以下のファイルが生成されるはずです。

  • /src/components/ArticlePageContent/index.js
  • /sitecore/definitions/components/ArticlePageContent.sitecore.js

1つ目はコンポーネント(レンダリング)の定義ファイルで、2つ目はそのデータソーステンプレートの定義ファイルです。

まずはArticlePageContent.sitecore.jsの中身を覗いてみましょう。

// eslint-disable-next-line no-unused-vars
import { CommonFieldTypes, SitecoreIcon, Manifest } from '@sitecore-jss/sitecore-jss-manifest';

/**
 * Adds the ArticlePageContent component to the disconnected manifest.
 * This function is invoked by convention (*.sitecore.js) when 'jss manifest' is run.
 * @param {Manifest} manifest Manifest instance to add components to
 */
export default function(manifest) {
  manifest.addComponent({
    name: 'ArticlePageContent',
    icon: SitecoreIcon.DocumentTag,
    fields: [
      { name: 'heading', type: CommonFieldTypes.SingleLineText },
    ],
    /*
    If the component implementation uses <Placeholder> or withPlaceholder to expose a placeholder,
    register it here, or components added to that placeholder will not be returned by Sitecore:
    placeholders: ['exposed-placeholder-name']
    */
  });
}
Enter fullscreen mode Exit fullscreen mode

基本的にはページテンプレートの定義ファイルと同じです。Sitecoreデプロイすると、この定義に基づいてレンダリングとテンプレートが生成されます。

さて、今回はページアイテムのフィールドを表示するのでフィールドは不要です。

デフォルトで用意されてるheadingフィールドは削除してしまいましょう。

// eslint-disable-next-line no-unused-vars
import { CommonFieldTypes, SitecoreIcon, Manifest } from '@sitecore-jss/sitecore-jss-manifest';

/**
 * Adds the ArticlePageContent component to the disconnected manifest.
 * This function is invoked by convention (*.sitecore.js) when 'jss manifest' is run.
 * @param {Manifest} manifest Manifest instance to add components to
 */
export default function(manifest) {
  manifest.addComponent({
    name: 'ArticlePageContent',
    icon: SitecoreIcon.DocumentTag,
    fields: [
-     { name: 'heading', type: CommonFieldTypes.SingleLineText },
    ],
    /*
    If the component implementation uses <Placeholder> or withPlaceholder to expose a placeholder,
    register it here, or components added to that placeholder will not be returned by Sitecore:
    placeholders: ['exposed-placeholder-name']
    */
  });
}
Enter fullscreen mode Exit fullscreen mode

次に/src/components/ArticlePageContent/index.jsを開いてください。

import React from 'react';
import { Text } from '@sitecore-jss/sitecore-jss-react';

const ArticlePageContent = (props) => (
  <div>
    <p>ArticlePageContent Component</p>
    <Text field={props.fields.heading} />
  </div>
);

export default HomePageContent;
Enter fullscreen mode Exit fullscreen mode

中身はReactコンポーネントです。

props.fieldsプロパティでコンポーネントのデータソースのフィールドを取得できます。

さらに@sitecore-jss/sitecore-jss-reactパッケージのTextコンポーネントを使用してフィールドをレンダリングすると、エクスペリエンスエディタでの編集が可能になります。

Textの他にもRichTextDateFieldなどが用意されているので、フィールドのタイプに応じて使い分けましょう。

今回はコンポーネントではなくページアイテムのフィールドを取得したいのですが、デフォルトではpropsにはそのデータが含まれていません。

現在のページの情報を取得するにはwithSitecoreContextと呼ばれるHOCを使用する必要があります。

import React from 'react';
import {
  Text,
  withSitecoreContext  // withSitecoreContextをインポート
} from '@sitecore-jss/sitecore-jss-react';

const ArticlePageContent = (props) => (
  <div>
    <p>ArticlePageContent Component</p>
    <Text field={props.fields.heading} />
  </div>
);

// エクスポート時にwithSitecoreContextを適用する
export default withSitecoreContext()(ArticlePageContent);
Enter fullscreen mode Exit fullscreen mode

こうすることでprops.sitecoreContextから現在のページの情報を取得することができるようになります。このプロパティには、データベース名やページアイテムのIDなどが含まれています。
ページアイテムのフィールドを取得するにはprops.sitecoreContext.route.fieldsを使用します。

最終的なArticlePageComponent/index.jsのソースコードは以下の通りです。

import React from 'react';
import {
  Text,
  RichText,  // RichTextコンポーネントを追加
  withSitecoreContext  // withSitecoreContextをインポート
} from '@sitecore-jss/sitecore-jss-react';

const ArticlePageContent = (props) => (
  <div>
    {/* articleTitleフィールドを表示 */}
    <h1><Text field={props.sitecoreContext.route.fields.articleTitle} /></h1>
    <div>
      {/* articleContentフィールドを表示 */}
      <RichText field={props.sitecoreContext.route.fields.articleContent} />
    </div>
  </div>
);

// withSitecoreContextを適用
export default withSitecoreContext()(ArticlePageContent);
Enter fullscreen mode Exit fullscreen mode

コンポーネントをページに挿入する

作成したArticlePageContentコンポーネントを、ページのプレースホルダーに挿入します。

デフォルトでjss-mainプレースホルダーが用意されています。src/Layout.jsを開いてみてください。

import React from 'react';
import { Placeholder, VisitorIdentification } from '@sitecore-jss/sitecore-jss-react';
import { NavLink } from 'react-router-dom';
import { withTranslation } from 'react-i18next';
import Helmet from 'react-helmet';

///////// (省略) ///////////////

const Layout = ({ route }) => (
  <React.Fragment>
    {/* react-helmet enables setting <head> contents, like title and OG meta tags */}
    <Helmet>
      <title>
        {(route.fields && route.fields.pageTitle && route.fields.pageTitle.value) || 'Page'}
      </title>
    </Helmet>

    {/*
      VisitorIdentification is necessary for Sitecore Analytics to determine if the visitor is a robot.
      If Sitecore XP (with xConnect/xDB) is used, this is required or else analytics will not be collected for the JSS app.
      For XM (CMS-only) apps, this should be removed.

      VI detection only runs once for a given analytics ID, so this is not a recurring operation once cookies are established.
    */}
    <VisitorIdentification />

    <Navigation />

    {/* root placeholder for the app, which we add components to using route data */}
    <div className="container">
      <Placeholder name="jss-main" rendering={route} />
    </div>
  </React.Fragment>
);

export default Layout;

Enter fullscreen mode Exit fullscreen mode

このファイルは、ページ全体で使用するレイアウトの定義ファイルです。<Placeholder name="jss-main" rendering={route}>の部分でプレースホルダーを生成しています。

プレースホルダを追加するには、Sitecore JSSでレイアウトにプレースホルダを追加するを参考にしてください。

このjss-mainプレースホルダーに、先程作成したコンポーネントを挿入します。先程定義した/data/routes/article/en.ymlファイルを開いてください。

name: article
displayName: Article
template: ArticlePage
fields:
  articleTitle: My first JSS page
  articleContent: |
    <div>
      <p>This is my first JSS page.</p>
    </div>
# jss-mainプレースホルダーにTopPageContentコンポーネントを登録
placeholders:
  jss-main:
  - componentName: ArticlePageContent
Enter fullscreen mode Exit fullscreen mode

最後の4行を追加しました。ここではプレースホルダにどのコンポーネントを挿入するかを定義します。ページアイテムのプレゼンテーション詳細を設定しているイメージです。
コンポーネントのデータソースのフィールドを設定することもできますが、今回は使用しないため割愛します。

動作確認

コマンドラインでjss startを実行して、/articleページにアクセスしてみましょう。

設定したフィールドの値が表示されれば成功です。

デプロイ

以下のページでデプロイ方法が解説されています。

Sitecore Japanの公式YouTubeチャンネルで日本語の解説もあるので、ぜひ参考にしてください。

Top comments (0)