Erstellen Sie einen Blog in Oracle JET mit Headless Oracle Content Management

Einführung

Oracle JavaScript Extension Toolkit (Oracle JET) ist ein komplettes, modulares Open-Source-Entwicklungstoolkit JavaScript, mit dem Entwickler ansprechende Benutzeroberflächen erstellen können. Der Service basiert auf Branchenstandards und dem beliebten Open-Source-Framework, Preact, einer einfachen Alternative zu React mit einer ähnlichen API. Oracle JET bietet erweiterte Funktionen und Services, mit denen Entwickler bessere Anwendungen schneller erstellen können.

In diesem Tutorial erstellen wir einen einfachen Blog in Oracle JET in der virtuellen DOM-(VDOM-)Architektur, indem wir Oracle Content Management als Headless CMS sowie sein Software Development Kit (SDK) für die Inhaltsbereitstellung nutzen. Dieses Oracle JET-Beispiel ist unter GitHub verfügbar.

Das Tutorial besteht aus drei Schritten:

  1. Oracle Content Management vorbereiten
  2. Blog in Oracle JET erstellen
  3. Anwendung für Deployment vorbereiten

Voraussetzungen

Bevor Sie mit diesem Tutorial fortfahren, sollten Sie zuerst folgende Informationen lesen:

Um diesem Tutorial zu folgen, benötigen Sie:

Was wir entwickeln

Unser Blog wird aus einer zweistelligen Website bestehen, auf der Besucher Blogartikel, die in Themen organisiert sind, erkunden können. Die erste Seite, die Homepage, besteht aus Branding (Firmenname und Logo), einigen Links und einer nach Thema sortierten Liste von Artikeln. Die zweite Seite, die Artikelseite, zeigt einen Blog-Artikel, einschließlich Informationen über den Autor des Blogs.

So sieht die Homepage am Ende dieses Tutorials aus:

Diese Abbildung zeigt die Homepage für die Demo-Site von Cafe Supremo mit einer Liste der verfügbaren Themen und Artikel.

So sieht die Artikelseite am Ende dieses Tutorials aus:

Diese Abbildung zeigt eine Artikelseite mit dem Namen "Schöne Latte-Kunst erstellen".

Um fortzufahren, benötigen Sie ein aktives Abonnement für Oracle Content Management und müssen mit der Rolle "Inhaltsadministrator" angemeldet sein.

Aufgabe 1: Oracle Content Management vorbereiten

Wenn noch keine Oracle Content Management-Instanz vorhanden ist, erfahren Sie im Schnellstart, wie Sie sich für Oracle Cloud registrieren, eine Oracle Content Management-Instanz bereitstellen und Oracle Content Management als Headless CMS konfigurieren.

Für dieses Tutorial haben Sie zwei Möglichkeiten, ein Contentmodell zu erstellen. Es ist ein herunterladbares Assetpack verfügbar, das Ihr leeres Repository mit Inhaltstypen und zugehörigen Inhalten ausfüllt, oder Sie können Ihr eigenes Contentmodell und Ihren eigenen Inhalt erstellen.

So bereiten Sie Oracle Content Management vor:

  1. Erstellen Sie ein Kanal- und Asset-Repository.
  2. Erstellen Sie ein Contentmodell mit einer der beiden folgenden Methoden:

Kanal- und Anlagen-Repository erstellen

Sie müssen zunächst einen Kanal und ein Asset-Repository in Oracle Content Management erstellen, damit Sie Inhalte veröffentlichen können.

So erstellen Sie einen Kanal und ein Asset-Repository in Oracle Content Management:

  1. Melden Sie sich als Administrator bei der Oracle Content Management-Weboberfläche an.

  2. Wählen Sie im linken Navigationsmenü die Option Inhalt, und wählen Sie dann in der Auswahlliste im Seitenheader die Option Kanäle veröffentlichen aus.

    Diese Abbildung zeigt die im Dropdown-Menü im Header der Seite "Inhalt" ausgewählte Option "Veröffentlichungskanäle".

  3. Klicken Sie in der oberen rechten Ecke auf Erstellen, um einen neuen Channel zu erstellen. Benennen Sie den Kanal "OCEGettingStartedChannel" für dieses Tutorial, und halten Sie den Zugriff öffentlich. Klicken Sie auf Speichern, um den Channel zu erstellen.

    Diese Abbildung zeigt den Bereich "Veröffentlichungskanaldefinition" mit "OCEGettingStartedChannel" im Feld "Kanalname".

  4. Wählen Sie im linken Navigationsmenü die Option Inhalt, und wählen Sie dann in der Auswahlliste im Seitenheader die Option Repositories aus.

    Diese Abbildung zeigt die Option "Repositorys", die im Dropdown-Menü im Header der Inhaltsseite ausgewählt wurde.

  5. Klicken Sie in der oberen rechten Ecke auf Erstellen, um ein neues Asset-Repository zu erstellen. Benennen Sie das Asset-Repository 'OCEGettingStartedRepository' für den Zweck dieses Tutorials.

    Diese Abbildung zeigt den Bereich für die Repository-Definition mit "OCEGettingStartedRepository" im Feld für den Repository-Namen.

  6. Wählen Sie im Feld Kanäle veröffentlichen den Kanal OCEGettingStartedChannel aus, um Oracle Content Management anzugeben, dass Inhalte im Repository OCEGettingStartedRepository im Kanal OCEGettingStartedChannel veröffentlicht werden können. Klicken Sie anschließend auf Speichern.

    Diese Abbildung zeigt den Bereich für die Repository-Definition mit "OCEGettingStartedChannel" im Feld "Veröffentlichungskanäle".

