Universal Editor Custom Asset Picker

This extension allows creating a configurable, custom asset picker for Universal Editor that is tailored to your need by simply providing a JSON configuration file. Relevant crosswalk project needs to follow certain guidelines. It's useful in case where we want to enable authors to select assets of certain file types only from specified repositories etc.

Extension Overview

Asset picker

This extension enhances Universal Editor properties panel for media elements. It replaces standard asset picker with a custom version of asset picker, with provided configuration applied while selecting assets.

The extension will enable you to list the repositories your authors will be able to pick from.

Configuration also supports following types of filters:

Configuration in Edge Delivery Site

Adding a component for author in crosswalk site is like adding any other custom component, with some added fields. A sample custom component's definition requires updates in component-model.json and a new component-definition.json. See examples below:

A new Component Model in component-models.json

This model is necessary for Universal Editor to use the Custom Asset Picker.

For assets hosted in AEM Assets, the component model can be configured to use Dynamic Media with OpenAPI capabilities via URL references, or Edge Delivery Media Bus.

Configure component-models.json to leverage Dynamic Media with OpenAPI Delivery

[
...
	{
	    "id": "custom-asset-one",
	    "fields": [
	      {
	        "component": "custom-asset-namespace:custom-asset",
	        "name": "image",
	        "label": "Image",
	        "configUrl": "https://main--xwalk-test-gems--githubusername.aem.page/tools/assets-selector/image.config.json",
	        "valueType": "string"
	      },
	      {
	        "component": "text",
	        "name": "imageTitle",
	        "label": "Alt Text",
	        "valueType": "string"
	      }
	    ]
	  }
]

Configure component-models.json to leverage Edge Delivery Media Bus

[
	{
	    "id": "custom-asset-one",
	    "fields": [
	      {
	        "name": "image",
	        "component": "custom-asset-namespace:custom-asset",
	        "label": "Image",
	        "configUrl": "https://main--xwalk-test-gems--githubusername.aem.page/tools/assets-selector/image.config.json",
	        "valueType": "string"
	      },
	      {
	        "name": "imageMimeType",
	        "component": "custom-asset-namespace:custom-asset-mimetype",
	        "valueType": "string"
	      },
	      {
	        "name": "imageAlt",
	        "label": "Alt Text",
	        "component": "text",
	        "valueType": "string"
	      }
	    ]
	}
]

In addition to the component model definition for Dynamic Media with OpenAPI Delivery, an opt-in component definition for imageMimeType ensures that the Edge Delivery Media Bus is used for media delivery.

A New Definition in component-definition.json

{
  "groups": [
    …
    {
      "title": "Blocks",
      "id": "blocks",
      "components": [
       …
        {
          "title": "Custom Image One",
          "id": "custom-asset-one",
          "plugins": {
            "xwalk": {
              "page": {
                "resourceType": "core/franklin/components/block/v1/block",
                "template": {
                  "name": "Custom Image One",
                  "model": "custom-asset-one"
                }
              }
            }
          }
        }
      ]
    }
  ]
}

Note that the value of model is the id of model we created in component-models.json

Entry in component-filters.json

[
  …
  {
    "id": "section",
    "components": [
      "text",
      "image",
      "button",
      …
      "custom-asset-one"
    ]
  }
]

Overriding name of component for using custom asset picker

in component-models.json file, the component property need to have component as custom-asset-namespace:custom-asset and custom-asset-namespace:custom-asset-mimetype. If desired, this can be overridden by following method:

Configuration File

This is sample asset picker configuration file that allows filtering assets. Following are the fields that can be configured:

