Skip to main content

Use model builders

Canvas Sitecore integration allows to define a model builder for component. It can be helpful when item fields is not enough and we need to prepare data from backend side.

Use model builders

Implement Uniform.ModelBuilders.IComponentModelBuilder, Uniform.Platform.Canvas.ModelBuilder interface

public interface IComponentModelBuilder
{
[CanBeNull]
object BuildModel(
[NotNull] Item pageItem,
[NotNull] Item datasourceItem,
[NotNull] IReadOnlyDictionary<string, string> parameters
);
}

pageItem - current page item datasourceItem - current datasource item (can be the same as a page item) parameters - key-value parameters defined for component on Canvas composition <result> - json-serializable object

Register model builder via Sitecore config

<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<uniform>
<siteConfigurations>
<siteConfiguration name="MySite">
<canvas>
<canvasModelBuilderService ref="uniform/services/canvasModelBuilderService">
<modelBuilders hint="raw:RegisterModelBuilder">
<builder componentId="<CANVAS_COMPONENT_ID>" type="Namespace.ModelBuilderType, Assembly" />
</modelBuilders>
</canvasModelBuilderService>
</canvas>
</siteConfiguration>
</siteConfigurations>
</uniform>
</sitecore>
</configuration>

Update enhancers to use model instead of Sitecore item for particular component.

@uniformdev/canvas-sitecore package contains a few helpers to work with model builders.

  • getModel function

    const model = await getModel({
    id: itemId,
    pageId,
    component,
    config,
    isPreview,
    });
  • create an enhancer from createItemEnhancer function with useModelBuilder option

    const modelEnhancer = createItemEnhancer({
    pageId,
    pageItem: pageData,
    config,
    isPreview,
    useModelBuilder: true,
    });

Implement model builder

  1. In Visual Studio, create a new project

    • Project template: Class Library (.NET Framework)
    • Framework: 4.6.2+
  2. Add the Sitecore NuGet repository as a package source in your solution.

  3. Add the Uniform NuGet repository as a package source in your solution.

    info

    Contact our support team for a link to this repository.

  4. Add a reference to the following packages:

    • Sitecore.Kernel
    • Uniform.Platform.Canvas.ModelBuilder

Implement Sample Rendering model and model builder

using System.Collections.Generic;

using Sitecore.Data.Items;

using Uniform.ModelBuilders;

namespace MySite.ModelBuilders
{
public class SampleRenderingModel
{
public string Title { get; set; }

public string Text { get; set; }
}

public class SampleRenderingModelBuilder : IComponentModelBuilder
{
public object BuildModel(Item pageItem, Item datasourceItem, IReadOnlyDictionary<string, string> parameters)
{
return new SampleRenderingModel()
{
Title = datasourceItem["Title"],
// Rich Text fields needs to be rendered
Text = ModelBuilderHelper.RenderField(datasourceItem, "Text")
};
}
}
}

Register Sample Rendering model builder

Create App_Config\Include\zzz_MySite\MySite.Uniform.Canvas.config config with the following content

<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<uniform>
<siteConfigurations>
<siteConfiguration name="MySite">
<canvas>
<canvasModelBuilderService ref="uniform/services/canvasModelBuilderService">
<modelBuilders hint="raw:RegisterModelBuilder">
<sampleRendering componentId="sampleRendering" type="MySite.ModelBuilders.SampleRenderingModelBuilder, MySite" />
</modelBuilders>
</canvasModelBuilderService>
</canvas>
</siteConfiguration>
</siteConfigurations>
</uniform>
</sitecore>
</configuration>

Update enhanceComposition function

import { EnhancerBuilder, enhance } from "@uniformdev/canvas";
import { createItemEnhancer } from '@uniformdev/canvas-sitecore';

export async function enhanceComposition({ composition, pageId, pageData, config, context, isPreview }) {
const modelEnhancer = createItemEnhancer({
pageId,
pageItem: pageData,
config,
isPreview,
useModelBuilder: true
});

const enhancers = new EnhancerBuilder()
.component('sampleRendering', b => b.data('item', modelEnhancer))

await enhance({ composition, enhancers, context });
}