Use model builders

Canvas Sitecore integration allows to define a model builder for component. It can be helpful when item fields isn't enough and you need to prepare data from back-end side.

Implement Uniform.ModelBuilders.IModelBuilder, Uniform.ComponentModel interface

public interface IModelBuilder { [CanBeNull] object BuildModel([NotNull] Item datasourceItem); bool CanBuildModel([NotNull] Item datasourceItem); }

datasourceItem - current datasource item (can be the same as a page item)
<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"> <componentModel> <componentModelBuilderService ref="uniform/services/componentModelBuilderService"> <modelBuilders hint="raw:RegisterModelBuilder"> <builder componentId="<CANVAS_COMPONENT_ID>" parameterName="<CANVAS_PARAMETER_NAME>" type="Namespace.ModelBuilderType, Assembly" /> </modelBuilders> </componentModelBuilderService> </componentModel> </siteConfiguration> </siteConfigurations> </uniform> </sitecore> </configuration>

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

  • getModelOrItem function

    const model = await getModelOrItem({ id: itemId, componentType: component.type, parameterName, config, isPreview, // disable fallback to item result when model is missing modelOnly, });
  • getPageItemId function

    const pageId = getPageItemId({ composition });
  • create an enhancer from createItemEnhancer function

    const modelEnhancer = createItemEnhancer({ pageId, isPreview, config, allowMultipleItems, // disable fallback to item result when model is missing modelOnly, logger, });
  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.ComponentModel

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 : IModelBuilder { public object BuildModel(Item datasourceItem) { return new SampleRenderingModel() { Title = datasourceItem["Title"], // Rich Text fields needs to be rendered Text = ModelBuilderHelper.RenderField(datasourceItem, "Text") }; } public bool CanBuildModel(Item datasourceItem) { return datasourceItem.Paths.IsContentItem; } } }

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"> <componentModel> <componentModelBuilderService ref="uniform/services/componentModelBuilderService"> <modelBuilders hint="raw:RegisterModelBuilder"> <sampleRendering componentId="sampleRendering" parameterName="datasource" type="MySite.ModelBuilders.SampleRenderingModelBuilder, MySite" /> </modelBuilders> </componentModelBuilderService> </componentModel> </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, config, context, isPreview }) { const modelEnhancer = createItemEnhancer({ pageId, config, isPreview, }); const enhancers = new EnhancerBuilder() .component('sampleRendering', b => b.data('item', modelEnhancer)) await enhance({ composition, enhancers, context }); }

Uniform.ModelBuilders.ItemFieldsModelBuilder, Uniform.ComponentModel allows to build simple models without custom code.

<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/"> <sitecore> <uniform> <siteConfigurations> <siteConfiguration name="MySite"> <componentModel> <componentModelBuilderService ref="uniform/services/componentModelBuilderService"> <modelBuilders hint="raw:RegisterModelBuilder"> <primaryHero componentId="primaryHero" parameterName="datasource" type="Uniform.ModelBuilders.ItemFieldsModelBuilder, Uniform.ComponentModel"> <!-- camel-cased by default --> <UseCamelCase>false</UseCamelCase> <Templates hint="list:AddTemplate"> <PrimaryHero>{9E922288-97F6-4368-9231-72043A99CBA9}</PrimaryHero> </Templates> <Fields hint="raw:AddField"> <!-- use `title` as property key --> <field prop="title">HeroTitle</field> <!-- use field raw value (item[field]) --> <field raw="true">RawValueField</field> <!-- mark field as optional can be helpful when templates have different set of fields --> <field optional="true">OptionalField</field> <!-- ignore field expanders (standard FieldRenderer will be used) --> <field expander="false">HeroDesc</field> </Fields> </primaryHero> </modelBuilders> </componentModelBuilderService> </componentModel> </siteConfiguration> </siteConfigurations> </uniform> </sitecore> </configuration>

Model builders may have implicit Sitecore item dependencies. In order to support incremental cache purge for Data Types, we need to define such kind of dependencies explicitly.

info

You can skip this step if you don't intend to utilize Data Types.

warning

This functionality requires latest v7.2-patch-2 version of the Uniform connector (Sitecore package named Uniform Canvas v7.2.230517-1 Upgrade Package for UFS v7.2) which needs to be installed on top of previously installed v7.2 or v7.2-patch-1 (Sitecore package named Uniform Canvas v7.2.23XXXX for Sitecore 8.2.0-10.3.0). If you use .NET SDK please make sure to update your dependencies as per packages.config

Use Uniform.Models.ModelBuilderResult, Uniform.ComponentModel as model builder result

using System.Collections.Generic; using Sitecore.Data.Items; using Uniform.ModelBuilders; using Uniform.Models; namespace MySite.ModelBuilders { public class SampleRenderingModel { public string Title { get; set; } public string GlobalTitle { get; set; } } public class SampleRenderingModelBuilder : IModelBuilder { public object BuildModel(Item datasourceItem) { var dependencies = new List<ID>(); var globalSettings = datasourceItem.Database.GetItem("/sitecore/content/GlobalSettings"); if (globalSettings != null) { dependencies.Add(globalSettings.ID); } var model = new SampleRenderingModel() { Title = datasourceItem["Title"], GlobalTitle = globalSettings != null ? globalSettings["Title"] : "" }; // you don't need to add `datasourceItem` to the dependency list return new ModelBuilderResult(model, dependencies); } public bool CanBuildModel(Item datasourceItem) { return datasourceItem.Paths.IsContentItem; } } }