Skip to content

Instantly share code, notes, and snippets.

@kamsar
Created November 7, 2014 17:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kamsar/8f8beffd0db83d8dd13a to your computer and use it in GitHub Desktop.
Save kamsar/8f8beffd0db83d8dd13a to your computer and use it in GitHub Desktop.
Synthesis Sitecore MVC prototype
using Synthesis.Mvc.Pipelines.GetRenderer;
using Sitecore.Mvc.Pipelines.Response.GetModel;
using Sitecore.Mvc.Presentation;
using Synthesis;
namespace Synthesis.Mvc.Pipelines.GetModel
{
public class GetFromSynthesis : GetModelProcessor
{
protected virtual object GetFromViewPath(Rendering rendering, GetModelArgs args)
{
var viewPath = rendering.ToString().Replace("View: ", string.Empty);
var renderer = rendering.Renderer;
var viewRenderer = renderer as ViewRenderer;
if (viewRenderer != null) viewPath = viewRenderer.ViewPath;
var modelType = new ViewModelTypeResolver().GetViewModelType(viewPath);
// Check to see if no model has been set
if (modelType == typeof(object)) return null;
// Check that the model is a Synthesis type (if not, we ignore it)
if (!typeof(IStandardTemplateItem).IsAssignableFrom(modelType)) return null;
// if we got here we know that the view requested a model of a Synthesis type. We'll give it one.
// note that we're not validating that the item IS of the correct template, but that's because reflection
// is slow, and the validation of Synthesis typing here is pretty much to avoid typing models for components
// that are built into Sitecore.
return rendering.Item.AsStronglyTyped();
}
public override void Process(GetModelArgs args)
{
if (args.Result == null)
{
args.Result = GetFromViewPath(args.Rendering, args);
}
}
}
}
using System;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Sitecore.Web.UI.WebControls;
using Synthesis;
using Synthesis.FieldTypes;
using Synthesis.FieldTypes.Interfaces;
namespace Synthesis.Mvc.Helpers
{
public static class SynthesisMvcHtmlHelper
{
public static IHtmlString DateTimeFor<T>(this HtmlHelper<T> helper, Func<T, IDateTimeField> selector)
{
return DateTimeFor(helper, selector, "g");
}
public static IHtmlString DateTimeFor<T>(this HtmlHelper<T> helper, Func<T, IDateTimeField> selector, string format)
{
return DateTimeFor(helper, selector, x => { x.Format = format; });
}
public static IHtmlString DateTimeFor<T>(this HtmlHelper<T> helper, Func<T, IDateTimeField> selector, Action<Date> parameters)
{
var field = selector(helper.ViewData.Model);
if (field.HasValue || Sitecore.Context.PageMode.IsPageEditor)
{
var date = new Date();
date.AttachToDateTimeField(field);
parameters(date);
return new MvcHtmlString(date.RenderAsText());
}
return new MvcHtmlString(string.Empty);
}
public static IHtmlString FileLinkFor<T>(this HtmlHelper<T> helper, Func<T, IFileField> selector, string linkText = null, string cssClass = null)
{
return FileLinkFor(helper, selector, linkText, new { @class = cssClass });
}
public static IHtmlString FileLinkFor<T>(this HtmlHelper<T> helper, Func<T, IFileField> selector, string linkText, object attributes)
{
var field = selector(helper.ViewData.Model);
if (field.HasValue)
{
var sb = new StringBuilder();
sb.Append("<a href=\"");
sb.Append(HttpUtility.HtmlEncode(field.Url));
sb.Append("\"");
foreach (var attribute in attributes.GetType().GetProperties().Where(x => x.CanRead))
{
var value = attribute.GetValue(attributes, null);
if (value == null) continue;
sb.AppendFormat(" {0}=\"{1}\"", attribute.Name.Replace('_', '-'), HttpUtility.HtmlEncode(value));
}
sb.Append(">");
sb.Append(linkText ?? field.Url);
sb.Append("</a>");
return new MvcHtmlString(sb.ToString());
}
return new MvcHtmlString(string.Empty);
}
public static IHtmlString ImageFor<T>(this HtmlHelper<T> helper, Func<T, IImageField> selector, string cssClass)
{
return ImageFor(helper, selector, x => { x.CssClass = cssClass; });
}
public static IHtmlString ImageFor<T>(this HtmlHelper<T> helper, Func<T, IImageField> selector, int? maxWidth = null, int? maxHeight = null, string cssClass = null)
{
return ImageFor(helper, selector, x =>
{
if (maxWidth.HasValue)
x.MaxWidth = maxWidth.Value;
if (maxHeight.HasValue)
x.MaxHeight = maxHeight.Value;
x.CssClass = cssClass;
});
}
public static IHtmlString ImageFor<T>(this HtmlHelper<T> helper, Func<T, IImageField> selector, Action<Image> parameters)
{
var field = selector(helper.ViewData.Model);
if (field.HasValue || Sitecore.Context.PageMode.IsPageEditor)
{
var imageRenderer = new Image();
imageRenderer.AttachToImageField(field);
parameters(imageRenderer);
return new MvcHtmlString(imageRenderer.RenderAsText());
}
return new MvcHtmlString(string.Empty);
}
public static IHtmlString TextFor<T>(this HtmlHelper<T> helper, Func<T, ITextField> selector)
{
return TextFor(helper, selector, true);
}
public static IHtmlString TextFor<T>(this HtmlHelper<T> helper, Func<T, ITextField> selector, bool editable)
{
var field = selector(helper.ViewData.Model);
if (field.HasTextValue || Sitecore.Context.PageMode.IsPageEditor)
{
if (editable)
return new MvcHtmlString(field.RenderedValue);
var richText = field as RichTextField;
if (richText != null) return new MvcHtmlString(richText.ExpandedLinksValue);
return new MvcHtmlString(field.RawValue);
}
return new MvcHtmlString(string.Empty);
}
public static IHtmlString HyperlinkFor<T>(this HtmlHelper<T> helper, Func<T, IHyperlinkField> selector, string linkText = null, string cssClass = null)
{
return HyperlinkFor(helper, selector, x =>
{
if (linkText != null)
x.Text = linkText;
if (cssClass != null)
x.CssClass = cssClass;
});
}
public static IHtmlString HyperlinkFor<T>(this HtmlHelper<T> helper, Func<T, IHyperlinkField> selector, Action<Link> parameters)
{
var field = selector(helper.ViewData.Model);
if (field.HasValue || Sitecore.Context.PageMode.IsPageEditor)
{
var link = new Link();
link.AttachToLinkField(field);
parameters(link);
return new MvcHtmlString(link.RenderAsText());
}
return new MvcHtmlString(string.Empty);
}
}
}
using System;
using System.Web.Compilation;
namespace Synthesis.Mvc
{
/// <summary>
/// Credit where due: this is based on Fortis' model resolver:
/// https://github.com/Fortis-Collection/fortis/blob/master/Fortis.Mvc/Pipelines/GetModel/GetFromView.cs
/// </summary>
public class ViewModelTypeResolver
{
public Type GetViewModelType(string viewPath)
{
if (string.IsNullOrWhiteSpace(viewPath)) return typeof(object);
// Retrieve the compiled view
var compiledViewType = BuildManager.GetCompiledType(viewPath);
var baseType = compiledViewType.BaseType;
// Check to see if the view has been found and that it is a generic type
if (baseType == null || !baseType.IsGenericType) return typeof(object);
return baseType.GetGenericArguments()[0];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment