Crear un componente meteorológico personalizado custom-component

AEM SPA Obtenga información sobre cómo crear un componente meteorológico personalizado para utilizarlo con el Editor de tiempo de la. Aprenda a desarrollar cuadros de diálogo de autor y modelos Sling para ampliar el modelo JSON y rellenar un componente personalizado. Se usan la API de clima abierto y el componente React de clima abierto.

Objetivo

  1. AEM Comprenda el papel de los modelos Sling en la manipulación de la API del modelo JSON proporcionada por los usuarios de la interfaz de usuario de.
  2. AEM Obtenga información sobre cómo crear nuevos cuadros de diálogo de componentes de.
  3. AEM SPA Aprenda a crear un componente personalizado de la aplicación que sea compatible con el marco de trabajo del editor de.

Qué va a generar

Se crea un componente meteorológico simple. SPA Los autores de contenido pueden añadir este componente a la. AEM Mediante un cuadro de diálogo de, los autores pueden establecer la ubicación del tiempo que se mostrará. AEM AEM SPA La implementación de este componente ilustra los pasos necesarios para crear un componente de red de nueva creación que sea compatible con el marco de trabajo del Editor de.

Configurar el componente de tiempo abierto

Requisitos previos

Revise las herramientas y las instrucciones necesarias para configurar un entorno de desarrollo local. SPA AEM AEM Este capítulo es una continuación del capítulo Navegación y enrutamiento; sin embargo, para continuar, todo lo que necesita es un proyecto de habilitado para el uso de la local implementado en una instancia de la aplicación.

Abrir clave de API meteorológica

Se necesita una clave de API de Tiempo abierto para seguir junto con el tutorial. El registro es gratis para una cantidad limitada de llamadas API.

AEM Definición del componente de

AEM Un componente se define como un nodo y propiedades. En el proyecto, estos nodos y propiedades se representan como archivos XML en el módulo ui.apps. AEM A continuación, cree el componente de en el módulo ui.apps.

  1. En el IDE que elija, abra la carpeta ui.apps.

  2. Vaya a ui.apps/src/main/content/jcr_root/apps/wknd-spa-react/components y cree una nueva carpeta llamada open-weather.

  3. Cree un nuevo archivo con el nombre .content.xml debajo de la carpeta open-weather. Rellene open-weather/.content.xml con lo siguiente:

    code language-xml
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:Component"
        jcr:title="Open Weather"
        componentGroup="WKND SPA React - Content"/>
    

    Crear definición de componente personalizado

    AEM jcr:primaryType="cq:Component": identifica que este nodo es un componente de la.

    jcr:title es el valor que se muestra a los autores de contenido y componentGroup determina la agrupación de componentes en la interfaz de usuario de creación.

  4. Debajo de la carpeta custom-component, cree otra carpeta denominada _cq_dialog.

  5. Debajo de la carpeta _cq_dialog cree un nuevo archivo denominado .content.xml y rellénelo con lo siguiente:

    code language-xml
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
        jcr:primaryType="nt:unstructured"
        jcr:title="Open Weather"
        sling:resourceType="cq/gui/components/authoring/dialog">
        <content
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/container">
            <items jcr:primaryType="nt:unstructured">
                <tabs
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/tabs"
                    maximized="{Boolean}true">
                    <items jcr:primaryType="nt:unstructured">
                        <properties
                            jcr:primaryType="nt:unstructured"
                            jcr:title="Properties"
                            sling:resourceType="granite/ui/components/coral/foundation/container"
                            margin="{Boolean}true">
                            <items jcr:primaryType="nt:unstructured">
                                <columns
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
                                    margin="{Boolean}true">
                                    <items jcr:primaryType="nt:unstructured">
                                        <column
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/container">
                                            <items jcr:primaryType="nt:unstructured">
                                                <label
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                    fieldDescription="The label to display for the component"
                                                    fieldLabel="Label"
                                                    name="./label"/>
                                                <lat
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
                                                    fieldDescription="The latitude of the location."
                                                    fieldLabel="Latitude"
                                                    step="any"
                                                    name="./lat" />
                                                <lon
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
                                                    fieldDescription="The longitude of the location."
                                                    fieldLabel="Longitude"
                                                    step="any"
                                                    name="./lon"/>
                                            </items>
                                        </column>
                                    </items>
                                </columns>
                            </items>
                        </properties>
                    </items>
                </tabs>
            </items>
        </content>
    </jcr:root>
    

    Definición de componente personalizado

    El archivo XML anterior genera un cuadro de diálogo muy sencillo para Weather Component. La parte crítica del archivo son los nodos internos <label>, <lat> y <lon>. Este cuadro de diálogo contiene dos numberfields y un textfield que permiten al usuario configurar el tiempo que se mostrará.

    Se crea un modelo Sling junto a para exponer el valor de las propiedades label,lat y long a través del modelo JSON.

    note note
    NOTE
    Puede ver muchos más ejemplos de cuadros de diálogo al ver las definiciones de los componentes principales. También puede ver campos de formulario adicionales, como select, textarea, pathfield, disponibles debajo de /libs/granite/ui/components/coral/foundation/form en CRXDE-Lite.

    AEM Con un componente tradicional de la, se suele requerir un script HTL. SPA Dado que el componente se procesará mediante el script, no se necesita un script HTL.

Creación del modelo Sling

Los modelos Sling son objetos Java antiguos comunes ("POJO") impulsados por anotaciones que facilitan la asignación de datos desde el JCR a variables Java. AEM Los modelos Sling suelen funcionar para encapsular lógica empresarial compleja del lado del servidor para componentes de la.

SPA En el contexto del Editor de modelos de Sling, los modelos de Sling exponen el contenido de un componente a través del modelo JSON mediante una función que utiliza el Exportador del modelo Sling.

  1. En el IDE de su elección, abra el módulo core en aem-guides-wknd-spa.react/core.

  2. Cree un archivo con el nombre OpenWeatherModel.java en core/src/main/java/com/adobe/aem/guides/wkndspa/react/core/models.

  3. Rellene OpenWeatherModel.java con lo siguiente:

    code language-java
    package com.adobe.aem.guides.wkndspa.react.core.models;
    
    import com.adobe.cq.export.json.ComponentExporter;
    
    // Sling Models intended to be used with SPA Editor must extend ComponentExporter interface
    public interface OpenWeatherModel extends ComponentExporter {
        public String getLabel();
        public double getLat();
        public double getLon();
    }
    

    Esta es la interfaz de Java para nuestro componente. SPA Para que nuestro modelo Sling sea compatible con el marco de trabajo del Editor de la, debe ampliar la clase ComponentExporter.

  4. Cree una carpeta denominada impl debajo de core/src/main/java/com/adobe/aem/guides/wkndspa/react/core/models.

  5. Cree un archivo de nombre OpenWeatherModelImpl.java por debajo de impl y rellénelo con lo siguiente:

    code language-java
    package com.adobe.aem.guides.wkndspa.react.core.models.impl;
    
    import org.apache.sling.models.annotations.*;
    import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
    import com.adobe.cq.export.json.ComponentExporter;
    import com.adobe.cq.export.json.ExporterConstants;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.sling.api.SlingHttpServletRequest;
    import com.adobe.aem.guides.wkndspa.react.core.models.OpenWeatherModel;
    
    // Sling Model annotation
    @Model(
        adaptables = SlingHttpServletRequest.class,
        adapters = { OpenWeatherModel.class, ComponentExporter.class },
        resourceType = OpenWeatherModelImpl.RESOURCE_TYPE,
        defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
    )
    @Exporter( //Exporter annotation that serializes the modoel as JSON
        name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
        extensions = ExporterConstants.SLING_MODEL_EXTENSION
    )
    public class OpenWeatherModelImpl implements OpenWeatherModel {
    
        @ValueMapValue
        private String label; //maps variable to jcr property named "label" persisted by Dialog
    
        @ValueMapValue
        private double lat; //maps variable to jcr property named "lat"
    
        @ValueMapValue
        private double lon; //maps variable to jcr property named "lon"
    
        // points to AEM component definition in ui.apps
        static final String RESOURCE_TYPE = "wknd-spa-react/components/open-weather";
    
        // public getter method to expose value of private variable `label`
        // adds additional logic to default the label to "(Default)" if not set.
        @Override
        public String getLabel() {
            return StringUtils.isNotBlank(label) ? label : "(Default)";
        }
    
        // public getter method to expose value of private variable `lat`
        @Override
        public double getLat() {
            return lat;
        }
    
        // public getter method to expose value of private variable `lon`
        @Override
        public double getLon() {
            return lon;
        }
    
        // method required by `ComponentExporter` interface
        // exposes a JSON property named `:type` with a value of `wknd-spa-react/components/open-weather`
        // required to map the JSON export to the SPA component props via the `MapTo`
        @Override
        public String getExportedType() {
            return OpenWeatherModelImpl.RESOURCE_TYPE;
        }
    }
    

    La variable estática RESOURCE_TYPE debe apuntar a la ruta de acceso en ui.apps del componente. SPA getExportedType() se usa para asignar las propiedades JSON al componente de la a través de MapTo. @ValueMapValue es una anotación que lee la propiedad jcr guardada por el cuadro de diálogo.

