Monday, March 11, 2019

Working with external model data in Sitecore SXA variants

SXA and variant definitions

If you are working with SXA, I assume you heard about rendering variants (if not, you're doing it wrong).  There is some documentation on the options you get when creating your own rendering variant: https://doc.sitecore.com/developers/sxa/18/sitecore-experience-accelerator/en/create-a-rendering-variant.html

There is one variant definition option that I would like to highlight here, and that is the "Model".
Model: displays properties from the current Model. The SXA renderings model inherits from Sitecore.XA.Foundation.Mvc.Models.RenderingModelBase. In the Property path field, you can enter the path to the property that you want to display.

 You can use this Model field to display any data you want. I used it to display data from a custom database, but it could also be data from a webservice or any datasource you like. How to do this..

Create your (custom) model

You should start by creating your own component: https://doc.sitecore.com/developers/sxa/18/sitecore-experience-accelerator/en/create-a-new-sxa-module.html  (or copy an existing one and change the data, but that is another topic). What you need is a custom controller, model and probably also a view. Create the necessary items in Sitecore and create your variant definition.

To write the needed code, you can refer to my blog article on custom renderings with variants or to the official docs. The important part here is actually the model class. All (custom) properties you add there will be available in the variants. Fill the data in your repository (called from the controller).
Suppose we have this model:
public class CustomModel: VariantsRenderingModel
{
  public string CustomProperty { get; set; }
  public CustomClass CustomClassProperty { get; set; }
}
and we would like to show the CustomProperty value and a property from the CustomClassProperty as well. Let's create our variant...

Create the variant definition 

In the variant definition that was created for your custom component, you can add a "Model" field.
You can select a tag (just as in other variant fields) and set a css class or other attributes. The Property Path is the really interesting one: here you can define the property from your Model you want to show. As you can see in the screenshots, you just need to add the name of the property as it is in your model class. And you can also get properties from a property..  (like the "Name" property from the CustomClass that was a property of my model).

You will notice that the variant field does not have all properties like a "Field" variant field - e.g. you cannot create a link (which makes sense of course). 

Model data

I am struggling with a few things still..  example: my model has a url and I would like to show that in the variant..  but I can only show the value of the model property - I can't seem to embed this in a "a href..".  I guess there will always be such edge cases that go just that one step further than what is possible ootb. I could go for a quick fix and have my model give me the html for the link..  and if I find a cleaner solution, I'll update the blog :)

Conclusion

Displaying all sorts of external data with variant in SXA was actually easier than expected. Not the first time the product has amazed me in a good way 😃



3 comments:

  1. Hi Gert,

    Your post seems useful fro my use case as I want to render a field from external API.

    But I dont know if I am doing it right way.
    I created a model property like
    public class BlogViewCount: VariantsRenderingModel
    {
    public string CustomProperty { get; set; }
    }
    and then referred it like Metro.Feature.Blogs.Models.BlogViewCount.CustomProperty in Property Path of Model rendering variant field. But its always empty.

    Can you please correct me if its wrong way to refer model property.

    ReplyDelete
    Replies
    1. I think you should just place "CustomProperty" in the property path. Questions like this are easier to handle on Sitecore StackExchange though: https://sitecore.stackexchange.com

      Delete