I've been playing around with custom rendering with IContentDataExtensions.RenderContentData with different tags and I don't want to register alot of TemplateModels just to get to my view.
In my example
@Html.RenderContentData(myContentData, false, "MyTag")
It seems like there are some ideas in MvcContentRenderer that would support this by using IViews and checking ViewEngines but it doesn't really work (see detailed description below).
The problem is MvcContentRenderer doesn't really use "MyTag" that I send as parameter.
The problem seems to be that the method IContentDataExtensions.RenderContentData(this HtmlHelper html, IContentData contentData, bool isContentInContentArea, string templateTag) only determines which ModelTemplate to use and sends it as a parameter to the overload
RenderContentData(this HtmlHelper html, IContentData contentData, bool isContentInContentArea, TemplateModel templateModel, IContentRenderer contentRenderer) which in turn calls contentRenderer.Render(HtmlHelper helper, PartialRequest partialRequestHandler, IContentData contentData, TemplateModel templateModel).
contentRenderer in this case is by default MvcContentRenderer.
If the TemplateModel is TemplateTypeCategories.MvcPartialView, the MvcContentRenderer.Render method has nice parts to let you customize your rendering by implementing the IView interface. It also has a mechanism to try to resolve your view by asking the ViewEngines for a view called either the name + tag, or simply the name from the TemplateModel.
An example of the IView implementation are described in Jonas Bergqvist's blog http://world.episerver.com/blogs/Jonas-Bergqvist/Dates/2013/6/Hidden-template-functionality-in-the-MVC-implementation/.
But I would like to have the "magic find your view" functionality in MVC and it's a bit tricky since my implementation does not receive the tag or the TemplateModel.
I have also noted that the ViewEngine mechanism doesn't receive the tag from my parameter.
Both the IView and ViewEnginge mechanism checks the ViewData for the tags, but the parameter from RenderContentData nor the TemplateModel used is passed.
So my question is: Is something broken, or am I trying to do something in a way where it's not meant to be used? Do I really need to register TemplateModels just to get a tag specific path?
It sounds like a bug when the View Engine "mechanism" doesn't receive the tag. This should be fixed. I will try this out tomorrow.
Cool, I was testing with the latest around christmas (think it was 7.18 or something, don't have the code around). I can check for tomorrow and give you more details if you need.
The tag will only be used by the TemplateResolver to get the correct view, it will not be send to the block renderer as you wrote. I think it could be a good feature to set that in the RouteData collection. I will create a feature request for this.
Cool, that would be great! Thnx!
stumbled on the same issue.. and only now realized at what time Alf posted the original question ;)
Anyway Jonas, any bug # for reference? Seems like still present in 8.0+
It's the the CMS backlog. I can't say when it's going to be fixed, but it's at least in the backlog.
Been there too, so I ended up with this simple "fix":
public class TemplateTagContext : IDisposable
private readonly HtmlHelper _helper;
private readonly object _originalTag;
public TemplateTagContext(HtmlHelper helper, string tag)
_helper = helper;
_originalTag = _helper.ViewContext.ViewData["Tag"];
_helper.ViewContext.ViewData["Tag"] = tag;
public void Dispose()
_helper.ViewContext.ViewData["Tag"] = _originalTag;
Html helper extension:
public static TemplateTagContext BeginTemplateTag(this HtmlHelper helper, string tag)
return new TemplateTagContext(helper, tag);
And finally in the view: