Strongly-typed wrapping framework for Sitecore CMS.
xWrap is a small and light-weigh library created to improve the developer workflow when building Sitecore solutions.
Functionality and features
- provides functionality for strongly-typed wrapping fields
- provides functionality for strongly-typed wrapping items
- provides functionality for strongly-typed wrapping rendering parameters
- provides functionality for MVC support based on strongly-typed view models
- built on a
wrapper
design pattern - super light-weight
- uses only standard Sitecore API, no inventions
- native support for Sitecore Experience Editor out of the box
- compliant with helix principles and modular architecture
- provides convenient field and item extensions
- fully configurable through sitecore include config files
The framework is a set of NuGet packages that can be used in your solution:
Within helix modular architecture:
- Install xWrap.Mvc nuget package to your project layer module (will include config files)
- Install xWrap.Mvc.Framework nuget package to your feature or foundation layer module
This section covers the basic framework functionality.
- Wrapping fields
- Wrapping items
- View rendering with strongly-typed fields
- View rendering with strongly-typed datasource
- View rendering with strongly-typed datasource and rendering parameters
- Controller rendering with strongly-typed fields
- Controller rendering with strongly-typed datasource
- Controller rendering with strongly-typed datasource and rendering parameters
Item fields can be wrapped into strongly-typed intepretation by using convenient extension methods usign both field names or field IDs:
var item = Sitecore.Context.Item;
ILinkFieldWrapper linkField = item.LinkField("link field name");
Guid linkedItemId = linkField.Value;
Item linkedItem = linkField.GetTarget();
INumberFieldWrapper numberField = linkedItem.NumberField(new ID("{686E1737-890D-4AA8-9EA2-AB7AC7CB0525}"));
decimal numberFieldValue = numberField.Value;
There is an option to wrap custom sitecore item templates into item wrappers:
[TemplateId("{655C4BD7-1D6A-4806-95EA-22B94603CC8F}")]
public class TestItem : ItemWrapper
{
public TestItem(Item item) : base(item)
{
}
public ITextFieldWrapper Text => this.WrapField<ITextFieldWrapper>("text field name");
public ICheckboxFieldWrapper Checkbox => this.WrapField<ICheckboxFieldWrapper>("checkbox field name");
public IDateTimeFieldWrapper DateTime => this.WrapField<IDateTimeFieldWrapper>("datetime field name");
public ILinkFieldWrapper Link => this.WrapField<ILinkFieldWrapper>("link field name");
public IImageFieldWrapper Image => this.WrapField<IImageFieldWrapper>("image field name");
public IGeneralLinkFieldWrapper GeneralLink => this.WrapField<IGeneralLinkFieldWrapper>("general link field name");
public IFileFieldWrapper File => this.WrapField<IFileFieldWrapper>("file field name");
public IRichTextFieldWrapper RichText => this.WrapField<IRichTextFieldWrapper>("rich text field name");
public INumberFieldWrapper Number => this.WrapField<INumberFieldWrapper>("number field name");
public IIntegerFieldWrapper Integer => this.WrapField<IIntegerFieldWrapper>("integer");
public INameValueListFieldWrapper NameValueList => this.WrapField<INameValueListFieldWrapper>("Name value list field name");
public INameLookupValueListFieldWrapper NameLookupValue => this.WrapField<INameLookupValueListFieldWrapper>("Name lookup value list field name");
}
And then use it like this:
var testItem = new TestItem(Sitecore.Context.Item);
TemplateId
attribute is optional but nice to have in order to validate the item which is being passed to be wrapped.
If you building a simple view rendering, and you don't need a controller for it, you can use this option:
- Define model of the view to be
Xwrap.Mvc.IViewModel
- Use field extensions to render fields
@using Xwrap.Extensions
@model Xwrap.Mvc.IViewModel
<div class="row">
<div class="col-md-12">
ImageField: @Model.RenderingItem.ImageField("image")
</div>
</div>
Building a simple view rendering without a controller and datasource item wrapping into a strongly-typed representation:
- Create a wrapper for your item template, fx
TestItem
[TemplateId("{655C4BD7-1D6A-4806-95EA-22B94603CC8F}")]
public class TestItem : ItemWrapper
{
public TestItem(Item item) : base(item)
{
}
public IImageFieldWrapper Image => this.WrapField<IImageFieldWrapper>("image field name");
}
- Define model of the view to be
Xwrap.Mvc.IViewModel<TestItem>
- Use rendering item to render fields
@model Xwrap.Mvc.IViewModel<TestItem>
<div class="row">
<div class="col-md-12">
ImageField: @Model.RenderingItem.Image
</div>
</div>
Building a simple view rendering without a controller with datasource item and rendering parameters wrapping into a strongly-typed representation:
- Create a wrapper for your item template, fx
TestItem
[TemplateId("{655C4BD7-1D6A-4806-95EA-22B94603CC8F}")]
public class TestItem : ItemWrapper
{
public TestItem(Item item) : base(item)
{
}
public IImageFieldWrapper Image => this.WrapField<IImageFieldWrapper>("image field name");
}
- Create rendering parameters wrapper for your parameters:
public class TestRenderingParameters : RenderingParametersWrapper
{
public TestRenderingParameters(RenderingParameters parameters) : base(parameters)
{
}
public ICheckboxFieldWrapper CheckboxParam => this.CheckboxField("checkbox parameter name");
}
- Define model of the view to be
Xwrap.Mvc.IViewModel<TestItem, TestRenderingParameters>
- Use rendering item to render fields and rendering parameters to access strongly-typed params
@model Xwrap.Mvc.IViewModel<TestItem, TestRenderingParameters>
<div class="row">
<div class="col-md-12">
@if (@Model.RenderingParameters.CheckboxParam.Value)
{
Image field: @Model.RenderingItem.Image
}
</div>
</div>
Using controller renderings with wrapping on field level on the view model class:
- Create view model class:
public class TestViewModel : ViewModel
{
public TestViewModel(IViewModel viewModel) : base(viewModel)
{
}
public IRichTextFieldWrapper RichTextField => this.RenderingItem.RichTextField("rich text field name");
}
- Create controller and inject
IViewModelFactory
using System.Web.Mvc;
using Models;
using Xwrap.Mvc;
public class TestController : Controller
{
private readonly IViewModelFactory viewModelFactory;
public TestController(IViewModelFactory viewModelFactory)
{
this.viewModelFactory = viewModelFactory;
}
public ActionResult TestView()
{
var viewModel = new TestViewModel(this.viewModelFactory.GetViewModel());
return this.View(viewModel);
}
}
- Use view model fields in the view:
@model TestViewModel
<div class="row">
<div class="col-md-12">
RichTextField: @Model.RenderingItem.RichTextField
</div>
</div>
Using controller renderings with wrapping on field level on the view model class:
- Create item wrapper:
[TemplateId("{655C4BD7-1D6A-4806-95EA-22B94603CC8F}")]
public class TestItem : ItemWrapper
{
public TestItem(Item item) : base(item)
{
}
public IImageFieldWrapper Image => this.WrapField<IImageFieldWrapper>("image field name");
}
- Create view model class:
public class TestItemViewModel: ViewModel<TestItem>
{
public TestItemViewModel(IViewModel<TestItem> viewModel) : base(viewModel)
{
}
}
- Create controller and inject
IViewModelFactory
using System.Web.Mvc;
using Models;
using Xwrap.Mvc;
public class TestController : Controller
{
private readonly IViewModelFactory viewModelFactory;
public TestController(IViewModelFactory viewModelFactory)
{
this.viewModelFactory = viewModelFactory;
}
public ActionResult TestView()
{
var viewModel = new TestItemViewModel(this.viewModelFactory.GetViewModel<TestItem>());
return this.View(viewModel);
}
}
- Use rendering item fields in the view:
@model TestItemViewModel
<div class="row">
<div class="col-md-12">
ImageField: @Model.RenderingItem.Image
</div>
</div>
- Create item wrapper:
[TemplateId("{655C4BD7-1D6A-4806-95EA-22B94603CC8F}")]
public class TestItem : ItemWrapper
{
public TestItem(Item item) : base(item)
{
}
public IImageFieldWrapper Image => this.WrapField<IImageFieldWrapper>("image field name");
}
- Create rendering parameters wrapper
public class TestRenderingParameters : RenderingParametersWrapper
{
public TestRenderingParameters(RenderingParameters parameters) : base(parameters)
{
}
public ICheckboxFieldWrapper CheckboxParam => this.CheckboxField("checkbox parameter name");
}
- Create view model class:
public class TestItemViewModel: ViewModel<TestItem, TestRenderingParameters>
{
public TestItemViewModel(IViewModel<TestItem, TestRenderingParameters> viewModel) : base(viewModel)
{
}
}
- Create controller and inject
IViewModelFactory
using System.Web.Mvc;
using Models;
using Xwrap.Mvc;
public class TestController : Controller
{
private readonly IViewModelFactory viewModelFactory;
public TestController(IViewModelFactory viewModelFactory)
{
this.viewModelFactory = viewModelFactory;
}
public ActionResult TestView()
{
var model = this.viewModelFactory.GetViewModel<TestItem, TestRenderingParameters>();
var viewModel = new TestItemViewModel(model);
return this.View(viewModel);
}
}
- Use rendering item fields in the view:
@model TestItemViewModel
<div class="row">
<div class="col-md-12">
@if (@Model.RenderingParameters.CheckboxParam.Value)
{
Image field: @Model.RenderingItem.Image
}
</div>
</div>
ITextFieldWrapper TextField = item.TextField("text");
ICheckboxFieldWrapper CheckboxField = item.CheckboxField("checkbox field name");
IDateTimeFieldWrapper DateTimeField = item.DateTimeField("datetime field name");
ILinkFieldWrapper LinkField = item.LinkField("link field name");
IImageFieldWrapper ImageField = item.ImageField("image field name");
IGeneralLinkFieldWrapper GeneralLinkField = item.GeneralLinkField("general link field name");
IFileFieldWrapper FileField = item.FileField("file field name");
IRichTextFieldWrapper RichTextField = item.RichTextField("rich text field name");
INumberFieldWrapper NumberField = item.NumberField("number field name");
IIntegerFieldWrapper IntegerField = item.IntegerField("integer field name");
INameValueListFieldWrapper NameValueListField = item.NameValueListField("Name value list field name");
INameLookupValueListFieldWrapper NameLookupValueField = item.NameLookupValueField("Name lookup value list field name");
public class TestRenderingParameters : RenderingParametersWrapper
{
public TestRenderingParameters(RenderingParameters parameters) : base(parameters)
{
}
public ITextFieldWrapper TextParam => this.TextField("text parameter name");
public ILinkFieldWrapper LinkParam => this.LinkField("link parameter name");
public IListFieldWrapper ListParam => this.ListField("list parameter name");
public IIntegerFieldWrapper IntegerParam => this.IntegerField("integer parameter name");
public INumberFieldWrapper NumberParam => this.NumberField("number parameter name");
public ICheckboxFieldWrapper CheckboxParam => this.CheckboxField("checkbox parameter name");
}
Item wrappers can be generated from serialized items either using Unicorn and Rainbow or hedgehoc's TDS.