Migrating Your Storefront to SGJC Controllers

If you are migrating a storefront based on the SiteGenesis Pipelines (SGPP), this section identifies areas code changes are necessary.
Important: For a conceptual understanding of the differences between developing with pipelines and controllers, see Comparing Pipelines and SGJC Controllers.
To migrate your storefront, perform the following steps:
Note: Job pipelets do not have script equivalents, so do not need to be migrated.

See also:Pipelet to Script Method Conversion

This topic assumes that you downloaded Eclipse and installed the Salesforce B2C Commerce plugin. It also assumes that you already uploaded your storefront to your Sandbox instance and included it on the cartridge path. If you have not done performed these steps, see Getting Started for Developers.

Create a Controller Cartridge

Controller cartridges always override Pipeline cartridges. If controllers and their exported methods match the names of pipelines and their start nodes, the controllers are used instead of the pipelines. You can selectively override storefront functionality by creating a controller cartridge and adding more functionality to it over time.

It's also possible to add controllers in the same cartridge as pipelines. However, this approach does not offer the fallback option to remove the cartridge from the path so you can compare pipeline and controller functionality. It also does not let you fallback to the pipeline functionality by simply removing the controller cartridge from the path.

  1. Create an empty cartridge.
    1. In Eclipse, select File > New > Digital Cartridge.
    2. To connect your cartridge to your server, follow the rest of the steps.
  2. Right-click the cartridge folder in the Navigation tab and select New > Folder.
  3. For the Folder Name, enter controllers

Copy Portions of the Latest Version of SiteGenesis to Your Controller Cartridge

Salesforce recommends copying the following folders and files from the app_storefront_controllers cartridge to your cartridge as a first step, before converting your pipelines.

Note: If your application is based on the latest version of SGJC, you can choose to not copy these files. Instead, you can put the app_storefront_controllers cartridge in your cartridge path.

Add Your Controller Cartridge to the Cartridge Path in Business Manager

  1. Select Administration > Sites > Manage Sites.
  2. Select SiteGenesis or your site and click the Settings tab.
  3. Add your_cartridge to the list of cartridges.
    Note: It does not matter where you put the cartridge on the path, controller cartridges always override pipeline cartridges.
  4. Click Apply.

Converting Scripts

Instead of using script nodes to call scripts, controllers require scripts as CommonJS modules. Controllers either call the scripts directly or call the script methods directly. Therefore, you must convert existing scripts into CommonJS modules.

Note: B2C Commerce also recommends removing script logic in ISML templates, which currently can't be run through the script debugger. Instead, you can create CommonJS modules that can be referenced via a require statement in the isscript tag. This approach lets you set breakpoints in the script file and debug the logic in the debugger.

Migrating from B2C Commerce script to JavaScript Files

While it is not necessary to convert your existing .ds files into .js files, you can do so to take advantage of a preferred editing tool.

Note:

Previous versions of SiteGenesis included all server-side B2C Commerce script files with the .ds extension and client-side JavaScript with the .js extension.

Currently, SGJC only has legacy script files that use the .ds extension. Most script (script, controller, model, and view) files now use the .js extension. These .js files function identically to .ds files, can be called from pipelines, and can be edited in the B2C Commerce eclipse plugin or in other IDEs.

The folder in which the .js file is placed indicates whether it is a server-side or client-side script. Files in the top-level js folder (as seen in the app_storefront_core cartridge) are client-side scripts. All other files are server-side scripts.

Example: JavaScript module that works with both pipelines and controllers: ​​

 //input parameters used by script nodes
 * @input Basket : dw.order.Basket
 * @input ValidateTax : Boolean
 * @output BasketStatus : dw.system.Status
 * @output EnableCheckout : Boolean
 */

function execute (pdict) {  //called by pipelines and calls validate function
    validate(pdict);

    return PIPELET_NEXT;
}

/**
 * Function: validate
 *
 * Main function of the validation script.
 *
 * @param {dw.system.PipelineDictionary} pdict
 * @param {dw.order.Basket} pdict.Basket
 * @param {Boolean} pdict.ValidateTax
 * @returns {dw.system.Status}
 */
//The validate function is called directly by controllers
function validate(pdict) {  
    var Status = require('dw/system/Status');  //require is inside the function,
    var basket = pdict.Basket;
    // type: Boolean
    var validateTax = pdict.ValidateTax;
...

}

Converting Pipelines

Pipelines are converted to controllers.

Note: There are several utility pipelines, such as the Error pipeline, that you can convert before migrating more specific pipelines.
  1. Identify a pipeline with a public start node to convert.
    Note: For a pipeline to be successfully converted, all public start nodes in the pipeline must be converted. You can't convert only part of a pipeline.
  2. Identify all of the variables used in the pipeline and their assigned values. This step helps to identify the correct scoping for variables.
  3. Create functions for each subpipeline.
    1. Require the appropriate script modules when they are needed in the application logic. Calling the require method can impact performance (unlike an importPackage directive). Therefore, Salesforce recommends loading modules selectively. Place the require method call within the narrowest scope possible.
    2. Replace all pipelets with script methods, except where pipelets do not have an equivalent script method. If a pipelet does not have an equivalent, use the dw.system.Pipelet method to call the pipelet.
    3. Control access to private subpipeline functions. You can control access by using guards or by creating a public property for your function and setting it to false.
    4. Remember to resolve variables for each request.
    5. Render a template and handle any return values cleanly.
  4. Call the subpipeline functions.
Important:

Always completely convert a controller before uploading it to your instance.

B2C Commerce checks for the existence of a controller on the cartridge path before checking for a pipeline. However, B2C Commerce does not check for the existence of the function or subpipeline. If you call a controller function that does not exist, the call results in an error. If you partially convert a pipeline to a controller, any subpipelines that are not converted throw errors.

For example, suppose that you have a pipeline MySale with subpipelines Start and Convert. Further suppose that you create a controller MySale with a Start function but no Convert function. In this example, calling MySale-Convert causes an error, even if you have both the pipeline and controller on the cartridge path.

Converting Templates

You don’t have to modify templates. However, you can consider removing script logic from your templates. This aids reusability and a cleaner separation of view and model functionality.
Note: You can use the require method in isscript tags to include script functionality. This approach lets you set breakpoints for debugging.

Maintaining Integrations

Many partner cartridges were created with pipelines and there is no way to call a pipeline from a controller by design. Therefore, you can either keep existing integrations in your pipeline cartridge or you can rewrite them to use controllers.

Assessing Your Migration

Because controllers and pipelines share a similar URL structure, all of the performance assessment and troubleshooting tools for pipelines can be used for controllers. For example, you can use the Pipeline Profiler and the Object Churn report.