{
    "repoNames": [
      "author-pxxxxxx-eyyyyyy.adobeaemcloud.com",
      "delivery-pxxxxxx-eyyyyyy.adobeaemcloud.com",
    ],
   "aemTierType": [
        "delivery",
        "author"
    ],
    "expiryOptions": {
        "allowSelectionAndDrag": false,
    },
    "filterSchema": [
        {
          "fields": [
            {
              "defaultValue": ["image/*"],
              "element": "checkbox",
              "name": "type",
              "options": [
                {
                  "label": "Image",
                  "readOnly": true,
                  "value": "image/*"
                }
              ]
            }
          ],
          "groupKey": "FileTypeGroup",
          "header": "File Type"
        },
        {
          "fields": [
            {
              "columns": 3,
              "defaultValue": ["arena"],
              "element": "taggroup",
              "name": "property=xcm:keywords.id=",
              "options": [
                {
                  "label": "Demo",
                  "value": "demo"
                }
              ]
            }
          ],
          "groupKey": "AssetTagsGroup",
          "header": "Assets Tags"
        }
      ],
    "filterSchemaMapping": {
      "author-pxxxxxx-eyyyyyy.adobeaemcloud.com": [
        {
          "fields": [
            {
              "defaultValue": ["image/*"],
              "element": "checkbox",
              "name": "type",
              "options": [
                {
                  "label": "Image",
                  "readOnly": true,
                  "value": "image/*"
                }
              ]
            }
          ],
          "groupKey": "FileTypeGroup",
          "header": "File Type"
        },
        {
          "fields": [
            {
              "defaultValue": ["dam:assetStatus==approved"],
              "element": "radiogroup",
              "name": "property",
              "options": [
                {
                  "label": "Approved",
                  "value": "dam:assetStatus==approved"
                }
              ],
              "readOnly": true
            }
          ],
          "groupKey": "StatusGroup",
          "header": "Approval Status"
        },
        {
          "fields": [
            {
              "columns": 3,
              "defaultValue": ["arena"],
              "element": "taggroup",
              "name": "property=xcm:keywords.id=",
              "options": [
                {
                  "label": "arena",
                  "value": "arena"
                }
              ]
            }
          ],
          "groupKey": "AssetTagsGroup",
          "header": "Assets Tags"
        }
      ],
      "author-pxxxxxx-eyyyyyy.adobeaemcloud.com": []
    },
    "alwaysUseDMDelivery": true,
    "assetDomainMapping": {
    	  "delivery-pxxxxxx-eyyyyyy.adobeaemcloud.com":"mediapreprod.store.testdomain.com",
        "delivery-pxxxxxx-eyyyyyy.adobeaemcloud.com": "media.store.testdomain.com",
        "delivery-pxxxxxx-eyyyyyy.adobeaemcloud.com": "mediauat.store.testdomain.com"
        "delivery-pxxxxxx-eyyyyyy.adobeaemcloud.com": "mediaqa.store.testdomain.com"
 	  },
    "rootPath": "/content/dam"
}

Troubleshooting

CORS Issues

Problem: The Asset Selector doesn't behave as configured (missing filters, unexpected AEM repositories, undesirable selection actions, etc. - essentially any/everything defined in this configuration file not be honored)

Diagnosis: The most common issue behind the behaviour above is CORS (Cross-Origin Resource Sharing) errors when fetching the configuration file.

When to check for CORS errors:

How to identify CORS errors:

  1. Open your browser's Developer Tools (F12)

  2. Check the Console tab for errors like:

    • Access to fetch at '...' from origin '...' has been blocked by CORS policy
    • No 'Access-Control-Allow-Origin' header is present on the requested resource

Common Causes:

Configuration files hosted on third-party domains (from the perspective of experience.adobe.com where Universal Editor runs) may trigger CORS errors.

Sample Use Case - Resolving CORS for EDS-hosted Configuration:

If your configuration file is being served from an Edge Delivery Services (EDS) site with *.aem.page domain (e.g., https://main--xwalk-test-gems--githubusername.aem.page/tools/assets-selector/image.config.json), you need to add the appropriate CORS headers to allow the Universal Editor to fetch the configuration.

Add the required headers to your EDS site by following the instructions in the AEM Custom HTTP Response Headers documentation.

Issue the following curl and note the presence of Access-Control-Allow-Origin: https://experience.adobe.com in the response headers. e.g., if the configUrl is https://main--xwalk-test-gems--githubusername.aem.page/tools/assets-selector/image.config.json, the execution of the command below on a terminal-window should look like:

# curl -sD- 'https://main--xwalk-test-gems--githubusername.aem.page/tools/assets-selector/image.config.json' | grep -i "access-control"
access-control-allow-origin: https://experience.adobe.com

Limitations