Now that we’ve seen how to render multilists using reference items, and we’ve also seen the amount of extra markup it creates, lets take a look at the other option for generating more complex markup within rendering variants: NVelocity templates. Before we begin though, there are a few important points I’d like to note.
- There is no way (as far as I know) to actively debug NVelocity templates in Sitecore
- I have found very limited documentation and examples on using NVelocity in SXA
- While you can accomplish a tremendous amount by default, we will need to get our hands dirty and code for this example
As usual, lets start with an analysis of what we need to accomplish. All we’re really trying to generate with our template is an anchor tag for each item. For difficulties sake, lets say the text being displayed within the anchor tags also needs to be wrapped in a span tag. Why? Because that’s what the imaginary designs require, and its not possible to implement without an NVelocity template.
As a quick recap, lets take a quick look at some basic functionality:
Apologies if its hard to read, I haven’t looked into overriding the default rouge highlighting or adding a specific NVelocity language highlighter
With that quick review complete, these links look easy to do! We’ll just do a foreach, loop through the CTALink items, and create the anchor tag for each of them, right? Nope. When we loop through the $item.CTALinks field, we’re not actually looping through the collection of items, we’re looping through the raw value string, which means every iteration of the foreach is for a letter, not an item. Additionally, even if we were able to get the link items, we wouldn’t be able to access the target URL and link description separately. The solution to all of this? We will write our own custom token replacement methods.
To get an idea for what methods we want to write, lets think about the three things we’ve just decided we’re missing.
- Given a multilist field, we need to retrieve a collection sitecore items
- Given an item with a general link field, we need to retrieve its target URL
- Given an item with a general link field, we need to retrieve its title
We’re going to go ahead and write three different methods to address each of these needs. In the same feature project where we should be keeping the view for our hero, I’ll make a new directory called Processors
and create an AddTemplateRenderers
file inside. That file will contain the following code to create the custom token replacement methods and add them to the NVelociy token renderers.
After the processors code has been written, we will need to patch our new template rendering processor into the velocity template renderer pipeline. For this we’ll create a new config file in our hero project with the following code:
Now all that’s left to do is publish and test these new custom token replacements. To access each of these methods, or any other method you create, you simply need to use $fieldTokens.MethodName(parameters)
. With that in mind, let’s head back to our rendering variant.
- Delete the CTA Link variant reference and all it’s children
- Delete the div with col-12 as well. We’ll just add this class on the NVelocity template wrapper
- In its place, right click and insert a VariantTemplate item
- Leave thet tag as
div
and add thecol-12
class - In the template field, we’ll insert the following code utilizing our new token replacement methods
Now let’s head back and see what markup gets generated.
This looks significantly cleaner than the markup generated by the reference items and matches our original markup perfectly! We could argue that the end result looks the same and it just took a lot more work, but the key takeaway is the potential that NVelocity unleashes within rendering variants. Additionally, while we do need to invest startup time creating these helper methods, thay can be shared across all components. You could even create a foundation level project to store a token replacement library, and with proper method naming, for all future variants NVelocity templates would require no additional work. In the end though, as with most comparisons, it’s a tradeoff of simplicity vs customization, and whichever method you choose is a game day decision based off each unique situation.