I very love Glass Mapper as (once being configured) it takes away from you much of the manual efforts of wiring up your models.
Often working with Rendering Parameters, I decided to simplify their usage by having a strongly-typed HTML Helper powered by Glass Mapper. Here is how the usage looks like:
<div class="@(Html.GetRenderingParametersClassFor<ISingleClass>(m => m.Class))">
your content here
</div>
It benefits from usage simplicity and also from having IntelliSense. Here's an example of what ISingleClass
looks like:
[SitecoreType(TemplateId = ISingleClassConstants.TemplateIdString)]
public partial interface ISingleClass : IGlassBase
{
[SitecoreField(ISingleClassConstants.ClassFieldName)]
Guid Class { get; }
}
In Sitecore items of a given type may look as smth. similar below:
OK, won't make it any longer: here's the code that does all the magic:
public static class HtmlHelperExtensions
{
public static string GetRenderingParametersClassFor<T>(this HtmlHelper html, Func<T, object> getField, string fieldName = "Class") where T : class
{
var selectedItem = GetSelectedRenderingParameter(html, getField);
return selectedItem?[fieldName] ?? "";
}
private static Item GetSelectedRenderingParameter<T>(this HtmlHelper html, Func<T, object> getField) where T : class
{
T renderingParameters = GetRenderingParameters<T>(html);
var selectedItemId = getField(renderingParameters)?.ToString();
return Context.Database.GetItem(selectedItemId);
}
public static T GetRenderingParameters<T>(this HtmlHelper html) where T : class
{
//TODO: wire-up ISitecoreService to get resolved via DI of your choise
var sitecoreService = new SitecoreService(PageContext.Current.Database);
var parameters = RenderingContext.CurrentOrNull.Rendering["Parameters"];
var nameValueCollection = WebUtil.ParseUrlParameters(parameters);
var config = sitecoreService.GlassContext[typeof(T)] as SitecoreTypeConfiguration;
var renderingParametersModelFactory = new RenderingParametersModelFactory(sitecoreService);
return renderingParametersModelFactory.CreateModel<T>(nameValueCollection, config.TemplateId);
}
}
Bonus: in some cases you may also want selecting a HTML tag from rendering parameters, for example your editors could choose between heading tags they want to be on your rendering (like H1, H2, H3, H4 or may be just a generating paragraph P-tag):
In that case you can add one more method into the above HTML helper class:
public static MvcTag TagFrom<T>(this HtmlHelper html, Func<T, object> getField, string className = null) where T : class
{
var selectedItem = GetSelectedRenderingParameter(html, getField);
string tag = selectedItem?["Tag"] ?? "";
html.ViewContext.ViewBag.Tag = tag;
if (!string.IsNullOrWhiteSpace(tag))
{
var tagBuilder = new TagBuilder(tag);
if (!string.IsNullOrWhiteSpace(className))
{
tagBuilder.Attributes.Add("class", className);
}
html.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
}
return new MvcTag(html.ViewContext);
}
Once compiled, you can then render you tags as below:
@using (Html.TagFrom<ITagRenderingParameter>(m => m.Tag, "tag_class"))
{
@Html.Glass().Editable(m => m.Title)
}
And choose which HTML tag just from a Rendering Parameters dropdown:
Hope this helps!