diff --git a/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs b/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs index ef872853b..54cfed0de 100644 --- a/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs +++ b/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs @@ -102,44 +102,12 @@ namespace Orchard.Core.Contents.Controllers { var viewModel = new EditTypeViewModel(); TryUpdateModel(viewModel); - if (!ModelState.IsValid) { + if (!ModelState.IsValid) return EditType(id); - } - var contentTypeDefinitionParts = viewModel.Parts.Select( - p => new ContentTypeDefinition.Part( - new ContentPartDefinition( - p.PartDefinition.Name, - p.PartDefinition.Fields.Select( - f => new ContentPartDefinition.Field( - new ContentFieldDefinition(f.FieldDefinition.Name), - f.Name, - f.Settings - ) - ), - p.PartDefinition.Settings - ), - p.Settings - ) - ).ToList(); - - if (viewModel.Fields.Any()) { - var implicitContentTypeDefinitionPart = new ContentTypeDefinition.Part( - new ContentPartDefinition( - viewModel.Name, - viewModel.Fields.Select( - f => new ContentPartDefinition.Field( - new ContentFieldDefinition(f.FieldDefinition.Name), - f.Name, - f.Settings - ) - ), - null - ), - null - ); - contentTypeDefinitionParts.Add(implicitContentTypeDefinitionPart); - } + 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 -> @@ -151,11 +119,48 @@ namespace Orchard.Core.Contents.Controllers { viewModel.Settings ) ); - // little == lot return RedirectToAction("Index"); } + private static ContentTypeDefinition.Part GenerateTypePart(EditTypePartViewModel viewModel) { + return new ContentTypeDefinition.Part( + new ContentPartDefinition( + viewModel.PartDefinition.Name, + viewModel.PartDefinition.Fields.Select( + f => new ContentPartDefinition.Field( + new ContentFieldDefinition(f.FieldDefinition.Name), + f.Name, + f.Settings + ) + ), + viewModel.PartDefinition.Settings + ), + viewModel.Settings + ); + } + + private static ContentTypeDefinition.Part GenerateTypePart(EditTypeViewModel viewModel) { + return new ContentTypeDefinition.Part( + new ContentPartDefinition( + viewModel.Name, + viewModel.Fields.Select( + f => new ContentPartDefinition.Field( + new ContentFieldDefinition(f.FieldDefinition.Name), + f.Name, + f.Settings + ) + ), + null + ), + null + ); + } + + #endregion + + #region Parts + public ActionResult EditPart(string id) { if (!Services.Authorizer.Authorize(Permissions.CreateContentTypes, T("Not allowed to edit a part."))) return new HttpUnauthorizedResult(); @@ -187,30 +192,66 @@ namespace Orchard.Core.Contents.Controllers { //todo: apply the changes along the lines of but definately not resembling // for now this _might_ just get a little messy -> - _contentDefinitionService.AlterPartDefinition( - new ContentPartDefinition( - viewModel.Name, - viewModel.Fields.Select( - f => new ContentPartDefinition.Field( - new ContentFieldDefinition(f.FieldDefinition.Name), - f.Name, - f.Settings - ) - ), - viewModel.Settings - ) - ); - // little == lot + _contentDefinitionService.AlterPartDefinition(GeneratePart(viewModel)); return RedirectToAction("Index"); } + public ActionResult AddFieldTo(string id) { + if (!Services.Authorizer.Authorize(Permissions.CreateContentTypes, T("Not allowed to edit a part."))) + return new HttpUnauthorizedResult(); + + var contentPartDefinition = _contentDefinitionService.GetPartDefinition(id); + + if (contentPartDefinition == null) { + //id passed in might be that of a type w/ no implicit field + var contentTypeDefinition = _contentDefinitionService.GetTypeDefinition(id); + if (contentTypeDefinition != null) + contentPartDefinition = new ContentPartDefinition(id); + else + return new NotFoundResult(); + } + + //get all of the field types + + + var viewModel = new AddFieldViewModel(contentPartDefinition); + + return View(viewModel); + } + + [HttpPost, ActionName("AddFieldTo")] + public ActionResult AddFieldToPOST(string id) { + if (!Services.Authorizer.Authorize(Permissions.CreateContentTypes, T("Not allowed to edit a part."))) + return new HttpUnauthorizedResult(); + + var contentPartDefinition = _contentDefinitionService.GetPartDefinition(id); + var contentTypeDefinition = _contentDefinitionService.GetTypeDefinition(id); + + if (contentTypeDefinition != null) + return RedirectToAction("EditType", new { id }); + + return RedirectToAction("EditPart", new {id}); + } + + private static ContentPartDefinition GeneratePart(EditPartViewModel viewModel) { + return new ContentPartDefinition( + viewModel.Name, + viewModel.Fields.Select( + f => new ContentPartDefinition.Field( + new ContentFieldDefinition(f.FieldDefinition.Name), + f.Name, + f.Settings + ) + ), + viewModel.Settings + ); + } + #endregion #region Content - #endregion - public ActionResult List(ListContentsViewModel model) { const int pageSize = 20; var skip = (Math.Max(model.Page ?? 0, 1) - 1) * pageSize; @@ -328,5 +369,7 @@ namespace Orchard.Core.Contents.Controllers { void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) { ModelState.AddModelError(key, errorMessage.ToString()); } + + #endregion } } diff --git a/src/Orchard.Web/Core/Contents/ViewModels/AddFieldViewModel.cs b/src/Orchard.Web/Core/Contents/ViewModels/AddFieldViewModel.cs new file mode 100644 index 000000000..d623a24ff --- /dev/null +++ b/src/Orchard.Web/Core/Contents/ViewModels/AddFieldViewModel.cs @@ -0,0 +1,12 @@ +using Orchard.ContentManagement.MetaData.Models; +using Orchard.Mvc.ViewModels; + +namespace Orchard.Core.Contents.ViewModels { + public class AddFieldViewModel : BaseViewModel { + public AddFieldViewModel(ContentPartDefinition part) { + Part = part; + } + + public ContentPartDefinition Part { get; private set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Contents/Views/Admin/AddFieldTo.ascx b/src/Orchard.Web/Core/Contents/Views/Admin/AddFieldTo.ascx new file mode 100644 index 000000000..230a73d64 --- /dev/null +++ b/src/Orchard.Web/Core/Contents/Views/Admin/AddFieldTo.ascx @@ -0,0 +1,10 @@ +<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %> +<%@ Import Namespace="Orchard.Core.Contents.ViewModels" %><% +Html.RegisterStyle("admin.css"); %> +

