Customize SFRA Controllers and Routes
You can customize SFRA controllers and routes to work for your own storefront.
Inheriting Functionality from Another Controller and Extending It
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 theShow
route by appending middleware that adds properties to theviewData
object for rendering. Usingserver.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 useserver.append
. -
res
: Gets the current.
getViewDataviewData
object from the response object. -
res
: Updates the.
setViewDataviewData
object used for rendering the template. Create your customized template in the same location and with the same name as the template rendered by thesuperModule
controller. For example, if this controller inherits functionality fromapp_storefront_base
, the rendering template depends on the product type being rendered. The rendering template can be eitherproduct/productDetails
,product/bundleDetails
, orproduct/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();
Replacing or Adding a Route
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();
});
Overriding Instead of Replacing a Step in the Middleware Chain
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
.Changing the Access on an Existing Route
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 requests -
htt:
Filter for http requests -
https:
Filter for https requests -
include:
Filter for remote includes -
post:
Filter for post requests
If the request doesn't match the filtering condition, the
function returns an Error with the text Params do not match
route
.
Customizing a Controller with a Web Service or a Call to a Third Party
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.