HCL Commerce Version 9.1.11.0 or later

Creating a custom widget

Un widget es un marco que muestra un tipo específico de contenido de la tienda, como anuncios, recomendaciones de productos o enlaces de navegación. Este documento explica los pasos a seguir para crear un widget personalizado.

About this task

En este documento, se crea un nuevo widget denominado widget de ejemplo con dos propiedades que se indican a continuación:
Table 1. Propiedades del widget
Propiedad Descripción
Título Esta entrada de texto es el título que se proporciona al widget.
Altura Los botones de selección se proporcionan con dos opciones: Alto y Corto.

Procedure

  1. Añada una definición de widget en las herramientas.
    • La adición de una definición de widget en las herramientas depende de las definiciones de widget proporcionadas en la tabla PLWIDGETDEF. Antes de realizar cualquier cambio en la interfaz de usuario de herramientas, las definiciones del widget deben insertarse en la tabla. En este ejemplo, se añade una definición de widget para el ID de tienda (STOREENT) 0:
      INSERT INTO PLWIDGETDEF(PLWIDGETDEF_ID, STOREENT_ID, IDENTIFIER, VENDOR, WIDGETTYPE, JSPPATH, DEFINITIONXML, STATE, CREATEDATE, LASTUPDATE) 
      VALUES(-100000, 0, 'example_widget', 'hcl', 1, '', '<Definition> </Definition>', 1, CURRENT DATE, CURRENT DATE);
      Note: El valor de PLWIDGETDEF_ID debe ser exclusivo. No seleccione un valor que esté cerca de los valores predeterminados. Esto evitará conflictos con las futuras definiciones de widget proporcionadas por HCL Commerce.
      Query: SELECT * FROM plwidgetdef ORDER BY PLWIDGETDEF_ID
      Table 2. Tabla PLWIDGETDEF
      PLWIDGETDEF_ID STOREENT_ID IDENTIFIER UI_OBJECT_NAME VENDOR WIDGETTYPE DEFENITIONXML
      1504 11501 'SubCategoryPageContainer' NULL 'ibm' 2 'Container/SubCategoryPageContainer.jsp'
      1505 11501 'SearchLandingPageContainer' NULL 'ibm' 2 'Container/LandingPageContainer.jsp'
      1506 11501 'StaticContentContainer' NULL 'ibm' 2 'Container/StaticContentContainer.jsp'
      1507 11501 'SearchResultPageContainer' NULL 'ibm' 2 'Container/SubCategoryPageContainerWithTabs.jsp'
      1508 11501 'ProductPageContainer' NULL 'ibm' 2 'Container/ProductPageContainer.jsp'
      1509 11501 'ProductPageContainer(2)' NULL 'ibm' 2 'Container/ProductPageContainerFullWidth.jsp'
      -100000 11501 'example_widget' NULL hcl' 1 ''
  2. Añada el PLWIDGETDEF_ID creado a la tabla PLSTOREWIDGET para todas las tiendas para las que desea habilitar este widget. En este ejemplo, habilitar el widget para la tienda EmeraldCAS. El ID de tienda es 12501).

    INSERT INTO WCS.PLSTOREWIDGET 
    
    (PLSTOREWIDGET_ID, STOREENT_ID, PLWIDGETDEF_ID, STATE, DEFINITIONXML, OPTCOUNTER) 
    
    VALUES(-100000, 12501, -100000, 1, NULL, 0);
  3. Después de actualizar la base de datos con una nueva definición de widget (ID - 100000), actualice la interfaz de usuario de herramientas. Dos componentes manejan la lógica de negocio de las definiciones de widget y su gestión:
    • Detalles de widget de diseño
    • Diseño widget, que se encuentra bajo el directorio de componentes del creador de páginas. Este directorio se puede encontrar en commerce-tooling/src/app/features/page-builder/components.
  4. Actualice el archivo layout-widgets.json en el componente Layout-widget.
    El componente Layout-widget es responsable de listar widgets en la pestaña Diseño de la herramienta Compositor de páginas. El componente Layout-widget consta de los archivos siguientes:
    • layout-widgets.component.ts
    • layout-widgets.component.html
    • layout-widgets.component.scss
    • layout-widgets.json
  5. Añada las líneas de código siguientes al archivo layout-widgets.json.
    {
    "id": "-100000",
    "name": "example-widget",
    "title": "PAGE_BUILDER.EXAMPLE_WIDGET",
    "description": "PAGE_BUILDER.EXAMPLE_WIDGET_DESCRIPTION",
    "properties": [
    {
    "name": "title",
    "value": "Title!"
    },
    {
    "name": "height",
    "value": "short"
    }
  6. Guarde y cierre el archivo.
  7. Después de actualizar el código, añada nuevas series de conversión en los archivos de traducción. Para visualizar los campos Nombre y Descripción de forma precisa, actualice el archivo en-US.json disponible en la ubicación commerce-tooling/assets/i18:
    "EXAMPLE_WIDGET": "Example Widget",
    "EXAMPLE_WIDGET_DESCRIPTION": "Example widget description!",
    "TITLE": "Title",
    "HEIGHT": "Height",
    "SHORT": "Short",
    "TALL": "Tall",
    "INVALID_TITLE": "Invalid title",
  8. Guarde y cierre el archivo. El widget de ejemplo se muestra en la pestaña Widgets de la sección Diseño, tal como se muestra a continuación:
  9. Después de actualizar el nombre y la descripción del widget, modifique layout-widget-details. Siga Propiedades y contenido del widget para modificar y actualizar las propiedades de widget.
  10. El layout-widget-details se compone de cuatro archivos:
    • layout-widget-details.json: Este archivo tiene los detalles widget definidos y listados.
      • Actualice el archivo layout-widget-details.json con las siguientes líneas de código:
        {
        "id": "-100000",
        "title": "PAGE_BUILDER.EXAMPLE_WIDGET",
        "exampleWidgetType: true
        }
        Note: Como es un widget personalizado, el indicador example-widget-type distintivo se añade porque los parámetros que contiene son diferentes de los demás widgets.
    • layout-widget-details.component.html: Esta es la plantilla del componente layout-widget-details. Basándose en el tipo de widget, este archivo debe actualizarse para la entrada de texto y una entrada de cuadro de selección con un distintivo que activa o desactiva los campos personalizados.
      • Actualice el archivo layout-widget-details.component.html con las siguientes líneas de código:
        <ng-container *ngIf="widgetType.exampleWidgetType">
        <mat-form-field appearance="outline">
        <mat-label>{{'PAGE_BUILDER.TITLE' | translate}}</mat-label>
        <input matInput id="titleInput" formControlName="titleInput" [maxlength]="256" autocomplete="off">
        <mat-error *ngIf="titleInput.errors">
        {{'PAGE_BUILDER.INVALID_TITLE' | translate }}
        </mat-error>
        </mat-form-field>
        <div class="hc-type-label">{{ 'PAGE_BUILDER.HEIGHT' | translate }}</div>
        <mat-radio-group formControlName="height">
        <mat-radio-button value="short">{{'PAGE_BUILDER.SHORT'| translate}}</mat-radio-button>
        <mat-radio-button value="tall">{{'PAGE_BUILDER.TALL'| translate}}</mat-radio-button>
        </mat-radio-group>
        </ng-container>
    • layout-widget-details.component.ts: Este archivo actúa como controlador del componente. A continuación se muestran las pocas funciones que se pueden gestionar actualizando este archivo:
      1. Cargando los detalles del widget del archivo layout-widget-details.json.
      2. Establecer los distintivos necesarios.
      3. Control de los cambios realizados en el widget.
      4. Persistencia de los cambios realizados en widget.
      • Añada dos controles de formulario, titleInput y height. Actualice el archivo con las siguientes líneas de código:
        widgetTypes: Array<any> = (LayoutWidgetTypes as any).default;
        widgetType: any = null;
        widgetForm: FormGroup;
        name: FormControl;
        wrap: FormControl;
        autoSlideshow: FormControl;
        interval: FormControl;
        playDirection: FormControl;
        populationChoice: FormControl;
        emsType: FormControl;
        emsName: FormControl;
        titleInput: FormControl;
        height: FormControl;
        
        @ViewChild("nameInput") nameInput: ElementRef<HTMLInputElement>;
      • Defina e inicialice los controles titleInput y height. Cambie los métodos createFormControls() y createForm() para definir e inicializar los controles.
      • Actualice el archivo con las siguientes líneas de código:
        this.height.setValue(widgetProperties.height);
        if (this.widgetType?.exampleWidgetType) {
        this.titleInput.enable();
        this.height.enable();
        } else {
        this.titleInput.disable();
        this.height.disable();
        }
        private createForm() {
        this.widgetForm = new FormGroup({
        name: this.name,
        wrap: this.wrap,
        autoSlideshow: this.autoSlideshow,
        interval: this.interval,
        playDirection: this.playDirection,
        populationChoice: this.populationChoice,
        emsType: this.emsType,
        emsName: this.emsName,
        titleInput: this.titleInput,
        height: this.height
        });
        }
        }
      • Implemente la lógica de carga inicial para campos personalizados en el método initialize(). Actualice el archivo con las siguientes líneas de código:
        this.emsName.setValue(widgetProperties.emsName);
        this.titleInput.setValue(widgetProperties.title);
        this.height.setValue(widgetProperties.height);
        if (this.widgetType?.exampleWidgetType) {
        	this.titleInput.enable();
        	this.height.enable();
        } else {
        	this.titleInput.disable();
        	this.height.disable();				
        }
        if (this.widgetType?.selectMarketingSpot && widgetProperties.emsType === "local") {
        	this.emsName.enable();
        } else {
        	this.emsName.disable();
        }
        if (this.widgetType?.carousel) {
        	this.interval.enable();
        } else {
        	this.interval.disable();
        }
        } else {
        	this.name.setValue("");
        	this.wrap.setValue(false);
        	this.autoSlideshow.setValue(false);
        	this.interval.setValue(5000);
        	this.playDirection.setValue("forward");
        	this.populationChoice.setValue(null);
        	this.emsType.setValue(null);
        	this.emsName.setValue("");
        	this.titleInput.setValue("");
        	this.height.setValue(null);
        }
        }
      • Implemente la lógica para persistir los detalles de widget en el método save(). Actualice el archivo con las siguientes líneas de código:
        if (this.widgetType?.exampleWidgetType) {
        		this.updateProperty("titleInput", this.titleInput.value);
        		this.updateProperty("height", this.height.value);
        	}
      • Guarde y cierre el archivo. El panel de detalles widget aparece en la pestaña Widget de la sección Diseño, tal como se muestra en la imagen siguiente:

Results

El Widget de ejemplo recién personalizado se lista en la lista de widget y se puede editar o actualizar según sea necesario.