Developing Widgets

  1.  Introduction:

A widget provides a unit of UI functionality that can be deployed on one or more pages of your web store.

Widgets are made up of a set of source files and resources. These provide the widget with its functionality and include:

  • Templates: Display templates for showing content using knockout.js data bindings.
  • JavaScript: View model per widget (optional).
  • CSS: Styles for the widget. Can be pure CSS or Less.
  • Locale resources: Translation resources per locale for the widget.
  • Images: Images used for the widget, referenced via the widget asset mappings.

Widgets also consist of auxiliary files that contain help, configuration, and meta-data describing the widget. They include:

  • Meta-data: The meta-data that describes the widget.
  • Elements: Small pieces or fragments of functionality for a widget, including a display template snippet and a view model.
  • Configurable widget settings: A mechanism for providing configurable widget settings that the page layout designer can use to customize the widget’s behavior on the Design tab, for example, limiting the number of products to display on a Related Products widget.
  • Configuration: Default configuration can be delivered with the widget.
  1. Create the widget structure:

Widgets are added to an extension’s structure in a /widget directory that is at the same level as the extension’s ext.json file. Each widget should have its own child directory in the /widget directory.        III.  Define widget meta-data in widget.json:

Much like the ext.json file defines meta-data for an extension, a widget.json file defines meta-data for a widget. An example of a widget.json file is provided below:

{
  "version": 1,
  "global": false,
  "javascript": " widget-type-js ",
  "i18nresources": " widget-type ",
  "availableToAllPages": true,
  "jsEditable": true,
  "config": {
   }
  "translations" : [
   {
    "language": "en",
    "name": " Name in English "
   },
   {
    "language": "de",
    "name": " Name in German "
   }
  ]  
}
  • javascript : The name of the widget’s main JavaScript file, to which .js is appended, to load in the Storefront.
  • jsEditable : A flag that determines whether it is possible to edit the widget’s JavaScript code within the Design tab. Defaults to false.
  • i18nresources : The namespace name for the resources of this widget, to which ns is pre-appended and .json is post-appended.
  • imports : By default, widgets have access to data and functions contained in the common view models (user, cart, order and so on). However, in order for a widget to have access to page-specific view models, those view models must be explicitly defined in the imports property. The possible values that are acceptable for the imports property depends on the type of page the widget will be placed on.

availableToAllPages : Set this property to true to allow the widget to be placed on all page types; the widget will appear in the Component library for all pages.

  • pageTypes : Defines which page types the widget can be placed on; the widget will appear in the Component library for the specified pages.

Available page types include: productcategoryhomecartcheckoutconfirmationarticleerrorsearchResultsnoSearchResults.

  • translations : An array that provides translations for the widget name. This name is displayed in the Components library panel that you use to add a widget to a page layout.
  • version : Specifies the version of the widget, used to ensure the right version of a widget is used in the storefront.
  • name : If your storefront only uses one language, meaning you do not need multiple translations for the name of the component, you can choose to use the name property instead of the translations property.
  • global : Defines the widget as a global widget. A global widget does not include a display template. It is automatically added to all pages but, due to the lack of template, it is excluded from template rendering. Global widgets are useful for tasks like logging web analytics or loading JavaScript libraries. Defaults to false.
  • minWidth : The minimum width that this widget will fit into it. The system will check if the widget will fit in the region in Grid View.
  1. Acceptable values for the imports property: 

When defining a widget, one of the properties you may choose to set in the widget.json file is the import property. By default, widgets have access to data and functions contained in the common view models (user, cart, site and so on). However, in order for a widget to have access to page-specific view models, those view models must be explicitly defined in the imports property. The possible values that are acceptable for the imports property depends on the type of page the widget will be placed on. To determine which page-specific view models your widget can have access to, determine the page type the widget will be placed on and then review the acceptable values for that page type in the following sections.

  • Category Acceptable imports values include:

• category

• categoryId

• dimensionId

• productTypes

  • Product Acceptable imports values include:

• product

• productTypes

• productVariantOptions

  • Cart Acceptable imports values include:

• defaultShippingCountry

• order

• payment

• shippingCountries

• shippingCountriesPriceListGroup

• shippingmethods

  • Checkout Acceptable imports values include:

• billingCountries

• defaultBillingCountry

• defaultShippingCountry

• order

• payment

• paymentauthorization

• shippingCountries

