This post is part of a 3-part series of posts on how to extend the Sitecore Commerce Business Tools. It contains all the contents I presented at SUGCON EU in London in April 2019 and adds some additional insights.
The other parts are:
The Sitecore Commerce Businesss Tools represent a great way to extend Sitecore Commerce with new functionality and it is easy to do. These blog posts show you how the Business Tools work and how to extend them in different ways.
How does it work?
When I started working on the presentation for SUGCON, the first thing I was wondering was, how do the business tools actually work?
Now there is actually a fair bit of documentation on how the business tools work, but if you look for BizFx or business tools you won’t find it immediately, because it is hidden under the innocent sounding term Commerce Views Service.
There you can read the following:
“The Commerce Views plugin provides a data-driven mechanism for servicing a dynamic business experience. The views provide a mechanism for narrowing or translating data from core entity storage into a dynamic API that can be directly leveraged by the business experience.”
Now, I don’t exactly know what that means but it is full of experience and experience is always good.
But what it boils down to is that the output from the views service, drives what the user sees in the business tools.
It is what’s called a data-driven application.
The business tools is a single page application (SPA) and it is written in Angular. It gets its data from the commerce service you connect it to and normally that would be the authoring service.
When you start up the business tools for instance by going to https://localhost:4200 and you trace which calls the business tools is doing to the authoring service, you will see the following:
If you look closely you will see that these calls are actually done twice: once with the
OPTIONS method to check if the call is available and once with the
GET method to get the actual data.
These calls are going to the Commerce Engine Authoring role. They retrieve data that is used to drive the user interface
If you look at the data, for instance for the
GetNavigationView() call, you will see the following:
If you have worked with the commerce engine before you will recognize the OData structure.
These 4 calls, lead to the following UI being displayed in your browser:
It’s easy to see which call is responsible for which part of the screen.
- The first
GetNavigationViewcall renders the navigation in the left sidebar;
GetEnvironmentsViewcall renders the list of environments in the upper left corner;
GetLanguagesViewcall renders the list of languages;
- And finally the second
GetNavigationViewcall renders the main navigation in the center screen;
If you look at the structure of the data for each call you will see that they all return an EntityView.
An EntityView represents “a flattened, dynamic service response focused on supporting a dynamic user experience”.
An EntityView has:
- a name
- Child entity views;
- UIHint (an indication on how the view should be rendered);
If you look at the result of GetNavigationView for instance, it consists of a main view called Navigation and 8 child entity views called:
Let’s go back to our main dashboard and let’s click on Merchandising.
If you look at the URL in the browser, you will see the url looks like this:
which basically means show the entity view called
MerchandisingBoard. In Angular this is called a route and Angular will update the user interface based on the route. Note that changing the url is not doing any calls to the server, because there is nothing listening there for it.
If you have a look at the network panel to see which call the Business tools are doing, you will see the following;
This time, the
GetEntityView method is called. What is interesting to know of course, is which parameters are used to call
GetEntityView, the PUT method is used and the payload looks like this:
As you can see the requested view(Name) is called MerchandisingDashboard. You will also note 3 other parameters, which we’ll have a look at later.
If you look at the OData response, you will note that it returns an EntityView called
MerchandisingDashboard with two child views:
You will also notice the Catalogs view has two child views, both have the name Summary. Each child view contains 5 properties, which you see displayed in the table of catalogs:
- Display Name;
- Price Book Name;
- Promotion Book Name;
- Default Inventory Set Name;
The response we get is rendered like this.
You can recognize each entity view and the properties.
Notice that the Catalogs view has two UI elements we haven’t seen before:
These two buttons are called actions. The first button lets you create a new catalog and the second can be used to delete a catalog.
Each Entity View can have a number of actions. Here they are represented as buttons, but if there are more than 3 actions for a view, they are represented as a drop down menu.
We’ll see later how you can add an action to a view.
Let’s click on the first catalog name and see what happens.
First thing you should notice is that the URL now looks like this:
There’s a fair bit of information in this url:
Masterrefers to the name view we want to be displayed;
1indicates the version of the entity we want to see;
Entity-Catalog-Habitat-Masteris the id of the entity we want to view;
This url renders the following screen:
This screen consists of a total of 5 entity views (of which you see 3 in the image).
All elements of an entity view should by now look familiar.
Behind the scenes
So, what happens behind the scenes when the business tools do a call to the commerce engine.
If you know a little bit about the commerce engine, you will know there is one concept that is very important which are the pipelines.
For instance, to create the languages view, GetLanguagesView runs the IBizFxLanguagesPipeline:
And GetNavigationView() runs the IBizFxNavigationPipeline:
And GetEntityView() runs, you can probably guess the GetEntityViewPipeline.
Now you know which pipelines are involved in the process and how entity views work, the next question is of course: how can I extend this? You can read how to extend it in the next blog post.