通过无外设的 Oracle Content Management 在 Next.js 中构建小型站点

简介

Next.js 是一个开源响应前端开发 Web 框架,支持服务器端呈现和生成基于 React 的 Web 应用程序的静态网站等功能。

要在 Next.js 应用程序中使用 Oracle Content Management 内容,可以使用作为 GitHub 上开源资料档案库的 Next.js 最小样例。

在本教程中,我们将利用 Oracle Content Management 作为无外设 CMS 及其软件开发工具包 (SDK) 在 Next.js 中构建一个简单的最小站点,以便在 JavaScript 中提供内容。GitHub 上提供了此 Next.js 示例。

本教程包含三个任务:

  1. 准备 Oracle Content Management
  2. 在 Next.js 中构建最小站点
  3. 准备应用程序以进行部署

先决条件

在继续本教程之前,建议您先阅读以下信息:

要遵循本教程,您将需要:

正在构建的内容

利用 Next.js 最少功能,您可以轻松地从 Oracle Content Management 资料档案库检索图像和其他内容。

要了解我们正在构建的内容,本教程的最终状态就是 Next.js 基本的站点,它使用来自 Oracle Content Management 的内容:

https://headless.mycontentdemo.com/samples/oce-nextjs-minimal-sample

主页 将在本教程结束时显示如下内容:

此图显示 Next.js 最小站点的登录页面。

与我们联系页面 将在本教程结束时显示如下内容:

此图显示了 Next.js 最低站点的联系人我们页面。

要继续,您需要具有对 Oracle Content Management 的有效订阅,并使用内容管理员角色登录。

任务 1:准备 Oracle Content Management

如果您还没有 Oracle Content Management 实例,请参阅 快速入门 来了解如何注册 Oracle Cloud、预配 Oracle Content Management 实例以及将 Oracle Content Management 配置为无外设 CMS。

在本教程中,您将需要创建内容模型。有一个 可下载资产包 ,它将使用内容类型和关联内容填写空库。

要准备 Oracle Content Management,请执行以下操作:

  1. 创建渠道和资产信息库
  2. 导入 Oracle Content Management 样品资产包

创建渠道和资产信息库

您首先需要在 Oracle Content Management 中创建渠道和资产存储库,以便可以发布内容。

要在 Oracle Content Management 中创建渠道和资产存储库,请执行以下操作:

  1. 以管理员身份登录到 Oracle Content Management Web 界面。

  2. 在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 发布渠道

    此图显示在“内容”页标题的下拉菜单中选择的“发布渠道”选项。

  3. 在右上角,单击 创建 以创建新通道。为本教程的目的命名通道 ‘ OCEMinimalChannel ’,并将访问保持为公共。单击 保存 以创建通道。

    此图显示发布渠道定义面板,在通道名称字段中显示 "OCEMinimalChannel"。

  4. 在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 资料档案库

    此图显示在“内容”页标题的下拉菜单中选择的“资料档案库”选项。

  5. 在右上角,单击 创建 以创建新的资产资料档案库。为本教程的目的,将资产存储库命名为 'OCEMinimalRepository'。

    此图显示了系统信息库定义面板,其中 "OCEMinimalRepository" 位于系统信息库名称字段中。

  6. 发布渠道 字段中,选择 OCEMinimalChannel 通道以指示 Oracle Content Management OCEMinimalRepository 资料档案库中的内容可以发布到 OCEMinimalChannel 通道。完成后单击 保存

    此图显示了系统信息库定义面板,其中 "OCEMinimalChannel" 位于 "Publishing Channels"(发布通道)字段中。

创建内容模型

下一个任务是创建内容模型。您可以使用以下两种方法之一:

导入 Oracle Content Management 样品资产包

您可以下载预配置的 Oracle Content Management 样例资产包,其中包含本教程的所有必需内容类型和资产。如果您愿意,也可以 创建自己的内容模型 ,而不是下载示例资产包。

