Skip to main content

Advanced topics

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 });
}