The project is currently MVC3 but could be upgraded if required.
I'm trying to get a content editor for a simple cms improved. At the moment we use
@Html.EditorFor(model=>model.Content) //Content is a List<EditableContent>
EditableContent has a (brand new) property of string EditorView. The idea is this will name suitable editors for particular items of content.
What I want to do is use my default EditableContent template if EditorView is null, otherwise use the EditorView as the named template. I'm aware of the overload for EditorFor that takes a template, but that's going to use the same template for each item of content, but that's not what I want.
I did try taking my default template and basically doing
//Shared/EditorTemplates/EditableContent.cshtml
@model Website.Areas.Admin.EditableContent
@if (!string.IsNullOrWhiteSpace(Model.EditorView))
{
<text>
@Model.EditorView
@Html.EditorForModel(Model.EditorView)
</text>
}
else
{
//Original template
}
Weirdly in this case, the view is located (I have a slightly custom view engine which appears to locate the view correctly). The name of the view (via @Model.EditorView ) is emitted to the page, but @Html.EditorForModel() doesn't produce anything.
Any ideas how I can use a custom template per item using EditorFor or similar ?
Interface
interface IEditableContent
{
public virtual DatabaseContext.Content Content { get; set; }
}
Implementation
class SomeTypeEditableContent : IEditableContent
{
public SomeTypeEditableContent(DatabaseContext.Content c)
{
Content = c;
}
}
Service (Repository or Controller action)
List<IEditableContent> lEditableContent = new List<IEditableContent>();
foreach(var c in db.Contents)
{
switch (c.EditorView)
{
case "SomeType":
lEditableContent.Add(new SomeTypeEditableContent(c));
break;
default:
lEditableContent.Add(new DefaultEditableContent(c));
break;
}
}
View
@Html.EditorFor(model=>model.ListContent) //List<IEditableContent>
Editable SomeType Template
@model SomeTypeEditableContent
//Display this as a editable string
Default Editable Content Template
@model IEditableContent
//Use default display
I'm sorry I do not have the time to test it. Let me know how it goes and i'll edit / delete this answer if it does not. I would have posted this as a comment but I needed anotation and formating. But at least it gives you an idea of what I had in mind.
-Edit-
The point of this exemple is to show you that MVC framework should be able to determine the proper template for a implementated interface even if simply providing the object typed as the interface. It will use refelction (i believe?) to find the highest class definition then look for the template.
-Edit 2 (based off comments)-
Changed the exemple to match new specifications
It seems weird that you are trying to override the editor template from a view that is already overriding the template. I'm not sure if that will work (it might, but I have never tried so I don't know). I've already added a couple comments to your question above.
If it turns out that trying to specify templates from the EditorTemplates folder doesn't work, which would be understandable, I think you could achieve what you want by introducing a custom EditorForModel()
override. You can use David Ebbo's Razor Generator VS extension to define a razor helper that will be usable across your entire project.
/// /Views/Helpers/AndiEditorForExtensions.cshtml
@helper AndiEditorFor(HtmlHelper html, Website.Areas.Admin.EditableContent model) {
if (!string.IsNullOrWhiteSpace(Model.EditorView)) {
<text>
@Model.EditorView
@Html.EditorForModel(Model.EditorView)
</text>
}
else {
// Call @Html.EditorFor(), which will use the default editor template (i.e., NOT your custom one defined in the database)
@Html.EditorFor(model)
}
}
Then from your normal code that loads the EditableContent items from the db and displays them, call your custom extension:
@Html.AndiEditorFor(model)
A better option might be to skip the Razor Generator altogether. Just define a custom HtmlHelper, mimicking the EditorExtensions methods . Add a similar if/else to handle Model.EditorView having a value or not.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.