您可以从 Oracle Content Management Samples Asset Pack 上载我们在本教程中使用的内容的副本。这允许您试验内容类型并修改内容。如果要导入 Oracle Content Management 样品资产包,您可以下载资产包档案 OCESamplesAssetPack.zip,然后将其提取到您选择的目录:

  1. 从 Oracle Content Management 下载 页下载 Oracle Content Management 样品资产包 (OCESamplesAssetPack.zip)。将下载的 zip 文件解压缩到您计算机上的某个位置。提取之后,此位置将包含一个名为 OCEMinimal_data.zip 的文件。

  2. 以管理员身份登录到 Oracle Content Management Web 界面。

  3. 在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 资料档案库 。现在选择 OCEMinimalRepository,然后单击顶部操作栏中的 导入内容 按钮。

    此图显示“资料档案库”页,其中选择了 OCEMinimalRepository 项。

  4. 将 OCEMinimal_data.zip 从本地计算机上载到 Documents 文件夹。

    此图显示了 OCEMinimal_data.zip 文件的上载确认屏幕。

  5. 上载后,选择 OCEMinimal_data.zip,然后单击 OK 将内容导入资产存储库。

    此图显示了已启用“确定”按钮的所选 OCEMinimal_data.zip 文件。

  6. 成功导入内容后,导航到 资产 页并打开 OCEMinimalRepository 系统信息库。您将看到所有相关的图像和内容项现在已添加到资产存储库中。

    此图显示 OCEMinimalRepository 系统信息库,其中包含刚导入的所有资产。

  7. 单击左上角的 全选 ,然后单击 发布 将所有导入资产添加到您之前创建的发布渠道 OCEGettingStartedChannel。

    此图显示 OCEMinimalRepository 系统信息库,其中选定了所有资产,操作栏中的“发布”选项可见。

  8. 在发布之前,您需要验证所有资产。首先将 OCEMinimalChannel 添加为所选通道,然后单击 验证 按钮。

    此图显示“验证结果”页,其中 OCEMinimalChannel 通道已添加到“渠道”字段中,所有要验证的资产以及启用“验证”按钮。

  9. 在验证资产后,您可以通过单击右上角的 发布 按钮将所有资产发布到选定的渠道。

    此图显示“验证结果”页,其中 OCEMinimalChannel 通道已添加到“渠道”字段中,所有已验证资产,并且启用了“发布”按钮。

完成此操作后,您可以在 资产 页面上看到所有资产都已发布。(您可以按资产名称上方的图标。)

此图显示“资产”页,其中所有资产均已发布。

导入 Oracle Content Management 样品资产包后,您可以开始 在 Next.js 中构建最小站点

创建您自己的内容模型

您也可以创建自己的内容模型,而不是 导入 Oracle Content Management 样品资产包

在本教程中,我们使用名为 'MinimalMain' 的内容类型作为此示例的主要内容类型。此内容类型包括页眉和页脚徽标以及应该包含在导航中的页面的列表。

此图显示了最小示例的主页。

要创建内容模型的内容类型,请执行以下操作:

  1. 以管理员身份登录到 Oracle Content Management Web 界面。
  2. 在左侧导航菜单中选择 内容 ,然后从页面标题的选择列表中选择 资产类型
  3. 单击右上角的 创建
  4. 选择创建内容类型(而非数字资产类型)。对所有必需的内容类型重复此操作。

此图显示了 Oracle Content Management Web 界面中的“创建资产类型”对话框。

我们将创建三种内容类型,每个类型都有自己的字段集:

第一个内容类型 MinimalMain 应具有以下字段:

显示名称 字段类型 必需 计算机名
headerLogo 单值介质字段 headerLogo
footerLogo 单值介质字段 footerLogo
多值参考字段

MinimalMain 内容类型定义应如下所示:

此图显示内容类型 ‘ MinimalMain ’ 的定义。它包括以下数据字段:headerLogo、footerLogo、页面。

