Step 16: Asset Management

This step describes and explains how to manage the assets used by a component.

Assets include components and custom components that Oracle Content Management must know about to manage the life cycle of the assets.

Oracle Content Management content Folder

Each site that you create in Oracle Content Management comes with its own content folder. This is a hidden folder that you won't normally see. When the site is published, all the files in the content folder are also published to the file system.

For example, when you select an image using the Image component, Oracle Content Management makes a copy of the image you selected and places it in the content folder. Your URL always points to this copied version of the image so that if you delete the original image, your site won't break. This also applies to the other components provided by Oracle Content Management: Gallery, Gallery Grid, Document, Social Bar, File Download, as well as background images for slots and componentGroups.

For a custom component to take part in this asset life cycle, the custom component must tell Oracle Content Management about any assets it wants the service to manage on its behalf. Because this involves making a copy of the asset, the custom component must also use Oracle Content Management APIs to select the asset so that we know how to manage it.

Manage URLs

The URL to an asset changes based on a number of criteria.

  • The runtime URL to a component is different than the Site Builder URL to the component

  • If you copy a page, Oracle Content Management also makes a copy of all the referenced assets in the content folder so you never have two components pointing to the same asset in the content folder

  • Dropping a componentGroup onto the page makes new copies for any assets referenced by a component in the componentGroup

In addition, while a relative URL may be fine for a local component, remote components require the fully qualified URL to any asset that you want Oracle Content Management to manage on your behalf so they can render their inline frame content with the full URL.

Because you can't rely on the URL remaining static, you must only hold references to the ID to the asset in your code and retrieve the asset's URL when you want to render the asset.

Manage Assets

These Sites SDK APIs are available for managing assets.

SitesSDK.getProperty('componentAssets', callback);

  • This gets the array of current assets

  • Each asset entry consists of:

    • id: Unique ID for the asset.

    • title: Oracle Content Management title metadata.

    • description: Oracle Content Management description metadata.

    • fileName: Original name of the selected file. Useful for display in the Settings panel for your custom component so users know what file they selected. This is not the name of the file copied to the content folder.

    • source: Macro enabled URL to the asset. This value will change over time and should not be referenced by your component, but it must be saved as part of the asset.

    • url: Fully qualified URL to the asset based on the context in which getPropert() was called.

SitesSDK.setProperty('componentAssets', [assets]);

  • Call this to save all the assets you want Oracle Content Management to manage on your behalf.

  • If you don't call this, then no asset will be saved.

  • Any assets not in this array will be deleted when the site is published.

  • The assets parameter is an array of assets in the same format as you get returned by getProperty and is also returned by filePicker.

    Note:

    No url value is stored. That value is dynamically created when you ask for the assets.

SitesSDK.filePicker(options, callback);

  • An API to bring up the file picker to select the list of assets.

  • It calls the callback on successful selection of assets passing in the array of selected assets.

  • Nothing is saved at this point and it’s up to the component to call setProperty('componentAssets', [assets]); to save items from this selection combined with any other assets to be saved.

Example of Select Asset

