Custom Component Rendering in Sitecore SXA
Hello Everyone. In this blog, i am going to explain you that how we can a create custom SXA controller rendering. As we all know SXA provides most of the component OOTB only but still there are time where we need to create our own controller rendering to meet business requirements. As a traditional Sitecore developer, we could have easily create Controller rendering and used it to add in Page but when we are working in SXA, there are some standard rules which we need to follow while developing a Custom SXA Controller rendering.
We will understand this with a example. Let's consider, we have requirement to develop a form. The form has two variations which is listed below.
- Normal Form
- Form on top of Hero Banner
Let's see how we can develop this component
First Way : We can use Sitecore Forms for normal form Or we can create Rendering Variant of Page Content. Create Scriban template to create the Hero Banner Component.Then again use Component variant field to add Form Component
Second Way : Creating a Custom Controller rendering for better control.
This blog is mostly focus on second way of implementation. First we will see the Sitecore part and the we will see the Code part.
Lets create the Sitecore component. Here we are goint to clone the Promo component and give our component name as CustomSXAComponent.Below is the screenshot for your reference. I am not going to go deep to explain How to clone a component in SXA
Note: Path of Rendering View : Create the same folder structure inside web root folder. ex. Views-->CustomSXAComponent-->CustomSXAComponent.cshtml. If not created, it will give you error that no such folder exists.
Rendering
Template
Rendering Parameter template
Rendering Variant
When we clone a component, it jautomatically creates Rendering, Template and Template Folders and Rendering Parameter Templates. Rendering Variant, we have to manually add it inside Rendering variant node under Presentation. The simple step is to duplicate existing a Variant and change the name of the parent to your component name. In our case you can see its CustomSXAComponent.Now add the rendering to Allowed Control of the Page Content module. Navigate to Presentation --> Available Renderings --> Select Page Content --> Add CustomSXAComponent in Allowed Controls. Once done, it will show inside Page Content Module in Experience Editor.
The Sitecore part is done and let's move to code part now.
First Step : Add a Controller (CustomSXAController).
public class CustomSXAComponentController : VariantsController
{
private readonly ICustomSXAComponentRepository _customSXAComponentRepository;
public DBAServiceFormController(ICustomSXAComponentRepository customSXAComponentRepository) {
_customSXAComponentRepository = customSXAComponentRepository ?? throw new ArgumentException(nameof(customSXAComponentRepository));
}
protected override object GetModel()
{
return _customSXAComponentRepository.GetModel();
}
}
The Controller should Inherit from Variant Controller. Override the GetModel() to get the model. You might have notice that, we are not having Action defined in Controller. In SXA, it is not required. When we Inherit the Variant Controller, we use the Index Action of parent controller. We just ovveride the GetModel() method to get our own kind of required model and use it directly in the view.
Second Step : Add a CustomModel(CustomSXAComponentModel).
public class CustomSXAComponentModel : VariantsRenderingModel
{
//Add all required model properties here required for your Component. In our Case Form Field ex. Form Title, FieldList etc.
}
The Model should Inherit from VariantsRenderingModel. This will get all the base model propertied required automatically for an SXA component. Ex.Datasource Item, Component ClassName etc.
Third Step : Add a InterfaceRepository and Repository Class(ICustomSXAComponentRepository, CustomSXARepoistory).
public class ICustomSXAComponentRepository : VariantsRepository
{
}
public class CustomSXAComponentRepository : ICustomSXAComponentRepository
{
public override IRenderingModelBase GetModel()
{
CustomSXAComponentModel model = new CustomSXAComponentModel();
try
{
FillBaseProperties(model);
if (model.DataSourceItem != null)
{
// Add Logic to read your custom model properties
}
}
catch(Exception ex)
{
Sitecore.Diagnostics.Log.Error($"Error Info --> GetModel() --> {ex.Message.ToString()}", this);
}
return model;
}
}
Your interface should inherit from VariantsRepository. This will have the GetModel() method which when overriden will get you all the base model properties.Then your repository will inherit your interface repository.
Fourth Step : Register and Map all the dependency and in config.
public class CustomSXAComponentConfigurator : IServicesConfigurator
{
public void Configure(IServiceCollection serviceCollection)
{
serviceCollection.AddTransient();
serviceCollection.AddTransient();
}
}
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:environment="http://www.sitecore.net/xmlconfig/environment">
<sitecore>
<services>
<configurator type="Shrikant.Feature.CustomSXAComponent.IoC.CustomSXAComponentConfigurator, Shrikant.Feature.CustomSXAComponent"/>
</services>
</sitecore>
</configuration>
By above step, we inject all dependency in constructor and also register them in Sitecore service configurator
Fifth Step : Add a View(CustomSXACompoent.cshtml).
@using Sitecore.XA.Foundation.MarkupDecorator.Extensions
@using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
@using Sitecore.XA.Foundation.Variants.Abstractions.Fields;
@using Sitecore.XA.Foundation.RenderingVariants.Fields;
@using Sitecore.XA.Foundation.RenderingVariants.Extensions;
@model Shrikant.Feature.CustomSXAComponent.Models.CustomSXAComponentModel
<div @Html.Sxa().Component(Model.Rendering.RenderingCssClass ?? "", Model.Attributes)>
<div class="component-content">
<div class="row">
@foreach (BaseVariantField field in Model.VariantFields)
{
@Html.RenderingVariants().RenderVariant(field, Model.Item, Model.RenderingWebEditingParams, Model);
}
</div>
@if (Model.DataSourceItem != null)
{
//Your custom Html structure should be place your. In our case, we can add the form html here.
}
</div>
</div>
If you see the first two line of html markup. the same markup should be followed for SXA custom rendering which is created. First div for getting @Html.Sxa().Component(Model.Rendering.RenderingCssClass ?? "", Model.Attributes) and second div with class called component-content. This is standard structure and we need to follow in our view too.
<div @Html.Sxa().Component(Model.Rendering.RenderingCssClass ?? "", Model.Attributes)>
<div class="component-content">
</div>
</div>
Then we are having foreach loop to read all rendering variant fields and show them Configured in Sitecore. In our case, we can create scriban rendering variant field which will hold the markup for banner. After that we can read the form values from our custom model and create the required markup for form.When Banner is not required, just create a variant and don't add any variant field in Sitecore. So it will only take your form markup only.
<div class="row">
@foreach (BaseVariantField field in Model.VariantFields)
{
@Html.RenderingVariants().RenderVariant(field, Model.Item, Model.RenderingWebEditingParams, Model);
}
</div>
There are many more possible ways to play with the HTML and create different variations.I have just tried to shown you one way possible. We can also term this kind of implementation as Hybrid, where we are using SXA rendering variations, Custom HTML in view and many more things.This just showcase the power of SXA components and thier extensions.
Extra Information
Any component which has any scripy dependency, we are following a specific format for writing JavaScript.Below is the same code format. Lets conider our case that we are submitting form via AJAX
XA.component.CustomSXAComponent = (function ($) {
var pub = {};
let siteKey = "";
pub.init = function () {
$(document).ready(function () {
//Add Logic here for Form Submission
}
return pub;
})(jQuery);
XA.register('CustomSXAComponent', XA.component.CustomSXAComponent);
The you can add this in SXA themes either by SXA CLI or directly uploading files in Sitecore Themese used by your site.
Hope you like this blog. Thanks for reading. Happy Learning!! Happy Sitecoring!!
You can check my other blogs too if interested. Blog Website
Comments
Post a Comment