第二种内容类型 MinimalPage 应具有以下字段:

显示名称 字段类型 必需 计算机名
小节 多值参考字段 小节

MinimalPage 内容类型应如下所示:

此图显示内容类型 ‘ MinimalPage ’ 的定义。它包括以下数据字段:部分。

第三种和最终内容类型 MinimalSection 应具有以下字段:

显示名称 字段类型 必需 计算机名
类型 单值文本字段 X 类型
标题 单值文本字段 标题
身体 单值大文本字段 身体
图像 单值图像字段 图像
操作 单值嵌入式内容字段 操作

MinimalSection 内容类型应如下所示:

此图显示内容类型 ‘ MinimalSection ’ 的定义。它包括以下数据字段:类型、标题、正文、图像、操作。

创建内容类型后,可以将这些内容类型添加到先前创建的 OCEMinimalRepository 系统信息库中:

  1. 以管理员身份登录到 Oracle Content Management Web 界面。
  2. 导航到 OCEMinimalRepository
  3. 编辑资料档案库,并在 资产类型 下指定所有三个新创建的内容类型。单击 保存 按钮以保存更改。

此图显示 Oracle Content Management 中的“编辑资料档案库”页,其中新创建的三个内容类型与 OCEMinimalRepository 资料档案库关联。

将内容类型添加到资料档案库后,可以在 资产 页上打开 OCEMinimalRepository 资料档案库,然后开始为所有内容类型创建内容项。

此图显示 Oracle Content Management Web 界面中“资产”页上的内容项,左侧带有集合、渠道、语言、类型、内容项选择和状态的选项。

任务 2:在 Next.js 中构建最小站点

要在服务器端呈现的 Next.js 应用程序中使用 Oracle Content Management 内容,可以使用 Next.js 最小站点样例,该站点样例在 GitHub 上作为开源资料档案库提供。

注意: 请记住,使用 Next.js 示例是可选的,在本教程中使用它可帮助您快速入门。您还可以构建自己的 Next.js 应用。

要在 Next.js 中构建最小站点,请执行以下操作:

  1. 克隆示例资料档案库并安装依赖项
  2. 配置 Next.js 应用程序
  3. 使用 Oracle Content Management Content SDK
  4. 使用内容 SDK 提取内容

克隆示例资料档案库和安装相关性

Next.js 最小站点样例在 GitHub 上作为开源系统信息库提供。

您首先需要将示例从 GitHub 克隆到本地计算机,并将目录更改为系统信息库根:

git clone https://github.com/oracle/oce-nextjs-minimal-sample.git
    cd oce-nextjs-minimal-sample

现在,您已经有了代码库,您需要下载应用程序的依赖项。从根目录运行以下命令:

npm install

配置 Next.js 应用程序

在此 Next.js 最少站点样例中,您需要配置一些信息,以便您的 Oracle Content Management Content SDK(以及任何其他请求)可以使用正确的通道标记将正确的实例 URL 和 API 版本作为目标。在脚本 /server-config-utils.js 中使用这些值来实例化新的传送客户机。

此应用程序使用 .env.local 文件,该文件由 Next.js 读取并使用 process.env 在应用程序内提供给代码。

在文本编辑器中打开 .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=ba0efff9c021422cb134c2fd5daf6015

更改每个键 - 值对以反映您的实例 URL、要定位的 API 版本以及与发布渠道关联的通道标记。此教程的渠道为 OCEMinimalChannel。

使用 Oracle Content Management Content SDK

Oracle Content Management 提供了 SDK 来帮助发现和使用应用程序中的内容。SDK 作为 NPM 模块 发布,项目托管在 GitHub 上。

在此处 了解有关 SDK 的更多信息。

SDK 已在 package.json 文件中注册为此项目的运行时相关性。

使用内容 SDK 提取内容