<%:Html.TitleForPage(T("Add a new field to {0}", Model.Part.Name).ToString())%>

<% +using (Html.BeginFormAntiForgeryPost()) { %> + <%:Html.ValidationSummary() %> +
+ +
<% +} %> diff --git a/src/Orchard.Web/Core/Contents/Views/Admin/EditPart.ascx b/src/Orchard.Web/Core/Contents/Views/Admin/EditPart.ascx index 78589bdc0..c3f6642c5 100644 --- a/src/Orchard.Web/Core/Contents/Views/Admin/EditPart.ascx +++ b/src/Orchard.Web/Core/Contents/Views/Admin/EditPart.ascx @@ -1,7 +1,7 @@ <%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %> <%@ Import Namespace="Orchard.Core.Contents.ViewModels" %><% Html.RegisterStyle("admin.css"); %> -

<%:Html.TitleForPage(T("Edit Part").ToString())%>

<% +

<%:Html.TitleForPage(T("Edit Part").ToString()) %>

<% using (Html.BeginFormAntiForgeryPost()) { %> <%:Html.ValidationSummary() %>
@@ -9,9 +9,9 @@ using (Html.BeginFormAntiForgeryPost()) { %> <%--// has unintended consequences (renamging the part) - changing the name creates a new part of that name--%> <%:Html.TextBoxFor(m => m.Name, new {@class = "textMedium"}) %>
- <%:Html.EditorFor(m => m.Settings, "Settings", "")%> + <%:Html.EditorFor(m => m.Settings, "Settings", "") %>

<%:T("Fields") %>

-
<%: Html.ActionLink(T("Add").Text, "AddField", new { }, new { @class = "button" })%>
+
<%: Html.ActionLink(T("Add").Text, "AddFieldTo", new { area = "Contents", id = Model.Name }, new { @class = "button" }) %>
<%:Html.EditorFor(m => m.Fields, "Fields", "") %>
diff --git a/src/Orchard.Web/Core/Contents/Views/Admin/EditType.ascx b/src/Orchard.Web/Core/Contents/Views/Admin/EditType.ascx index 86c390021..79fc9d4e4 100644 --- a/src/Orchard.Web/Core/Contents/Views/Admin/EditType.ascx +++ b/src/Orchard.Web/Core/Contents/Views/Admin/EditType.ascx @@ -1,7 +1,8 @@ <%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %> <%@ Import Namespace="Orchard.Core.Contents.ViewModels" %><% Html.RegisterStyle("admin.css"); %> -

<%:Html.TitleForPage(T("Edit Content Type").ToString())%>

<% +

<%:Html.TitleForPage(T("Edit Content Type").ToString())%>

+<% using (Html.BeginFormAntiForgeryPost()) { %> <%:Html.ValidationSummary() %>
@@ -14,11 +15,11 @@ using (Html.BeginFormAntiForgeryPost()) { %>
<%:Html.EditorFor(m => m.Settings) %>

<%:T("Parts") %>

-
<%: Html.ActionLink(T("Add").Text, "AddPart", new { }, new { @class = "button" })%>
+
<%: Html.ActionLink(T("Add").Text, "AddPart", new { }, new { @class = "button" }) %>
<%:Html.EditorFor(m => m.Parts, "Parts", "") %>

<%:T("Fields") %>

-
<%: Html.ActionLink(T("Add").Text, "AddField", new { }, new { @class = "button" })%>
- <%:Html.EditorFor(m => m.Fields, "Fields", "")%> +
<%: Html.ActionLink(T("Add").Text, "AddFieldTo", new { area = "Contents", id = Model.Name }, new { @class = "button" }) %>
+ <%:Html.EditorFor(m => m.Fields, "Fields", "") %>
<% diff --git a/src/Orchard.Web/Core/Contents/Views/EditorTemplates/Part.ascx b/src/Orchard.Web/Core/Contents/Views/EditorTemplates/Part.ascx index 214c22b7c..e7807302f 100644 --- a/src/Orchard.Web/Core/Contents/Views/EditorTemplates/Part.ascx +++ b/src/Orchard.Web/Core/Contents/Views/EditorTemplates/Part.ascx @@ -11,12 +11,10 @@ <% } %> --%> - <%:Html.EditorFor(m => m.Settings, "Settings", "") %><% - if (Model.PartDefinition.Settings.Any() || Model.PartDefinition.Fields.Any()) { %> + <%:Html.EditorFor(m => m.Settings, "Settings", "") %>

<%:T("Global configuration") %>

<%:Html.ActionLink(T("Edit").Text, "EditPart", new { area = "Contents", id = Model.PartDefinition.Name }) %>
<%:Html.DisplayFor(m => m.PartDefinition.Settings, "Settings", "PartDefinition") %> - <%:Html.EditorFor(m => m.PartDefinition.Fields, "Part.Fields") %><% - } %> + <%:Html.EditorFor(m => m.PartDefinition.Fields, "Part.Fields") %> <%:Html.Hidden("PartDefinition.Name", Model.PartDefinition.Name) %>
\ No newline at end of file diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index 566bc1913..9b37e12af 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -77,6 +77,7 @@ + @@ -208,6 +209,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ScaffoldingCommands.cs b/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ScaffoldingCommands.cs index 92c051d12..127f9590f 100644 --- a/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ScaffoldingCommands.cs +++ b/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ScaffoldingCommands.cs @@ -1,8 +1,101 @@ -using Orchard.Commands; +using System; +using System.IO; +using System.Linq; +using System.Web.Hosting; +using Orchard.Commands; using Orchard.Environment.Extensions; namespace Orchard.DevTools.Commands { [OrchardFeature("Scaffolding")] public class ScaffoldingCommands : DefaultOrchardCommandHandler { + private readonly IExtensionManager _extensionManager; + + public ScaffoldingCommands(IExtensionManager extensionManager) { + _extensionManager = extensionManager; + } + + [OrchardSwitch] + public bool IncludeInSolution { get; set; } + + [CommandHelp("scaffolding create module [/IncludeInSolution:true|false]\r\n\t" + "Create a new Orchard module")] + [CommandName("scaffolding create module")] + [OrchardSwitches("IncludeInSolution")] + public void CreateModule(string moduleName) { + Context.Output.WriteLine(T("Creating Module {0}", moduleName)); + + if (_extensionManager.AvailableExtensions().Any(extension => extension.ExtensionType == "Module" && String.Equals(moduleName, extension.DisplayName, StringComparison.OrdinalIgnoreCase))) { + Context.Output.WriteLine(T("Creating Module {0} failed: a module of the same name already exists", moduleName)); + return; + } + + IntegrateModule(moduleName); + + Context.Output.WriteLine(T("Module {0} created successfully", moduleName)); + } + + + [CommandHelp("scaffolding create controller \r\n\t" + "Create a new Orchard controller in a module")] + [CommandName("scaffolding create controller")] + public void CreateController(string moduleName, string controllerName) { + Context.Output.WriteLine(T("Creating Controller {0} in Module {1}", controllerName, moduleName)); + } + + private void IntegrateModule(string moduleName) { + string rootWebProjectPath = HostingEnvironment.MapPath("~/Orchard.Web.csproj"); + string projectGuid = Guid.NewGuid().ToString().ToUpper(); + + CreateFilesFromTemplates(moduleName, projectGuid); + if (IncludeInSolution) { + // Add project reference to Orchard.Web.csproj + string webProjectReference = string.Format( + "\r\n \r\n {{{1}}}\r\n Orchard.{0}\r\n ", + moduleName, projectGuid); + string webProjectText = File.ReadAllText(rootWebProjectPath); + webProjectText = webProjectText.Insert(webProjectText.LastIndexOf("\r\n"), webProjectReference); + File.WriteAllText(rootWebProjectPath, webProjectText); + + // Add project to Orchard.sln + string solutionPath = Directory.GetParent(rootWebProjectPath).Parent.FullName + "\\Orchard.sln"; + if (File.Exists(solutionPath)) { + string projectReference = string.Format( + "EndProject\r\nProject(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"Orchard.{0}\", \"Orchard.Web\\Modules\\Orchard.{0}\\Orchard.{0}.csproj\", \"{{{1}}}\"\r\n", + moduleName, projectGuid); + string projectConfiguationPlatforms = string.Format( + "GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU\r\n", + projectGuid); + string solutionText = File.ReadAllText(solutionPath); + solutionText = solutionText.Insert(solutionText.LastIndexOf("EndProject\r\n"), projectReference); + solutionText = solutionText.Replace("GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n", projectConfiguationPlatforms); + solutionText = solutionText.Insert(solutionText.LastIndexOf("EndGlobalSection"), "\t{" + projectGuid + "} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}\r\n\t"); + + File.WriteAllText(solutionPath, solutionText); + } + else { + Context.Output.WriteLine(T("Warning: Solution file could not be found at {0}", solutionPath)); + } + } + } + + private static void CreateFilesFromTemplates(string moduleName, string projectGuid) { + string modulePath = HostingEnvironment.MapPath("~/Modules/Orchard." + moduleName + "/"); + string propertiesPath = modulePath + "Properties"; + string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard.DevTools/ScaffoldingTemplates/"); + + Directory.CreateDirectory(modulePath); + Directory.CreateDirectory(propertiesPath); + string templateText = File.ReadAllText(templatesPath + "ModuleAssemblyInfo.txt"); + templateText = templateText.Replace("$$ModuleName$$", moduleName); + templateText = templateText.Replace("$$ModuleTypeLibGuid$$", Guid.NewGuid().ToString()); + File.WriteAllText(propertiesPath + "\\AssemblyInfo.cs", templateText); + File.WriteAllText(modulePath + "\\Web.config", File.ReadAllText(templatesPath + "ModuleWebConfig.txt")); + templateText = File.ReadAllText(templatesPath + "ModuleManifest.txt"); + templateText = templateText.Replace("$$ModuleName$$", moduleName); + File.WriteAllText(modulePath + "\\Module.txt", templateText); + templateText = File.ReadAllText(templatesPath + "\\ModuleCsProj.txt"); + templateText = templateText.Replace("$$ModuleName$$", moduleName); + templateText = templateText.Replace("$$ModuleProjectGuid$$", projectGuid); + File.WriteAllText(modulePath + "\\Orchard." + moduleName + ".csproj", templateText); + } } } +