Contentmodelle erstellen

Im nächsten Schritt erstellen Sie ein Contentmodell. Sie haben zwei Möglichkeiten:

Oracle Content Management-Musterassetpaket importieren

Sie können ein vorkonfiguriertes Oracle Content Management-Beispielassetspack herunterladen, das alle erforderlichen Inhaltstypen und Assets für dieses Tutorial enthält. Falls gewünscht, können Sie auch ein eigenes Contentmodell erstellen, anstatt das Beispielassetpaket herunterzuladen.

Sie können eine Kopie des Inhalts, den wir in diesem Tutorial verwenden, aus dem Oracle Content Management Samples Asset Pack hochladen. Dadurch können Sie mit den Inhaltstypen experimentieren und den Inhalt ändern. Wenn Sie das Oracle Content Management Samples Asset Pack importieren möchten, können Sie das Asset Pack-Archiv, OCESamplesAssetPack.zip, herunterladen und in ein Verzeichnis Ihrer Wahl extrahieren:

  1. Laden Sie das Oracle Content Management Samples Asset Pack (OCESamplesAssetPack.zip) von der Oracle Content Management-Seite Downloads herunter. Extrahieren Sie die heruntergeladene ZIP-Datei in ein Verzeichnis auf Ihrem Computer. Nach der Extraktion enthält dieser Speicherort eine Datei mit dem Namen OCEGettingStarted_data.zip.

  2. Melden Sie sich als Administrator bei der Oracle Content Management-Weboberfläche an.

  3. Wählen Sie im linken Navigationsmenü die Option Inhalt, und wählen Sie dann in der Auswahlliste im Seitenheader die Option Repositories aus. Wählen Sie jetzt OCEGettingStartedRepository, und klicken Sie in der oberen Aktionsleiste auf die Schaltfläche Inhalt importieren.

    Diese Abbildung zeigt die Seite "Repositorys", wobei das Element OCEGettingStartedRepository ausgewählt ist.

  4. Laden Sie OCEGettingStarted_data.zip vom lokalen Rechner in den Ordner Dokumente hoch.

    Diese Abbildung zeigt den Bildschirm zur Bestätigung des Uploads für die Datei OCEGettingStarted_data.zip.

  5. Nachdem der Inhalt hochgeladen wurde, wählen Sie OCEGettingStarted_data.zip aus, und klicken Sie auf OK, um den Inhalt in das Asset-Repository zu importieren.

    Diese Abbildung zeigt die ausgewählte Datei OCEGettingStarted_data.zip mit aktivierter Schaltfläche "OK".

  6. Nachdem der Inhalt erfolgreich importiert wurde, navigieren Sie zur Seite Assets, und öffnen Sie das Repository OCEGettingStartedRepository. Sie sehen, dass jetzt alle zugehörigen Bilder und Inhaltselemente zum Asset-Repository hinzugefügt wurden.

    Diese Abbildung zeigt das Repository OCEGettingStartedRepository mit allen Assets, die gerade importiert wurden.

  7. Klicken Sie oben links auf Alle auswählen und dann auf Veröffentlichen, um alle importierten Assets zu dem Veröffentlichungskanal hinzuzufügen, den Sie zuvor erstellt haben, OCEGettingStartedChannel.

    Diese Abbildung zeigt das Repository OCEGettingStartedRepository, wobei alle Assets ausgewählt sind und die Option "Veröffentlichen" in der Aktionsleiste sichtbar ist.

  8. Vor der Veröffentlichung müssen Sie alle Assets validieren. Fügen Sie zunächst OCEGettingStartedChannel als ausgewählten Kanal hinzu, und klicken Sie auf die Schaltfläche Validieren.

    Diese Abbildung zeigt die Seite "Validierungsergebnisse", wobei der Kanal OCEGettingStartedChannel im Feld "Kanäle" hinzugefügt wurde, alle zu validierenden Assets und die Schaltfläche "Validieren" aktiviert sind.

  9. Nachdem die Assets validiert wurden, können Sie alle Assets im ausgewählten Channel veröffentlichen, indem Sie oben rechts auf die Schaltfläche Veröffentlichen klicken.

    Diese Abbildung zeigt die Seite "Validierungsergebnisse", wobei der Kanal OCEGettingStartedChannel im Feld "Kanäle" hinzugefügt wurde, alle Assets validiert wurden und die Schaltfläche "Veröffentlichen" aktiviert ist.

