diff --git a/.hgsubstate b/.hgsubstate
index 9325fa618..3486e5808 100644
--- a/.hgsubstate
+++ b/.hgsubstate
@@ -1,5 +1,5 @@
ec573e5476f7e8a5a61593d6393e9985e9484fcc src/Orchard.Web/Modules/Orchard.Forms
-d4e8bde4741a16cb341311395b211fcf211d2808 src/Orchard.Web/Modules/Orchard.Projections
+0d1100754d594a2977eaab40630f1c46a9e8cf2c src/Orchard.Web/Modules/Orchard.Projections
01b83c05050bb731d9f69256bbe8884d458ea1c9 src/Orchard.Web/Modules/Orchard.Rules
65057c6a5cd71f7994ba9bcbeece50dbb737620e src/Orchard.Web/Modules/Orchard.TaskLease
460f08a0d0befd36a3f7e974d8b782ae3df747e7 src/Orchard.Web/Modules/Orchard.Tokens
diff --git a/src/Orchard.Web/Core/Common/Views/Fields.Common.Text.cshtml b/src/Orchard.Web/Core/Common/Views/Fields.Common.Text.cshtml
index 4cf10f9d6..c0bab8363 100644
--- a/src/Orchard.Web/Core/Common/Views/Fields.Common.Text.cshtml
+++ b/src/Orchard.Web/Core/Common/Views/Fields.Common.Text.cshtml
@@ -1,8 +1,7 @@
-@using Orchard.Utility.Extensions;
-@{
- string name = Model.Name;
+@{
+ string name = Model.Field.DisplayName;
string value = Model.Value;
}
@if (HasText(name) && HasText(value)) {
-
@name.CamelFriendly(): @value
+@name: @value
}
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs
index 80c302e36..7f537098f 100644
--- a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs
+++ b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs
@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
-using System.Text;
using System.Text.RegularExpressions;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Common.Models;
using Orchard.Core.Routable.Events;
using Orchard.Core.Routable.Models;
+using Orchard.Utility.Extensions;
namespace Orchard.Core.Routable.Services {
public class RoutableService : IRoutableService {
@@ -51,20 +50,6 @@ namespace Orchard.Core.Routable.Services {
}
}
- public static string RemoveDiacritics(string slug) {
- string stFormD = slug.Normalize(NormalizationForm.FormD);
- var sb = new StringBuilder();
-
- foreach (char t in stFormD) {
- UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(t);
- if (uc != UnicodeCategory.NonSpacingMark) {
- sb.Append(t);
- }
- }
-
- return (sb.ToString().Normalize(NormalizationForm.FormC));
- }
-
public void FillSlugFromTitle(TModel model) where TModel : IRoutableAspect {
if ((model.Slug != null && !string.IsNullOrEmpty(model.Slug.Trim())) || string.IsNullOrEmpty(model.Title))
return;
@@ -84,7 +69,7 @@ namespace Orchard.Core.Routable.Services {
slugContext.Slug = slugContext.Slug.Substring(0, 1000);
// dots are not allowed at the begin and the end of routes
- slugContext.Slug = RemoveDiacritics(slugContext.Slug.Trim('.').ToLower());
+ slugContext.Slug = StringExtensions.RemoveDiacritics(slugContext.Slug.Trim('.').ToLower());
}
foreach (ISlugEventHandler slugEventHandler in _slugEventHandlers) {
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs
index a6bfaabd9..be8c8e78b 100644
--- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs
+++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs
@@ -10,6 +10,7 @@ using Orchard.Core.Contents.Controllers;
using Orchard.Core.Contents.Settings;
using Orchard.Localization;
using Orchard.UI.Notify;
+using Orchard.Utility.Extensions;
namespace Orchard.ContentTypes.Controllers {
public class AdminController : Controller, IUpdateModel {
@@ -63,7 +64,7 @@ namespace Orchard.ContentTypes.Controllers {
ModelState.AddModelError("Name", T("A type with the same Id already exists.").ToString());
}
- if (!String.IsNullOrWhiteSpace(viewModel.Name) && !ContentDefinitionService.IsLetter(viewModel.Name[0])) {
+ if (!String.IsNullOrWhiteSpace(viewModel.Name) && !viewModel.Name[0].IsLetter()) {
ModelState.AddModelError("Name", T("The technical name must start with a letter.").ToString());
}
@@ -71,10 +72,6 @@ namespace Orchard.ContentTypes.Controllers {
ModelState.AddModelError("DisplayName", T("A type with the same Display Name already exists.").ToString());
}
- if (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.Name, viewModel.Name, StringComparison.OrdinalIgnoreCase))) {
- ModelState.AddModelError("Name", T("A type with the same Name already exists.").ToString());
- }
-
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
return View(viewModel);
@@ -97,6 +94,10 @@ namespace Orchard.ContentTypes.Controllers {
return Json(_contentDefinitionService.GenerateContentTypeNameFromDisplayName(displayName));
}
+ public ActionResult FieldName(string partName, string displayName) {
+ return Json(_contentDefinitionService.GenerateFieldNameFromDisplayName(partName, displayName));
+ }
+
public ActionResult Edit(string id) {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content type.")))
return new HttpUnauthorizedResult();
@@ -147,7 +148,6 @@ namespace Orchard.ContentTypes.Controllers {
return RedirectToAction("List");
}
-
[HttpPost, ActionName("Edit")]
[FormValueRequired("submit.Delete")]
public ActionResult Delete(string id) {
@@ -371,21 +371,21 @@ namespace Orchard.ContentTypes.Controllers {
var viewModel = new AddFieldViewModel {
Part = partViewModel,
- Fields = _contentDefinitionService.GetFields()
+ Fields = _contentDefinitionService.GetFields().OrderBy(x => x.FieldTypeName)
};
return View(viewModel);
}
[HttpPost, ActionName("AddFieldTo")]
- public ActionResult AddFieldToPOST(string id) {
+ public ActionResult AddFieldToPOST(AddFieldViewModel viewModel, string id) {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content part.")))
return new HttpUnauthorizedResult();
var partViewModel = _contentDefinitionService.GetPart(id);
var typeViewModel = _contentDefinitionService.GetType(id);
if (partViewModel == null) {
- //id passed in might be that of a type w/ no implicit field
+ // id passed in might be that of a type w/ no implicit field
if (typeViewModel != null) {
partViewModel = new EditPartViewModel {Name = typeViewModel.Name};
_contentDefinitionService.AddPart(new CreatePartViewModel {Name = partViewModel.Name});
@@ -396,34 +396,137 @@ namespace Orchard.ContentTypes.Controllers {
}
}
- var viewModel = new AddFieldViewModel();
- if (!TryUpdateModel(viewModel)) {
- Services.TransactionManager.Cancel();
- return AddFieldTo(id);
+ viewModel.DisplayName = viewModel.DisplayName ?? String.Empty;
+ viewModel.DisplayName = viewModel.DisplayName.Trim();
+ viewModel.Name = viewModel.Name ?? String.Empty;
+
+ if (String.IsNullOrWhiteSpace(viewModel.DisplayName)) {
+ ModelState.AddModelError("DisplayName", T("The Display Name name can't be empty.").ToString());
}
- try {
- _contentDefinitionService.AddFieldToPart(viewModel.DisplayName, viewModel.FieldTypeName, partViewModel.Name);
+ if (String.IsNullOrWhiteSpace(viewModel.Name)) {
+ ModelState.AddModelError("Name", T("The Technical Name can't be empty.").ToString());
}
- catch (Exception ex) {
- Services.Notifier.Information(T("The \"{0}\" field was not added. {1}", viewModel.DisplayName, ex.Message));
- Services.TransactionManager.Cancel();
- return AddFieldTo(id);
+
+ if (_contentDefinitionService.GetPart(partViewModel.Name).Fields.Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase))) {
+ ModelState.AddModelError("Name", T("A field with the same name already exists.").ToString());
+ }
+
+ if (!String.IsNullOrWhiteSpace(viewModel.Name) && !viewModel.Name[0].IsLetter()) {
+ ModelState.AddModelError("Name", T("The technical name must start with a letter.").ToString());
+ }
+
+ if (!String.Equals(viewModel.Name, viewModel.Name.ToSafeName(), StringComparison.OrdinalIgnoreCase)) {
+ ModelState.AddModelError("Name", T("The technical name contains invalid characters.").ToString());
+ }
+
+ if (_contentDefinitionService.GetPart(partViewModel.Name).Fields.Any(t => String.Equals(t.DisplayName.Trim(), Convert.ToString(viewModel.DisplayName).Trim(), StringComparison.OrdinalIgnoreCase))) {
+ ModelState.AddModelError("DisplayName", T("A field with the same Display Name already exists.").ToString());
}
if (!ModelState.IsValid) {
+ viewModel.Part = partViewModel;
+ viewModel.Fields = _contentDefinitionService.GetFields();
+
+ Services.TransactionManager.Cancel();
+
+ return View(viewModel);
+ }
+
+ try {
+ _contentDefinitionService.AddFieldToPart(viewModel.Name, viewModel.FieldTypeName, partViewModel.Name);
+ }
+ catch (Exception ex) {
+ Services.Notifier.Information(T("The \"{0}\" field was not added. {1}", viewModel.Name, ex.Message));
Services.TransactionManager.Cancel();
return AddFieldTo(id);
}
- Services.Notifier.Information(T("The \"{0}\" field has been added.", viewModel.DisplayName));
+ Services.Notifier.Information(T("The \"{0}\" field has been added.", viewModel.Name));
- if (typeViewModel != null)
- return RedirectToAction("Edit", new { id });
+ if (typeViewModel != null) {
+ return RedirectToAction("Edit", new {id});
+ }
return RedirectToAction("EditPart", new { id });
}
+ public ActionResult EditField(string id, string name) {
+ if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content type.")))
+ return new HttpUnauthorizedResult();
+
+ var partViewModel = _contentDefinitionService.GetPart(id);
+
+ if (partViewModel == null) {
+ return HttpNotFound();
+ }
+
+ var fieldViewModel = partViewModel.Fields.FirstOrDefault(x => x.Name == name);
+
+ if(fieldViewModel == null) {
+ return HttpNotFound();
+ }
+
+ var viewModel = new EditFieldNameViewModel {
+ Name = fieldViewModel.Name,
+ DisplayName = fieldViewModel.DisplayName
+ };
+
+ return View(viewModel);
+ }
+
+ [HttpPost, ActionName("EditField")]
+ [FormValueRequired("submit.Save")]
+ public ActionResult EditFieldPOST(string id, EditFieldNameViewModel viewModel) {
+ if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content type.")))
+ return new HttpUnauthorizedResult();
+
+ if (viewModel == null)
+ return HttpNotFound();
+
+ var partViewModel = _contentDefinitionService.GetPart(id);
+
+ if (partViewModel == null) {
+ return HttpNotFound();
+ }
+
+ // prevent null reference exception in validation
+ viewModel.DisplayName = viewModel.DisplayName ?? String.Empty;
+
+ // remove extra spaces
+ viewModel.DisplayName = viewModel.DisplayName.Trim();
+
+ if (String.IsNullOrWhiteSpace(viewModel.DisplayName)) {
+ ModelState.AddModelError("DisplayName", T("The Display Name name can't be empty.").ToString());
+ }
+
+ if (_contentDefinitionService.GetPart(partViewModel.Name).Fields.Any(t => t.Name != viewModel.Name && String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) {
+ ModelState.AddModelError("DisplayName", T("A field with the same Display Name already exists.").ToString());
+ }
+
+ if (!ModelState.IsValid) {
+ return View(viewModel);
+ }
+
+ var field = _contentDefinitionManager.GetPartDefinition(id).Fields.FirstOrDefault(x => x.Name == viewModel.Name);
+
+ if(field == null) {
+ return HttpNotFound();
+ }
+
+ field.DisplayName = viewModel.DisplayName;
+ _contentDefinitionManager.StorePartDefinition(partViewModel._Definition);
+
+ Services.Notifier.Information(T("Display name changed to {0}.", viewModel.DisplayName));
+
+ // redirect to the type editor if a type exists with this name
+ var typeViewModel = _contentDefinitionService.GetType(id);
+ if (typeViewModel != null) {
+ return RedirectToAction("Edit", new { id });
+ }
+
+ return RedirectToAction("EditPart", new { id });
+ }
public ActionResult RemoveFieldFrom(string id) {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content part.")))
diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj b/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj
index 888bb95cc..d6cb327d5 100644
--- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj
+++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj
@@ -14,6 +14,7 @@
Orchard.ContentTypes
v4.0
false
+ false
true
@@ -57,6 +58,7 @@
+
@@ -115,6 +117,9 @@
+
+
+