我们现在可以利用 Content SDK 提取内容,以便在 Next.js 应用中呈现。

Content SDK 使用 DeliveryClient 对象指定端点。可以使用该客户端对象进行所有请求。

脚本文件夹包含使用 Content SDK 从 Oracle Content Management 获取数据的代码。

脚本 /server-config-utils.js 文件导入 Content SDK,然后使用 .env.local 中指定的配置创建传送客户机。

以下命令导入 SDK:

import { createDeliveryClient, createPreviewClient } from '@oracle/content-management-sdk';

以下命令创建传送客户机:

return createDeliveryClient(serverconfig);

脚本 /services.js 文件包含用于获取此 Next.js 最少应用程序数据的函数。

fetchOceMinimalMain() 方法使用 minimalmain 斜杠检索内容类型 MinimalMain。

export async function fetchOceMinimalMain() {
      const data = await getItem('minimalmain', 'fields.headerlogo,fields.footerlogo,fields.pages');
      if (!data.hasError) {
        const { fields } = data;
        const { headerlogo, footerlogo } = fields;
        // Extract the sourceset for the headerImage and footerImage and put it back in the data
        data.headerRenditionURLs = getSourceSet(headerlogo);
        data.footerRenditionURLs = getSourceSet(footerlogo);
      }
      return data;
    }

对于呈现图像,service.js 提供了一种辅助方法来检索从资产重现中构建的资产的资源集。

function getSourceSet(asset) {
      const urls = {};
      urls.srcset = '';
      urls.jpgSrcset = '';
      if (asset.fields && asset.fields.renditions) {
        asset.fields.renditions.forEach((rendition) => {
          addRendition(urls, rendition, 'jpg');
          addRendition(urls, rendition, 'webp');
        });
      }
      // add the native rendition to the srcset as well
      urls.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;
      return urls;
    }

fetchPage() 方法使用页面的插件值检索内容类型 MinimalPage。

export async function fetchPage(pageslug) {
      // Get the page details
      const page = await getItem(pageslug, 'fields.sections');
      return page;
    }

getRenditionURLs() 方法将使用该映像的 ID 检索可以在某个部分中定义的任何图像的重现 URL。

export function getRenditionURLs(identifier) {
      const client = getClient();
      return client.getItem({
        id: identifier,
        expand: 'fields.renditions',
      }).then((asset) => getSourceSet(asset))
        .catch((error) => logError('Fetching Rendition URLs failed', error));
    }

现在,我们已经有了数据查询,可以在 Next.js 组件 中呈现响应。

Next.js 组件

Next.js 基于 React 和 React,使用一种称为 JSX 的技术(类似于 HTML 的 JavaScript 语法扩展)来呈现内容。尽管您可以编写纯 JavaScript 来呈现 Oracle Content Management 中的数据,但强烈建议您使用 JSX。

最低站点应用程序将每个页面细分为多个较小的组件。

接下来几部分概述了 Next.js 如何在我们每个组件中呈现应用:

页文件夹

在我们的站点中,我们提供了一条路径 - /page。请求定向到页 / 页 /[[。.slug]].jsx 文件中定义的主组件。通过在 next.config.js 中指定重定向,将根路径请求重定向到 /page。

  async redirects() {
        return [
          {
            source: '/',
            destination: '/page/',
            permanent: true,
          },
        ]
      }

所有页面都有一个标题,其中包含公司徽标和链接以及页脚,其中包含徽标和社交媒体图标。通过静态 URL 访问页面,并在将任何相关数据传递给任何子组件之前获取所需的所有数据。

Next.js 会将 page 目录中的任何页面视为应用程序的路由。

主要组件

所有页面由位于 page/page/[[。.slug]].jsx 的 Main 组件呈现。通过在双括号 ([[。。.slug]]) 中包含参数来捕获 Next.js 中的所有路由都是可选的。默认情况下,页列表中的第一页的根页没有传递到该页的参数,因此我们将 slug 参数定义为可选参数。