Anschließend können Sie auf der Seite Anlagen sehen, dass alle Assets veröffentlicht wurden. (Sie können das Symbol über dem Anlagennamen anzeigen.)

Diese Abbildung zeigt die Seite "Anlagen", auf der alle Assets veröffentlicht sind.

Nach dem Import des Oracle Content Management Samples Asset Packs können Sie den Blog in Oracle JET erstellen.

Erstellen Sie ein eigenes Contentmodell

Anstatt das Oracle Content Management Samples Asset Pack zu importieren, können Sie auch ein eigenes Contentmodell erstellen.

Für dieses Tutorial verwenden wir den Inhaltstyp "OCEGettingStartedHomePage", um die Homepage für unseren Blog zu erstellen. Diese Homepage besteht aus Branding (Firmenname und Logo), einigen URLs für Links und einer Liste von Blog-Themen, die auf der Seite enthalten sein sollten.

So erstellen Sie Inhaltstypen für das Contentmodell:

  1. Melden Sie sich als Administrator bei der Oracle Content Management-Weboberfläche an.
  2. Wählen Sie im linken Navigationsmenü die Option Inhalt, und wählen Sie dann in der Auswahlliste im Seitenheader die Option Anlagentypen aus.
  3. Klicken Sie oben rechts auf Erstellen.
  4. Wählen Sie diese Option, um einen Inhaltstyp zu erstellen (kein digitaler Vermögensgegenstandstyp). Wiederholen Sie diesen Vorgang für alle erforderlichen Inhaltstypen.

Diese Abbildung zeigt das Dialogfeld "Assettyp erstellen" in der Oracle Content Management-Webbenutzeroberfläche.

Wir erstellen vier Inhaltstypen mit jeweils eigenen Feldern:

Der erste Inhaltstyp OCEGettingStartedHomePage muss die folgenden Felder enthalten:

Anzeigename Feldtyp Erforderlich Rechnername
Unternehmensname Einwertiges Textfeld X company_name
Unternehmenslogo Einwertiges Textfeld X company_logo
Themen Referenzfeld für mehrere Werte X Themen
Kontakt-URL Einwertiges Textfeld X contact_url
Info zu URL Einwertiges Textfeld X about_url

So sollte die Inhaltstypdefinition OCEGettingStartedHomePage aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedHomePage". Sie enthält die folgenden Datenfelder: Unternehmensname, Unternehmenslogo, Themen, Kontakt-URL und Info-URL.

Der zweite Inhaltstyp OCEGettingStartedTopic muss das folgende Feld enthalten:

Anzeigename Feldtyp Erforderlich Rechnername
Thumbnail Bildfeld mit einem Wert X Thumbnail

So sollte der Inhaltstyp OCEGettingStartedTopic aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedTopic". Dieses Datenfeld enthält: Miniaturansicht.

Der dritte Inhaltstyp OCEGettingStartedAuthor muss die folgenden Felder enthalten:

Anzeigename Feldtyp Erforderlich Rechnername
Avatar Bildfeld mit einem Wert X Avatar

So sollte der Inhaltstyp OCEGettingStartedAuthor aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedAuthor". Es enthält dieses Datenfeld: Avatar.

Der vierte und letzte Inhaltstyp OCEGettingStartedArticle muss die folgenden Felder enthalten:

Anzeigename Feldtyp Erforderlich Rechnername
Veröffentlichungsdatum Einwertiges Datumsfeld X published_name
Autor Einwertiges Referenzfeld X Autor
Bild Bildfeld mit einem Wert X Bild
Bildunterschrift Einwertiges Textfeld X image_caption
Artikelinhalt Einwertiges Großtextfeld X article_content
Thema Einwertiges Referenzfeld X Thema

So sollte der Inhaltstyp OCEGettingStartedArticle aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedArticlePage". Sie enthält die folgenden Datenfelder: Veröffentlichungsdatum, Autor, Bild, Bildbeschriftung, Artikelinhalt und Thema.

Nachdem Sie die Inhaltstypen erstellt haben, können Sie diese Inhaltstypen dem zuvor erstellten Repository hinzufügen: OCEGettingStartedRepository:

  1. Melden Sie sich als Administrator bei der Oracle Content Management-Weboberfläche an.
  2. Navigieren Sie zu OCEGettingStartedRepository.
  3. Bearbeiten Sie das Repository, und geben Sie unter Anlagentypen alle vier neu erstellten Inhaltstypen an.
  4. Klicken Sie auf die Schaltfläche Speichern, um die Änderungen zu speichern.

Diese Abbildung zeigt die Seite "Repository bearbeiten" in Oracle Content Management, wobei die vier neu erstellten Inhaltstypen mit dem Repository OCEGettingStartedRepository verknüpft sind.

