Migrating Your Storefront to SGJC Controllers
If you are migrating a storefront based on the SiteGenesis Pipelines (SGPP), some code changes are necessary.
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.
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.
- Create an empty cartridge.
- In Eclipse, select File > New > Digital Cartridge.
- To connect your cartridge to your server, follow the rest of the steps.
- Right-click the cartridge folder in the Navigation tab and select New > Folder.
- 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.
app_storefront_controllers
cartridge in your cartridge path.- /scripts/request β the OnRequest.ds and onSession.ds scripts replace onRequest and onSession pipelines.
- /scripts/util β Class.ds supports prototyping and inheritance.
-
/scripts β Contains a series of useful .ds and .json files:
- app.ds β lets you get any controller, model, or view.
- guard.ds β lets you restrict access to public controller functions.
- meta.ds β used to retrieve and set page metadata information
- object.ds β utility functions for managing and extending objects.
- hooks.json β file to configure hooks for your storefront. Hooks can point to any JavaScript or B2C Commerce script that you want to require for reuse in other scripts. You can also create this file with any name, as long as the package.json for your cartridge points to it.
- view.ds β lets you define and initialize parameters relevant to rendering a template.
Add Your Controller Cartridge to the Cartridge Path in Business Manager
- Select Administration > Sites > Manage Sites.
- Select SiteGenesis or your site and click the Settings tab.
- 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.
- 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.
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.
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.
- 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.
- Identify all of the variables used in the pipeline and their assigned values. This step helps to identify the correct scoping for variables.
- Create functions for each subpipeline.
- 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.
- 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.
- 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.
- Remember to resolve variables for each request.
- Render a template and handle any return values cleanly.
- Call the subpipeline functions.
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
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.