组件导入 API 以从 services.js 文件获取数据。

import { fetchOceMinimalMain, fetchPage, getRenditionURLs } from '../scripts/services';

页面的 URL 是动态 URL,其中包含作为路径的页面拼写,例如 URL 路径是

Next.js 对具有动态 URL 的页面使用静态站点生成时,会调用 getStaticPaths() 以获取该页面的所有路径。

export async function getStaticPaths() {
      const appData = await fetchOceMinimalMain();
      const { fields } = appData;
    
      // Generate the paths we want to pre-render based on posts
      const paths = fields.pages.map((page) => ({
        params: { slug: [page.slug] },
      }));
      // Also add the path for the root /
      paths.push({
        params: { slug: [] },
      });
      return {
        paths,
        fallback: false,
      };
    }

getStaticProps() 函数用于获取页面单个实例的数据。页面标准是从传递到方法的参数中获取的。然后使用页面幻灯片获取此页面所需的所有数据。

export async function getStaticProps(context) {
      // fetch the minimal main data
      const appData = await fetchOceMinimalMain();
      // find the slug param from the context. If its null, default to the first page slug
      const { params } = context;
      let { slug } = params;
      if (slug == null) {
        slug = appData.fields.pages[0].slug;
      }
      // fetch the page corresponding to the slug
      const pageData = await fetchPage(slug);
      const { headerRenditionURLs, footerRenditionURLs, fields } = appData;
      const { sections } = pageData.fields;
    
      // for each section in the page, if a image is present, get the corresponding rendition urls
      // and insert it back into the section
      const promises = [];
      sections.forEach((section) => {
        // add a promise to the total list of promises to get any section rendition urls
        if (section.fields.image) {
          promises.push(
            getRenditionURLs(section.fields.image.id)
              .then((renditionURLs) => {
                // eslint-disable-next-line no-param-reassign
                section.renditionURLs = renditionURLs;
              }),
          );
        }
      });
    
      // execute all the promises and return all the data
      await Promise.all(promises);
      return {
        props: {
          headerRenditionURLs,
          footerRenditionURLs,
          pages: fields.pages,
          pageData,
        },
      };
    }

页组件

“页面”组件负责呈现为页面定义的所有区段。打开位于组件 /Page.jsx 的“页面”组件。它只是使用从主组件传递到它的数据。它不会从服务器获取任何其他数据。它使用“区段”组件呈现区段数据。

Page.propTypes = {
      pageData: PropTypes.shape().isRequired,
    };

“页眉”组件位于组件 /Header.jsx 和位于组件 /Footer.jsx 的“页脚”组件中,仅使用从主组件传递给它们的数据。它们无法从服务器获取任何其他数据。

部分组件

“区段”组件位于组件 /Section.jsx,由“页面”组件使用,用于呈现 MinimalSection 类型的任何内容项。

此组件具有从“页面”组件传递到它的数据。

错误组件

“错误”组件位于组件 /Error.jsx,由页面和主要组件使用。如果调用服务器期间出现任何错误,则会显示错误。

任务 3:准备应用程序进行部署

现在,我们已构建了 Next.js 博客站点,需要在本地开发服务器中看到该站点,这样,在应用投入使用之前,我们就可以调试任何问题并预览应用。

在两个步骤中准备应用程序以进行部署:

  1. 启动本地开发服务器
  2. 使用脚本在开发和生产过程中构建和运行应用程序

搭建本地开发服务器

可以通过运行以下命令在本地启动开发服务器。

npm run dev

然后,打开浏览器以 http://localhost:3000 查看您的站点执行操作。

注意: 这不会预先呈现页面。要预先呈现页面,请参见下一节。

使用脚本在开发和生产过程中构建和运行应用程序

对于生产,构建脚本将用于静态生成站点。

npm run build

启动脚本用于启动满足静态生成的页面的 Node.js 服务器。

npm run start