Nachdem Sie die Inhaltstypen zum Repository hinzugefügt haben, können Sie das Repository OCEGettingStartedRepository auf der Seite Assets öffnen und mit der Erstellung Ihrer Inhaltselemente für alle Inhaltstypen beginnen.

Diese Abbildung zeigt Inhaltselemente auf der Seite "Anlagen" in der Oracle Content Management-Weboberfläche mit Optionen auf der linken Seite für Sammlungen, Kanäle, Sprachen, Typen, Inhaltselementauswahl und Status.

Aufgabe 2: Blog in Oracle JET erstellen

Um Ihren Oracle Content Management-Inhalt in einer Oracle JET-Anwendung zu konsumieren, können Sie das Oracle JET-Blogbeispiel verwenden, das als Open-Source-Repository unter GitHub verfügbar ist.

Hinweis: Beachten Sie, dass die Verwendung des Oracle JET-Beispiels optional ist. In diesem Tutorial erhalten Sie einen schnellen Einstieg. Sie können auch eine eigene Oracle JET-Anwendung erstellen, z.B. eine Startervorlage vom Oracle JET-Team.

So erstellen Sie den Blog in Oracle JET:

  1. Beispiel-Repository klonen und Abhängigkeiten installieren
  2. Oracle JET CLI installieren und Oracle Spectra UI-Komponenten hinzufügen
  3. Oracle JET-Anwendung konfigurieren
  4. Mit dem Oracle Content Management Content-SDK arbeiten
  5. Content mit dem Content-SDK abrufen

Beispiel-Repository klonen und Abhängigkeiten installieren

Das Oracle JET-Blogbeispiel ist als Open-Source-Repository unter GitHub verfügbar.

Sie müssen das Beispiel zunächst von GitHub auf den lokalen Computer klonen und in das Repository-Root-Verzeichnis ändern:

git clone https://github.com/oracle-samples/oce-jet-blog-sample.git
cd oce-jet-blog-sample

Nachdem Sie Ihre Codebasis eingerichtet haben, müssen Sie Abhängigkeiten für die Anwendung herunterladen. Führen Sie den folgenden Befehl aus dem Root-Verzeichnis aus:

npm install

Oracle JET-CLI installieren und Oracle Spectra-UI-Komponenten hinzufügen

Als Nächstes müssen Sie die Oracle JET-CLI installieren, um Oracle JET-Befehle auszuführen. Ihrerseits darf keine Aktion erforderlich sein, da dies eine Abhängigkeit ist, die in der Datei package.json installiert ist. Bei Problemen mit der Oracle JET-CLI können Sie die Anweisungen in der Oracle JET-CLI-Dokumentation befolgen. Die Oracle JET-CLI finden Sie unter GitHub. Sie benötigen die Oracle JET-CLI, um einige benutzerdefinierte Komponenten zu installieren und auch die Anwendung zu bedienen.

Danach müssen Sie einige benutzerdefinierte Komponenten installieren, die Sie in diesem Oracle JET-Beispiel verwenden. Diese Komponenten verfügen über ein eigenes CSS, das Sie verwenden möchten. Die Komponenten der Spectra UI sind:

Um diese Komponenten hinzuzufügen, müssen Sie die Exchange-URL als Referenz konfigurieren und die benutzerdefinierten Oracle JET-Komponenten (für US-Instanzen) installieren:

ojet configure --exchange-url=https://devinstance4wd8us2-wd4devcs8us2.uscom-central-1.oraclecloud.com/profile/devinstance4wd8us2-wd4devcs8us2/s/devinstance4wd8us2-wd4devcs8us2_compcatalog_3461/compcatalog/0.2.0
ojet add component oj-sp-welcome-page oj-sp-image-card oj-sp-item-overview-page oj-sp-item-overview --username=comp.catalog --password=bXwphh6RMFjn#g

Weitere Informationen über die Verbindung mit der Komponentenaustausch-URL finden Sie in der Visual Builder-Dokumentation.

Oracle JET-Anwendung konfigurieren

In diesem Oracle JET-Blogbeispiel müssen Sie einige Informationen konfigurieren, damit Ihr Oracle Content Management Content-SDK (und alle anderen Anforderungen) die richtige Instanz-URL und API-Version mit dem richtigen Channel-Token als Ziel festlegen kann. Diese Werte werden in src/scripts/server-config-utils.js verwendet, um einen neuen Zustellungsclient zu instanziieren.

Öffnen Sie src/config/content.json in einem Texteditor. Folgende Informationen werden angezeigt:

{
  "serverUrl": "https://samples.mycontentdemo.com",
  "apiVersion": "v1.1",
  "channelToken": "47c9fb78774d4485bc7090bf7b955632"
}

