Context
As I’ve mentioned in the previous post, I’m this one is going to be dedicated to one of the features. I think that it makes sense to start from a catalog, as an e-commerce implementation will heavily rely on product information all over the site.
Let’s dive into …
Implementation
Catalog feature in our case covered most of the components on the site where you might see products, not including check-out: product recommendations on a home page, product listing component, product details page, etc.
[gallery ids=“2425,2427,2426” type=“rectangular”]
PRESENTATION
As componentization is mainly driven on a site by it an end-user experience, which is a presentation layer, so let’s start here and go down to the bottom. As you might expect in Habitat your components would be assigned to pages defined on a project level, while components themselves sit at a feature level - no change here. While the original storefront implementation has catalogs folder renderings, it contains a few pages and functionality related to bag and wishlists, that we moved to other features.
[gallery ids=“2455,2456” type=“rectangular”]
This clean-up is done due to the fact, that e.g. if you do not have ordering capabilities on a site you still might use the catalog feature.
Templates breakdown for those components is quite simple - mostly we have templates of data source type, that are used to control various properties of a component.
Front-end logic related to those components was decoupled from original scripts and injected only when the component is used.
FEATURES BACK-END
If we take a look at a code attached to a ProductRecommendations rendering this would lead us to Catalog feature back-end implementation. Over here we have quite a lite controller that relies on dependency injection to get access to products information from Commerce Server. The functionality is injected via controller constructor params instantiated by Windsor and implemented using a facade pattern (or repository as it is usually called).
https://gist.github.com/asmagin/e5347eaaa7cea566b20281bd4b5871ef
Using facades here is a common practice to make a controller more testable, as you could easily substitute it with a mock-object. Also, this helps to remove direct references from controllers to a search API, Commerce Connect API, or even direct calls to Sitecore Commerce API.
https://gist.github.com/asmagin/d1fd316dd5a44b8beb3fb205c3417886
The code above makes calls to managers who are a part of the foundation layer. Managers are something that we carry over from the original storefront implementation as they contain most of the logic, however, they were moved to the foundation layer as they were supposed to hide specifics of integration with an e-commerce platform.
FOUNDATION
Most of the work in the foundation layer was done around wrapping and decoupling direct calls to Commerce Server. This also helps to make controllers of the feature layer thinner and easier to test.
Ideally, you would have generalized API for an abstract e-commerce platform that you should be able to expose from the foundation and reference in the feature layer. The complexity of this exercise was far beyond the scope of this project. Even a possibility to create and maintain API of that kind, let’s say, for a base functionality of 5 top commerce vendors is questionable, from my point of view. I’m not even talking about all customizations that are usually added to them.
In the next post, I am going to cover the challenges of the implementation as well as some aspects of front-end integrations and testing.
Posts in series
- Inception: Sitecore Storefront to Habitat Migrating
- Mapping Sitecore StoreFront to Habitat
- Sitecore Catalog Feature for Habitat
Follow me on Twitter @true_shoorik. Would be glad to discuss the ideas above in the comments.