• shippingCountriesPriceListGroup

• shippingmethods

  • Confirmation Acceptable imports values include:

• confirmation

• defaultShippingCountry

• shippingCountries

• shippingCountriesPriceListGroup

  • Order Details Acceptable imports values include:

• defaultShippingCountry

• orderDetails

• shippingCountries

• shippingCountriesPriceListGroup

  • Shopper Profile Acceptable imports values include:

• defaultShippingCountry

• shippingCountries

• shippingCountriesPriceListGroup

  • Wish List Acceptable imports values include:

• space

  1. Create the widget template file:

With the exception of global widgets, all widgets require a template file, called display.template , in the /widget/<widget-type>/templates directory.

The template is rendered within the context of the widget and should be written as straight HTML with no surrounding script tag. All knockout bindings and behavior are available in the HTML template code.

  1. Create custom widget JavaScript:

To add custom JavaScript to a widget you must create a JavaScript file under the <extension-name>/widget/<widget-type>/js directory. The name of the JavaScript file must match the value of the javascript property in the widget.json file, minus the .js extension. The convention is to use the widget-type as the JavaScript file name, without the .js suffix.

Custom JavaScript for a widget assumes that the file will perform some custom logic and return an object with extensions to the widget’s view model. The JavaScript file should implement the following format using RequireJS

define(
// Dependencies
['jquery', 'knockout'],
// Module Implementation
function($,ko) {
  // We recommend enabling strict checking mode
  'use strict';
  // Private variables and functions can be defined here...
  var SOME_CONSTANT = 1024;
  var privateMethod = function () {
     // ...
  };
  return {
    // Widget JS
    // Some member variables...
    textInput: ko.observable(),
    // Some public methods...
    doSomethingWithInput: function () {
      //...
    }
  }
});

The define statement above can be modified to include widget-specific libraries or other JavaScript files, if required. When a widget is instantiated all properties returned from the JavaScript file specified will be copied into that instance of the widget’s view model. This allows you to define properties, make Web API calls, or handle UI events.

  1. Include multiple JavaScript files:

If your widget requires multiple JavaScript files, then any additional JavaScript files can be loaded through the dependencies in the widget module’s define statement.

To derive the path of the dependency, use the path js/ to reference the widget’s JavaScript folder followed by the path to the dependency but omitting the .js extension. For example, if a widget called myWidget includes the following JavaScript files:

myWidget/
       js/
        file1.js
        file2.js
        myWidget.js

And myWidget.js is the main JavaScript file for the widget and it is dependent on the other three JavaScript files, then the require dependencies in myWidget.js would look like this:

// Dependencies
['js/file1','js/file2'],
  1. Running custom logic:

If you must run custom logic when a widget is instantiated, then add an onLoad function to the widget JavaScript’s return object:

onLoad: function(widget) {
//onLoad code here.
}

If you require some logic to run each time the widget appears on the page, add the beforeAppear() function to the widget JavaScript’s return object:

beforeAppear: function(page) {
// Code to run before showing the widget here.
}
  1. Configure a widget’s style:

CSS specific to a widget is contained in the /widget/<widget-type>/less directory.

These files are always named widget.less and any CSS can be added here. Styling across the Storefront is built using Less. A Less file, like widget.less, can define style using the Less language or native CSS. Less files are compiled to make one CSS file.

  1.  Localize a widget:

Any text in a widget that does not come from a remote API call can be defined in a resource bundle so that it can be localized.

A child directory exists in the /locales directory for each locale you want to provide resources for and their names can be either a two-letter language code (for example, en ) or a two-letter language code and a two-letter country code with an underscore in between (for example, en_US ). ISO 639-1 defines the two-letter language codes. ISO 3166-1 alpha-2 defines the two-letter country codes.

The naming convention for resource files contained in these directories is ns.<widget-type>.json , for example, ns.mywidget.json . The ns prefix stands for “namespace” and widget-type corresponds to the /widget/widget-type directory. Resource files are in JSON format.

  1. Add customizable widget settings: 

You can add settings to a widget that provide a finer level control over the widget’s behavior when it is added to a layout.

Any customizable settings that have been configured for a widget are available via the widget’s Settings tab.

Any configurable widget settings you create are added to the widget’s view model and can be referenced from the widget’s HTML template using a data-bind attribute.

  1. Define a widget’s configurable settings:

Widget settings are defined using a JSON-based schema. To add configurable settings to your widget, add the following files to your directory /<extension-name>/widget/<widget-type>/config/.

The structure of a config.json file looks similar to the following:

{
 "widgetDescriptorName": "configdemo",
 "titleResourceId": "title",
 "descriptionResourceId": "description",
 "properties": [
   {
     "id": "enabled",
     "type": "booleanType",
     "name": "enabled",
     "helpTextResourceId": "enabledHelpText",
     "labelResourceId": "enabledLabel",
     "defaultValue": true
   },
   {
     "id": "coupon",
     "type": "stringType",
     "name": "coupon",
     "helpTextResourceId": "couponHelpText",
     "labelResourceId": "couponLabel",
     "defaultValue": "SHIP100",
     "minLength": 6,
     "maxLength": 10,
     "required": true
   },
   {
     "id": "minSpend",
     "type": "stringType",
     "name": "minSpend",
     "helpTextResourceId": "minSpendHelpText",
     "labelResourceId": "minSpendLabel",
     "defaultValue": "100",
     "required": true
   },
   {
     "id": "bannerSize",
     "type": "optionType",
     "name": "bannerSize",
     "required": true,
     "helpTextResourceId": "sizeHelpText",
     "labelResourceId": "sizeLabel",
     "defaultValue": "s",
     "options": [
        {
          "id": "sizeSmall",
          "value": "s",
          "labelResourceId": "sizeSmallLabel"
        },
        {
          "id": "sizeMedium",
          "value": "m",
          "labelResourceId": "sizeMediumLabel"
        },
        {
          "id": "sizeLarge",
          "value": "l",
          "labelResourceId": "sizeLargeLabel"
        }
      ]
    }
 ]
}

The widgetDescriptorName property names the widget for which these settings are defined and it must match the name property in the widget’s widget.json file. The properties array defines the configurable settings that should be added to the widget’s Settings tab. For each property, the following standard keys are supported:

  • id : A unique ID for the property. You use this ID in the widget’s HTML template to create a data-bind to the property.
  • name : A display name for the property that appears on the Settings tab.
  • type : The data type of the property.
  • helpTextResourceId : The name of the key in the resource files whose value provides help text for the property.
  • labelResourceId : The name of the key in the resource files whose value provides a label for the property on the Settings tab.
  • defaultValue : The property’s default value, which must be a valid value for the property’s data type.
  • required : A Boolean flag that determine if the property requires a value.
  1. Use supported data types for configuration:

There are a number of data types that are supported for widget settings. To specify the data type for a setting, you set the type key to one of the following values:

  • stringType : Produces a text entry field that allows the page designer to specify a free form text value.
  • optionType : Produces a drop-down list of preset values. The values are specified using an options array.
  • booleanType : Produces a checkbox that allows the property to be enabled or disabled.
  • mediaType : Produces a menu that allows you to select a media item (e.g. Image) from your library, or by uploading a new file.
  • sectionTitleType : Produces a read-only Section Title, , defined by the labelResourceId , and an optional block of descriptive help text, defined by the helpTextResourceId , to allow you to group widget settings together
  • collectionType : Produces a picker that allows you to select from the collections defined in your catalog. You define the maximum number of collections that can be chosen using the maxLength property.
  • multiSelectOptionType : Produces a list of preset values, as does optionType ; however, you can select multiple values from this list. By default, the control created for this data type is a drop-down list; however, you can add the displayAsCheckboxes property to the setting definition and set it to true to display a set of checkboxes instead.

Depending on the data type it uses, a property will also support a number of data type-specific keys. For the stringType data type, you can add the following keys:

  • minLength : Minimum length of the string value.
  • maxLength : Maximum length of the string value.
  • pattern : A regex pattern to use for validating the string value.

For the numberType data type, you can add the following keys:

  • minimum : Minimum value.
  • maximum : Maximum value.

For the optionType and multiSelectOptionType data types, you can add an options key that contains a list of objects that describe the entries in the drop-down list. Each option has the following keys:

  • id : Unique ID for the option.
  • value : The value of the option.* labelResourceId : The resource key used to display the option in the drop-down list.

As previously mentioned, the configurable settings you create are added to the widget’s view model and can be referenced from templates using a data-bind attribute (data-bind="text : coupon").

  1. Fragment a widget into elements:

Technology & Innovation

0 Comments

Leave a Reaply

recent posts

archives