vhil / xWrap

Sitecore strongly-typed wrapper framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

xWrap - Sitecore Experience Wrapper

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

Getting started

This section covers the basic framework functionality.

  1. Wrapping fields
  2. Wrapping items
  3. View rendering with strongly-typed fields
  4. View rendering with strongly-typed datasource
  5. View rendering with strongly-typed datasource and rendering parameters
  6. Controller rendering with strongly-typed fields
  7. Controller rendering with strongly-typed datasource
  8. Controller rendering with strongly-typed datasource and rendering parameters

1. Wrapping fields

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;

2. Wrapping items

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.

3. View rendering with strongly-typed fields

If you building a simple view rendering, and you don't need a controller for it, you can use this option:

  1. Define model of the view to be Xwrap.Mvc.IViewModel
  2. 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>

4. View rendering with strongly-typed datasource

Building a simple view rendering without a controller and datasource item wrapping into a strongly-typed representation:

  1. 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");
}
  1. Define model of the view to be Xwrap.Mvc.IViewModel<TestItem>
  2. 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>

5. View rendering with strongly-typed datasource and rendering parameters

Building a simple view rendering without a controller with datasource item and rendering parameters wrapping into a strongly-typed representation:

  1. 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");
}
  1. 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");
}
  1. Define model of the view to be Xwrap.Mvc.IViewModel<TestItem, TestRenderingParameters>
  2. 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>

6. Controller rendering with strongly-typed fields

Using controller renderings with wrapping on field level on the view model class:

  1. Create view model class:
public class TestViewModel : ViewModel
{
	public TestViewModel(IViewModel viewModel) : base(viewModel)
	{
	}

	public IRichTextFieldWrapper RichTextField => this.RenderingItem.RichTextField("rich text field name");
}
  1. 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);
	}
}
  1. Use view model fields in the view:
@model TestViewModel

<div class="row">
	<div class="col-md-12">
		RichTextField: @Model.RenderingItem.RichTextField
	</div>
</div>

7. Controller rendering with strongly-typed datasource

Using controller renderings with wrapping on field level on the view model class:

  1. 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");
}
  1. Create view model class:
public class TestItemViewModel: ViewModel<TestItem>
{
	public TestItemViewModel(IViewModel<TestItem> viewModel) : base(viewModel)
	{
	}
}
  1. 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);
	}
}
  1. Use rendering item fields in the view:
@model TestItemViewModel

<div class="row">
	<div class="col-md-12">
		ImageField: @Model.RenderingItem.Image
	</div>
</div>

8. Controller rendering with strongly-typed datasource and rendering parameters

  1. 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");
}
  1. Create rendering parameters wrapper
public class TestRenderingParameters : RenderingParametersWrapper
{
	public TestRenderingParameters(RenderingParameters parameters) : base(parameters)
	{
	}

	public ICheckboxFieldWrapper CheckboxParam => this.CheckboxField("checkbox parameter name");
}
  1. Create view model class:
public class TestItemViewModel: ViewModel<TestItem, TestRenderingParameters>
{
	public TestItemViewModel(IViewModel<TestItem, TestRenderingParameters> viewModel) : base(viewModel)
	{
	}
}
  1. 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);
	}
}
  1. 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>

Documentation

List of available field wrapper extensions:

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

List of available rendering parameter field wrapping options:

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

Hints

Item wrappers can be generated from serialized items either using Unicorn and Rainbow or hedgehoc's TDS.

About

Sitecore strongly-typed wrapper framework

License:MIT License


Languages

Language:C# 98.4%Language:JavaScript 1.6%