Ändern Sie jedes Schlüssel/Wert-Paar entsprechend Ihrer Instanz-URL, der gewünschten API-Version und dem Channel-Token, das mit Ihrem Veröffentlichungskanal verknüpft ist. Der Kanal für dieses Tutorial ist OCEGettingStartedChannel. Das Kanaltoken befindet sich in der Datei src/config/content.json. Sie können hier auch den Wert von "expressServerPort" für Ihre localhost-Portnummer hinzufügen.

Hinweis: Es wird empfohlen, diese Werte als Umgebungsvariablen in Ihrem Hosting-Provider oder in einer lokalen .env-Datei zu speichern. Wenn Sie die Instanz-URL oder das Kanaltoken öffentlich anzeigen, kann dies möglicherweise zu verteilten Denial-of-Service-(DDoS-)Angriffen führen. Dieses Risiko wird gemindert, indem sichergestellt wird, dass CORS (Cross-Origin Resource Sharing) für Ihre Instanz ordnungsgemäß konfiguriert ist.

Mit dem Oracle Content Management Content-SDK arbeiten

Oracle Content Management bietet ein SDK, mit dem Sie Inhalte in Ihren Anwendungen erkennen und verwenden können. Das SDK wird als NPM-Modul veröffentlicht, und das Projekt wird unter GitHub gehostet.

Weitere Informationen zum SDK finden Sie hier.

Das SDK wurde als Laufzeitabhängigkeit dieses Projekts in der Datei package.json registriert.

Content mit dem Content-SDK abrufen

Wir können das Content-SDK jetzt nutzen, um Inhalte abzurufen, damit wir sie in unserer Oracle JET-Anwendung wiedergeben können.

Der Ordner src/scripts enthält den Code zum Abrufen von Daten aus Oracle Content Management mit dem Content-SDK.

Die Datei src/scripts/server-config-utils.js importiert das Inhalts-SDK und erstellt dann einen Zustellungsclient mit der in src/config/content.json angegebenen Konfiguration.

Mit dem folgenden Befehl wird das SDK importiert:

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

Der folgende Befehl erstellt den Delivery Client:

return createDeliveryClient(serverconfig);

Die Datei src/scripts/services.js enthält den gesamten Code zum Abrufen von Daten für die Anwendung. Es gibt eine Hauptfunktion für jede Seitenkomponente in der Anwendung, um alle Daten für diese Seite abzurufen.

Zur Wiedergabe der Bilder bietet die services.js eine Helper-Methode zum Abrufen des Quellsets für ein Asset, das aus den Formatvarianten für das Asset erstellt wird.

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, 'png');
      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;
}

Homepage-Daten

Die Homepage benötigt mehrere Datenaufrufe, um alle Daten abzurufen:

  1. Zunächst werden Elemente im Kanal abgefragt, die in src/config/content.json angegeben sind.
  2. Dann werden die Details für jedes der Themenelemente abgerufen.
  3. Schließlich rufen wir alle Artikeldaten für jedes der Themen ab.

Öffnen Sie src/scripts/services.js, und suchen Sie die Funktion getTopicsListPageData(), die alle Themendaten für die Homepage abruft.

export function getTopicsListPageData() {
  const client = getClient();

  return fetchHomePage(client)
    .then((data) => (
      getRenditionURLs(client, data.logoID)
        .then((renditionUrls) => {
          data.companyThumbnailRenditionUrls = renditionUrls;
          return data;
        })
    ));
}

Die Funktion fetchHomePage(), die von der Funktion getTopicsListPageData() aufgerufen wird, ruft alle Elemente im Kanal ab. Hiermit werden die Logo-ID, der Firmenname, die Informations- und Kontakt-URLs sowie eine Themenliste abgerufen. Beachten Sie, dass wir für diesen Beispielblog die Homepage "HomePage_JET" abfragen.

function fetchHomePage(client) {
  return client.queryItems({
    q: '(type eq "OCEGettingStartedHomePage" AND name eq "HomePage_JET")',
  }).then((data) => {
    const logoID = data.items[0].fields.company_logo.id;
    const title = data.items[0].fields.company_name;
    const aboutUrl = data.items[0].fields.about_url;
    const contactUrl = data.items[0].fields.contact_url;

    const { topics } = data.items[0].fields;
    const promises = [];

    topics.forEach((origTopic) => {
      // add a promise to the total list of promises to get the full topic details
      promises.push(
        fetchTopic(client, origTopic.id)
          .then((topic) => topic),
      );
    });

    // execute all the promises returning a single dimension array of all
    // of the topics and the other home page data
    return Promise.all(promises)
      .then((allTopics) => (
        {
          logoID,
          companyTitle: title,
          aboutUrl,
          contactUrl,
          topics: flattenArray(allTopics),
        }
      )).catch((error) => logError('Fetching topics failed', error));
  }).catch((error) => logError('Fetching home page data failed', error));
}

Die Funktion fetchTopic() wird dann für jede Themen-ID aufgerufen, um die vollständigen Themendetails abzurufen.

