Extend the Sitecore HtmlHelper
When you work with Sitecore MVC you usually also work with Razor as your view
engine. To support you in your Razor views, ASP.NET MVC has a number of useful
helper methods (e.g. to generate a form). These methods are part of the
HtmlHelper
class and are invoked with @Html.MethodToCall()
. Sitecore has it’s own html
helper, available with @Html.Sitecore().MethodToCall()
. You may know the
following method to output the content of a Sitecore field, including inline
editing for the Experience
Editor:
@Html.Sitecore().Field("My Field")
Sometimes you need more functionalities and you wish you could extend the Sitecore html helper. I will show you two possibilities how you can easily accomplish this.
Extension methods
The ASP.NET HtmlHelper
as well as the SitecoreHelper
class are normal
classes, what means you can write extension
methods for it. So if
you want to extends the Sitecore html helper with a custom implementation, you
just need to write an extension method for the SitecoreHelper
class:
public static MvcHtmlString GetExtensionMethodString(this SitecoreHelper helper)
{
return new MvcHtmlString("This comes from the extension method!");
}
Which you can call with:
@Html.Sitecore().GetExtensionMethodString()
The benefits are clear: It’s very simple and your co-developers don’t even need to know if this method is a Sitecore extension or your custom code, they can simply use it the same way as it would be a Sitecore helper method.
Custom HtmlHelper
Extension methods have one big disadvantage: You can’t override methods nor can you use protected methods of the “original” html helper. So another possibility is to write a custom html helper the same way as Sitecore does. The goal is to have something we can call like this:
@Html.Custom().MethodToCall()
Also here the concept is very easy. Custom()
is an extension method of the
ASP.NET HtmlHelper
and returns a new instance of our custom html helper, which
inherits from the SitecoreHelper
. First we need the custom html helper with a
new method:
public class CustomSitecoreHelper : SitecoreHelper
{
public CustomSitecoreHelper(System.Web.Mvc.HtmlHelper htmlHelper)
: base(htmlHelper)
{
}
public MvcHtmlString GetCustomHelperString()
{
return new MvcHtmlString("This comes from our custom html handler!");
}
}
In this class it is also possible to use and/or override protected
and
public
methods of the original Sitecore html helper. One useful protected
method could be GetValueFromCurrentRendering()
or it could make sense to
override the FormHandler()
for multiple forms handling (see this blog
post).
Last but not least we need to write the HtmlHelper
extension method to get
your custom helper:
public static CustomSitecoreHelper Custom(this System.Web.Mvc.HtmlHelper htmlHelper)
{
// get the helper from current thread
var threadData = ThreadHelper.GetThreadData<CustomSitecoreHelper>();
if (threadData != null) return threadData;
// create new helper if needed
var helper = new CustomSitecoreHelper(htmlHelper);
ThreadHelper.SetThreadData(helper);
return helper;
}
Now we are able to use it:
@Html.Custom().GetCustomHelperString()
In theory you are now able to “forget” the Sitecore html helper and always use your custom one. This would have a similar effect to your co-workers like extension methods. Because we inherit from the Sitecore html helper, you can also call it’s method over the custom class:
@Html.Custom().Field("My Field")
How do you handle these situations in your daily business? Do you have a third, even better option? If you have ever tried something like this, what did you experience?