SPA Actualización del estado de la

AEM A continuación, actualice el código React para incluir el componente React Open Weather y haga que se asigne al componente de la aplicación de tiempo abierto creado en los pasos anteriores.

  1. Instale el componente React Open Weather como una dependencia npm:

    code language-shell
    $ cd aem-guides-wknd-spa.react/ui.frontend
    $ npm i react-open-weather
    
  2. Cree una nueva carpeta denominada OpenWeather en ui.frontend/src/components/OpenWeather.

  3. Agregue un archivo de nombre OpenWeather.js y rellénelo con lo siguiente:

    code language-js
    import React from 'react';
    import {MapTo} from '@adobe/aem-react-editable-components';
    import ReactWeather, { useOpenWeather } from 'react-open-weather';
    
    // Open weather API Key
    // For simplicity it is hard coded in the file, ideally this is extracted in to an environment variable
    const API_KEY = 'YOUR_API_KEY';
    
    // Logic to render placeholder or component
    const OpenWeatherEditConfig = {
    
        emptyLabel: 'Weather',
        isEmpty: function(props) {
            return !props || !props.lat || !props.lon || !props.label;
        }
    };
    
    // Wrapper function that includes react-open-weather component
    function ReactWeatherWrapper(props) {
        const { data, isLoading, errorMessage } = useOpenWeather({
            key: API_KEY,
            lat: props.lat, // passed in from AEM JSON
            lon: props.lon, // passed in from AEM JSON
            lang: 'en',
            unit: 'imperial', // values are (metric, standard, imperial)
        });
    
        return (
            <div className="cmp-open-weather">
                <ReactWeather
                    isLoading={isLoading}
                    errorMessage={errorMessage}
                    data={data}
                    lang="en"
                    locationLabel={props.label} // passed in from AEM JSON
                    unitsLabels={{ temperature: 'F', windSpeed: 'mph' }}
                    showForecast={false}
                  />
            </div>
        );
    }
    
    export default function OpenWeather(props) {
    
            // render nothing if component not configured
            if (OpenWeatherEditConfig.isEmpty(props)) {
                return null;
            }
    
            // render ReactWeather component if component configured
            // pass props to ReactWeatherWrapper. These props include the mapped properties from AEM JSON
            return ReactWeatherWrapper(props);
    
    }
    
    // Map OpenWeather to AEM component
    MapTo('wknd-spa-react/components/open-weather')(OpenWeather, OpenWeatherEditConfig);
    
  4. Actualizar import-components.js a las ui.frontend/src/components/import-components.js para incluir el componente OpenWeather:

    code language-diff
      // import-component.js
      import './Container/Container';
      import './ExperienceFragment/ExperienceFragment';
    + import './OpenWeather/OpenWeather';
    
  5. AEM Implemente todas las actualizaciones en un entorno de local desde la raíz del directorio del proyecto con sus habilidades con Maven:

    code language-shell
    $ cd aem-guides-wknd-spa.react
    $ mvn clean install -PautoInstallSinglePackage
    

