mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Starting to get a UI around content type management
- added a DisplayName to the ContentTypeDefinition - added a CreateRouteValues rvd to go along with the existing display and edit - set default display, edit and create route values for ContentItemMetadata (* should get fallback route values in a different manner. probably not good to refer to an area, even by string, in core from the fwk) - starting to shape up the content type list into a more consistent UI - added create type action, view, etc. for creating new content types - supporting service has a few default parts hard-coded for now --HG-- branch : dev
This commit is contained in:
@@ -167,7 +167,7 @@ namespace Orchard.Core.Tests.Feeds.Controllers {
|
||||
|
||||
var mockContentManager = new Mock<IContentManager>();
|
||||
mockContentManager.Setup(x => x.GetItemMetadata(It.IsAny<IContent>()))
|
||||
.Returns(new ContentItemMetadata { DisplayText = "foo" });
|
||||
.Returns(new ContentItemMetadata(hello) { DisplayText = "foo" });
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
//builder.RegisterModule(new ImplicitCollectionSupportModule());
|
||||
|
@@ -1,19 +1,37 @@
|
||||
using Orchard.Localization;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Core.Contents {
|
||||
public class AdminMenu : INavigationProvider {
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public AdminMenu(IContentDefinitionManager contentDefinitionManager, IContentManager contentManager) {
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Content"), "1",
|
||||
menu => {
|
||||
menu.Add(T("Create New Content"), "1.1", item => item.Action("Create", "Admin", new { area = "Contents" }));
|
||||
var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name);
|
||||
|
||||
builder.Add(T("Content"), "1", menu => {
|
||||
menu.Add(T("Manage Content"), "1.2", item => item.Action("List", "Admin", new {area = "Contents"}));
|
||||
//foreach (var contentTypeDefinition in contentTypeDefinitions) {
|
||||
// var ci = _contentManager.New(contentTypeDefinition.Name);
|
||||
// var cim = _contentManager.GetItemMetadata(ci);
|
||||
// var createRouteValues = cim.CreateRouteValues;
|
||||
// if (createRouteValues.Any())
|
||||
// menu.Add(T("Create New {0}", contentTypeDefinition.DisplayName), "1.3", item => item.Action(cim.CreateRouteValues["Action"] as string, cim.CreateRouteValues["Controller"] as string, cim.CreateRouteValues));
|
||||
//}
|
||||
});
|
||||
builder.Add(T("Site Configuration"), "11",
|
||||
menu => menu.Add(T("Content Types"), "3", item => item.Action("Types", "Admin", new { area = "Contents" })));
|
||||
menu => menu.Add(T("Content Types"), "3", item => item.Action("Index", "Admin", new { area = "Contents" })));
|
||||
}
|
||||
}
|
||||
}
|
10
src/Orchard.Web/Core/Contents/ContentTypeDefinitionStub.cs
Normal file
10
src/Orchard.Web/Core/Contents/ContentTypeDefinitionStub.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Orchard.Core.Contents {
|
||||
public class ContentTypeDefinitionStub {
|
||||
[StringLength(128)]
|
||||
public string Name { get; set; }
|
||||
[Required, StringLength(1024)]
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Core.Contents.Services;
|
||||
using Orchard.Core.Contents.ViewModels;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
@@ -16,37 +16,72 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
[ValidateInput(false)]
|
||||
public class AdminController : Controller, IUpdateModel {
|
||||
private readonly INotifier _notifier;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IContentDefinitionService _contentDefinitionService;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices orchardServices,
|
||||
INotifier notifier,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
IContentDefinitionService contentDefinitionService,
|
||||
IContentManager contentManager,
|
||||
ITransactionManager transactionManager) {
|
||||
Services = orchardServices;
|
||||
_notifier = notifier;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentDefinitionService = contentDefinitionService;
|
||||
_contentManager = contentManager;
|
||||
_transactionManager = transactionManager;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; private set; }
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
#region Types
|
||||
|
||||
public ActionResult Index() {
|
||||
return Types();
|
||||
}
|
||||
|
||||
public ActionResult Types() {
|
||||
return View("Types", new ContentTypeListViewModel {
|
||||
Types = _contentDefinitionManager.ListTypeDefinitions()
|
||||
return View("Types", new ListContentTypesViewModel {
|
||||
Types = _contentDefinitionService.GetTypeDefinitions()
|
||||
});
|
||||
}
|
||||
|
||||
public ActionResult List(ListContentViewModel model) {
|
||||
public ActionResult CreateType(CreateTypeViewModel viewModel) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateContentType, T("Not allowed to create a content type.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("CreateType")]
|
||||
public ActionResult CreateTypePOST(CreateTypeViewModel viewModel) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateContentType, T("Not allowed to create a content type.")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var model = new ContentTypeDefinitionStub();
|
||||
TryUpdateModel(model);
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
Services.TransactionManager.Cancel();
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
_contentDefinitionService.AddTypeDefinition(model);
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
#endregion
|
||||
|
||||
public ActionResult List(ListContentsViewModel model) {
|
||||
const int pageSize = 20;
|
||||
var skip = (Math.Max(model.Page ?? 0, 1) - 1) * pageSize;
|
||||
|
||||
@@ -63,8 +98,8 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
return View("List", model);
|
||||
}
|
||||
|
||||
private ListContentViewModel.Entry BuildEntry(ContentItem contentItem) {
|
||||
var entry = new ListContentViewModel.Entry {
|
||||
private ListContentsViewModel.Entry BuildEntry(ContentItem contentItem) {
|
||||
var entry = new ListContentsViewModel.Entry {
|
||||
ContentItem = contentItem,
|
||||
ContentItemMetadata = _contentManager.GetItemMetadata(contentItem),
|
||||
ViewModel = _contentManager.BuildDisplayModel(contentItem, "List"),
|
||||
@@ -84,8 +119,8 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
}
|
||||
|
||||
ActionResult CreatableTypeList() {
|
||||
var model = new ContentTypeListViewModel {
|
||||
Types = _contentDefinitionManager.ListTypeDefinitions()
|
||||
var model = new ListContentTypesViewModel {
|
||||
Types = _contentDefinitionService.GetTypeDefinitions()
|
||||
};
|
||||
|
||||
return View("CreatableTypeList", model);
|
||||
@@ -107,6 +142,7 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Create(CreateItemViewModel model) {
|
||||
//todo: need to integrate permissions into generic content management
|
||||
var contentItem = _contentManager.New(model.Id);
|
||||
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
||||
if (ModelState.IsValid) {
|
||||
|
@@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Core.Contents.Handlers {
|
||||
public class ContentsModuleHandler : ContentHandlerBase {
|
||||
public override void GetContentItemMetadata(GetContentItemMetadataContext context) {
|
||||
if (context.Metadata.CreateRouteValues == null) {
|
||||
context.Metadata.CreateRouteValues = new RouteValueDictionary {
|
||||
{"Area", "Contents"},
|
||||
{"Controller", "Item"},
|
||||
{"Action", "Create"}
|
||||
};
|
||||
}
|
||||
if (context.Metadata.EditorRouteValues == null) {
|
||||
context.Metadata.EditorRouteValues = new RouteValueDictionary {
|
||||
{"Area", "Contents"},
|
||||
|
27
src/Orchard.Web/Core/Contents/Permissions.cs
Normal file
27
src/Orchard.Web/Core/Contents/Permissions.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Security.Permissions;
|
||||
|
||||
namespace Orchard.Core.Contents {
|
||||
public class Permissions : IPermissionProvider {
|
||||
public static readonly Permission CreateContentType = new Permission { Name = "CreateContentType", Description = "Create custom content type." };
|
||||
|
||||
public string ModuleName {
|
||||
get { return "Contents"; }
|
||||
}
|
||||
|
||||
public IEnumerable<Permission> GetPermissions() {
|
||||
return new Permission[] {
|
||||
CreateContentType,
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
|
||||
return new[] {
|
||||
new PermissionStereotype {
|
||||
Name = "Administrator",
|
||||
Permissions = new[] {CreateContentType}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Core.Contents.Services {
|
||||
public class ContentDefinitionService : IContentDefinitionService {
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
|
||||
public ContentDefinitionService(IOrchardServices services, IContentDefinitionManager contentDefinitionManager) {
|
||||
Services = services;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public IEnumerable<ContentTypeDefinition> GetTypeDefinitions() {
|
||||
return _contentDefinitionManager.ListTypeDefinitions();
|
||||
}
|
||||
|
||||
public ContentTypeDefinition GetTypeDefinition(string name) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void AddTypeDefinition(ContentTypeDefinitionStub definitionStub) {
|
||||
if (string.IsNullOrWhiteSpace(definitionStub.Name))
|
||||
definitionStub.Name = GenerateTypeName(definitionStub.DisplayName);
|
||||
|
||||
while (_contentDefinitionManager.GetTypeDefinition(definitionStub.Name) != null)
|
||||
definitionStub.Name = VersionTypeName(definitionStub.Name);
|
||||
|
||||
//just giving the new type some default parts for now
|
||||
_contentDefinitionManager.AlterTypeDefinition(
|
||||
definitionStub.Name,
|
||||
cfg => cfg.Named(definitionStub.Name, definitionStub.DisplayName)
|
||||
.WithPart("CommonAspect")
|
||||
//.WithPart("RoutableAspect") //need to go the new routable route
|
||||
.WithPart("BodyAspect"));
|
||||
|
||||
Services.Notifier.Information(T("Created content type: {0}", definitionStub.DisplayName));
|
||||
}
|
||||
|
||||
public void RemoveTypeDefinition(string name) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
//gratuitously stolen from the RoutableService
|
||||
private static string GenerateTypeName(string displayName) {
|
||||
if (string.IsNullOrWhiteSpace(displayName))
|
||||
return "";
|
||||
|
||||
var name = displayName;
|
||||
//todo: might need to be made more restrictive depending on how name is used (like as an XML node name, for instance)
|
||||
var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s]+");
|
||||
|
||||
name = dissallowed.Replace(name, "-");
|
||||
name = name.Trim('-');
|
||||
|
||||
if (name.Length > 128)
|
||||
name = name.Substring(0, 128);
|
||||
|
||||
return name.ToLowerInvariant();
|
||||
}
|
||||
|
||||
private static string VersionTypeName(string name) {
|
||||
var version = 2;
|
||||
var nameParts = name.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (nameParts.Length > 1 && int.TryParse(nameParts.Last(), out version)) {
|
||||
version = version > 0 ? ++version : 2;
|
||||
//this could unintentionally chomp something that looks like a version
|
||||
name = string.Join("-", nameParts.Take(nameParts.Length - 1));
|
||||
}
|
||||
|
||||
return string.Format("{0}-{1}", name, version);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
|
||||
namespace Orchard.Core.Contents.Services {
|
||||
public interface IContentDefinitionService : IDependency {
|
||||
IEnumerable<ContentTypeDefinition> GetTypeDefinitions();
|
||||
ContentTypeDefinition GetTypeDefinition(string name);
|
||||
void AddTypeDefinition(ContentTypeDefinitionStub contentTypeDefinition);
|
||||
void RemoveTypeDefinition(string name);
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Contents.ViewModels {
|
||||
public class CreateTypeViewModel : BaseViewModel {
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Contents.ViewModels {
|
||||
public class ContentTypeListViewModel : BaseViewModel {
|
||||
public class ListContentTypesViewModel : BaseViewModel {
|
||||
public IEnumerable<ContentTypeDefinition> Types { get; set; }
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using Orchard.ContentManagement;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Contents.ViewModels {
|
||||
public class ListContentViewModel : BaseViewModel {
|
||||
public class ListContentsViewModel : BaseViewModel {
|
||||
public string Id { get; set; }
|
||||
public int? Page { get; set; }
|
||||
public IList<Entry> Entries { get; set; }
|
@@ -1,5 +1,4 @@
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ContentTypeListViewModel>" %>
|
||||
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ListContentTypesViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<% Html.AddTitleParts(T("Create Content").ToString()); %>
|
||||
<p>
|
||||
|
13
src/Orchard.Web/Core/Contents/Views/Admin/CreateType.ascx
Normal file
13
src/Orchard.Web/Core/Contents/Views/Admin/CreateType.ascx
Normal file
@@ -0,0 +1,13 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CreateTypeViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<h1><%:Html.TitleForPage(T("New Content Type").ToString())%></h1><%
|
||||
using (Html.BeginFormAntiForgeryPost()) { %>
|
||||
<%:Html.ValidationSummary() %>
|
||||
<fieldset>
|
||||
<label for="DisplayName"><%:T("Display Name") %></label>
|
||||
<%:Html.TextBoxFor(m => m.DisplayName, new {@class = "textMedium", autofocus = "autofocus"}) %>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<button class="primaryAction" type="submit"><%:T("Create") %></button>
|
||||
</fieldset><%
|
||||
} %>
|
@@ -1,5 +1,4 @@
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ListContentViewModel>" %>
|
||||
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ListContentsViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<% Html.AddTitleParts(T("Browse Contents").ToString()); %>
|
||||
<p>
|
||||
|
9
src/Orchard.Web/Core/Contents/Views/Admin/Types.ascx
Normal file
9
src/Orchard.Web/Core/Contents/Views/Admin/Types.ascx
Normal file
@@ -0,0 +1,9 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<ListContentTypesViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<h1><%:Html.TitleForPage(T("Content Types").ToString())%></h1>
|
||||
<div class="manage"><%: Html.ActionLink(T("Create new type").ToString(), "CreateType", null, new { @class = "button primaryAction" })%></div>
|
||||
<%=Html.UnorderedList(
|
||||
Model.Types,
|
||||
(t,i) => Html.DisplayFor(m => t).ToHtmlString(),
|
||||
"contentItems"
|
||||
) %>
|
@@ -1,24 +0,0 @@
|
||||
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<ContentTypeListViewModel>" %>
|
||||
|
||||
<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %>
|
||||
<% Html.AddTitleParts(T("Create Content").ToString()); %>
|
||||
<p>
|
||||
Create content</p>
|
||||
<table>
|
||||
<% foreach (var t in Model.Types) {%>
|
||||
<tr>
|
||||
<td>
|
||||
<%:t.Name %>
|
||||
</td>
|
||||
<td>
|
||||
<%:Html.ActionLink(T("List Items").ToString(), "List", "Admin", new RouteValueDictionary{{"Area","Contents"},{"Id",t.Name}}, new Dictionary<string, object>()) %>
|
||||
</td>
|
||||
<td>
|
||||
<%:Html.ActionLink(T("Create Item").ToString(), "Create", "Admin", new RouteValueDictionary{{"Area","Contents"},{"Id",t.Name}}, new Dictionary<string, object>()) %>
|
||||
</td>
|
||||
<td>
|
||||
<%:Html.ActionLink(T("Edit Type").ToString(), "ContentTypeList", "Admin", new RouteValueDictionary{{"Area","Orchard.MetaData"},{"Id",t.Name}}, new Dictionary<string, object>()) %>
|
||||
</td>
|
||||
</tr>
|
||||
<%} %>
|
||||
</table>
|
@@ -0,0 +1,14 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.ContentManagement.MetaData.Models.ContentTypeDefinition>" %>
|
||||
<div class="summary">
|
||||
<div class="properties">
|
||||
<h3><%:Model.DisplayName%></h3>
|
||||
<p><%:Model.Name %> - <%:Html.ActionLink("[new content]", "Create", new {area = "Contents", id = Model.Name}) %></p>
|
||||
</div>
|
||||
<div class="related">
|
||||
<%:Html.ActionLink(T("List Items").ToString(), "List", new {area = "Contents", id = Model.Name})%><%:T(" | ")%>
|
||||
<%:Html.ActionLink(T("[Edit]").ToString(), "EditType", new {area = "Contents", id = Model.Name})%><%:T(" | ") %>
|
||||
<% using (Html.BeginFormAntiForgeryPost(Url.Action("RemoveType", new {area = "Contents", id = Model.Name}), FormMethod.Post, new { @class = "inline link" })) { %>
|
||||
<button type="submit" class="linkButton" title="<%:T("Delete") %>"><%:T("[Delete]")%></button><%
|
||||
} %>
|
||||
</div>
|
||||
</div>
|
@@ -76,8 +76,15 @@
|
||||
<Compile Include="Common\ViewModels\ContainerEditorViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\TextContentFieldDisplayViewModel.cs" />
|
||||
<Compile Include="Common\ViewModels\TextContentFieldEditorViewModel.cs" />
|
||||
<Compile Include="Contents\ContentTypeDefinitionStub.cs" />
|
||||
<Compile Include="Contents\Controllers\ItemController.cs" />
|
||||
<Compile Include="Contents\Handlers\ContentsModuleHandler.cs" />
|
||||
<Compile Include="Contents\Permissions.cs" />
|
||||
<Compile Include="Contents\Services\ContentDefinitionService.cs" />
|
||||
<Compile Include="Contents\Services\IContentDefinitionService.cs" />
|
||||
<Compile Include="Contents\ViewModels\CreateTypeViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ListContentsViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ListContentTypesViewModel.cs" />
|
||||
<Compile Include="Localization\Drivers\LocalizedDriver.cs" />
|
||||
<Compile Include="Routable\Controllers\ItemController.cs" />
|
||||
<Compile Include="Routable\Drivers\RoutableDriver.cs" />
|
||||
@@ -105,9 +112,7 @@
|
||||
<Compile Include="Contents\AdminMenu.cs" />
|
||||
<Compile Include="Contents\Controllers\AdminController.cs" />
|
||||
<Compile Include="Contents\ViewModels\CreateItemViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ContentTypeListViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\EditItemViewModel.cs" />
|
||||
<Compile Include="Contents\ViewModels\ListContentViewModel.cs" />
|
||||
<Compile Include="Dashboard\AdminMenu.cs" />
|
||||
<Compile Include="Dashboard\Controllers\AdminController.cs" />
|
||||
<Compile Include="Dashboard\Routes.cs" />
|
||||
@@ -216,11 +221,13 @@
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Container.ascx" />
|
||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.TextContentField.ascx" />
|
||||
<Content Include="Contents\Module.txt" />
|
||||
<Content Include="Contents\Views\Admin\Types.aspx" />
|
||||
<Content Include="Contents\Views\Admin\CreateType.ascx" />
|
||||
<Content Include="Contents\Views\Admin\Types.ascx" />
|
||||
<Content Include="Contents\Views\Admin\List.aspx" />
|
||||
<Content Include="Contents\Views\Admin\Edit.aspx" />
|
||||
<Content Include="Contents\Views\Admin\CreatableTypeList.aspx" />
|
||||
<Content Include="Contents\Views\Admin\Create.aspx" />
|
||||
<Content Include="Contents\Views\DisplayTemplates\ContentTypeDefinition.ascx" />
|
||||
<Content Include="Contents\Views\DisplayTemplates\Items\Contents.Item.ascx" />
|
||||
<Content Include="Contents\Views\EditorTemplates\Items\Contents.Item.ascx" />
|
||||
<Content Include="Contents\Views\Item\Preview.aspx" />
|
||||
|
@@ -54,7 +54,7 @@ namespace Orchard.Core.Settings.Metadata {
|
||||
private ContentTypeDefinitionRecord Acquire(ContentTypeDefinition contentTypeDefinition) {
|
||||
var result = _typeDefinitionRepository.Fetch(x => x.Name == contentTypeDefinition.Name).SingleOrDefault();
|
||||
if (result == null) {
|
||||
result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name };
|
||||
result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name, DisplayName = contentTypeDefinition.DisplayName};
|
||||
_typeDefinitionRepository.Create(result);
|
||||
}
|
||||
return result;
|
||||
@@ -100,6 +100,7 @@ namespace Orchard.Core.Settings.Metadata {
|
||||
ContentTypeDefinition Build(ContentTypeDefinitionRecord source) {
|
||||
return new ContentTypeDefinition(
|
||||
source.Name,
|
||||
source.DisplayName,
|
||||
source.ContentTypePartDefinitionRecords.Select(Build),
|
||||
_settingsReader.Map(Parse(source.Settings)));
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ namespace Orchard.Core.Settings.Metadata.Records {
|
||||
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Name { get; set; }
|
||||
public virtual string DisplayName { get; set; }
|
||||
public virtual bool Hidden { get; set; }
|
||||
public virtual string Settings { get; set; }
|
||||
|
||||
|
@@ -40,6 +40,9 @@ namespace Orchard.Blogs.Drivers {
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetDisplayRouteValues(BlogPost post) {
|
||||
if (post.Blog == null)
|
||||
return new RouteValueDictionary();
|
||||
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Blogs"},
|
||||
{"Controller", "BlogPost"},
|
||||
@@ -50,6 +53,9 @@ namespace Orchard.Blogs.Drivers {
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetEditorRouteValues(BlogPost post) {
|
||||
if (post.Blog == null)
|
||||
return new RouteValueDictionary();
|
||||
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Blogs"},
|
||||
{"Controller", "BlogPostAdmin"},
|
||||
@@ -59,6 +65,18 @@ namespace Orchard.Blogs.Drivers {
|
||||
};
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetCreateRouteValues(BlogPost post) {
|
||||
if (post.Blog == null)
|
||||
return new RouteValueDictionary();
|
||||
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Blogs"},
|
||||
{"Controller", "BlogPostAdmin"},
|
||||
{"Action", "Create"},
|
||||
{"blogSlug", post.Blog.Slug},
|
||||
};
|
||||
}
|
||||
|
||||
protected override DriverResult Display(BlogPost post, string displayType) {
|
||||
return Combined(
|
||||
ContentItemTemplate("Items/Blogs.BlogPost").LongestMatch(displayType, "Summary", "SummaryAdmin"),
|
||||
|
@@ -10,9 +10,9 @@ namespace Orchard.MetaData {
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder)
|
||||
{
|
||||
builder.Add(T("Content Types"), "5",
|
||||
builder.Add(T("Site Configuration"), "11",
|
||||
menu => menu
|
||||
.Add(T("Content Types"), "1.0", item => item.Action("ContentTypeList", "Admin", new { area = "Orchard.MetaData" }).Permission(Permissions.ManageMetaData))
|
||||
.Add(T("Content Types (metadata)"), "3.1", item => item.Action("ContentTypeList", "Admin", new { area = "Orchard.MetaData" }).Permission(Permissions.ManageMetaData))
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
%>
|
||||
<tr class="<%=contentTypeClass %>">
|
||||
<td>
|
||||
<%= Html.ActionLink(item.Name, "ContentTypeList", new {id=item.Name})%>
|
||||
<%= Html.ActionLink(string.IsNullOrWhiteSpace(item.Name) ? "unkwn" : item.Name, "ContentTypeList", new {id=item.Name})%>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
@@ -61,6 +61,14 @@ namespace Orchard.Pages.Drivers {
|
||||
};
|
||||
}
|
||||
|
||||
public override RouteValueDictionary GetCreateRouteValues(Page page) {
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Orchard.Pages"},
|
||||
{"Controller", "Admin"},
|
||||
{"Action", "Create"},
|
||||
};
|
||||
}
|
||||
|
||||
protected override DriverResult Display(Page page, string displayType) {
|
||||
return Combined(
|
||||
ContentItemTemplate("Items/Pages.Page").LongestMatch(displayType, "Summary", "SummaryAdmin"),
|
||||
|
@@ -1,24 +1,9 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Comments.Models;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Navigation.Models;
|
||||
using Orchard.Core.Settings.Models;
|
||||
using Orchard.Data;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Security;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Setup.Services;
|
||||
using Orchard.Setup.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Setup.Controllers {
|
||||
|
@@ -4,7 +4,6 @@ using System.Web;
|
||||
using Orchard.Comments.Models;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Navigation.Models;
|
||||
using Orchard.Core.Settings.Models;
|
||||
@@ -15,7 +14,6 @@ using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Descriptor;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.ContentManagement.MetaData.Services;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Security;
|
||||
using Orchard.Settings;
|
||||
@@ -149,9 +147,9 @@ namespace Orchard.Setup.Services {
|
||||
//hackInstallationGenerator.GenerateInstallEvents();
|
||||
|
||||
var contentDefinitionManager = environment.Resolve<IContentDefinitionManager>();
|
||||
contentDefinitionManager.AlterTypeDefinition("blogpost", cfg => cfg.WithPart("HasComments").WithPart("HasTags").WithPart("Localized"));
|
||||
contentDefinitionManager.AlterTypeDefinition("page", cfg => cfg.WithPart("HasComments").WithPart("HasTags").WithPart("Localized"));
|
||||
contentDefinitionManager.AlterTypeDefinition("sandboxpage", cfg => cfg.WithPart("HasComments").WithPart("HasTags").WithPart("Localized"));
|
||||
contentDefinitionManager.AlterTypeDefinition("blogpost", cfg => cfg.Named("blogpost", "Blog Post").WithPart("HasComments").WithPart("HasTags").WithPart("Localized"));
|
||||
contentDefinitionManager.AlterTypeDefinition("page", cfg => cfg.Named("page", "Page").WithPart("HasComments").WithPart("HasTags").WithPart("Localized"));
|
||||
contentDefinitionManager.AlterTypeDefinition("sandboxpage", cfg => cfg.Named("sandboxpage", "Sandbox Page").WithPart("HasComments").WithPart("HasTags").WithPart("Localized"));
|
||||
|
||||
// create home page as a CMS page
|
||||
var page = contentManager.Create("page", VersionOptions.Draft);
|
||||
|
@@ -638,9 +638,6 @@ table .button {
|
||||
overflow:hidden;
|
||||
padding:0 1.4em .8em;
|
||||
}
|
||||
.contentItems li.last {
|
||||
border-bottom:0;
|
||||
}
|
||||
#main .contentItems li .actions {
|
||||
color:#EAE9D9;
|
||||
height:auto;
|
||||
|
@@ -3,11 +3,45 @@ using System.Web.Routing;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public class ContentItemMetadata {
|
||||
public ContentItemMetadata(IContent item) {
|
||||
DisplayRouteValues = GetDisplayRouteValues(item);
|
||||
EditorRouteValues = GetEditorRouteValues(item);
|
||||
CreateRouteValues = GetCreateRouteValues(item);
|
||||
}
|
||||
|
||||
public string DisplayText { get; set; }
|
||||
public RouteValueDictionary DisplayRouteValues { get; set; }
|
||||
public RouteValueDictionary EditorRouteValues { get; set; }
|
||||
public RouteValueDictionary CreateRouteValues { get; set; }
|
||||
|
||||
public IEnumerable<string> DisplayGroups { get; set; }
|
||||
public IEnumerable<string> EditorGroups { get; set; }
|
||||
|
||||
private static RouteValueDictionary GetDisplayRouteValues(IContent item) {
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Contents"},
|
||||
{"Controller", "Item"},
|
||||
{"Action", "Display"},
|
||||
{"id", item.ContentItem.Id}
|
||||
};
|
||||
}
|
||||
|
||||
private static RouteValueDictionary GetEditorRouteValues(IContent item) {
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Contents"},
|
||||
{"Controller", "Admin"},
|
||||
{"Action", "Edit"},
|
||||
{"id", item.ContentItem.Id}
|
||||
};
|
||||
}
|
||||
|
||||
private static RouteValueDictionary GetCreateRouteValues(IContent item) {
|
||||
return new RouteValueDictionary {
|
||||
{"Area", "Contents"},
|
||||
{"Controller", "Admin"},
|
||||
{"Action", "Create"},
|
||||
{"id", item.ContentItem.ContentType}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -375,7 +375,7 @@ namespace Orchard.ContentManagement {
|
||||
public ContentItemMetadata GetItemMetadata(IContent content) {
|
||||
var context = new GetContentItemMetadataContext {
|
||||
ContentItem = content.ContentItem,
|
||||
Metadata = new ContentItemMetadata()
|
||||
Metadata = new ContentItemMetadata(content)
|
||||
};
|
||||
foreach (var handler in Handlers) {
|
||||
handler.GetContentItemMetadata(context);
|
||||
|
@@ -27,6 +27,7 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
context.Metadata.DisplayText = GetDisplayText(item) ?? context.Metadata.DisplayText;
|
||||
context.Metadata.DisplayRouteValues = GetDisplayRouteValues(item) ?? context.Metadata.DisplayRouteValues;
|
||||
context.Metadata.EditorRouteValues = GetEditorRouteValues(item) ?? context.Metadata.EditorRouteValues;
|
||||
context.Metadata.CreateRouteValues = GetCreateRouteValues(item) ?? context.Metadata.CreateRouteValues;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +68,7 @@ namespace Orchard.ContentManagement.Drivers {
|
||||
protected virtual string GetDisplayText(TContent item) { return null; }
|
||||
public virtual RouteValueDictionary GetDisplayRouteValues(TContent item) { return null; }
|
||||
public virtual RouteValueDictionary GetEditorRouteValues(TContent item) { return null; }
|
||||
public virtual RouteValueDictionary GetCreateRouteValues(TContent item) { return null; }
|
||||
|
||||
protected virtual DriverResult Display(ContentItemViewModel<TContent> viewModel, string displayType) { return GetDefaultItemTemplate(); }
|
||||
protected virtual DriverResult Editor(ContentItemViewModel<TContent> viewModel) { return GetDefaultItemTemplate(); }
|
||||
|
@@ -6,6 +6,7 @@ using Orchard.ContentManagement.MetaData.Models;
|
||||
namespace Orchard.ContentManagement.MetaData.Builders {
|
||||
public class ContentTypeDefinitionBuilder {
|
||||
private string _name;
|
||||
private string _displayName;
|
||||
private readonly IList<ContentTypeDefinition.Part> _parts;
|
||||
private readonly IDictionary<string, string> _settings;
|
||||
|
||||
@@ -20,6 +21,7 @@ namespace Orchard.ContentManagement.MetaData.Builders {
|
||||
}
|
||||
else {
|
||||
_name = existing.Name;
|
||||
_displayName = existing.DisplayName;
|
||||
_parts = existing.Parts.ToList();
|
||||
_settings = existing.Settings.ToDictionary(kv => kv.Key, kv => kv.Value);
|
||||
}
|
||||
@@ -30,11 +32,12 @@ namespace Orchard.ContentManagement.MetaData.Builders {
|
||||
}
|
||||
|
||||
public ContentTypeDefinition Build() {
|
||||
return new ContentTypeDefinition(_name, _parts, _settings);
|
||||
return new ContentTypeDefinition(_name, _displayName, _parts, _settings);
|
||||
}
|
||||
|
||||
public ContentTypeDefinitionBuilder Named(string name) {
|
||||
public ContentTypeDefinitionBuilder Named(string name, string displayName = null) {
|
||||
_name = name;
|
||||
_displayName = displayName ?? name;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@@ -3,8 +3,9 @@ using System.Linq;
|
||||
|
||||
namespace Orchard.ContentManagement.MetaData.Models {
|
||||
public class ContentTypeDefinition {
|
||||
public ContentTypeDefinition(string name, IEnumerable<Part> parts, IDictionary<string, string> settings) {
|
||||
public ContentTypeDefinition(string name, string displayName, IEnumerable<Part> parts, IDictionary<string, string> settings) {
|
||||
Name = name;
|
||||
DisplayName = displayName;
|
||||
Parts = parts;
|
||||
Settings = settings;
|
||||
}
|
||||
@@ -16,6 +17,7 @@ namespace Orchard.ContentManagement.MetaData.Models {
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
public string DisplayName { get; set; }
|
||||
public IEnumerable<Part> Parts { get; private set; }
|
||||
public IDictionary<string, string> Settings { get; private set; }
|
||||
|
||||
|
Reference in New Issue
Block a user