Estimated reading time:
Recently I came across a situation where I needed to use an NVelocity template in a Rendering Variant. We were creating a custom slider and using the awesome Slick Slider as it gives us a lot of nice options, and it has some good extras for accessibility that the OOTB Carousel component does not have at the time of writing. For the slide content, we still used a
Page Content component and a custom Rendering Variant, but on the slide I wanted to make the
Slide Image field a background image on the main
<div> element. The second requirement was that the design called for 2 types of slide, one with just the background image, and one where we could add a child component into a placeholder. This could be used as a promo/call to action, but needed to be detached from the slide content. This would allow the client to personalize and test the call to action separately from the slide imagery.
Here is an example of the markup I needed to reproduce in the Rendering Variant:
The first problem is that currently OOTB you can’t set an image field as a background image on a html tag. Fortunately there are some nice blog posts already out there on how to extend the NVelocity template:
- Michael West has post post on a Custom Rendering Variant Token Tool for SXA
- Chaitanya Marwah hit prettly close with this post on Design Sitecore SXA components using Variant Template
Just as a refersher on how to extend the template, first we need a new processor adding to the
getVelocityTemplateRenderers pipeline. Implement
IGetTemplateRenderersPipelineProcessor and add your code to the
And patch it in:
Next, create the static method to get the url from an image field:
This now lets us create the Template definition with the following code:
So the next task is to add the placeholder in the right place. This is where the problem started. There is no way to add a placeholder into a template out of the box. Adding a placeholder requires a valid view context, so trying to add one in the same way that we added the token for the image url would be overly complex.
Michael West came up with a great suggestion, in the template we create the start of the
<div> markup. Like this:
I would set the
Tag field to empty, so that there is no other markup added. Next we create a section that contains the placeholder items. Finally we can add a
Text item in the variant definition with
</div> in the text to close the earlier
Now all I need to do is to add the placeholder item in between those 2 items and I should be golden!
Or so I thought… it turns out that even with the
Tag field empty in a
VariantTemplate item still adds a
div surrounding the contents of the
Template field. So the markup looked like this:
Which is invalid and although most browsers helpfully try to close the div’s, it didn’t give me what I needed. After a bit of digging, the offending code can be found here in the
Sitecore.XA.Foundation.RenderingVariants.Pipelines.RenderVariantField.RenderTemplate processor. Here is the
You can see here on line 6, that if the
varitantField.Tag property is null or white space, then a
div tag will be defaulted too! So now I knew where the problem was, I can set about fixing it!
First we need to override the
RenderTemplate processor in the
RenderVariantField pipeline. So create a new processor class and inherit from the existing one. Then override the
Now on line 12, we check to see if the
variantField.Tag has been filled in or not. If it has, we pass this through to the base method and let it do its thing. If not, we will take over. We have to get the
templateRenderer and build the
parameters object to be able to render the field. But now we are not creating any surrounding tag, we are just executing the template and adding the resuling html to the
Now our variant renders exactly as I wanted it to, with a
div containing a background image, the placeholder in the middle and then the closing
I’m not sure why the default behaviour is to force a
div tag around template variants if the
Tag field is left empty. But hopefully this option will help others who need to be a bit more creative with the rendering variant definitions!
Thanks to Michael West for helping out with the original idea!