Cree un blog en Angular con Oracle Content Management sin cabecera

Introducción

Angular es una plataforma para crear aplicaciones web móviles y de escritorio. Pero, ¿qué sucede cuando se necesita un sistema de gestión de contenido (CMS) para servir todo su contenido? Afortunadamente, Oracle Content Management, con sus completas capacidades de CMS sin cabecera, cuenta con una solución elegante para sus necesidades de administración y gobernanza de contenido.

En este tutorial, crearemos un blog sencillo en Angular aprovechando Oracle Content Management como un CMS sin cabecera, así como su kit de desarrollo de software (SDK) para la entrega de contenido en JavaScript. Este ejemplo angular está disponible en GitHub.

El tutorial incluye tres pasos:

  1. Preparación de Oracle Content Management
  2. Construir el blog en Angular
  3. Preparar la aplicación para el despliegue

Requisitos

Antes de continuar con este tutorial, le recomendamos que lea primero la siguiente información:

Para seguir este tutorial, necesitará:

Lo que estamos construyendo

Nuestro blog consistirá en un sitio de tres páginas que permite a los visitantes explorar artículos de blog organizados en temas. La primera página, la página de inicio, consistirá en marca (nombre y logotipo de la compañía), algunos enlaces y una lista de temas de blog.

Para ver lo que estamos creando, este es el estado final de nuestro tutorial, un blog Angular básico que consume contenido de Oracle Content Management:

https://headless.mycontentdemo.com/samples/oce-angular-blog-sample

Esto es el aspecto que tendrá la página inicial al final de este tutorial:

En esta imagen se muestra la página inicial del sitio de demostración de Café Supremo con una lista de los temas disponibles.

La segunda página, la página de tema, muestra las vistas previas de cada artículo de blog que pertenece al tema. A continuación, se muestra el aspecto de una página de tema individual:

En esta imagen se muestra una página de tema denominada 'Recetas' con una lista de los artículos disponibles para ese tema.

Por último, la página de artículo presenta el artículo final del blog, incluida información sobre el autor del blog. A continuación, se muestra cómo se verá una página de artículo individual:

En esta imagen se muestra una página de artículo individual, con el contenido y una referencia de autor.

Para continuar, deberá tener una suscripción activa a Oracle Content Management y conectarse con el rol de administrador de contenido.

Tarea 1: Preparación de Oracle Content Management

Si aún no tiene una instancia de Oracle Content Management, consulte Inicio rápido para obtener información sobre cómo registrarse en Oracle Cloud, aprovisionar una instancia de Oracle Content Management y configurar Oracle Content Management como CMS sin cabecera.

Para este tutorial, necesitará crear un modelo de contenido de dos formas. Hay un paquete de activos descargable disponible que llenará su repositorio vacío con tipos de contenido y contenido asociado, o puede crear su propio contenido y modelo de contenido.

Para preparar Oracle Content Management:

  1. Cree un canal y un repositorio de activos.
  2. Cree un modelo de contenido mediante uno de los dos métodos siguientes:

Crear un canal y un repositorio de activos

Primero debe crear un canal y un repositorio de activos en Oracle Content Management para poder publicar contenido.

Para crear un canal y un repositorio de activos en Oracle Content Management:

  1. Conéctese a la interfaz web de Oracle Content Management como administrador.

  2. Seleccione Contenido en el menú de navegación de la izquierda y, a continuación, seleccione Publicar canales en la lista de selección de la cabecera de página.

    En esta imagen se muestra la opción Canales de publicación seleccionada en el menú desplegable de la cabecera de la página Contenido.

  3. En la esquina superior derecha, haga clic en Crear para crear un nuevo canal. Asigne un nombre al canal 'OCEGettingStartedChannel' para este tutorial y mantenga el acceso público. Haga clic en Guardar para crear el canal.

    En esta imagen se muestra el panel de definición de canal de publicación, con 'OCEGettingStartedChannel' en el campo de nombre de canal.

  4. Seleccione Contenido en el menú de navegación de la izquierda y, a continuación, seleccione Repositorios en la lista de selección de la cabecera de página.

    En esta imagen se muestra la opción Repositorios seleccionada en el menú desplegable de la cabecera de la página Content.

  5. En la esquina superior derecha, haga clic en Crear para crear un nuevo repositorio de activos. Asigne al repositorio de activos el nombre 'OCEGettingStartedRepository' para que realice este tutorial.

    En esta imagen se muestra el panel de definición del repositorio, con 'OCEGettingStartedRepository' en el campo de nombre del repositorio.

  6. En el campo Canales de publicación, seleccione el canal OCEGettingStartedChannel para indicar a Oracle Content Management que el contenido del repositorio OCEGettingStartedRepository se puede publicar en el canal OCEGettingStartedChannel. Haga clic en Guardar cuando haya terminado.

    En esta imagen se muestra el panel de definición del repositorio, con 'OCEGettingStartedChannel' en el campo Canales de publicación.

Creación de un modelo de contenido

El siguiente paso es crear un modelo de contenido. Puede utilizar uno de los siguientes métodos:

Importación del Paquete de Activos de Muestras de Oracle Content Management

Puede descargar un paquete de activos de ejemplo de Oracle Content Management preconfigurado que contiene todos los tipos de contenido y activos necesarios para este tutorial. Si lo prefiere, también puede crear su propio modelo de contenido en lugar de descargar el paquete de activos de ejemplo.

Puede cargar una copia del contenido que estamos utilizando en este tutorial desde el paquete de activos de muestras de Oracle Content Management. Esto le permitirá experimentar con los tipos de contenido y modificar el contenido. Si desea importar el paquete de activos de muestras de Oracle Content Management, puede descargar el archivo de paquete de activos, OCESamplesAssetPack.zip, y extraerlo a un directorio de su elección:

  1. Descargue el paquete de activos de muestras de Oracle Content Management (OCESamplesAssetPack.zip) desde la página descargas de Oracle Content Management. Extraiga el archivo zip descargado en una ubicación de la computadora. Después de la extracción, esta ubicación incluirá un archivo denominado OCEGettingStarted_data.zip.

  2. Conéctese a la interfaz web de Oracle Content Management como administrador.

  3. Seleccione Contenido en el menú de navegación de la izquierda y, a continuación, seleccione Repositorios en la lista de selección de la cabecera de página. Ahora seleccione OCEGettingStartedRepository y haga clic en el botón Importar contenido de la barra de acción superior.

    En esta imagen se muestra la página Repositorios, con el elemento OCEGettingStartedRepository seleccionado.

  4. Cargue OCEGettingStarted_data.zip desde su equipo local a la carpeta Documents.

    En esta imagen se muestra la pantalla de confirmación de carga del archivo OCEGettingStarted_data.zip.

  5. Una vez cargado, seleccione OCEGettingStarted_data.zip y haga clic en Aceptar para importar el contenido en el repositorio de activos.

    En esta imagen se muestra el archivo OCEGettingStarted_data.zip seleccionado con el botón OK activado.

  6. Una vez que el contenido se haya importado correctamente, navegue a la página Activos y abra el repositorio OCEGettingStartedRepository. Verá que todas las imágenes y los elementos de contenido relacionados se han agregado ahora al repositorio de activos.

    En esta imagen se muestra el repositorio OCEGettingStartedRepository, con todos los activos que se acabaron de importar.

  7. Haga clic en Seleccionar todo en la parte superior izquierda y, a continuación, en Publicar para agregar todos los activos importados al canal de publicación que ha creado anteriormente, OCEGettingStartedChannel.

    En esta imagen se muestra el repositorio OCEGettingStartedRepository, con todos los activos seleccionados y la opción Publish en la barra de acción visible.

  8. Antes de la publicación, debe validar todos los activos. Primero agregue OCEGettingStartedChannel como canal seleccionado y, a continuación, haga clic en el botón Validar.

    En esta imagen se muestra la página Resultados de validación, con el canal OCEGettingStartedChannel agregado en el campo Canales, todos los activos que se van a validar y el botón Validar activado.

  9. Después de validar los activos, puede publicar todos los activos en el canal seleccionado haciendo clic en el botón Publicar en la esquina superior derecha.

    En esta imagen se muestra la página Resultados de validación, con el canal OCEGettingStartedChannel agregado en el campo Canales, todos los activos validados y el botón Publicar activado.

Cuando termine, puede ver en la página Activos que se han publicado todos los activos. (Puede indicar el icono encima del nombre del activo).

En esta imagen se muestra la página Activos, con todos los activos ubicados.

Después de importar el paquete de activos de muestras de Oracle Content Management, puede iniciar la creación del blog en Angular.

Crear su propio modelo de contenido

En lugar de importar el paquete de activos de muestras de Oracle Content Management, también puede crear su propio modelo de contenido.

Para este tutorial, estamos usando un tipo de contenido llamado 'OCEGettingStartedHomePage' para crear la página de inicio para nuestro blog. Esta página de inicio consta de marcas (nombre y logotipo de la compañía), algunas URL para enlaces y una lista de temas de blog que se deben incluir en la página.

En esta imagen se muestra la página inicial del sitio de demostración de Café Supremo.

Para crear tipos de contenido para el modelo de contenido:

  1. Conéctese a la interfaz web de Oracle Content Management como administrador.
  2. Seleccione Contenido en el menú de navegación de la izquierda y, a continuación, seleccione Tipos de activo en la lista de selección de la cabecera de página.
  3. Haga clic en Crear en la esquina superior derecha.
  4. Elija crear un tipo de contenido (no un tipo de activo digital). Repita esta operación para todos los tipos de contenido necesarios.

En esta imagen se muestra el cuadro de diálogo Crear tipo de activo en la interfaz web de Oracle Content Management.

Crearemos cuatro tipos de contenido, cada uno con su propio conjunto de campos:

El primer tipo de contenido, OCEGettingStartedHomePage, debe tener los siguientes campos:

Nombre Mostrado Tipo de campo necesario Nombre de máquina
Nombre de compañía Campo de texto de valor único X company_name
Logo de compañía Campo de texto de valor único X company_logo
Temas Campo de referencia de varios valores X Temas
URL de Contacto Campo de texto de valor único X contact_url
Acerca de URL Campo de texto de valor único X about_url

Esto es lo que debería tener la definición de tipo de contenido OCEGettingStartedHomePage:

En esta imagen se muestra la definición del tipo de contenido 'OCEGettingStartedHomePage'. Incluye estos campos de datos: Nombre de la compañía, Logotipo de la compañía, Temas, URL del contacto y URL de información.

El segundo tipo de contenido, OCEGettingStartedTopic, debe tener el siguiente campo:

Nombre Mostrado Tipo de campo necesario Nombre de máquina
Vista en miniatura Campo de imagen de valor único X vista en miniatura

Este es el aspecto del tipo de contenido OCEGettingStartedTopic:

En esta imagen se muestra la definición del tipo de contenido 'OCEGettingStartedTopic'. Incluye este campo de datos: Miniatura.

El tercer tipo de contenido, OCEGettingStartedAuthor, debe tener los siguientes campos:

Nombre Mostrado Tipo de campo necesario Nombre de máquina
Avatar Campo de imagen de valor único X avatar

Este es el aspecto del tipo de contenido OCEGettingStartedAuthor:

En esta imagen se muestra la definición del tipo de contenido 'OCEGettingStartedAuthor'. Incluye este campo de datos: Avatar.

El cuarto y último tipo de contenido, OCEGettingStartedArticle, deben tener los siguientes campos:

Nombre Mostrado Tipo de campo necesario Nombre de máquina
Fecha de publicación Campo de fecha de valor único X published_name
Autor Campo de referencia de valor único X autor
Imagen Campo de imagen de valor único X imagen
Leyenda de Imagen Campo de texto de valor único X image_caption
Contenido de artículo Campo de texto grande de valor único X article_content
Tema Campo de referencia de valor único X Tema

Este es el aspecto del tipo de contenido OCEGettingStartedArticle:

En esta imagen se muestra la definición del tipo de contenido 'OCEGettingStartedArticlePage'. Incluye estos campos de datos: Fecha de publicación, Autor, Imagen, Título de imagen, Contenido de artículo y Tema.

Una vez creados los tipos de contenido, puede agregar estos tipos de contenido al repositorio que creó anteriormente, OCEGettingStartedRepository:

  1. Conéctese a la interfaz web de Oracle Content Management como administrador.
  2. Navegue hasta OCEGettingStartedRepository.
  3. Edite el repositorio y, en Tipos de activos, especifique los cuatro tipos de contenido recién creados.
  4. Haga clic en el botón Save (Guardar) para guardar los cambios.

En esta imagen se muestra la página Editar repositorio en Oracle Content Management, con los cuatro tipos de contenido recién creados asociados al repositorio OCEGettingStartedRepository.

Después de agregar los tipos de contenido al repositorio, puede abrir el repositorio OCEGettingStartedRepository en la página Activos e iniciar la creación de los elementos de contenido para todos los tipos de contenido.

En esta imagen se muestran los elementos de contenido de la página Activos de la interfaz web de Oracle Content Management, con opciones a la izquierda para recopilaciones, canales, idiomas, tipos, selección de elementos de contenido y estado.

Tarea 2: Construir el blog en Angular

Para consumir nuestro contenido de Oracle Content Management en una aplicación angular, podemos utilizar la muestra del blog Angular, que está disponible como repositorio de código abierto en GitHub.

Nota: Recuerde que el uso de la muestra Angular es opcional y la utilizamos en este tutorial para comenzar rápidamente. También puede crear su propia aplicación angular, como una sostenida por la CLI angular con compatibilidad con representaciones del lado del servidor agregada mediante la CLI angular.

Para construir el blog en Angular:

  1. Clonar el repositorio de ejemplo e instalar dependencias
  2. Configuración de la aplicación Angular
  3. Trabajar con el SDK de Oracle Content Management Content
  4. Utilizar el SDK de contenido para recuperar el contenido

Clonación del repositorio de ejemplo e instalación de dependencias

La muestra de blog angular está disponible como un repositorio de código abierto en GitHub.

Primero debe clonar el ejemplo de GitHub a su equipo local y cambiar el directorio a la raíz del repositorio:

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

Ahora que tiene su base de código, necesita descargar dependencias para la aplicación. Ejecute el siguiente comando desde el directorio raíz:

npm install

Configuración de la aplicación angular

En esta muestra de blog angular, debe configurar algunas partes de información para que el SDK de Oracle Content Management Content (y cualquier otra solicitud) pueda dirigirse a la URL de instancia y la versión de API correctas con el token de canal correcto. Estos valores se utilizan en src/scripts/server-config-utils.js para instanciar un nuevo cliente de entrega.

Esta aplicación utiliza un archivo .env que lee Webpack cuando agrupa las aplicaciones cliente y servidor. Mediante webpack.DefinePlugin, los valores leídos del archivo .env se pueden poner a disposición de cualquier lugar de la aplicación.

Abra el archivo .env en un editor de texto. Verá la siguiente información:

# 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=47c9fb78774d4485bc7090bf7b955632

Cambie cada par clave-valor para reflejar su URL de instancia, la versión de API que desea dirigir y el token de canal asociado a su canal de publicación. El canal para este tutorial es OCEGettingStartedChannel.

Trabajar con el SDK de Oracle Content Management Content

Oracle Content Management ofrece un SDK para ayudar a detectar y utilizar contenido en las aplicaciones. El SDK se publica como módulo NPM y el proyecto se aloja en GitHub.

Obtenga más información sobre el SDK aquí.

El SDK se ha registrado como una dependencia de tiempo de ejecución de este proyecto en el archivo package.json.

Utilizar el SDK de contenido para recuperar el contenido

Ahora podemos aprovechar el SDK de contenido para recuperar contenido para poder presentarlo en nuestra aplicación angular.

El SDK de contenido utiliza un objeto DeliveryClient para especificar el punto final. Puede realizar todas las solicitudes utilizando ese objeto de cliente.

La carpeta src/scripts contiene el código para obtener datos de Oracle Content Management mediante el SDK de contenido.

El archivo src/scripts/server-config-utils.js importa el SDK de contenido y, a continuación, crea un cliente de entrega mediante la configuración especificada en .env.

El siguiente comando importa el SDK:

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

El siguiente comando crea el cliente de entrega:

return createDeliveryClient(serverconfig);

Para la representación de imágenes, services.js proporciona un método auxiliar para recuperar el juego de orígenes para un activo que se crea a partir de las representaciones del activo.

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;
    }

El archivo src/scripts/services.js contiene todo el código para obtener datos para la aplicación. Hay una función principal para cada componente de página de la aplicación para obtener todos los datos de esa página.

Datos de página inicial

La página inicial necesita varias llamadas de datos para obtener todos sus datos:

  1. En primer lugar, consultamos los elementos del canal especificado en .env.
  2. Para cada uno de los elementos de tema, recuperamos sus detalles.

Abra src/scripts/services.js y busque la función getTopicsListPageData(), que obtiene todos los datos de la página inicial.

export function getTopicsListPageData() {
      const client = getClient();
    
      return fetchHomePage(client)
        .then((data) => (
          getRenditionURLs(client, data.logoID)
            .then((renditionUrls) => {
              data.companyThumbnailRenditionUrls = renditionUrls;
              return data;
            })
        ));
    }

La función fetchHomePage(), llamada por la función getTopicsListPageData(), obtiene todos los elementos del canal. Se obtiene el ID del logotipo, el nombre de la compañía, las URL de contacto y de encendido, y una lista de temas.

function fetchHomePage(client) {
      return client.queryItems({
        q: '(type eq "OCEGettingStartedHomePage" AND name eq "HomePage")',
      }).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));
    }

A continuación, se llama a la función fetchTopic() para cada ID de tema a fin de obtener los detalles completos del tema.

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() también llama a getRenditionURLs() para obtener la URL de la imagen que se va a presentar.

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

Datos de página de tema

La página de temas recibe un ID de tema y necesita varias llamadas de datos para obtener todos sus datos:

  1. Obtener todos los artículos del tema especificado.
  2. Para cada artículo, obtenga sus URL de representación.

Abra src/scripts/services.js y busque la función fetchTopicArticles(topicId), que se utiliza para obtener todos los datos de la página del tema.

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.id)
              .then((renditionUrls) => {
                article.renditionUrls = renditionUrls;
                // Note: the spread operator is used here so that we return a top level
                // object, rather than a value which contains the object
                // i.e we return
                //   {
                //     field1: 'value', field2 : "value", etc
                //   },
                // rather than
                //   {
                //     name: {
                //             field1: 'value', field2 : "value", etc
                //           }
                //    }
                return {
                  ...article,
                };
              }),
          );
        });
    
        // execute all the promises and return all the data
        // 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));
    }

El método fetchTopicArticles() también utiliza getRenditionURLs() como se ha visto anteriormente para obtener la imagen del artículo.

Datos de la Página de Artículo

La página de artículo recibe un ID de artículo y requiere varias llamadas de datos para obtener todos sus datos:

  1. Obtenga los detalles del artículo especificado. Para cada artículo, obtenga sus URL de representación.
  2. Obtenga las URL de representación para el avatar de autor.

Abra src/scripts/services.js y busque la función fetchArticleDetails(articleId), que obtiene los datos de la página de artículo.

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));
    }

El método fetchArticleDetails() también utiliza getRenditionURLs() como se ha visto anteriormente para obtener la imagen de avatar.

Ahora que tenemos nuestras consultas de datos, podemos presentar las respuestas en nuestros componentes angulares.

Representación del Cliente frente al Servidor

Con la representación del cliente (CSR), el cliente es responsable de crear y presentar el contenido de una página web mediante JavaScript. Con la representación del servidor (SSR), toda la página se crea en el servidor y se devuelve una página web completa al cliente.

Cuando se solicita la página web del servidor en la representación del cliente, el documento HTML devuelto contiene HTML de esqueleto y no contiene contenido real. Contiene una referencia a un paquete de JavaScript, que el cliente luego solicita del servidor. Al recibir este paquete, el cliente ejecuta JavaScript y rellena la página web. Hasta que el cliente haya terminado de ejecutar JavaScript, todo lo que ve el usuario es una página web en blanco. Una desventaja de las aplicaciones representadas por el cliente es que cuando algunos rastreadores web indexan el sitio, no hay contenido real que indexar.

Con la representación del servidor (SSR), toda la página se crea en el servidor y se devuelve una página web completa al cliente. La ventaja de esto es que los crawlers web pueden indexar todo el contenido en la página web.

Representación angular del lado del servidor

El flujo de la aplicación del blog Angular es el siguiente:

  1. El cliente realiza una solicitud al servidor para una ruta determinada.
  2. El servidor Express recibe la solicitud.
  3. El servidor Express transfiere todas las solicitudes de cliente para páginas al motor Express de Angular Univeral
  4. El motor Express de Angular Univeral toma un archivo HTML de plantilla y lo rellena con lo siguiente
    1. Marcador para la ruta determinada
    2. Los datos de la ruta se serializan
    3. Referencias a hojas de estilos
    4. Referencias a paquetes de JavaScript para ejecutar en el cliente
  5. El servidor Express devuelve el documento HTML creado por el motor Express de Angular Univeral al cliente
  6. El cliente recibe el HTML y lo representa. El usuario verá una página web totalmente formada.
  7. El cliente solicita cualquier paquete de JavaScript del servidor. Después de recibirlo, el cliente ejecuta JavaScript en el paquete.
    1. "hidrata" el HTML, agregando en cualquier JavaScript del cliente, como listeners de eventos.
    2. Angular toma automáticamente los datos serializados de la página e los inyecta en el código JavaScript para que estén disponibles para los componentes
  8. Si el documento HTML contiene una hoja de estilo, el cliente solicita la hoja de estilo.

La CLI angular admite la agregación de compatibilidad con representaciones del servidor a una aplicación angular existente. Consulte https://angular.io/guide/universal para obtener más información.

Servidor Express

La aplicación de servidor utiliza un servidor Express para recibir la solicitud y avanzar al motor Express de Angular Univeral.

El archivo de servidor Express se encuentra en server.js. Angular CLI crea este archivo al agregar soporte de representación del servidor.

Componentes Angulares

Los componentes angulares se escriben en TypeScript y definen una plantilla que define la vista. Estas plantillas contienen directivas HTML ordinarias, angulares y marcadores de enlace, que permiten a Angular ajustar el HTML antes de que se presente.

La aplicación del blog desglosa cada página en una serie de componentes más pequeños.

En las siguientes secciones se ofrece una visión general de cómo Angular presenta nuestra aplicación en cada uno de nuestros componentes:

Módulo de aplicación

Módulo de aplicación ubicado en src/app/app.module.ts. Inicia la aplicación con el componente de aplicación.

Este archivo define las distintas rutas de nuestra aplicación. En nuestro sitio, queremos ofrecer tres rutas:

Tenga en cuenta que tanto la página de tema como la página de artículo toman un argumento proporcionado por Oracle Content Management en su URL.

Las rutas de página inicial, página de tema y página de artículo definen los resueltos utilizados para obtener todos los datos necesarios para la ruta antes de crear los componentes de la ruta.

const appRoutes: Routes = [
      // home page - list of Topics
      {
        path: 'topics',
        component: TopicsListComponent,
        resolve: { routeData: TopicsListDataResolver }
      },
      // list of articles for a specific Topic
      {
        path: 'articles/:topicId',
        component: ArticlesListComponent,
        resolve: { routeData: ArticlesListDataResolver }
      },
      // details for a specific Article
      {
        path: 'article/:articleId',
        component: ArticleDetailsComponent,
        resolve: { routeData: ArticleDetailsDataResolver }
      },
      // no path specified, go to home
      {
        path: '',  redirectTo: '/topics', pathMatch: 'full'
      },
      // path not found
      { path: '**', component: PageNotFoundComponent },
    ];

Este módulo de aplicación es el punto de entrada al presentar la aplicación en el cliente.

Módulo Raíz para Representación del Servidor

El punto de entrada principal de esta aplicación angular, al presentar la aplicación en el servidor, es el módulo de servidor de aplicaciones ubicado en src/app/app.server.module.ts.

Este módulo importa el módulo de aplicación, ubicado en src/app/app.server.module.ts, junto con ServerModule de Angular. La aplicación del servidor inicia el mismo componente de aplicación que el cliente y utiliza todos los mismos componentes.

La CLI angular crea el archivo del módulo de servidor al agregar soporte de representación del servidor.

Solucionador de datos de lista de temas

Los temas muestran el solucionador de datos, ubicado en src/resolver/topics-list-data.resolver.ts, gestiona la obtención de los datos para presentarlos en la página inicial.

Cuando el cliente se hidrata, estos datos se obtienen de transferState, que se rellenó durante la representación del servidor y se serializó en el documento HTML devuelto al cliente.

Durante la representación del servidor o la representación del cliente cuando se produce la navegación del cliente, transferState no contendrá los datos. Los datos se obtienen del servidor de Oracle Content Management, mediante el SDK de contenido, llamando al método getTopicsListPageData() desde src/scripts/services.js.

Solucionador de datos de lista de artículos

Los artículos muestran el solucionador de datos, ubicado en src/resolver/articles-list-data.resolver.ts, gestiona la obtención de los datos para presentar en la página del tema.

Cuando el cliente se hidrata, estos datos se obtienen de transferState, que se rellenó durante la representación del servidor y se serializó en el documento HTML devuelto al cliente.

Durante la representación del servidor o la representación del cliente cuando se produce la navegación del cliente, transferState no contendrá los datos. Los datos se obtienen del servidor de Oracle Content Management mediante el SDK de contenido, llamando al método fetchTopicArticles() desde src/scripts/services.js.

Solucionador de datos de detalles de artículo

El artículo detalla el solucionador de datos, ubicado en src/resolver/article-details-data.resolver.ts, maneja obtener los datos para presentar en la página del artículo.

Cuando el cliente se hidrata, estos datos se obtienen de transferState, que se rellenó durante la representación del servidor y se serializó en el documento HTML devuelto al cliente.

Durante la representación del servidor o la representación del cliente cuando se produce la navegación del cliente, transferState no contendrá los datos. Los datos se obtienen del servidor de Oracle Content Management, mediante el SDK de contenido, llamando al método fetchArticleDetails() desde src/scripts/services.js.

Componente de aplicación

El componente de aplicación, ubicado en src/app/app.component.ts, define la vista raíz.

Este componente contiene las etiquetas de enlace de enrutador. Angular intercambiará componentes dentro y fuera de la página dentro de dichas etiquetas, según la ruta actual.

Componente TopicsList

La página inicial consta de una lista compuesta por temas individuales. Se presenta en el componente TopicsList, ubicado en src/app/topics-list/topics-list.component.ts.

En ngOnInit, el componente obtiene los datos de la ruta activa, que se rellenó mediante la resolución de datos de lista de temas.

ngOnInit() {
      const data = this.route.snapshot.data.routeData;
      . . .
    }

Cuando se representa el componente, obtiene todos los datos de sus variables de miembro.

El marcado para el componente TopicsList se encuentra en src/app/topics-list/topics-list.component.html.

Componente TopicListItem

El componente TopicsList utiliza el componente TopicsListItem para mostrar el tema individual en la lista.

Se encuentra en src/app/topic-list-item.component.ts y recibe todos sus datos como propiedades. No obtiene datos adicionales del servidor.

El marcado para el componente TopicsListItem se encuentra en src/app/topic-list-item.component.html.

Componente ArticlesList

La página Tema muestra los artículos del tema cuyo ID se transfiere al componente en la URL. Se presenta en el componente ArticlesList, ubicado en src/app/articles-list.component.ts.

En ngOnInit puede ver que el componente obtiene los datos de la ruta activa, que fue rellenada por el solucionador de datos de lista de artículos.

ngOnInit() {
      const data = this.route.snapshot.data.routeData;
      . . .
    }

Cuando se representa el componente, obtiene todos los datos de sus variables de miembro.

El marcado para el componente ArticlesList se encuentra en src/app/articles-list.component.html.

Componente ArticleListItem

El componente ArticlesList utiliza el componente ArticleListItem para mostrar el artículo individual en la lista.

Este componente se encuentra en src/app/article-list-item.component.ts y recibe todos sus datos como propiedades. No obtiene datos adicionales del servidor.

El marcado para el componente ArticleListItem se encuentra en src/app/article-list-item.component.html.

Componente ArticleDetails

La página Artículo muestra detalles del artículo cuyo ID se transfiere a la URL. Se presenta en el componente ArticleDetails, ubicado en src/app/article-details.component.ts.

En ngOnInit puede ver que el componente obtiene los datos de la ruta activa, que fue rellenada por el solucionador de datos de lista de artículos.

ngOnInit() {
      // get the values from the routed URL
      this.articleId = this.route.snapshot.params[PAGE_PARAM_TOPIC_ARTICLE_ID];
      this.topicId = this.route.snapshot.queryParams[PAGE_PARAM_TOPIC_ID];
      this.topicName = this.route.snapshot.queryParams[PAGE_PARAM_TOPIC_NAME];
    
      const data = this.route.snapshot.data.routeData;
      . . .
    }

Cuando se representa el componente, obtiene todos los datos de sus variables de miembro.

El marcado para el componente ArticleDetails se encuentra en src/app/article-details.component.html.

Tarea 3: Preparación de la aplicación para el despliegue

Ahora que hemos creado nuestro sitio de blog Angular, tenemos que verlo en un servidor de desarrollo local para que podamos depurar cualquier problema y obtener una vista previa de la aplicación antes de que entre en marcha.

Prepare la aplicación para el despliegue en dos pasos:

  1. Acceder a un servidor de desarrollo local
  2. Utilizar scripts para crear y ejecutar la aplicación en desarrollo y producción

Aceleración de un Servidor de Desarrollo Local

Puede iniciar un servidor de desarrollo localmente ejecutando el siguiente comando.

npm run dev

A continuación, abra el explorador a http://localhost:4200 para ver el sitio en acción.

Uso de scripts para crear y ejecutar la aplicación en desarrollo y producción

Para la producción, el script de creación se utilizaría para crear el cliente y el código de servidor.

npm run build

Este script primero ejecuta la creación del cliente y, a continuación, ejecuta la creación del servidor. La distancia/servidor y la distancia/explorador incorporadas se deben desplegar en la máquina servidor antes de iniciar la aplicación de servidor, mediante el siguiente comando:

npm run start

Conclusión

En este tutorial, creamos un sitio de blog en Angular, que puede encontrarse en GitHub. Este sitio utiliza Oracle Content Management como CMS sin cabecera. Después de configurar Oracle Content Management con un canal de contenido publicado para el tutorial del sitio de blog, hemos instalado y ejecutado el sitio Angular para recuperar el contenido necesario y crear el sitio.

Para obtener más información sobre Angular, visite el sitio web de Angular.

Obtenga información sobre los conceptos importantes de Oracle Content Management en la documentación.

Puede encontrar más ejemplos como este en la página Ejemplos de Oracle Content Management en el Centro de ayuda de Oracle.