This section shows you how to select an asset, store its ID, and re-fetch the actual values from the stored assets.

  1. Edit the settings.html file.

  2. Change the template object to include an Image selection.

    <div>
        <!-- Image selection -->
        <label id="imageLabel" for="imageAsset" class="settings-heading" data-bind="text: 'Image'"></label>
        <input id="imageAsset" data-bind="value: imageName" readonly class="settings-text-box">
        <button id="imageSelect" type="button" class="selectbutton" data-bind="click: showFilePicker">Select Image</button>
    </div>
  3. Change the viewModel to add an observable to store the ID of the selected asset.

    self.imageID = ko.observable();
  4. Change the viewModel to manage selection of the asset by bringing up the file picker and displaying the name of the selected asset.

    //
    // handle component assets
    //
    self.assets = []
     
    // bring up a file picker to select the assets
    self.showFilePicker = function () {
        // select an image
        SitesSDK.filePicker({
            'multiSelect': false,
            'supportedFileExtensions': ['jpg', 'png']
        }, function (result) {
            if (result.length === 1) {
                // update the array of assets
                self.assets = result;
     
                // update the image in customSettingsData
                self.imageID(result[0].id);
            }
        });
    };
     
    // update the display name based on the assets
    self.imageName = ko.computed(function () {
        var imageName = '',
            imageID = self.imageID();
        for (var i = 0; i < self.assets.length; i++) {
            if (self.assets[i].id === imageID) {
                imageName = self.assets[i].fileName;
                break;
            }
        }
     
        return imageName
    }, self); 
  5. Update the viewModel to first retrieve the assets before getting the customSettingsData. This code will also cause the self.imageName to be invoked when the self.ImageID() observable changes.

    SitesSDK.getProperty('componentAssets', function (assets) {
        self.assets = assets;
        SitesSDK.getProperty('customSettingsData', function (data) {
            //update observable
            self.imageWidth(data.imageWidth);
            self.imageID(data.imageID);
            self.titleText(data.titleText);
            self.userText(data.userText);
     
            // note that viewModel is initialized and can start saving data
            self.initialized(true);
            self.saveData = true;
        });
    });
  6. Finally, update the save function to save the imageID and make sure to update the componentAssets with your list of referenced assets.

    self.save = ko.computed(function () {
        var saveconfig = {
            'imageWidth': isNaN(self.imageWidth()) ? self.imageWidth() : self.imageWidth() + 'px',
            'imageID': self.imageID(),
            'titleText': self.titleText(),
            'userText': self.userText()
        };
     
        // store the selected asset and update custom settings
        if (self.saveData) {
            SitesSDK.setProperty('componentAssets', self.assets);
            SitesSDK.setProperty('customSettingsData', saveconfig);
        }
    }, self);

Check the Results for Select Asset

  1. Refresh your page in your site so Site Builder can pick up changes to the component.

  2. Take the page into Edit mode.

  3. Drag and drop your component on the page.

  4. Bring up the Settings panel.

  5. Click the Select image button.

  6. Browse (or upload) and select an image.

    Note that the name of the image is stored showing the selected image.

  7. Close out of the Settings panel.

  8. Bring up the Settings panel again.

    Note that the name of the image is again reflected.

Example of Render Asset

This section shows you how to retrieve the assets and render them in your component, and also have the component dynamically update whenever values are changed in your settings panel.

Note:

Although this is showing an example for a local component that is in an inline frame on the page, similar code will work for components rendered inline in the page.
  1. Edit the render.html file.

  2. Update the template to include your asset:.

    <!-- ko if: imageURL -->
    <div style="flex-shrink:0;">
        <img data-bind="attr: {style: imageStyle, id: 'imageId', src: imageURL, alt: '', title: ''}, click: imageClicked" />
    </div>
    <!-- /ko -->
  3. In the viewModel, create two observables to get the imageID from the customSetttingsData and store the imageURL retrieved from the stored list of assets.

    self.imageID = ko.observable();
    self.imageURL = ko.observable();
  4. Update the viewModel so that whenever the imageID changes, it gets the corresponding image asset URL.

    self.imageID.subscribe(function (imageID) {
        // whenever the image changes get the updated referenced asset
        SitesSDK.getProperty('componentAssets', function (assets) {
            for (var i = 0; i < assets.length; i++) {
                if (assets[i].id === imageID) {
                    self.imageURL(assets[i].url);
                    break;
                }
            }
        });
    });
  5. Update the viewModel to retrieve the ID from the customSettingsData.

Check the Results for Render Asset

  1. Refresh your page in your site so Site Builder can pick up changes to the component.

  2. Take the page into Edit mode.

  3. Drag and drop your component on the page.

  4. Bring up the Settings panel.

  5. Click the Select image button.

  6. Browse (or upload) and select an image.

    Note that the name of the image is stored showing the selected image.

  7. Close out of the Settings panel.

    At this point you should see your selected image rendered in the component.

Continue to Tutorial Review.