Step 2: Review the Structure of Your Local Component Rendering

In this step we review the structure of the default files created for a local component.

For a simple Hello World example, four JavaScript objects and the number of lines of code may seem like too much, but this is to provide you with the basis for building more complex components, as well as dealing with interaction with the Oracle Cloud Sites Service page lifecycle.

To review the structure of your local component:

  1. On the Oracle Content Management home page, click Developer.

    The Developer page is displayed.

  2. Click View all Components.

  3. From the menu, choose Create Local Component.

  4. Enter a name for the component; for example, A_Local_Component.

  5. Enter an optional description.

  6. Click Create.

    After you have done this you’ll see a component named A_Local_Component in your list of components.

  1. Using the Oracle Content Management desktop sync client, locate your component and sync it with the file system.

    If you don’t have the desktop client, you can view all components and select the component in the Components page of the Oracle Content Management interface and drill down to see the files.

  2. If you list the files under the component, you will see these files:

    assets
        render.js
        settings.html
    appinfo.json
    _folder_icon.jpg
  3. Open the render.js file under the /assets directory.

    The main points of the render.js file are:
    • It is structured as a JavaScript AMD module so that it can be “required” into the page.

    • It also includes references to KnockoutJS and JQuery that are already loaded as part of the Oracle Content Management page.

Consider the structure of the render.js file.

In the contents of the render.js file there are two JavaScript objects that implement the required Oracle Content Management component APIs: sampleComponentFactory and SampleComponentImpl. These objects are an example of an implementation for creating any KnockoutJS based components. The implementation of these objects will change based on the technology you use.

  • sampleComponentFactory
    • This object is returned by the render.js AMD module.

    • This is a very simple Factory object and implements the single createComponent() interface.

    • More complex implementations may use the args value passed to return different implementations of the component based on the viewMode parameter. This enables you to have a significantly lighter-weight implementation of the component for runtime versus Site Builder.

  • SampleComponentImpl
    • The main function within this object is the render function, which is used to render the component onto the page.

      To render the Knockout component into the page, the render function dynamically adds the template to the page, then applies the viewModel bindings to the template.

    • The rest of the implementation deals with initialization of the viewModel parameter and template, and with handling the messaging between the page and the component.

The last two objects in the render.js file, sampleComponentTemplate and SampleComponentViewModel, provide a custom implementation for the component. The implementation of these will differ based on your requirements.

  • sampleComponentTemplate
    • This object provides the KnockoutJS template creation. It waits until the component has all the data initialized before attempting to display anything.

  • SampleComponentViewModel
    • The viewModel retrieves the information stored by Oracle Content Management on behalf of the component, then selects how to appropriately lay out the component based on that data

    • General Knockout observables used by the template to handle access to the metadata stored on the component’s behalf:

      self.imageWidth = ko.observable('200px');
      self.alignImage = ko.observable();
      self.layout = ko.observable();
      self.showTopLayout = ko.observable();
      self.showStoryLayout = ko.observable();
    • Triggers and actions integration:

      Trigger: A function to raise an Oracle Content Management trigger from the component that can be bound to actions of other components on the page.

          self.imageClicked = function (data, event) {
            self.raiseTrigger("imageClicked"); // matches appinfo.json
          };

      Action: A function to handle the callback for when the component is told to execute an action with a given payload.

          self.executeActionsListener = function (args) {
            // get action and payload
            var payload = args.payload,
            action = args.action;
      
            // handle 'setImageWidth' actions
            if (action && action.actionName === 'setImageWidth') {
              $.each(payload, function(index, data) {
                if (data.name === 'imageWidth') {
                  self.imageWidth(data.value);
                }
              });
            }
          };

      Callback to execute any registered actions on demand.

      SitesSDK.subscribe(SitesSDK.MESSAGE_TYPES.EXECUTE_ACTION, 
      $.proxy(self.executeActionsListener, self));
    • Subscriptions to component life cycle:

      • Component initialization: Make sure the component doesn’t render until all data has been fetched. This is handled through Knockout observables.

        self.componentLayoutInitialized = ko.observable(false);
        self.customSettingsDataInitialized = ko.observable(false);

        Get the initial values for any required properties. This is handled by callbacks to retrieve the data.

        SitesSDK.getProperty('componentLayout', self.updateComponentLayout);
        SitesSDK.getProperty('customSettingsData', self.updateCustomSettingsData);
      • Metadata updates: Callback whenever component metadata stored on the component’s behalf is changed; for example, when the user invokes the Settings panel and updates the data.

        SitesSDK.subscribe(SitesSDK.MESSAGE_TYPES.SETTINGS_UPDATED, 
        $.proxy(self.updateSettings, self));
        

Note:

Because the Oracle Content Management server always sets the mime-type for .html files, you cannot upload a .html file and use the required "text!" plug-in to load it. Therefore, for templates, you either need to use a different extension to load it using the "text!" plug-in, or load it in-line in the JavaScript directly as shown in the seeded data.

Check the Results for Step 2

You should now have an overview of how the structure of a custom component renderer is created. To validate that it works:

  1. Update the sampleComponentTemplate object in the render.js file to change the following line. Change this code:

    '<!-- ko if: initialized -->'+

    Use this code instead:

    '<!-- ko if: initialized -->'+ 
    '<div data-bind="text:\'image width is: \' + imageWidth()"></div>' +
  2. Sync or upload the component to the Oracle Content Management instance server.

  3. Edit a page within the site and drop in the A_Local_Component custom component onto the page.

    At this point you should see image width is: 260px in the component.

  4. Bring up the Settings panel and click the Custom Settings button.

  5. Change the image Width field to 300px.

  6. At this point two things will happen in the component:
    1. The default image will expand from 260px to 300px in size.

    2. The text you added will update to image width is 300px.

Continue to Step 3: Review the Structure of Local Component Settings.