You can customize SFRA controllers and routes to work for your own storefront.
It's important to understand when to extend a controller and when to override it, because this decision can significantly impact functionality and performance.
When do I want to Override?
It's best to override if you want to avoid executing the middleware of the controller or script you're modifying.
When extending a controller, you first execute the original middleware, and then execute the additional steps included in your extension. If the original middleware steps include interaction with a third-party system, that interaction is still executed. If your extension also includes the interaction, the interaction is executed twice. Similarly, if the original middleware includes one or more steps that are computationally expensive, you can avoid executing the original middleware.
When do I want to Extend?
If the middleware you want to override is looking up a string or performing inexpensive operations, you can extend the controller or module.
How do I extend or Override?
Use the
module.superModule
mechanism to import the functionality
from a controller and then override or add to it.
Example: Adding Product Reviews to Product.Js
This example customizes the product detail page to include product review information. The code for this example is available in the Plugin_reviews demo cartridge.
Product.js
controller uses the following
APIs for customization:module.superModule
: Imports functionality from
the first controller with the same name and location found to the
right of the current cartridge on the cartridge path.server.extend
: Inherits the existing server
object and extends it with a list of new routes from the super module.
In this case, it adds the routes from the module.superModule
Project.js file.server.append
: Modifies the Show
route by appending
middleware that adds properties to the viewData
object for
rendering. Using server.append
causes a route to execute
both the original middleware chain and any additional steps. If you're
interacting with a web service or third-party system, don’t use
server.append
.res.
getViewData
: Gets the
current viewData
object from the response
object.res.
setViewData
: Updates the viewData
object used for rendering the template. Create your customized template in
the same location and with the same name as the template rendered by the
superModule
controller. For example, if this controller
inherits functionality from app_storefront_base
, the
rendering template depends on the product type being rendered. The rendering
template can be either product/productDetails
,
product/bundleDetails
, or
product/setDetails.
// Product.js
'use strict';
var server = require('server');
var page = module.superModule; //inherits functionality from next Product.js found to the right on the cartridge path
server.extend(page); //extends existing server object with a list of new routes from the Product.js found by module.superModule
server.append('Show', function (req, res, next) { //adds additional middleware
var viewData = res.getViewData();
viewData.product.reviews = [{
text: 'Lorem ipsum dolor sit amet, cibo utroque ne vis, has no sumo graece.' +
' Dicta persius his id. Ea maluisset scripserit contentiones quo, est ne movet dicam.' +
' Equidem scriptorem vis no. Civibus tacimates interpretaris has et,' +
' ei offendit ocurreret vis, eos purto pertinax eleifend ea.',
rating: 3.5
}, {
text: 'Very short review',
rating: 5
}, {
text: 'Lorem ipsum dolor sit amet, cibo utroque ne vis, has no sumo graece.',
rating: 1.5
}];
res.setViewData(viewData);
next();
});
module.exports = server.exports();
If you
want to completely replace a route, rather than append it, use
module.superModule
to inherit the functionality of the
controller and route you want to replace. Then register the functions you
want the route to use.
Example: replacing the Product-Varation
route
In your custom cartridge, create a Product.js
file in the same location as the Product.js
file in the
base cartridge. Use the following code to import the functionality of
Product.
js and redefine it.
var page = require('app_storefront_base/cartridge/controller/Product');
var server = require('server);
server.extend(page);
server.replace('Show', server.middleware.get, function(req, res, next){
res.render('myNewTemplate');
next();
});
We recommend that you replace a route to change individual steps in a middleware chain.
You can't change a step in
the middleware chain. However, you can either replace the whole route or
append a new step after the chain completes, but before the template
renders. Usually, if you're appending a step, it's to override or add data
to the ViewData
object.
Global
.You can use the middleware functions provided by Commerce Cloud or create your own. We recommend that you replace a route when changing access.
These middleware filtering functions are provided by Commerce Cloud:
get:
Filter for get requestshtt:
Filter for http requestshttps:
Filter for https requestsinclude:
Filter for remote includespost:
Filter for post requestsIf the request doesn't match the filtering condition, the
function returns an Error with the text Params do not match
route
.
In general, customizing a controller with a web service or third-party call uses the same
mechanisms as other types of customizations. However, it's important to make sure
that you don't execute the controller twice. Executing the controller twice is
possible if you use server.append
to customize the ViewData object
passed to the rendering template. Instead, simply replace the route entirely.