ヘッドレスOracle Content Managementを使用してNext.jsでイメージ・ギャラリを作成
イントロダクション
Next.jsは、サーバー側のレンダリングやReactベースのWebアプリケーション用の静的Webサイトの生成などの機能を可能にする、オープンソースのReactフロントエンド開発Webフレームワークです。
このチュートリアルでは、Oracle Content Managementをコンテンツ管理システムおよびそのコンテンツSDKとして使用して、Next.jsを使用してイメージ・ビューアを構築する基本ステップについて説明します。分類を使用してコンテンツを分類する方法、およびデジタル・アセットの様々なレンディションを様々なユースケースに使用できる方法を確認できます。このNext.jsサンプルは、GitHubで入手できます。
チュートリアルは、次の3つのタスクで構成されています。
前提条件
このチュートリアルを続行する前に、次の情報を先にお読みください。
このチュートリアルに従うには、次のものが必要です。
- Oracle Content Managementのサブスクリプション
- コンテンツ管理者ロールを持つOracle Content Managementアカウント
- ノード・バージョン10以上のWindowsまたはMacコンピュータ
構築しているもの
本イメージギャラリーはコーヒーショップで利用できる食品や飲料の画像から成る。
構築している機能を見ていくために、このイメージのギャラリー サイトのライブ バージョンであるチュートリアルの終わりを示します。
https://headless.mycontentdemo.com/samples/oce-nextjs-gallery-sample
カテゴリは分類の子ノードであり、階層に編成できます。オラクルのイメージ・ギャラリーでは、組織に関係なく、使用可能なすべてのカテゴリを表示します。これを実現するには、まず、コンテンツSDKのgetTaxonomies()メソッドを使用する使用可能な分類を見つける必要があります。
ノート: getTaxonomiesの実装では、REST APIリソースGET /published/api/v1.1/taxonomiesが使用されます。
次に、各分類のカテゴリ・セットを取得する必要があります。これを行うには、Content SDKのqueryTaxonomyCategories()メソッドを使用します。
ノート: queryTaxonomyCategoriesの実装では、REST API GET /published/api/v1.1/taxonomies/{id}/categoriesが使用されます。
Bagelsなどのカテゴリのプレビューを作成するには、イメージの数と最初の4つのイメージのURLを取得する必要があります。
カテゴリで公開されているアセットを検索するリクエストでは、次のように、問合せ文字列を使用してカテゴリ基準を指定します。
"(taxonomies.categories.nodes.id eq 892CD6BC4F654249A00CB7942EE8C773)"
イメージのロードを最適化するには、「サムネイル」という名前のイメージのレンディションを使用します。各イメージの使用可能なレンディションのセットを調べるコードについては、スクリプト/services.jsのretrieveThumbnailURL()を参照してください。
ノート:表示するデジタル資産の公開に加えて、分類をチャネルに公開する必要もあります。
続行するには、Oracle Content Managementのアクティブなサブスクリプションを持ち、コンテンツ管理者ロールでログインする必要があります。
タスク1: Oracle Content Managementの準備
このチュートリアルは、アセット・リポジトリを作成し、現在空のコンテンツ・モデルがある(つまり、コンテンツ・タイプは作成されていない)という前提に基づいています。
Oracle Content Managementインスタンスがまだない場合は、クイック・スタートを参照して、Oracle Cloudへの登録、Oracle Content Managementインスタンスのプロビジョニング、ヘッドレスCMSとしてのOracle Content Managementの構成方法を学んでください。
このチュートリアルでは、2つの方法のいずれかでコンテンツ・モデルを作成する必要があります。ダウンロード可能なアセット・パックが使用可能で、空のリポジトリにコンテンツ・タイプと関連付けられたコンテンツを入力するか、独自のコンテンツ・モデルおよびコンテンツを作成できます。
Oracle Content Managementを準備するには:
- チャネルおよびアセット・リポジトリを作成します。
- Oracle Content Managementサンプル資産パックのインポート
- 独自のイメージ・アセットのアップロード
- 分類の作成およびイメージ・アセットへのリンク
チャネルおよびアセット・リポジトリの作成
まず、コンテンツを公開できるように、Oracle Content Managementでチャネルおよびアセット・リポジトリを作成する必要があります。
Oracle Content Managementでチャネルおよびアセット・リポジトリを作成するには:
管理者としてOracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「チャネルの公開」を選択します。
右上隅にある「Create」をクリックして新しいチャネルを作成します。このチュートリアルの目的でチャネル'OCEImageGalleryChannel'に名前を付け、アクセスを公開したままにします。「保存」をクリックしてチャネルを作成します。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。
右上隅にある「Create」をクリックして、新しいアセット・リポジトリを作成します。このチュートリアルの目的で、アセット・リポジトリにOCEImageGalleryRepositoryという名前を付けます。
「チャネルの公開」フィールドで、OCEImageGalleryChannelを選択して、OCEImageGalleryRepositoryリポジトリのコンテンツをOCEImageGalleryChannelチャネルに公開できることをOracle Content Managementに示します。終了したら、「Save」をクリックします。
Oracle Content Managementサンプル資産パックのインポート
このチュートリアルに必要なすべてのコンテンツ・タイプおよびアセットを含む、事前構成されたOracle Content Managementサンプル・アセット・パックをダウンロードできます。
このチュートリアルで使用しているコンテンツのコピーは、Oracle Content Management Sample Asset Packからアップロードできます。これにより、コンテンツ・タイプを試行し、コンテンツを変更できます。アセット・パック・アーカイブOCESamplesAssetPack.zipをダウンロードして、選択したディレクトリに解凍できます。
Oracle Content Managementのダウンロード・ページから、Oracle Content Managementサンプル資産パック(OCESamplesAssetPack.zip)をダウンロードします。ダウンロードしたzipファイルをコンピュータ上の場所に抽出します。抽出後、この場所にはOCEImageGallery_data.zipというファイルが含まれます。
管理者としてOracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。次に、OCEImageGalleryRepositoryを選択し、上部のアクション・バーの「コンテンツのインポート」ボタンをクリックします。
ローカル・コンピュータから「ドキュメント」フォルダにOCEImageGallery_data.zipをアップロードします。
アップロード後、「OCEImageGallery_data.zip」を選択し、「OK」をクリックしてコンテンツをアセット・リポジトリにインポートします。
コンテンツが正常にインポートされたら、「アセット」ページに移動し、OCEImageGalleryRepositoryリポジトリを開きます。すべての関連イメージおよびコンテンツ・アイテムがアセット・リポジトリに追加されていることがわかります。
左上の「すべて選択」、「公開」の順にクリックして、インポートされたすべてのアセットを、前に作成した公開チャネル(OCEImageGalleryChannel)に追加します。
公開する前に、すべてのアセットを検証する必要があります。まず、選択したチャネルとしてOCEImageGalleryChannelを追加し、「検証」ボタンをクリックします。
アセットが検証されたら、右上隅にある「公開」ボタンをクリックして、選択したチャネルにすべてのアセットを公開できます。
これが完了すると、「アセット」ページで、すべてのアセットが公開されていることを確認できます。(アセット名の上のアイコンで確認できます。)
Oracle Content Management Sample Asset Packのインポート後、Next.jsでのイメージ・ギャラリーの作成を開始できます。
独自のイメージ・アセットのアップロード
このチュートリアルでは、「OCEImageGalleryRepository」というアセット・リポジトリを使用して、ギャラリ・サイトのホーム・ページを作成します。このホーム・ページは、「イメージ・ギャラリ」というタイトルと、イメージ・アセットが含まれるイメージ・コレクション・アルバムで構成されます。
イメージ・アセットをギャラリ・アセット・リポジトリに追加するには:
Oracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューの「アセット」をクリックします。
OCEImageGalleryRepositoryリポジトリを開きます。
ページの右上隅にある「追加」をクリックして、イメージ・アセットをギャラリ・アセット・リポジトリに追加します。
ローカル・コンピュータから独自の新規アセットをアップロードするか、Oracle Content Managementにすでに存在するアセットを選択します。
分類の作成およびイメージ・アセットへのリンク
Oracle Content Managementで分類を作成し、リポジトリ内のアセットにカテゴリを割り当てる必要があります。
Oracle Content Managementで分類を作成するには:
管理者としてOracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「分類」を選択します。
右上隅にある「作成」をクリックして新しい分類を作成します。このチュートリアルの目的で、チャネルに「OCEImageGalleryTaxonomy」という名前を付けます。
「作成」をクリックします。
次に、カテゴリを追加して分類を作成します。「カテゴリの追加」をクリックします。
親カテゴリ・アイテムに「Food」という名前を付け、次の子カテゴリを追加します。
- 朝食
- デザート
- 酒類
- サンドイッチ
画面の右上にある「完了」をクリックします。
「分類」ページで、OCEImageGalleryTaxonomy分類を選択し、アクション・バーの「昇格」をクリックして、アセット・リポジトリで使用できるようにします。
次に、OCEImageGalleryRepositoryリポジトリを編集して、そのリポジトリのOCEImageGalleryTaxonomy分類を有効にします。
管理者としてOracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。
OCEImageGalleryRepositoryリポジトリを選択して編集します。
「分類」フィールドでOCEImageGalleryTaxonomyを選択すると、その分類のカテゴリをOCEImageGalleryRepositoryリポジトリのアセットに割り当てることができます。
「保存」をクリックします。
次に、OCEImageGalleryRepositoryリポジトリ内の各イメージ・アセットに分類カテゴリを割り当てます。
Oracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューの「アセット」をクリックします。
OCEImageGalleryRepositoryリポジトリを開きます。
1つ以上のイメージ・アセットを選択し、アクション・バーの「詳細」をクリックし、メニューから「カテゴリ」を選択します。
「カテゴリ」パネルで、「カテゴリの追加」をクリックします。検索バーでカテゴリ名を検索するか、分類階層構造からカテゴリを選択し、「追加」をクリックして選択したカテゴリを割り当てます。資産には複数のカテゴリを割り当てることができます。
すべてのイメージ・アセットへの分類の割当てが終了したら、リポジトリ内のすべてのアセットを選択し、それらをOCEImageGalleryChannelチャネルに公開します。
タスク2: Next.jsでのイメージ・ギャラリの作成
Next.jsアプリケーションでOracle Content Managementコンテンツを利用するには、GitHubのオープンソース・リポジトリとして使用できるNext.jsイメージ・ギャラリー・サンプルを使用します。
ノート: Next.jsサンプルの使用はオプションであり、このチュートリアルで使用してすぐに開始できるようにしてください。独自のNext.jsアプリケーションを構築することもできます。
Next.jsでイメージ・ギャラリーを作成するには:
- サンプル・リポジトリのクローニングと依存関係のインストール
- Next.jsアプリケーションの構成
- Oracle Content Management Content SDKの使用
- コンテンツSDKを使用したコンテンツのフェッチ
サンプル・リポジトリのクローニングとインストールの依存性
Next.jsブログのサンプルは、GitHubのオープンソース・リポジトリとして使用できます。
まず、サンプルをGitHubからローカル・コンピュータにクローニングし、ディレクトリをリポジトリ・ルートに変更する必要があります。
git clone https://github.com/oracle/oce-nextjs-gallery-sample.git
cd oce-nextjs-gallery-sample
コード・ベースがあるので、アプリケーションの依存関係をダウンロードする必要があります。rootディレクトリから次のコマンドを実行します。
npm install
Next.jsアプリケーションの構成
このNext.jsイメージ・ギャラリのサンプルでは、Oracle Content Management Content SDK (およびその他のリクエスト)が適切なチャネル・トークンで正しいインスタンスURLおよびAPIバージョンをターゲット設定できるように、いくつかの情報を構成する必要があります。これらの値は、Script/server-config-utils.jsで新規配信クライアントをインスタンス化するために使用されます。
このアプリケーションは、Next.jsによって読み取られ、process.envを使用してアプリケーション内のコードで使用できるようにする.env.localファイルを使用します。
テキスト・エディタで.env.localファイルを開きます。次の情報が表示されます。
# The connection details for the Oracle Content Management server to be used for this application
SERVER_URL=https://samples.mycontentdemo.com
API_VERSION=v1.1
CHANNEL_TOKEN=e0b6421e73454818948de7b1eaddb091
各キーと値のペアを変更して、インスタンスURL、ターゲットとするAPIバージョン、および公開チャネルに関連付けられたチャネル・トークンを反映します。このチュートリアルのチャネルはOCEImageGalleryChannelです。
Oracle Content Management Content SDKの使用
Oracle Content Managementには、アプリケーションのコンテンツの検出および使用に役立つSDKが用意されています。SDKはNPMモジュールとして公開され、プロジェクトはGitHubでホストされます。
SDKの詳細は、ここを参照してください。
SDKは、package.jsonファイルのこのプロジェクトの実行時依存性として登録されました。
コンテンツSDKを使用したコンテンツのフェッチ
Content SDKを活用してコンテンツをフェッチし、Next.jsアプリケーションでレンダリングできるようになりました。
scriptフォルダには、Content SDKを使用してOracle Content Managementからデータを取得するためのコードが含まれます。
script/server-config-utils.jsファイルは、Content SDKをインポートし、.env.localで指定されている構成を使用して配信クライアントを作成します。
次のコマンドは、SDKをインポートします。
import { createDeliveryClient, createPreviewClient } from '@oracle/content-management-sdk';
次のコマンドは、配信クライアントを作成します。
return createDeliveryClient(serverconfig);
script/services.jsファイルには、アプリケーションのデータを取得するためのすべてのコードが含まれます。アプリケーションのページ・コンポーネントごとに、そのページのすべてのデータを取得するためのメイン機能が1つあります。
イメージをレンダリングするために、service.jsには、アセットのレンディションから構築されたアセットのソース・セットを取得するヘルパー・メソッドが用意されています。
function getSourceSet(asset) {
const urls = {};
.srcset = '';
urls.jpgSrcset = '';
urlsif (asset.fields && asset.fields.renditions) {
.fields.renditions.forEach((rendition) => {
assetaddRendition(urls, rendition, 'jpg');
addRendition(urls, rendition, 'webp');
;
})
}// add the native rendition to the srcset as well
.srcset += `${asset.fields.native.links[0].href} ${asset.fields.metadata.width}w`;
urls.native = asset.fields.native.links[0].href;
urls.width = asset.fields.metadata.width;
urls.height = asset.fields.metadata.height;
urlsreturn urls;
}
ホームページデータ
ホーム・ページには、すべてのデータを取得するために複数のデータ・コールが必要です。
- 最初に、.envで指定されたチャネルの分類をロードします。
- 分類ごとに、その分類内のすべてのカテゴリを取得します。
- カテゴリごとに、そのカテゴリに4つのコンテンツ項目があります。
- これらの各項目について、その翻訳URLを取得します。
src/scripts/services.jsを開き、ホーム・ページのすべてのデータを取得するために使用されるgetHomePageData()関数を見つけます。
export function getHomePageData() {
const deliveryClient = getClient();
// get the categories for all taxonomies then add all the category items to each category
return fetchAllTaxonomiesCategories(deliveryClient).then(
=> addItemsToCategories(deliveryClient, initialCategories).then(
(initialCategories) => {
(categories) // pull out all of the items for all of the categories then
// append the computed renditionUrls to each item.
const allItems = categories.map((category) => category.items);
const items = flattenArray(allItems);
// for each item, retrieve the rendition urls and add it to the item
.forEach((item) => {
items.renditionUrls = getSourceSet(item);
item;
})return { categories };
,
},
);
) }
getHomePageData()はfetchAllTaxonomiesCategories()を呼び出して、すべての分類内のすべてのカテゴリを取得します。
export function fetchAllTaxonomiesCategories(client) {
return client
.getTaxonomies()
.then((topLevelItem) => {
const taxonomyIds = topLevelItem.items.map((taxonomy) => taxonomy.id);
const promises = [];
// loop over each taxonomy id
.forEach((taxonomyId) => {
taxonomyIds// add a promise to the total list of promises to get the categories
// for the specific taxonomy id
.push(
promisesfetchCategoriesForTaxonomyId(client, taxonomyId)
.then((categoriesTopItem) => categoriesTopItem.items),
;
);
})
// execute all the promises returning a single dimension array of all
// of the categories for all of the taxonomies (note: no taxonomy information)
// is returned.
return Promise.all(promises)
.then((arrayOfCategoryArray) => flattenArray(arrayOfCategoryArray));
}).catch((error) => logError('Fetching taxonomies failed', error));
}
fetchAllTaxonomiesCategories()はfetchCategoriesForTaxonomyId()を呼び出して、特定の分類内のすべてのカテゴリを取得します。
function fetchCategoriesForTaxonomyId(client, taxonomyId) {
return client
.queryTaxonomyCategories({
id: `${taxonomyId}`,
}).then((topLevelItem) => topLevelItem)
.catch((error) => logError('Fetching categories for taxonomy failed', error));
}
次に、addItemsToCategories関数が呼び出され、4つのカテゴリ項目が各カテゴリに追加されます。
function addItemsToCategories(client, categories) {
const promises = [];
// loop over each category
.forEach((category) => {
categories// add a promise to the total list of promises to get the items
// for the specific category
.push(
promisesfetchItemsForCategory(client, category.id, true).then(
=> {
(topLevelItem) // add the item to the category before returning it
.items = topLevelItem.items;
category.totalResults = topLevelItem.totalResults;
categoryreturn {
...category,
;
},
},
);
);
})
// execute all the promises before returning the data
return Promise.all(promises).then((arrayOfItems) => flattenArray(arrayOfItems));
}
最後に、前述のgetSourceSetは、各アイテムのレンディションURLを取得するためにコールされます。
イメージ・グリッド・ページ・データ
イメージ・グリッド・ページはカテゴリIDを受信し、すべてのデータを取得するために複数のデータ・コールが必要です。
- 指定されたカテゴリのすべての項目を取得します。
- 各アイテムについて、その翻訳URLを取得します。
src/scripts/services.jsを開き、イメージ・グリッド・ページのすべてのデータを取得するために使用されるgetImageGridPageData()関数を見つけます。
export function getImageGridPageData(categoryId) {
const client = getClient();
return fetchItemsForCategory(client, categoryId, false).then(
=> {
(topLevelItem) const { totalResults } = topLevelItem;
// for each item, retrieve the rendition urls and add it to the item
.items.forEach((item) => {
topLevelItem.renditionUrls = getSourceSet(item);
item;
})return {
,
totalResultsitems: topLevelItem.items,
;
},
};
) }
これは、ホーム・ページと同様にfetchItemsForCategoryをコールしますが、制限はありません。これにより、4つだけでなくすべての項目が返されます。
データ問合せがあるため、Next.jsコンポーネントでレスポンスをレンダリングできます。
Next.jsコンポーネント
Next.jsはReactとReactに基づいており、JavaScriptのHTMLに似た構文拡張であるJSXと呼ばれるテクノロジーを使用してコンテンツをレンダリングしています。Oracle Content Managementからデータをレンダリングするために純粋なJavaScriptを記述できますが、JSXを使用することを強くお薦めします。
イメージ・ギャラリ・アプリケーションは、各ページを複数の小さいコンポーネントに分割し、その一部はホーム・グリッド・ページとイメージ・グリッド・ページの両方で使用されます。
次の数セクションでは、各コンポーネントでNext.jsによってアプリケーションをレンダリングする方法の概要を説明します。
ページ・フォルダ
サイトでは、次の2つのルートを提供します。
- ホームページには、イメージ・カテゴリのリストが表示されます。
- 特定のカテゴリIDのすべてのアイテムを表示するイメージ・グリッド・ページ
ページ・ディレクトリ内の次のページは、アプリケーションのルートとして処理されます。
索引コンポーネント
ホーム・ページは、分類のカテゴリのリストで構成され、そのカテゴリの4つのアイテムをプレビューします。これは、ページ/index.jsxにあるIndexコンポーネントによってレンダリングされます。
コンポーネントは、service.jsファイルからデータを取得するためにAPIをインポートします。
import { getHomePageData } from '../scripts/services';
getStaticProps()では、ビルド時にコールされ、コンポーネントはホーム・ページのレンダリングに必要なすべてのデータを取得します。
export async function getStaticProps() {
const data = await getHomePageData();
return {
props: { data },
;
} }
ギャラリ・コンポーネント
ギャラリ・コンポーネントは、リスト内の個々のカテゴリを表します。カテゴリ内の4つのアイテムのプレビューが表示されます。
これはsrc/components/Gallery.jsxにあり、すべてのデータをプロパティとして受信します。サーバーから追加データは取得されません。
ImageGridPageコンポーネント
イメージ・グリッド・ページ・コンポーネントには、URLのコンポーネントにIDが渡されるカテゴリ内のアイテムが表示されます。これは、ページ/カテゴリ/[id].jsxにあるArticleListPageコンポーネントによってレンダリングされます。
コンポーネントは、service.jsファイルからデータを取得するためにAPIをインポートします。
import { fetchAllTaxonomiesCategories, getImageGridPageData } from '../../scripts/services';
イメージ・グリッド・ページのURLは、カテゴリIDおよび名前をパスとして含む動的URLです。たとえば、URLパスは次のようになります。
- /category/categoryId1-name1
- /category/categoryId2-name2
- /category/categoryId3-name3
Next.jsが動的URLを持つページに静的サイト生成を使用する場合、getStaticPaths()を呼び出してそのページのすべてのパスを取得します。
export async function getStaticPaths() {
const categories = await fetchAllTaxonomiesCategories();
return {
paths: categories.map((category) => ({
params: { id: `${category.id}-${category.name}` },
,
}))fallback: true,
;
} }
getStaticProps()ファンクションは、イメージ・グリッド・ページの単一インスタンスのデータを取得するために使用されます。カテゴリIDおよび名前は、メソッドに渡されるパラメータから取得されます。カテゴリIDは、このページに必要なすべてのデータを取得するために使用されます。
export async function getStaticProps(context) {
const { params } = context;
const { id } = params;
const arr = id.split('-');
const categoryName = arr[1];
const categoryId = arr[0];
const data = await getImageGridPageData(categoryId);
return {
props: {
,
data,
categoryName,
};
} }
タスク3:デプロイのためのアプリケーションの準備
Next.jsのブログ・サイトが構築されたので、問題のデバッグやアプリケーションのプレビューを行う前に、ローカル開発サーバーでこのサイトを確認する必要があります。
デプロイメント用のアプリケーションを2つのステップで準備します。
ローカル開発サーバーのスピン・アップ
次のコマンドを実行して開発サーバーをローカルで起動できます。
npm run dev
次に、ブラウザをhttp://localhost:3000に開き、実際のサイトを表示します。
ノート:これは、ページを事前にレンダリングするためにページを事前にレンダリングしません。次のセクションを参照してください。
スクリプトを使用した開発と本番でのアプリケーションの構築および実行
本番の場合、ビルド・スクリプトはサイトの静的に生成するために使用されます。
npm run build
startスクリプトは、静的に生成されたページを提供するNode.jsサーバーを起動するために使用されます。
npm run start
ヘッドレスOracle Content Managementを使用してNext.jsでイメージ・ギャラリを作成
F49336-01
2021年10月
Copyright © 2021, Oracle and/or its affiliates.
原本著者: Oracle Corporation