Thursday, March 9, 2017

Variants on your custom Sitecore SXA renderings

Sitecore Hackathon 2017

One of the possible ideas of the 2017 Sitecore Hackathon was the Sitecore Experience Accelerator (SXA). With our "No Weekend 4 Us" team we took this challenge and created a custom component that works with SXA Variants (and did other fancy stuff, but that will be explained in another blog post). [Using SXA 1.2 on Sitecore 8.2-upd2]

Sitecore Experience Accelerator Variants

SXA comes with a set of default renderings and rendering variants. Rendering variants are configurable adaptations of the default renderings. To further encourage reusability, you can also create new rendering variants. This gives authors more options in the way they present their content.
Info on creating variants can be found on the SXA dev documentation, but what if you create a custom component for SXA and want to use this technology as well. I'll try to provide a step by step overview of the things to do. Our component was about blogs, so you might find that in the code examples...

Variant model repository

We created a repository based on the VariantsRepository of SXA:
using Sitecore.XA.Foundation.RenderingVariants.Repositories;

public class BlogVariantRepository : VariantsRepository, IBlogVariantRepository
{
  public T GetModel<T>(object model) where T : IRenderingModelBase
  {
    FillBaseProperties(model);
    return (T)model;
  }
}
The reason to do this is to get a variants-aware model later on. The repository has an interface, so we will inject it with dependency injection. We will do this the SXA way, by using their <ioc> pipeline.

Dependency Injection

<pipelines>
  <ioc>
    <processor type="X.Features.Blog.Pipelines.IoC.RegisterBlogServices, X.Features.Blog" />
  </ioc>
</pipelines>
public class RegisterBlogServices : IocProcessor
{
  public override void Process(IocArgs args)
  {
    args.ServiceCollection.AddTransient<IBlogVariantRepository, BlogVariantRepository>();
    ...
  }
}
We are using build-in DI of Sitecore 8.2 as used by SXA this way. It's actually a very easy way to insert your stuff to the container. As an extra there is no need to register your controller - SXA will take care of that for you.

Model - View - Controller


Model

Let's start with the model. 
public class BlogsModel : VariantsRenderingModel
{
    ..  // custom properties
}
The model inherits from the VariantsRenderingModel. This base class provides some interesting (and needed) properties. It actually is the RenderingModelBase (with info on Item, Rendering ...) extended with VariantFields. We will use the model repository we created earlier to fill the properties of this base class. Of course, it can be extended with any properties and function.

Controller

public class BlogsController : VariantsController
{
  private readonly IBlogVariantRepository blogVariantRepository;
  ...

  public BlogsController(IBlogVariantRepository blogVariantRepository, ...)
  {
    this.blogVariantRepository = blogVariantRepository;
    ...
  }

  public ActionResult BlogList()
  {
    var model = blogVariantRepository.GetModel<BlogsModel>(new BlogsModel());
    model.X = ...;
    return View(model);
   }
}
The controller inherits from VariantsController. Our repository is injected as explained earlier. We call the GetModel on our repository to get our base model with filled base properties. We can set values for other custom properties on the retrieved model object.

View

<div @Html.Sxa().Component("bloglist", Model.Attributes)>
  <div class="component-content">
    <div class="blog-list">
      @foreach (var item in Model.Blogs)
      {
        <div data-itemid="@item.Blog.ID.Guid">
        @foreach (var variantField in Model.VariantFields)
        {
          @Html.RenderingVariants().RenderVariant(variantField, item.Blog, false)
        }
        </div>
      }
    </div>
  </div>
</div>

This is just an example of what might be possible in the view - a bit more bound to the model we used as a test (with a list of blogs and each blog object included the underlying Sitecore item).

You can see here that we loop over all variant fields and simply display them. This means of course that we need a default variant to show anything.

That's it for the code.. now lets move on to Sitecore.

Sitecore (SXA) configuration

Rendering parameters template

First step is to create a rendering parameters template to use for your rendering. The template should inherit from /sitecore/templates/Foundation/Experience Accelerator/Rendering Variants/Rendering Parameters/IComponentVariant (don't forget to also inherit /sitecore/templates/System/Layout/Rendering Parameters/Standard Rendering Parameters instead of the Standard Template).

Using this base template will give you the variants dropdown in the rendering properties. By the way, SXA has a similar base template for Styling (/sitecore/templates/Foundation/Experience Accelerator/Presentation/Rendering Parameters/IStyling).








Rendering

In /sitecore/layout/Renderings/Feature/Experience Accelerator/[Feature-Name]/[Rendering-Name] create a Controller Rendering and fill in the usual fields (Controller, Action ..). And a tip to make it complete: give your rendering an icon ;)

To make the rendering available in the toolbox, go to the Presentation part of the SXA website (will be on the same level as the Home page). Under Available Renderings create a new Available Renderings item (might want to name if like your feature again). Add your newly created rendering in the "Renderings" box. Now we have a rendering in the toolbox - lets continue by creating the variants we need.

Variants

Variants are also defined in the "Presentation" section of your site. Under Rendering Variants create a new Item of type Variants and name it exactly as your rendering (important!). Under this Variants, create a Variant Definition. You might want to call the first one "default". Under the Variant Definition, create an Item of type Field. Choose a tag (e.g. "div"), fill in the Field name and set the other fields as desired (e.g. check "Is link" if you want a link to be generated on the field). Continue creating "Fields" as much as you want. And that is it. When you add the rendering from the Toolbox, you will see your variant in the dropdown and all the fields you created will be rendered. 

To make it really useful, you might want to create more Variant Definitions with different sets of Fields. This way you can easily create different outputs of the same rendering (and even more if you combine this with Styling).

More information on what you can do with the variants and their properties in the link mentioned above on the Sitecore doc site.

ps: thx to Dawid Rutkowski for pointing us in the right direction!

No comments:

Post a Comment