Site Genesis
SiteGenesis JavaScript Controllers (SGJC) is a demonstration ecommerce reference application that enables you to explore Salesforce B2C Commerce and its capabilities. You can use it as the basis of your own custom site, although SFRA is recommended for new projects.
Features specific to SGJC can be unfamiliar if storefront is based on an earlier version of SiteGenesis. Most of the features described here focus on reusability of code and can be useful when migrating your storefront code. .
SiteGenesis uses the following features:
CommonJS Modules and Require
CommonJS modules let you create scripts with reusable functionality. A module is a
.ds or .js file. You can place a
module either in a cartridgeβs script
folder or in a
modules
folder that is at the same level as other cartridges.
You can access modules that are in your cartridge, in other cartridges, and in the
modules folder.
The modules folder is a peer of cartridge folders. Salesforce recommends using it for globally shared modules, such as third-party modules.
+-- modules +-- mymodule1.js +-- My_Cartridge_1 +-- cartridge +-- scripts +-- mymodule2.js +-- My_Cartridge_2 +-- cartridge +-- scripts +-- mymodule3.js
Accessing Modules
Salesforce B2C Commerce supports CommonJS paths to access modules and relative paths.
Use the following syntax:
~ - the current cartridge name.
Example: require ('~/cartridge/scripts/guard')
. -
same folder (as with CommonJS). Example: require('./shipping');
.. - parent folder (as with CommonJS). Example:
require('../../util')
ImportPackage vs. Require
In
previous versions of SiteGenesis, the ImportPackage
statement was always used to import B2C Commerce packages into your scripts.
You can also use require
to import B2C Commerce script packages. For example:
require(βdw/system/Transactionβ)
Salesforce recommends using the require method to import B2C Commerce script packages, or other JavaScript or B2C Commerce script modules instead of ImportPackage.
Using the require()
function to load a module has an impact on
performance. To handle a request, a controller is loaded and then executed on a
global level, just as exported methods are executed. When the
controller module is initialized, the actual controller function is invoked.
If the dependencies to other modules are initialized on a global level, many
modules can be loaded unnecessarily. If possible, place
require()
statements in the most limited scope that is
appropriate (for example, as local variables within a function body). If your
require()
statements are placed at a global level, they are
loaded for every request. For example, require()
statements at
the top of a controller file are loaded with each request. Globally required
modules are loaded even if they are not needed in the current execution context.
If all modules execute their require()
statements globally, all
modules are loaded for every request. This overhead can significantly degrade
performance, depending on the number of modules. We suggest, instead, that you
move the require()
calls for non-API modules into the function
bodies so that they are resolved only when necessary. A
require()
isn't an import; it's a real function call. An
import in Java, in contrast, is only a compiler directive and has no effect at
run time.
Hooks
Hooks configure a piece of functionality to be called at a specific point in your application flow or at a specific event.
There are three types of hooks you can use with SiteGenesis:
- OCAPI hooks β B2C Commerce provides extension points that let you automatically call scripts before or after specific OCAPI calls.
- B2C Commerce hooks β B2C Commerce provides onSession and onRequest hooks to replace onSession and onRequest pipelines. It also provides hooks for Apple Pay on the web.
- Custom hooks β you can define custom extension points and call them in your storefront code using the B2C Commerce script System package HookMgr class methods.
Hook Definition
The package.json file points to the hook file for a cartridge, using the hooks keyword.
Example: package.json
{
"hooks": "./cartridge/scripts/hooks.json"
}
The hook file defines a uniquely named extension point and a script to run. Hook scripts must be
implemented as CommonJS modules. Therefore, the script
identifier
is a module identifier and can be a relative path or any other valid module
identifier.
Example: hook.json
{
"hooks": [
{
"name": "dw.ocapi.shop.basket.calculate",
"script": "./cart/calculate.js"
},
{
"name": "dw.system.request.onSession",
"script": "./request/OnSession"
},
{
"name": "app.payment.processor.default",
"script": "./payment/processor/default"
}
]
}
This example shows an OCAPI hook, a controller hook, and a custom hook. The OCAPI hook runs a script to calculate the cart. The controller hook calls the OnSession.js script in the scripts/request directory. You can call the custom hook by using the HookMgr classβs callHook method.
Example: calling a custom hook
return dw.system.HookMgr.callHook('app.payment.processor.default', 'Handle', {
Basket : cart
});
Running Multiple Hooks for an Extension Point
It's possible to register multiple scripts to call for an extension point. However, you can't control the order in which the scripts are called. Also, if you call multiple scripts, only the last hook called returns a value.
At run time, B2C Commerce runs all hooks registered for an extension point in all cartridges in your cartridge path. It runs them in the order of the cartridges on the path.
Error Logging
Controller and script logging is available in the:
- Custom error log β this log contains the hierarchy of controller and script functions and line numbers related to exceptions thrown. This log is intended for use by developers to debug their code.
- System error log β this log is primarily useful for Commerce Cloud Support.
Example: Custom error log
Error while executing script 'test_cartridge_treatascustom/cartridge/controllers/TestController.js': Wrapped com.demandware.beehive.core.internal.template.ServletAbortException: Requested template 'controller/testController' not found! (test_cartridge_treatascustom/cartridge/controllers/TestController.js#21)
at test_cartridge_treatascustom/cartridge/controllers/TestController.js:21 (isml)
at test_cartridge_treatascustom/cartridge/controllers/TestController.js:52 (anonymous)
Back to top.