function fetchTopic(client, topicId) {
  return client.getItem({
    id: topicId,
    expand: 'fields.thumbnail',
  }).then((topic) => {
    topic.renditionUrls = getSourceSet(topic.fields.thumbnail);
    return topic;
  }).catch((error) => logError('Fetching topic failed', error));
}

getTopicsListPageData() ruft auch getRenditionURLs() auf, um die URL des wiederzugebenden Bildes abzurufen.

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

Als Nächstes wird auf der Homepage auch die Funktion fetchTopicArticles(topicId) für jedes Thema aufgerufen. Damit werden alle Artikel für das angegebene Thema und die Formatierungs-URLs abgerufen.

export function fetchTopicArticles(topicId) {
  const client = getClient();
  return client.queryItems({
    q: `(type eq "OCEGettingStartedArticle" AND fields.topic eq "${topicId}")`,
    orderBy: 'fields.published_date:desc',
  }).then((data) => {
    const promises = [];
    const articles = data.items;

    articles.forEach((article) => {
      // add a promise to the total list of promises to get the article url
      promises.push(
        getRenditionURLs(client, article.fields.image_16x9.id)
          .then((renditionUrls) => {
            article.renditionUrls = renditionUrls;
            return {
              ...article,
            };
          }),
      );
    });

    // execute all the promises and return all the data
    return Promise.all(promises)
      .then((allArticles) => ({
        topicId,
        articles: flattenArray(allArticles),
      }));
  }).catch((error) => logError('Fetching topic articles failed', error));
}

Die Methode fetchTopicArticles() verwendet auch getRenditionURLs(), wie zuvor gesehen, um das Bild für den Artikel abzurufen.

Artikelseitendaten

Die Artikelseite erhält eine Artikel-ID und benötigt mehrere Datenaufrufe, um alle Daten abzurufen:

  1. Rufen Sie die Artikeldetails für den angegebenen Artikel ab. Rufen Sie für jeden Artikel die URLs der Formatvariante ab.
  2. Rufen Sie die Formatierungs-URLs für den Autor-Avatar ab.

Öffnen Sie src/scripts/services.js, und suchen Sie die Funktion fetchArticleDetails(articleId), mit der die Daten für die Artikelseite abgerufen werden.

export function fetchArticleDetails(articleId) {
  const client = getClient();
  return client.getItem({
    id: articleId,
    expand: 'fields.author,fields.image',
  }).then((article) => {
    const title = article.fields.author.name;
    const date = article.fields.published_date;
    const content = article.fields.article_content;
    const imageCaption = article.fields.image_caption;
    const { name } = article;
    const renditionUrls = getSourceSet(article.fields.image);
    const avatarID = article.fields.author.fields.avatar.id;
    // Get the author's avatar image
    return getRenditionURLs(client, avatarID)
      .then((authorRenditionUrls) => (
        // return an object with just the data needed
        {
          id: articleId,
          name,
          title,
          date,
          content,
          imageCaption,
          renditionUrls,
          authorRenditionUrls,
        }
      ));
  }).catch((error) => logError('Fetching article details failed', error));
}

Die Methode fetchArticleDetails() verwendet auch getRenditionURLs(), wie zuvor gesehen, um das Avatarimage abzurufen.

Struktur und Seiten von Oracle JET

Die folgenden Abschnitte bieten einen Überblick darüber, wie Oracle JET unsere Daten wiedergibt:

Oracle JET Blog - Anwendungsablauf

Der Haupteintragspunkt zu dieser Oracle JET-Anwendung ist die Datei src/app.tsx. Diese Datei importiert den Preact Router sowie alle Seiten für die Anwendung.

Auf unserer Website wollen wir drei Routen anbieten:

Wie im unten stehenden Router-Code ersichtlich, ist der Standard-Homepage-Pfad von '/' für die TopicsListPage, und jeder Artikel wird auf dem Server + 'article/:articleId' für die ArticleDetailsPage gehostet. Es wird hier mit der route()-Methode im Preact-Router weitergeleitet. Alle ungültigen Routen werden an NotFoundPage gesendet.

Hinweis: Zusätzliche Unterstützung für einen Basis-Routerpfad kann hier im Preact-Router geändert werden, indem base_url vor dem gewünschten Pfad angehängt wird. Eine spezielle appRoute()-Methode ist im Beispielcode enthalten, um die Preact Router route()-Methode bei einer base_url zu ersetzen.

<Router>
  <TopicsListPage path="/" />
  <ArticleDetailsPage path="/article/:articleId" />
  <NotFoundPage default />
</Router>

TopicsList Seite

Die Seite TopicsList (Home) besteht aus einer Themenliste, die sich aus einzelnen Themen zusammensetzt, sowie der Artikelliste für das ausgewählte Thema.

Die Klasse TopicsListPage ruft die Daten mit der Funktion fetchData() ab, die während der Phase componentDidMount der Laufzeit aufgerufen wird.

Die Funktion fetchData() lautet wie folgt:

fetchData() {
  this.setState(() => ({
    loading: true,
  }));

  getTopicsListPageData()
    .then((data) => {
      const promiseArr = [];
      for (let i = 0; i < data.topics.length; i += 1) {
        promiseArr.push(
          fetchTopicArticles(data.topics[i].id).then(
            (topicArticlesData) => { data.topics[i].articleData = topicArticlesData; },
          ),
        );
      }
      Promise.all(promiseArr).then(() => {
        this.setState({
          data,
          loading: false,
        });
      });
    });
}

Beachten Sie, dass der Status auf "Laden" gesetzt ist, um den Fortschrittskreis beim erstmaligen Laden anzuzeigen. Wenn der Ladevorgang abgeschlossen ist, wird er auf "false" gesetzt. Die Funktion getTopicsListPageData() wird einmal aufgerufen, und fetchTopicArticles() wird für jedes Thema aufgerufen. Das Ergebnis ist eine Zusage, die in diesem Codeabschnitt aufgelöst wird.

Sobald wir alle Daten haben, erstellen wir die Begrüßungsseite des Körpers mit dem Körper.

Der Körper wird wie folgt erstellt, wo wir eine oj-sp-image-card-Komponente verwenden:

const bodyElems = [];
let articleCards = [];
topics.forEach(
  (topic) => {
    bodyElems.push(
      <div className='topicType'>
        <div className='topicHeading'>{topic.name}</div>
        <div>{topic.description}</div>
      </div>,
    );
    topic.articleData.articles.forEach((article) => {
      articleCards.push(
        <oj-sp-image-card
          primaryText={article.name}
          secondaryText={article.description}
          imageSrc={article.renditionUrls.native}
          footerType='none'
          onClick={ function openArticleLink() { route(`/article/${article.id}`); } }
        />,
      );
    });
    bodyElems.push(
      <div className='articleItem'>
        {articleCards}
      </div>,
    );
    articleCards = [];
  },
);

Hier ist bodyElems eine Reihe von HTML-Elementen, die in die oj-sp-welcome-page-Komponente eingefügt werden. bodyElems wechselt zwischen einem Themenheader mit Beschreibung und den tatsächlichen Bildkarten für jeden Artikel unter diesem Thema.

Jede Bildkarte hat ein Bild mit einem Seitenverhältnis von 16:9. Dies ist auf die Einschränkung der Verwendung von 16:9-Bildgrößen für die oj-sp-image-card-Komponente zurückzuführen, und die 16:9-Formatvariante wird in renditionUrls mit dem Namen ojspcard für diesen Oracle JET-Beispielblogcode aufgeführt. Beachten Sie auch, dass die Aktion onClick der Bildkarte eine Funktion ist, die zur Artikelseite weitergeleitet wird.

Folgendes wird von der TopicsListPage zurückgegeben, die die oj-sp-welcome-page-Komponente mit der geschlitzten bodyElems enthält:

<oj-sp-welcome-page
  pageTitle={companyTitle}
  overlineText= 'Home'
  displayOptions={{
    imageStretch: 'full',
  }}
  illustrationForeground={companyThumbnailRenditionUrls.native}
  primaryAction={{
    label: 'About Us',
    icon: 'oj-ux-ico-information',
    display: 'on',
  }}
  onspPrimaryAction={ function openAboutLink() { window.open(aboutUrl, '_blank'); } }
  secondaryAction={{
    label: 'Contact Us',
    icon: 'oj-ux-ico-contact-edit',
    display: 'on',
  }}
  onspSecondaryAction={ function openContactLink() { window.open(contactUrl, '_blank'); } }
>
{bodyElems}
</oj-sp-welcome-page>

Die oj-sp-welcome-page-Komponente erstellt den Header der Seite und gibt den Platz an, in dem bodyElems eingefügt werden soll. Wie gesehen, haben wir einen Seitentitel, den "Home"-Text überstrichen, einige Schaltflächen und ein Anzeigebild. Das Anzeigebild enthält eine Quelle im Feld illustrationForeground, und das Bild wird mit dem Parameter displayOptions gestreckt. Es gibt zwei Schaltflächen, "Über uns" und "Kontakt", die Symbole in der oj-ux-Bibliothek haben, und beide Schaltflächen öffnen Links in einem neuen Tab zu uns und kontaktieren Sie uns Seiten.

ArticleDetails Seite

Die Seite ArticleDetails besteht aus allen Daten, die sich auf den Artikel selbst beziehen, wie Autor, Bilder und Text.

Die Klasse ArticleDetails ruft die Daten mit der Funktion fetchData() ab, die während der Phase componentDidMount der Laufzeit aufgerufen wird.

Die Funktion fetchData() lautet wie folgt:

fetchData(articleId) {
  this.setState(() => ({
    loading: true,
  }));

  fetchArticleDetails(articleId)
    .then((data) => this.setState(() => ({
      data,
      loading: false,
    })));
  }
}

Beachten Sie, dass der Status auf "Laden" gesetzt ist, um den Fortschrittskreis beim erstmaligen Laden anzuzeigen. Wenn der Ladevorgang abgeschlossen ist, wird er auf "false" gesetzt. Die Funktion fetchArticleDetails() wird einmal für die von uns verwendete articleId aufgerufen. Das Ergebnis ist eine Zusage, die in diesem Codeabschnitt aufgelöst wird.

Sobald alle Daten vorliegen, wird die Seite articleDetails erstellt.

Die Seite wird wie folgt erstellt, wobei wir eine oj-sp-item-overview-page-Komponente mit der oj-sp-item-overview-Komponente verwenden, die im "Overview"-Abschnitt und im "Haupt"-Abschnitt geschlitzter Hauptinhalt geschlitzt ist:

<oj-sp-item-overview-page
  overviewExpanded={false}
  translations={{
    goToParent: 'Back to Home',
  }}
  onspGoToParent={ function goToParent() { route('/'); } }
>
  <div slot='overview'>
    <oj-sp-item-overview
      itemTitle={title}
      itemSubtitle={formattedDate}
      photo={{
        src: data.authorRenditionUrls.small,
      }}
    />
  </div>
  <div slot='main'>
    <h1 style='text-align:center'>{name}</h1>
    <figure>
      {data.renditionUrls && (
        <picture>
          <source type='image/webp' srcSet={data.renditionUrls.srcset} />
          <source srcSet={data.renditionUrls.jpgSrcset} />
          <img
            src={data.renditionUrls.small}
            alt='Article'
            width={parseInt(data.renditionUrls.width, 10) * 0.66}
            height={parseInt(data.renditionUrls.height, 10) * 0.66}
          />
        </picture>
      )}
      <figcaption style='text-align:center'>{imageCaption}</figcaption>
    </figure>
    {/* eslint-disable-next-line @typescript-eslint/naming-convention */}
    <div dangerouslySetInnerHTML={{ __html: cleancontent }} />
  </div>
</oj-sp-item-overview-page>

Die oj-sp-item-overview-seitige Komponente stellt das Layout für die Seite articleDetails bereit. Insbesondere ist overviewExpanded falsch, um jetzt die gesamte Seite zu ersetzen, die Übersetzungen für goToParent sind "Zurück zu Home", und onspGoToParent ist eine Funktion, mit der die Logik abgeschlossen wird, um zur Seite topicsList zurückzukehren.

Es gibt zwei Slots, die von der oj-sp-item-overview-Seite aufgenommen werden können, und dies sind der "Überblick"-Slot und der "Haupt"-Slot, die Details zum Autor des Artikels enthalten und den Inhalt des Artikels angeben.

Die oj-sp-item-overview-Komponente wird in den Abschnitt "Überblick" geschoben und bietet ein Spaltenlayout für die Autorendetails. itemTitle ist der Name des Autors, der Untertitel ist das formatierte Datum, und das Foto ist die Quelle des Autorfotos.

Der "Haupt" geschlitzte Abschnitt enthält alle Details des Artikels, darunter den Titel des Artikels, ein Bild mit Beschriftung sowie den Artikel-Blogtext.

Aufgabe 3: Anwendung für Deployment vorbereiten

Nachdem wir unsere Oracle JET-Blogsite erstellt haben, müssen wir sie auf einem lokalen Entwicklungsserver sehen, damit wir Probleme debuggen und eine Vorschau der Anwendung anzeigen können, bevor sie live geht.

Die Datei package.json im Root-Verzeichnis des Projekts enthält Skripte, mit denen Sie die Bundles einfacher erstellen und die Anwendung ausführen können.

Entwicklung

Sie können das Entwicklungsskript während der Entwicklung verwenden:

npm run dev

Dieses Skript erstellt die Client- und Server-Bundles und startet die Anwendung auf einem lokalen Server. Webpack überwacht Codeänderungen und erstellt gegebenenfalls die Client- und Server-Bundles neu.

Production

Für die Produktion wird das Build-Skript verwendet, um die Client- und Server-Bundles zu erstellen:

npm run build

Nach Abschluss des Skripts kann die Anwendung mit dem folgenden Befehl ausgeführt werden:

npm run start

Schlussfolgerung

In diesem Tutorial haben wir eine Blog-Site in Oracle JET erstellt, die sich unter Github befindet. Diese Site verwendet Oracle Content Management als Headless CMS. Nachdem Sie Oracle Content Management mit einem Channel veröffentlichter Inhalte für das Tutorial der Blog-Site eingerichtet und konfiguriert haben, haben wir die Oracle JET-Site installiert und ausgeführt, um den erforderlichen Inhalt abzurufen und die Site zu erstellen.

Weitere Informationen zu Oracle JET finden Sie auf der Oracle JET-Website.

Machen Sie sich mit wichtigen Oracle Content Management-Konzepten in der Dokumentation vertraut.

Weitere Beispiele finden Sie auf der Seite Oracle Content Management - Beispiele im Oracle Help Center.