Now that we’ve explored the building blocks of creating SXA components without touching any code, what if for some reason you absolutely cannot create your component with rendering variants? In that case, we still have the option of writing custom components from scratch, it just takes a few more steps than it traditionally would. Let’s take a look at how we would do this by creating the hero component again, but as a custom rendering.
To kick it off, lets hop right into some code. The files we’ll need to create include:
Repository interface and implementation
Dependency registration class
Config to setup our dependency registration
You’ll notice there are a few extra files than we would need for regular MVC Sitecore, and we’ll go over what each of these do briefly as we create them. In the meantime, lets get started with our model. We’ll create it under Model/CustomHeroViewModel.cs.
Next, we’ll create the view under Views/CustomHero/GetCustomHero.cshtml and the controller under Controllers/CustomHeroController.cs. Two important things to note about the view are that the first two divs of markup in the view are required for SXA compliance, and the view is specifically named GetRenderingName because the default Index controller method will be looking for a view by that name.
You may have noticed that we’re inheriting from VariantsController and notStandardController. While StandardController will work fine, it doesn’t leave you open to extension with variants down the road. I haven’t yet seen a reason not to inherit from VariantsController from the beginning, so I’ve done so here.
Next come the SXA-specific files. We’re going to create the repository getting injected into our controller, as well as its interface under Repositories/. Even though our interface is empty, it is still required that we have one.
Finally, we’ll be registering our dependencies under Dependencies/RegisterDependencies.cs and adding the configurator node in a config file.
If you followed all of the steps, you should end up with project structure similar to this:
Great, that sums up all the required code! Let’s publish our new project and head over to Sitecore to get our new component working. While you could go through the process of creating all of the sitecore items manually, we have access to the Clone Rendering script we demonstrated in a previous post. Let’s use that, with the only difference being we’ll select to use the view we just published.
With those items all created for us, we only have a few more steps to complete manually.
Update the controller action to our custom controller Project.Feature.XA.CustomHero.Controllers.CustomHeroController,Project.Feature.XA.CustomHero
Add our new rendering to the available renderings in our SXA site
And that’s it! You should now be able to open up the experience editor and drag and drop your custom component.
What if you decide you really miss out on rendering variants though? No problem! Since we created our model and controller with the variant implementations, we can easily add a rendering variant block. Note: While we can add a rendering variant block, it’s important to know that we can’t switch back and forth. Once we include the rendering variant block and start rendering markup from Sitecore, we can’t add more of our custom markup within that block.
For this example, we’ll swap the CTA button markup with the rendering variant block and use the rendering variants in Sitecore to render the CTA buttons. While we should remove unnecessary code with this change as well, all we really need to change is the view.
Now that we’ve replaced the CTA markup with the variant loop, we’ll just create a rendering variant for our CustomHero rendering. This variant will contain only the NVelocity template we created earlier because the rendering variant will be injected directly where we placed our foreach loop.
And there you have it, you should be able to return to the experience editor and confirm that our new custom component with rendering variant is functioning correctly. While it’s not immediately clear when this combined method will be preferred, it does allow our custom components to maintain some level of rendering variant functionality which I’ve found to be much more content author friendly as the number of variants begin to increase.