Actualizar la directiva de plantilla

AEM SPA A continuación, navegue hasta la para comprobar las actualizaciones y permitir que se agregue el componente OpenWeather al elemento de la lista de elementos que se van a.

  1. Compruebe el registro del nuevo modelo Sling navegando hasta http://localhost:4502/system/console/status-slingmodels.

    code language-plain
    com.adobe.aem.guides.wkndspa.react.core.models.impl.OpenWeatherModelImpl - wknd-spa-react/components/open-weather
    
    com.adobe.aem.guides.wkndspa.react.core.models.impl.OpenWeatherModelImpl exports 'wknd-spa-react/components/open-weather' with selector 'model' and extension '[Ljava.lang.String;@2fd80fc5' with exporter 'jackson'
    

    Debería ver las dos líneas anteriores que indican que OpenWeatherModelImpl está asociado con el componente wknd-spa-react/components/open-weather y que está registrado a través del Exportador de modelos Sling.

  2. SPA Vaya a la plantilla de página de la página de en http://localhost:4502/editor.html/conf/wknd-spa-react/settings/wcm/templates/spa-page-template/structure.html.

  3. Actualice la directiva del contenedor de diseño para agregar el nuevo Open Weather como componente permitido:

    Actualizar directiva de contenedor de diseño

    Guarde los cambios en la directiva y observe Open Weather como un componente permitido:

    Componente personalizado como componente permitido

Crear el componente Tiempo abierto

AEM SPA A continuación, cree el componente Open Weather mediante el Editor de.

  1. Vaya a http://localhost:4502/editor.html/content/wknd-spa-react/us/en/home.html.

  2. En el modo Edit, agregue Open Weather a Layout Container:

    Insertar nuevo componente

  3. Abra el cuadro de diálogo del componente e introduzca Etiqueta, Latitud y Longitud. Por ejemplo San Diego, 32.7157 y -117.1611. Los números del hemisferio occidental y del hemisferio sur se representan como números negativos con la API de clima abierto

    Configurar el componente de tiempo abierto

    Este es el cuadro de diálogo que se creó en función del archivo XML anteriormente en el capítulo.

  4. Guarde los cambios. Observe que ahora se muestra el tiempo en San Diego:

    Componente meteorológico actualizado

  5. Vea el modelo JSON navegando a http://localhost:4502/content/wknd-spa-react/us/en.model.json. Buscar wknd-spa-react/components/open-weather:

    code language-json
    "open_weather": {
        "label": "San Diego",
        "lat": 32.7157,
        "lon": -117.1611,
        ":type": "wknd-spa-react/components/open-weather"
    }
    

    El modelo Sling genera los valores JSON. Estos valores JSON se pasan al componente React como props.

Enhorabuena. congratulations

AEM SPA ¡Enhorabuena! Ha aprendido a crear un componente de personalizado para utilizarlo con el Editor de segmentos de la aplicación También ha aprendido cómo los cuadros de diálogo, las propiedades JCR y los modelos Sling interactúan para generar el modelo JSON.

Siguientes pasos next-steps

AEM AEM SPA Ampliar un componente principal: aprenda a ampliar un componente principal de la existente para utilizarlo con el Editor de la. AEM SPA Comprender cómo añadir propiedades y contenido a un componente existente es una técnica potente para ampliar las capacidades de una implementación de Editor de segmentos de tiempo de ejecución de la aplicación de un editor de segmentos de tiempo de ejecución de la aplicación de un editor de tiempo de ejecución de la.

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4