mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Roughing in extensibility model for content type definition editor
IEventHandler method invocation will aggregate return values of type IEnumerable<T> Added IContentDefinitionEditorEvents and ContentDefinitionEditorEventsBase to framework assembly ContentTypes editor fires events to build and apply additional type and typepart TemplateViewModel classes As an example, added some content type settings to devtools "ShowDebugLinks" In content type definition builder moved DisplayedAs(name) into it's own method Added Html.RenderTemplates helper to execute renderpartial with prefix directly to bypass (for some cases) Html.EditorXxx, Html.DisplayXxx --HG-- branch : dev
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.ContentTypes.Services;
|
||||
using Orchard.ContentTypes.ViewModels;
|
||||
using Orchard.Data;
|
||||
@@ -14,20 +18,26 @@ namespace Orchard.ContentTypes.Controllers {
|
||||
public class AdminController : Controller {
|
||||
private readonly INotifier _notifier;
|
||||
private readonly IContentDefinitionService _contentDefinitionService;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
private readonly IContentDefinitionEditorEvents _extendViewModels;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices orchardServices,
|
||||
INotifier notifier,
|
||||
IContentDefinitionService contentDefinitionService,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
IContentManager contentManager,
|
||||
ITransactionManager transactionManager) {
|
||||
ITransactionManager transactionManager,
|
||||
IContentDefinitionEditorEvents extendViewModels) {
|
||||
Services = orchardServices;
|
||||
_notifier = notifier;
|
||||
_contentDefinitionService = contentDefinitionService;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentManager = contentManager;
|
||||
_transactionManager = transactionManager;
|
||||
_extendViewModels = extendViewModels;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
@@ -72,6 +82,19 @@ namespace Orchard.ContentTypes.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
class Updater : IUpdateModel {
|
||||
public AdminController Thunk { get; set; }
|
||||
public Func<string, string> _prefix = x => x;
|
||||
|
||||
public bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class {
|
||||
return Thunk.TryUpdateModel(model, _prefix(prefix), includeProperties, excludeProperties);
|
||||
}
|
||||
|
||||
public void AddModelError(string key, LocalizedString errorMessage) {
|
||||
Thunk.ModelState.AddModelError(_prefix(key), errorMessage.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ActionResult Edit(string id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateContentTypes, T("Not allowed to edit a content type.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
@@ -81,7 +104,19 @@ namespace Orchard.ContentTypes.Controllers {
|
||||
if (contentTypeDefinition == null)
|
||||
return new NotFoundResult();
|
||||
|
||||
return View(new EditTypeViewModel(contentTypeDefinition));
|
||||
var viewModel = new EditTypeViewModel(contentTypeDefinition);
|
||||
viewModel.Parts = viewModel.Parts.ToArray();
|
||||
|
||||
viewModel.Templates = _extendViewModels.TypeEditor(contentTypeDefinition);
|
||||
var entries = viewModel.Parts.Join(contentTypeDefinition.Parts,
|
||||
m => m.PartDefinition.Name,
|
||||
d => d.PartDefinition.Name,
|
||||
(model, definition) => new { model, definition });
|
||||
foreach (var entry in entries) {
|
||||
entry.model.Templates = _extendViewModels.TypePartEditor(entry.definition);
|
||||
}
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
@@ -94,26 +129,53 @@ namespace Orchard.ContentTypes.Controllers {
|
||||
if (contentTypeDefinition == null)
|
||||
return new NotFoundResult();
|
||||
|
||||
var updater = new Updater { Thunk = this };
|
||||
|
||||
var viewModel = new EditTypeViewModel();
|
||||
TryUpdateModel(viewModel);
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return Edit(id);
|
||||
|
||||
var contentTypeDefinitionParts = viewModel.Parts.Select(GenerateTypePart).ToList();
|
||||
if (viewModel.Fields.Any())
|
||||
contentTypeDefinitionParts.Add(GenerateTypePart(viewModel));
|
||||
_contentDefinitionManager.AlterTypeDefinition(id, typeBuilder => {
|
||||
|
||||
//todo: apply the changes along the lines of but definately not resembling
|
||||
// for now this _might_ just get a little messy ->
|
||||
_contentDefinitionService.AlterTypeDefinition(
|
||||
new ContentTypeDefinition(
|
||||
viewModel.Name,
|
||||
viewModel.DisplayName,
|
||||
contentTypeDefinitionParts,
|
||||
viewModel.Settings
|
||||
)
|
||||
);
|
||||
typeBuilder.DisplayedAs(viewModel.DisplayName);
|
||||
|
||||
// allow extensions to alter type configuration
|
||||
viewModel.Templates = _extendViewModels.TypeEditorUpdate(typeBuilder, updater);
|
||||
|
||||
foreach (var entry in viewModel.Parts.Select((part, index) => new { part, index })) {
|
||||
var partViewModel = entry.part;
|
||||
|
||||
// enable updater to be aware of changing part prefix
|
||||
var firstHalf = "Parts[" + entry.index + "].";
|
||||
updater._prefix = secondHalf => firstHalf + secondHalf;
|
||||
|
||||
// allow extensions to alter typePart configuration
|
||||
typeBuilder.WithPart(entry.part.PartDefinition.Name, typePartBuilder => {
|
||||
partViewModel.Templates = _extendViewModels.TypePartEditorUpdate(typePartBuilder, updater);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
_transactionManager.Cancel();
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
//var contentTypeDefinitionParts = viewModel.Parts.Select(GenerateTypePart).ToList();
|
||||
//if (viewModel.Fields.Any())
|
||||
// contentTypeDefinitionParts.Add(GenerateTypePart(viewModel));
|
||||
|
||||
////todo: apply the changes along the lines of but definately not resembling
|
||||
//// for now this _might_ just get a little messy ->
|
||||
//_contentDefinitionService.AlterTypeDefinition(
|
||||
// new ContentTypeDefinition(
|
||||
// viewModel.Name,
|
||||
// viewModel.DisplayName,
|
||||
// contentTypeDefinitionParts,
|
||||
// viewModel.Settings
|
||||
// )
|
||||
// );
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
@@ -108,6 +108,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
<Folder Include="Helpers\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||
|
@@ -1,12 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.ContentTypes.ViewModels {
|
||||
public class EditTypeViewModel : BaseViewModel {
|
||||
public EditTypeViewModel() {
|
||||
Settings = new SettingsDictionary();
|
||||
Fields = new List<EditPartFieldViewModel>();
|
||||
Parts = new List<EditTypePartViewModel>();
|
||||
}
|
||||
public EditTypeViewModel(ContentTypeDefinition contentTypeDefinition) {
|
||||
@@ -19,6 +21,8 @@ namespace Orchard.ContentTypes.ViewModels {
|
||||
|
||||
public string Name { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public IEnumerable<TemplateViewModel> Templates { get; set; }
|
||||
|
||||
public SettingsDictionary Settings { get; set; }
|
||||
public IEnumerable<EditPartFieldViewModel> Fields { get; set; }
|
||||
public IEnumerable<EditTypePartViewModel> Parts { get; set; }
|
||||
@@ -47,6 +51,7 @@ namespace Orchard.ContentTypes.ViewModels {
|
||||
|
||||
public EditPartViewModel PartDefinition { get; set; }
|
||||
public SettingsDictionary Settings { get; set; }
|
||||
public IEnumerable<TemplateViewModel> Templates { get; set; }
|
||||
}
|
||||
|
||||
public class EditPartViewModel : BaseViewModel {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.ContentTypes.ViewModels.EditTypeViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %><%
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<%@ Import Namespace="Orchard.ContentTypes.ViewModels" %><%
|
||||
Html.RegisterStyle("admin.css"); %>
|
||||
<h1><%:Html.TitleForPage(T("Edit Content Type").ToString())%></h1>
|
||||
<p class="breadcrumb"><%:Html.ActionLink(T("Content Types").Text, "index") %><%:T(" > ") %><%:T("Edit Content Type") %></p><%
|
||||
@@ -13,7 +14,7 @@ using (Html.BeginFormAntiForgeryPost()) { %>
|
||||
<%:Html.TextBoxFor(m => m.Name, new {@class = "textMedium", disabled = "disabled"}) %>
|
||||
<%:Html.HiddenFor(m => m.Name) %>
|
||||
</fieldset>
|
||||
<%:Html.EditorFor(m => m.Settings) %>
|
||||
<% Html.RenderTemplate(Model.Templates); %>
|
||||
<h2><%:T("Parts") %></h2>
|
||||
<div class="manage add-to-type"><%: Html.ActionLink(T("Add").Text, "AddPart", new { }, new { @class = "button" }) %></div>
|
||||
<%:Html.EditorFor(m => m.Parts, "Parts", "") %>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.ContentTypes.ViewModels.EditTypePartViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<%@ Import Namespace="Orchard.ContentTypes.ViewModels" %>
|
||||
<fieldset class="manage-part">
|
||||
<h3><%:Model.PartDefinition.Name %></h3>
|
||||
<div class="manage">
|
||||
@@ -11,7 +12,8 @@
|
||||
<button type="submit" title="<%:T("Remove") %>"><%:T("Remove") %></button>
|
||||
<% } %> --%>
|
||||
</div>
|
||||
<%:Html.EditorFor(m => m.Settings, "Settings", "") %>
|
||||
<% Html.RenderTemplate(Model.Templates); %>
|
||||
|
||||
<h4><%:T("Global configuration") %></h4>
|
||||
<div class="manage minor"><%:Html.ActionLink(T("Edit").Text, "EditPart", new { area = "Orchard.ContentTypes", id = Model.PartDefinition.Name }) %></div>
|
||||
<%:Html.DisplayFor(m => m.PartDefinition.Settings, "Settings", "PartDefinition") %>
|
||||
|
@@ -7,10 +7,14 @@ namespace Orchard.DevTools.Handlers {
|
||||
[UsedImplicitly]
|
||||
public class DebugLinkHandler : ContentHandler {
|
||||
protected override void BuildDisplayModel(BuildDisplayModelContext context) {
|
||||
context.AddDisplay(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { TemplateName="Parts/DevTools.ShowDebugLink", ZoneName = "recap", Position = "9999" });
|
||||
var devToolsSettings = context.ContentItem.TypeDefinition.Settings.GetModel<Settings.DevToolsSettings>();
|
||||
if (devToolsSettings.ShowDebugLinks)
|
||||
context.AddDisplay(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { TemplateName = "Parts/DevTools.ShowDebugLink", ZoneName = "recap", Position = "9999" });
|
||||
}
|
||||
protected override void BuildEditorModel(BuildEditorModelContext context) {
|
||||
context.AddEditor(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { TemplateName = "Parts/DevTools.ShowDebugLink", ZoneName = "recap", Position = "9999" });
|
||||
var devToolsSettings = context.ContentItem.TypeDefinition.Settings.GetModel<Settings.DevToolsSettings>();
|
||||
if (devToolsSettings.ShowDebugLinks)
|
||||
context.AddEditor(new TemplateViewModel(new ShowDebugLink { ContentItem = context.ContentItem }) { TemplateName = "Parts/DevTools.ShowDebugLink", ZoneName = "recap", Position = "9999" });
|
||||
}
|
||||
}
|
||||
}
|
@@ -80,6 +80,7 @@
|
||||
<Compile Include="Models\Simple.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Settings\DevToolsSettings.cs" />
|
||||
<Compile Include="ViewModels\ContentIndexViewModel.cs" />
|
||||
<Compile Include="ViewModels\ContentDetailsViewModel.cs" />
|
||||
<Compile Include="ViewModels\MetadataIndexViewModel.cs" />
|
||||
@@ -91,6 +92,7 @@
|
||||
<Content Include="ScaffoldingTemplates\ModuleCsProj.txt" />
|
||||
<Content Include="ScaffoldingTemplates\ModuleManifest.txt" />
|
||||
<Content Include="ScaffoldingTemplates\ModuleWebConfig.txt" />
|
||||
<Content Include="Views\DefinitionTemplates\DevToolsSettings.ascx" />
|
||||
<Content Include="Views\Home\_RenderableAction.ascx" />
|
||||
<Content Include="Views\Home\Simple.aspx" />
|
||||
<Content Include="Views\Content\Details.aspx" />
|
||||
|
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
|
||||
namespace Orchard.DevTools.Settings {
|
||||
|
||||
|
||||
public class DevToolsSettings {
|
||||
public bool ShowDebugLinks { get; set; }
|
||||
}
|
||||
|
||||
public class DevToolsSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
public override IEnumerable<TemplateViewModel> TypeEditor(ContentTypeDefinition definition) {
|
||||
var model = definition.Settings.GetModel<DevToolsSettings>();
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
var model = new DevToolsSettings();
|
||||
updateModel.TryUpdateModel(model, "DevToolsSettings", null, null);
|
||||
builder
|
||||
.WithSetting("DevToolsSettings.ShowDebugLinks", model.ShowDebugLinks ? true.ToString() : null);
|
||||
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Orchard.DevTools.Settings.DevToolsSettings>" %>
|
||||
<fieldset>
|
||||
<%:Html.LabelFor(m=>m.ShowDebugLinks) %>
|
||||
<%:Html.EditorFor(m=>m.ShowDebugLinks) %>
|
||||
<%:Html.ValidationMessageFor(m=>m.ShowDebugLinks) %>
|
||||
</fieldset>
|
Reference in New Issue
Block a user