Merge branch '1.10.x' into dev

# Conflicts:
#	src/Orchard.Web/Modules/Orchard.ContentTypes/Controllers/AdminController.cs
#	src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj
#	src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/EditPlacement.cshtml
This commit is contained in:
Lombiq
2019-08-28 14:26:54 +02:00
committed by Benedek Farkas
16 changed files with 326 additions and 311 deletions

View File

@@ -33,14 +33,14 @@ namespace Orchard.ContentTypes.Controllers {
IContentDefinitionManager contentDefinitionManager,
IPlacementService placementService,
Lazy<IEnumerable<IShellSettingsManagerEventHandler>> settingsManagerEventHandlers,
ShellSettings settings
) {
ShellSettings settings) {
Services = orchardServices;
_contentDefinitionService = contentDefinitionService;
_contentDefinitionManager = contentDefinitionManager;
_placementService = placementService;
_settingsManagerEventHandlers = settingsManagerEventHandlers;
_settings = settings;
T = NullLocalizer.Instance;
}
@@ -64,7 +64,7 @@ namespace Orchard.ContentTypes.Controllers {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to create a content type.")))
return new HttpUnauthorizedResult();
return View(new CreateTypeViewModel { DisplayName = suggestion, Name = suggestion.ToSafeName() });
return View(new CreateTypeViewModel { DisplayName = suggestion?.Trim(), Name = suggestion?.ToSafeName() });
}
[HttpPost, ActionName("Create")]
@@ -72,37 +72,33 @@ namespace Orchard.ContentTypes.Controllers {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to create a content type.")))
return new HttpUnauthorizedResult();
viewModel.DisplayName = viewModel.DisplayName ?? String.Empty;
viewModel.Name = viewModel.Name ?? String.Empty;
if (String.IsNullOrWhiteSpace(viewModel.DisplayName)) {
ModelState.AddModelError("DisplayName", T("The Display Name name can't be empty.").ToString());
ValidateDisplayName(viewModel.DisplayName);
// Additional Display Name validation.
if (!string.IsNullOrWhiteSpace(viewModel.DisplayName) &&
_contentDefinitionService.GetTypes().Any(t => string.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("DisplayName", T("A content type with this display name already exists.").Text);
}
if (String.IsNullOrWhiteSpace(viewModel.Name)) {
ModelState.AddModelError("Name", T("The Content Type Id can't be empty.").ToString());
}
ValidateTechnicalName(viewModel.Name);
if (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("Name", T("A type with the same Id 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 (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("DisplayName", T("A type with the same Display Name already exists.").ToString());
// Additional Technical Name validation.
if (!string.IsNullOrWhiteSpace(viewModel.Name) &&
_contentDefinitionService.GetTypes().Any(t => string.Equals(t.Name.ToSafeName(), viewModel.Name.ToSafeName(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("Name", T("A content type with this technical name already exists.").Text);
}
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
return View(viewModel);
}
var contentTypeDefinition = _contentDefinitionService.AddType(viewModel.Name, viewModel.DisplayName);
// adds CommonPart by default
// CommonPart is added by default to all Content Types.
_contentDefinitionService.AddPartToType("CommonPart", viewModel.Name);
var typeViewModel = new EditTypeViewModel(contentTypeDefinition);
@@ -116,14 +112,14 @@ namespace Orchard.ContentTypes.Controllers {
public ActionResult ContentTypeName(string displayName, int version) {
return Json(new {
result = _contentDefinitionService.GenerateContentTypeNameFromDisplayName(displayName),
version = version
version
});
}
public ActionResult FieldName(string partName, string displayName, int version) {
return Json(new {
result = _contentDefinitionService.GenerateFieldNameFromDisplayName(partName, displayName),
version = version
version
});
}
@@ -133,8 +129,7 @@ namespace Orchard.ContentTypes.Controllers {
var typeViewModel = _contentDefinitionService.GetType(id);
if (typeViewModel == null)
return HttpNotFound();
if (typeViewModel == null) return HttpNotFound();
return View(typeViewModel);
}
@@ -145,8 +140,7 @@ namespace Orchard.ContentTypes.Controllers {
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(id);
if (contentTypeDefinition == null)
return HttpNotFound();
if (contentTypeDefinition == null) return HttpNotFound();
var grouped = _placementService.GetEditorPlacement(id)
.OrderBy(x => x.PlacementInfo.GetPosition(), new FlatPositionComparer())
@@ -177,22 +171,22 @@ namespace Orchard.ContentTypes.Controllers {
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(id);
if (contentTypeDefinition == null)
return HttpNotFound();
if (contentTypeDefinition == null) return HttpNotFound();
contentTypeDefinition.ResetPlacement(PlacementType.Editor);
foreach (var placement in viewModel.AllPlacements) {
var placementSetting = placement.PlacementSettings;
contentTypeDefinition.Placement(PlacementType.Editor,
placementSetting.ShapeType,
placementSetting.Differentiator,
placementSetting.Zone,
placementSetting.Position);
contentTypeDefinition.Placement(
PlacementType.Editor,
placementSetting.ShapeType,
placementSetting.Differentiator,
placementSetting.Zone,
placementSetting.Position);
}
// persist changes
// Persist placement changes.
_contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition);
_settingsManagerEventHandlers.Value.Invoke(x => x.Saved(_settings), Logger);
@@ -208,12 +202,11 @@ namespace Orchard.ContentTypes.Controllers {
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(id);
if (contentTypeDefinition == null)
return HttpNotFound();
if (contentTypeDefinition == null) return HttpNotFound();
contentTypeDefinition.ResetPlacement(PlacementType.Editor);
// persist changes
// Persist placement reset.
_contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition);
_settingsManagerEventHandlers.Value.Invoke(x => x.Saved(_settings), Logger);
@@ -229,28 +222,33 @@ namespace Orchard.ContentTypes.Controllers {
var typeViewModel = _contentDefinitionService.GetType(id);
if (typeViewModel == null)
return HttpNotFound();
if (typeViewModel == null) return HttpNotFound();
var edited = new EditTypeViewModel();
TryUpdateModel(edited);
typeViewModel.DisplayName = edited.DisplayName ?? string.Empty;
if (String.IsNullOrWhiteSpace(typeViewModel.DisplayName)) {
ModelState.AddModelError("DisplayName", T("The Content Type name can't be empty.").ToString());
ValidateDisplayName(edited.DisplayName);
// Additional Display Name validation.
if (!string.IsNullOrWhiteSpace(edited.DisplayName) &&
_contentDefinitionService.GetTypes().Any(t =>
!string.Equals(t.Name, edited.Name, StringComparison.OrdinalIgnoreCase) &&
string.Equals(t.DisplayName.Trim(), edited.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("DisplayName", T("A content type with this display name already exists.").Text);
}
if (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), typeViewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase) && !String.Equals(t.Name, id))) {
ModelState.AddModelError("DisplayName", T("A type with the same name already exists.").ToString());
}
if (!ModelState.IsValid) return View(typeViewModel);
if (!ModelState.IsValid)
return View(typeViewModel);
typeViewModel.DisplayName = edited.DisplayName;
_contentDefinitionService.AlterType(typeViewModel, this);
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
return View(typeViewModel);
}
@@ -267,8 +265,7 @@ namespace Orchard.ContentTypes.Controllers {
var typeViewModel = _contentDefinitionService.GetType(id);
if (typeViewModel == null)
return HttpNotFound();
if (typeViewModel == null) return HttpNotFound();
_contentDefinitionService.RemoveType(id, true);
@@ -283,14 +280,13 @@ namespace Orchard.ContentTypes.Controllers {
var typeViewModel = _contentDefinitionService.GetType(id);
if (typeViewModel == null)
return HttpNotFound();
if (typeViewModel == null) return HttpNotFound();
var typePartNames = new HashSet<string>(typeViewModel.Parts.Select(tvm => tvm.PartDefinition.Name));
var viewModel = new AddPartsViewModel {
Type = typeViewModel,
PartSelections = _contentDefinitionService.GetParts(false/*metadataPartsOnly*/)
PartSelections = _contentDefinitionService.GetParts(metadataPartsOnly: false)
.Where(cpd => !typePartNames.Contains(cpd.Name) && cpd.Settings.GetModel<ContentPartSettings>().Attachable)
.Select(cpd => new PartSelectionViewModel { PartName = cpd.Name, PartDisplayName = cpd.DisplayName, PartDescription = cpd.Description })
.ToList()
@@ -306,21 +302,22 @@ namespace Orchard.ContentTypes.Controllers {
var typeViewModel = _contentDefinitionService.GetType(id);
if (typeViewModel == null)
return HttpNotFound();
if (typeViewModel == null) return HttpNotFound();
var viewModel = new AddPartsViewModel();
if (!TryUpdateModel(viewModel))
return AddPartsTo(id);
if (!TryUpdateModel(viewModel)) return AddPartsTo(id);
var partsToAdd = viewModel.PartSelections.Where(ps => ps.IsSelected).Select(ps => ps.PartName);
foreach (var partToAdd in partsToAdd) {
_contentDefinitionService.AddPartToType(partToAdd, typeViewModel.Name);
Services.Notifier.Success(T("The \"{0}\" part has been added.", partToAdd));
}
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
return AddPartsTo(id);
}
@@ -334,12 +331,12 @@ namespace Orchard.ContentTypes.Controllers {
var typeViewModel = _contentDefinitionService.GetType(id);
var viewModel = new RemovePartViewModel();
if (typeViewModel == null
|| !TryUpdateModel(viewModel)
|| !typeViewModel.Parts.Any(p => p.PartDefinition.Name == viewModel.Name))
if (typeViewModel == null || !TryUpdateModel(viewModel) ||
!typeViewModel.Parts.Any(p => p.PartDefinition.Name == viewModel.Name))
return HttpNotFound();
viewModel.Type = typeViewModel;
return View(viewModel);
}
@@ -351,9 +348,8 @@ namespace Orchard.ContentTypes.Controllers {
var typeViewModel = _contentDefinitionService.GetType(id);
var viewModel = new RemovePartViewModel();
if (typeViewModel == null
|| !TryUpdateModel(viewModel)
|| !typeViewModel.Parts.Any(p => p.PartDefinition.Name == viewModel.Name))
if (typeViewModel == null || !TryUpdateModel(viewModel) ||
!typeViewModel.Parts.Any(p => p.PartDefinition.Name == viewModel.Name))
return HttpNotFound();
_contentDefinitionService.RemovePartFromType(viewModel.Name, typeViewModel.Name);
@@ -361,6 +357,7 @@ namespace Orchard.ContentTypes.Controllers {
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
viewModel.Type = typeViewModel;
return View(viewModel);
}
@@ -376,7 +373,7 @@ namespace Orchard.ContentTypes.Controllers {
public ActionResult ListParts() {
return View(new ListContentPartsViewModel {
// only user-defined parts (not code as they are not configurable)
Parts = _contentDefinitionService.GetParts(true/*metadataPartsOnly*/)
Parts = _contentDefinitionService.GetParts(metadataPartsOnly: true)
});
}
@@ -384,7 +381,7 @@ namespace Orchard.ContentTypes.Controllers {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to create a content part.")))
return new HttpUnauthorizedResult();
return View(new CreatePartViewModel { Name = suggestion.ToSafeName() });
return View(new CreatePartViewModel { Name = suggestion?.ToSafeName() });
}
[HttpPost, ActionName("CreatePart")]
@@ -392,20 +389,28 @@ namespace Orchard.ContentTypes.Controllers {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to create a content part.")))
return new HttpUnauthorizedResult();
if (_contentDefinitionManager.GetPartDefinition(viewModel.Name) != null)
ModelState.AddModelError("Name", T("Cannot add part named '{0}'. It already exists.", viewModel.Name).ToString());
if (!ModelState.IsValid)
return View(viewModel);
ValidateTechnicalName(viewModel.Name);
// Additional Technical Name validation.
if (!string.IsNullOrWhiteSpace(viewModel.Name) &&
_contentDefinitionManager.ListPartDefinitions().Any(t => string.Equals(t.Name.ToSafeName(), viewModel.Name.ToSafeName(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("Name", T("A content part with this technical name already exists.").Text);
}
if (!ModelState.IsValid) return View(viewModel);
var partViewModel = _contentDefinitionService.AddPart(viewModel);
if (partViewModel == null) {
Services.Notifier.Error(T("The content part could not be created."));
return View(viewModel);
}
Services.Notifier.Success(T("The \"{0}\" content part has been created.", partViewModel.Name));
return RedirectToAction("EditPart", new { id = partViewModel.Name });
}
@@ -415,8 +420,7 @@ namespace Orchard.ContentTypes.Controllers {
var partViewModel = _contentDefinitionService.GetPart(id);
if (partViewModel == null)
return HttpNotFound();
if (partViewModel == null) return HttpNotFound();
return View(partViewModel);
}
@@ -429,16 +433,15 @@ namespace Orchard.ContentTypes.Controllers {
var partViewModel = _contentDefinitionService.GetPart(id);
if (partViewModel == null)
return HttpNotFound();
if (partViewModel == null) return HttpNotFound();
if (!TryUpdateModel(partViewModel))
return View(partViewModel);
if (!TryUpdateModel(partViewModel)) return View(partViewModel);
_contentDefinitionService.AlterPart(partViewModel, this);
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
return View(partViewModel);
}
@@ -455,8 +458,7 @@ namespace Orchard.ContentTypes.Controllers {
var partViewModel = _contentDefinitionService.GetPart(id);
if (partViewModel == null)
return HttpNotFound();
if (partViewModel == null) return HttpNotFound();
_contentDefinitionService.RemovePart(id);
@@ -471,13 +473,13 @@ namespace Orchard.ContentTypes.Controllers {
var partViewModel = _contentDefinitionService.GetPart(id);
// If the specified Part doesn't exist, try to find a matching Type,
// where the implicit Part with the same name can be created to store Fields.
if (partViewModel == null) {
//id passed in might be that of a type w/ no implicit field
var typeViewModel = _contentDefinitionService.GetType(id);
if (typeViewModel != null)
partViewModel = new EditPartViewModel(new ContentPartDefinition(id));
else
return HttpNotFound();
if (typeViewModel == null) return HttpNotFound();
else partViewModel = new EditPartViewModel(new ContentPartDefinition(id));
}
var viewModel = new AddFieldViewModel {
@@ -495,48 +497,28 @@ namespace Orchard.ContentTypes.Controllers {
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
if (typeViewModel != null) {
partViewModel = new EditPartViewModel { Name = typeViewModel.Name };
_contentDefinitionService.AddPart(new CreatePartViewModel { Name = partViewModel.Name });
_contentDefinitionService.AddPartToType(partViewModel.Name, typeViewModel.Name);
}
else {
return HttpNotFound();
}
if (partViewModel == null && typeViewModel == null) return HttpNotFound();
ValidateDisplayName(viewModel.DisplayName);
// Additional Display Name validation.
if (partViewModel != null && !string.IsNullOrWhiteSpace(viewModel.DisplayName) &&
partViewModel.Fields.Any(t => string.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("DisplayName", T("A content field with this display name already exists.").Text);
}
viewModel.DisplayName = viewModel.DisplayName ?? String.Empty;
viewModel.DisplayName = viewModel.DisplayName.Trim();
viewModel.Name = viewModel.Name ?? String.Empty;
ValidateTechnicalName(viewModel.Name);
if (String.IsNullOrWhiteSpace(viewModel.DisplayName)) {
ModelState.AddModelError("DisplayName", T("The Display Name name can't be empty.").ToString());
}
if (String.IsNullOrWhiteSpace(viewModel.Name)) {
ModelState.AddModelError("Name", T("The Technical Name can't be empty.").ToString());
}
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());
// Additional Technical Name validation.
if (partViewModel != null && !string.IsNullOrWhiteSpace(viewModel.Name) &&
partViewModel.Fields.Any(t => string.Equals(t.Name.ToSafeName(), viewModel.Name.ToSafeName(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("Name", T("A content field with this technical name already exists.").Text);
}
if (!ModelState.IsValid) {
viewModel.Part = partViewModel;
viewModel.Part = partViewModel ?? new EditPartViewModel { Name = typeViewModel.Name };
viewModel.Fields = _contentDefinitionService.GetFields();
Services.TransactionManager.Cancel();
@@ -544,22 +526,28 @@ namespace Orchard.ContentTypes.Controllers {
return View(viewModel);
}
// If the specified Part doesn't exist, create an implicit ,
// where the implicit Part with the same name can be created to store Fields.
if (partViewModel == null) {
partViewModel = _contentDefinitionService.AddPart(new CreatePartViewModel { Name = typeViewModel.Name });
_contentDefinitionService.AddPartToType(partViewModel.Name, typeViewModel.Name);
}
try {
_contentDefinitionService.AddFieldToPart(viewModel.Name, viewModel.DisplayName, viewModel.FieldTypeName, partViewModel.Name);
}
catch (Exception ex) {
Services.Notifier.Error(T("The \"{0}\" field was not added. {1}", viewModel.DisplayName, ex.Message));
Services.TransactionManager.Cancel();
return AddFieldTo(id);
}
Services.Notifier.Success(T("The \"{0}\" field has been added.", viewModel.DisplayName));
if (typeViewModel != null) {
return RedirectToAction("Edit", new { id });
}
return RedirectToAction("EditPart", new { id });
return typeViewModel == null ? RedirectToAction("EditPart", new { id }) : RedirectToAction("Edit", new { id });
}
public ActionResult EditField(string id, string name) {
@@ -568,15 +556,11 @@ namespace Orchard.ContentTypes.Controllers {
var partViewModel = _contentDefinitionService.GetPart(id);
if (partViewModel == null) {
return HttpNotFound();
}
if (partViewModel == null) return HttpNotFound();
var fieldViewModel = partViewModel.Fields.FirstOrDefault(x => x.Name == name);
if (fieldViewModel == null) {
return HttpNotFound();
}
if (fieldViewModel == null) return HttpNotFound();
var viewModel = new EditFieldNameViewModel {
Name = fieldViewModel.Name,
@@ -592,50 +576,37 @@ namespace Orchard.ContentTypes.Controllers {
if (!Services.Authorizer.Authorize(Permissions.EditContentTypes, T("Not allowed to edit a content type.")))
return new HttpUnauthorizedResult();
if (viewModel == null)
return HttpNotFound();
if (viewModel == null) return HttpNotFound();
var partViewModel = _contentDefinitionService.GetPart(id);
if (partViewModel == null) {
return HttpNotFound();
if (partViewModel == null) return HttpNotFound();
ValidateDisplayName(viewModel.Name);
// Additional Display Name validation.
if (!string.IsNullOrWhiteSpace(viewModel.DisplayName) &&
partViewModel.Fields.Any(f =>
!string.Equals(f.Name, viewModel.Name, StringComparison.OrdinalIgnoreCase) &&
string.Equals(f.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) {
ModelState.AddModelError("DisplayName", T("A content field with this display name already exists on this content part.").Text);
}
// prevent null reference exception in validation
viewModel.DisplayName = viewModel.DisplayName ?? String.Empty;
if (!ModelState.IsValid) return View(viewModel);
// 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();
}
if (field == null) return HttpNotFound();
_contentDefinitionService.AlterField(partViewModel, viewModel);
Services.Notifier.Success(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 });
// Redirect to the type editor if a type exists with this name.
return _contentDefinitionService.GetType(id) == null ?
RedirectToAction("EditPart", new { id }) : RedirectToAction("Edit", new { id });
}
public ActionResult RemoveFieldFrom(string id) {
@@ -645,12 +616,13 @@ namespace Orchard.ContentTypes.Controllers {
var partViewModel = _contentDefinitionService.GetPart(id);
var viewModel = new RemoveFieldViewModel();
if (partViewModel == null
|| !TryUpdateModel(viewModel)
|| !partViewModel.Fields.Any(p => p.Name == viewModel.Name))
if (partViewModel == null || !TryUpdateModel(viewModel) ||
!partViewModel.Fields.Any(p => p.Name == viewModel.Name))
return HttpNotFound();
viewModel.Part = partViewModel;
return View(viewModel);
}
@@ -662,9 +634,8 @@ namespace Orchard.ContentTypes.Controllers {
var partViewModel = _contentDefinitionService.GetPart(id);
var viewModel = new RemoveFieldViewModel();
if (partViewModel == null
|| !TryUpdateModel(viewModel)
|| !partViewModel.Fields.Any(p => p.Name == viewModel.Name))
if (partViewModel == null || !TryUpdateModel(viewModel) ||
!partViewModel.Fields.Any(p => p.Name == viewModel.Name))
return HttpNotFound();
_contentDefinitionService.RemoveFieldFromPart(viewModel.Name, partViewModel.Name);
@@ -672,21 +643,49 @@ namespace Orchard.ContentTypes.Controllers {
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
viewModel.Part = partViewModel;
return View(viewModel);
}
Services.Notifier.Success(T("The \"{0}\" field has been removed.", viewModel.Name));
if (_contentDefinitionService.GetType(id) != null)
return RedirectToAction("Edit", new { id });
return RedirectToAction("EditPart", new { id });
// Redirect to the type editor if a type exists with this name.
return _contentDefinitionService.GetType(id) == null ?
RedirectToAction("EditPart", new { id }) : RedirectToAction("Edit", new { id });
}
#endregion
private void ValidateDisplayName(string displayName) {
if (string.IsNullOrWhiteSpace(displayName)) {
ModelState.AddModelError("DisplayName", T("The display name name can't be empty.").Text);
}
else if (!string.Equals(displayName, displayName.Trim(), StringComparison.OrdinalIgnoreCase)) {
ModelState.AddModelError("DisplayName", T("The display name starts and/or ends with whitespace characters.").Text);
}
}
private void ValidateTechnicalName(string technicalName) {
if (string.IsNullOrWhiteSpace(technicalName)) {
ModelState.AddModelError("Name", T("The technical name (Id) can't be empty.").Text);
}
else {
var safeTechnicalName = technicalName.ToSafeName();
if (!string.Equals(technicalName, safeTechnicalName, StringComparison.OrdinalIgnoreCase)) {
ModelState.AddModelError("Name", T("The technical name contains invalid (non-alphanumeric) characters.").Text);
}
if (!safeTechnicalName.FirstOrDefault().IsLetter()) {
ModelState.AddModelError("Name", T("The technical name must start with a letter.").Text);
}
}
}
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
return base.TryUpdateModel(model, prefix, includeProperties, excludeProperties);
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
}
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {

View File

@@ -148,7 +148,6 @@
<Compile Include="ViewModels\RemovePartViewModel.cs" />
<Compile Include="ViewModels\CreateTypeViewModel.cs" />
<Compile Include="ViewModels\EditTypeViewModel.cs" />
<Compile Include="ViewModels\ListContentsViewModel.cs" />
<Compile Include="ViewModels\ListContentTypesViewModel.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,16 +0,0 @@
//using System.Collections.Generic;
//using Orchard.ContentManagement;
//namespace Orchard.ContentTypes.ViewModels {
// public class ListContentsViewModel {
// public string Id { get; set; }
// public int? Page { get; set; }
// public IList<Entry> Entries { get; set; }
// public class Entry {
// public ContentItem ContentItem { get; set; }
// public ContentItemMetadata ContentItemMetadata { get; set; }
// public ContentItemViewModel ViewModel { get; set; }
// }
// }
//}

View File

@@ -1,9 +1,11 @@
@using Orchard.Utility.Extensions
@model Orchard.ContentTypes.ViewModels.AddFieldViewModel
@{
Style.Require("ContentTypesAdmin");
Layout.Title = T("Add New Field To \"{0}\"", Model.Part.DisplayName).ToString();
Layout.Title = T("Add New Field To \"{0}\"", Html.Raw(Model.Part.DisplayName)).Text;
var returnUrl = Request.QueryString["returnUrl"];
}
@@ -31,48 +33,48 @@
}
@using(Script.Foot()){
<script type="text/javascript">
//<![CDATA[
$(function(){
var $name = $("#@Html.FieldIdFor(m=>m.Name)");
var $displayName = $("#@Html.FieldIdFor(m=>m.DisplayName)");
var partName = "@Model.Part.Name";
<script type="text/javascript">
//<![CDATA[
$(function(){
var $name = $("#@Html.FieldIdFor(m=>m.Name)");
var $displayName = $("#@Html.FieldIdFor(m=>m.DisplayName)");
var partName = "@Model.Part.Name";
var jsonUrl = "@Url.Action("FieldName", "Admin", new RouteValueDictionary { {"Area","Orchard.ContentTypes"} } )";
var version = 0;
var jsonUrl = "@Url.Action("FieldName", "Admin", new RouteValueDictionary { {"Area","Orchard.ContentTypes"} } )";
var version = 0;
var nameAltered;
$name.keypress(function() {
nameAltered = true;
});
var nameAltered;
$name.keypress(function() {
nameAltered = true;
});
var compute = function() {
// stop processing automatically if altered by the user
if(nameAltered) {
return true;
}
var compute = function() {
// stop processing automatically if altered by the user
if(nameAltered) {
return true;
}
$.post(jsonUrl, {
partName: partName,
displayName: $displayName.val(),
version: ++version,
__RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
},
function(data) {
if(version == data.version) {
$name.val(data.result);
}
},
"json"
);
};
$.post(jsonUrl, {
partName: partName,
displayName: $displayName.val(),
version: ++version,
__RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
},
function(data) {
if(version == data.version) {
$name.val(data.result);
}
},
"json"
);
};
//pull technical name input from tab order
$name.attr("tabindex", -1);
//pull technical name input from tab order
$name.attr("tabindex", -1);
$displayName.keyup(compute);
$displayName.blur(compute);
})
//]]>
</script>
$displayName.keyup(compute);
$displayName.blur(compute);
})
//]]>
</script>
}

View File

@@ -1,9 +1,12 @@
@model Orchard.ContentTypes.ViewModels.AddPartsViewModel
@{
Style.Require("ContentTypesAdmin");
Layout.Title = T("Add Parts To \"{0}\"", Model.Type.DisplayName).ToString();
Layout.Title = T("Add Parts To \"{0}\"", Html.Raw(Model.Type.DisplayName)).Text;
}
@T("Choose the Parts to add to this Content Type.")
@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
<fieldset>

View File

@@ -1,6 +1,8 @@
@model Orchard.ContentTypes.ViewModels.CreateTypeViewModel
@{ Layout.Title = T("New Content Type").ToString(); }
@{
Layout.Title = T("New Content Type").Text;
}
@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
@@ -14,48 +16,49 @@
</fieldset>
<fieldset>
<button class="primaryAction" type="submit">@T("Create")</button>
</fieldset>}
</fieldset>
}
@using(Script.Foot()){
<script type="text/javascript">
//<![CDATA[
$(function(){
var $name = $("#@Html.FieldIdFor(m=>m.Name)");
var $displayName = $("#@Html.FieldIdFor(m=>m.DisplayName)");
var jsonUrl = "@Url.Action("ContentTypeName", "Admin", new RouteValueDictionary { {"Area","Orchard.ContentTypes"} } )";
var version = 0;
<script type="text/javascript">
//<![CDATA[
$(function(){
var $name = $("#@Html.FieldIdFor(m=>m.Name)");
var $displayName = $("#@Html.FieldIdFor(m=>m.DisplayName)");
var jsonUrl = "@Url.Action("ContentTypeName", "Admin", new RouteValueDictionary { {"Area","Orchard.ContentTypes"} } )";
var version = 0;
var nameAltered;
$name.keypress(function() {
nameAltered = true;
});
var nameAltered;
$name.keypress(function() {
nameAltered = true;
});
var compute = function() {
// stop processing automatically if altered by the user
if(nameAltered) {
return true;
}
var compute = function() {
// stop processing automatically if altered by the user
if(nameAltered) {
return true;
}
$.post(jsonUrl, {
displayName: $displayName.val(),
version: ++version,
__RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
},
function(data) {
if(version == data.version) {
$name.val(data.result);
}
},
"json"
);
};
$.post(jsonUrl, {
displayName: $displayName.val(),
version: ++version,
__RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
},
function(data) {
if(version == data.version) {
$name.val(data.result);
}
},
"json"
);
};
//pull technical name input from tab order
$name.attr("tabindex", -1);
//pull technical name input from tab order
$name.attr("tabindex", -1);
$displayName.keyup(compute);
$displayName.blur(compute);
})
//]]>
</script>
$displayName.keyup(compute);
$displayName.blur(compute);
})
//]]>
</script>
}

View File

@@ -1,6 +1,8 @@
@model Orchard.ContentTypes.ViewModels.CreatePartViewModel
@{ Layout.Title = T("New Content Part").ToString(); }
@{
Layout.Title = T("New Content Part").Text;
}
@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
@@ -11,4 +13,5 @@
</fieldset>
<fieldset>
<button class="primaryAction" type="submit">@T("Create")</button>
</fieldset>}
</fieldset>
}

View File

@@ -1,5 +1,5 @@
@using Orchard.Utility.Extensions;
@model Orchard.ContentTypes.ViewModels.EditTypeViewModel
@{
Style.Require("ContentTypesAdmin");
Script.Require("jQuery");
@@ -45,13 +45,13 @@
</div>
}
@using(Script.Foot()){
<script type="text/javascript">
//<![CDATA[
(function ($) {
$(".manage-field h3,.manage-part h3").expandoControl(function (controller) { return controller.nextAll(".details"); }, { collapse: true, remember: false });
$(".manage-field h4").expandoControl(function (controller) { return controller.nextAll(".settings"); }, { collapse: true, remember: false });
})(jQuery);
//]]>
</script>
@using(Script.Foot()) {
<script type="text/javascript">
//<![CDATA[
(function ($) {
$(".manage-field h3,.manage-part h3").expandoControl(function (controller) { return controller.nextAll(".details"); }, { collapse: true, remember: false });
$(".manage-field h4").expandoControl(function (controller) { return controller.nextAll(".settings"); }, { collapse: true, remember: false });
})(jQuery);
//]]>
</script>
}

View File

@@ -1,9 +1,11 @@
@using Orchard.Utility.Extensions
@model Orchard.ContentTypes.ViewModels.EditFieldNameViewModel
@{
Style.Require("ContentTypesAdmin");
Layout.Title = T("Edit Field \"{0}\"", Html.Raw(Model.DisplayName)).ToString();
Layout.Title = T("Edit Content Field - {0}", Html.Raw(Model.DisplayName)).Text;
var returnUrl = Request.QueryString["returnUrl"];
}

View File

@@ -1,8 +1,9 @@
@model Orchard.ContentTypes.ViewModels.EditPartViewModel
@{
Style.Require("ContentTypesAdmin");
Script.Require("jQuery");
Layout.Title = T("Edit Part").ToString();
Layout.Title = T("Edit Content Part - {0}", Html.Raw(Model.DisplayName)).Text;
}
@using (Html.BeginFormAntiForgeryPost()) {
@@ -28,12 +29,12 @@
}
@using(Script.Foot()){
<script type="text/javascript">
//<![CDATA[
(function ($) {
$(".manage-field h3,.manage-part h3").expandoControl(function (controller) { return controller.nextAll(".details"); }, { collapse: true, remember: false });
$(".manage-field h4").expandoControl(function (controller) { return controller.nextAll(".settings"); }, { collapse: true, remember: false });
})(jQuery);
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
(function ($) {
$(".manage-field h3,.manage-part h3").expandoControl(function (controller) { return controller.nextAll(".details"); }, { collapse: true, remember: false });
$(".manage-field h4").expandoControl(function (controller) { return controller.nextAll(".settings"); }, { collapse: true, remember: false });
})(jQuery);
//]]>
</script>
}

View File

@@ -1,5 +1,7 @@
@using Orchard.ContentTypes.Services
@model Orchard.ContentTypes.ViewModels.EditPlacementViewModel
@{
Style.Require("ContentTypesAdmin");
Script.Require("PlacementEditor").AtFoot();
@@ -8,16 +10,19 @@
int i = 0;
}
@helper RenderPlacement(DriverResultPlacement p, int i) {
var placement = p.PlacementSettings;
@helper RenderPlacement(DriverResultPlacement p, int i)
{
var placement = p.PlacementSettings;
<li class="place" data-shape-type="@placement.ShapeType" data-shape-differentiator="@placement.Differentiator" data-shape-zone="Content" data-shape-position="@placement.Position">
<span class="toggle">Show Editor Shape</span>
<div class="shape-type"><h3>@placement.ShapeType @placement.Differentiator</h3></div>
<div class="shape-editor">
@try {
@try
{
@Display(p.Shape)
}
catch {
catch
{
}
</div>
@Html.HiddenFor(m => m.AllPlacements[i].PlacementSettings.ShapeType, new { @class = "type" })
@@ -29,13 +34,15 @@ var placement = p.PlacementSettings;
<div id="save-message" class="message message-Warning">@T("You need to hit \"Save\" in order to save your changes.")</div>
@using (Html.BeginFormAntiForgeryPost()) {
@using (Html.BeginFormAntiForgeryPost())
{
@Html.ValidationSummary()
<div id="placement">
<div data-tab="" class="zone-container" id="content-tab">
<h2>Content</h2>
<ul class="tabdrag">
@foreach (var p in Model.Content) {
@foreach (var p in Model.Content)
{
@RenderPlacement(p, i);
i++;
}
@@ -43,12 +50,14 @@ var placement = p.PlacementSettings;
</div>
<div id="sortableTabs">
@foreach (var tab in Model.Tabs) {
@foreach (var tab in Model.Tabs)
{
<div data-tab="@tab.Key" class="zone-container tab-container">
<a class="delete">Delete</a>
<h2>@tab.Key</h2>
<ul class="tabdrag">
@foreach (var p in tab.Value) {
@foreach (var p in tab.Value)
{
@RenderPlacement(p, i);
i++;
}
@@ -67,5 +76,4 @@ var placement = p.PlacementSettings;
<button class="primaryAction" type="submit" name="submit.Save" value="Save">@T("Save")</button>
<button class="primaryAction" type="submit" name="submit.Restore" value="Restore" itemprop="RemoveUrl" data-message="@T("Are you sure you want to restore these placements?")">@T("Restore")</button>
</fieldset>
}

View File

@@ -1,22 +1,25 @@
@model Orchard.ContentTypes.ViewModels.ListContentTypesViewModel
@{
Style.Require("ContentTypesAdmin");
Script.Require("jQuery");
Script.Include("admin-contenttypes.js");
Layout.Title = T("Manage Content Types").ToString();
Layout.Title = T("Manage Content Types").Text;
}
<div class="manage">
@Html.ActionLink(T("Create new type").ToString(), "Create", new{Controller="Admin",Area="Orchard.ContentTypes"}, new { @class = "button primaryAction" })
@Html.ActionLink(T("Create new type").Text, "Create", new { Controller = "Admin", Area = "Orchard.ContentTypes" }, new { @class = "button primaryAction" })
</div>
<fieldset class="bulk-actions">
<label for="search-box">@T("Filter:")</label>
<input id="search-box" class="text" type="text" autofocus="autofocus" />
</fieldset>
<ul class="contentItems">
@foreach (var type in Model.Types) {
<li data-record-text="@type.DisplayName">
@Html.DisplayFor(m => type)
</li>
<li data-record-text="@type.DisplayName">
@Html.DisplayFor(m => type)
</li>
}
</ul>

View File

@@ -1,20 +1,25 @@
@model Orchard.ContentTypes.ViewModels.ListContentPartsViewModel
@{
Script.Require("jQuery");
Script.Include("admin-contenttypes.js");
Layout.Title = T("Content Parts").ToString();
Layout.Title = T("Content Parts").Text;
}
<div class="manage">
@Html.ActionLink(T("Create new part").ToString(), "CreatePart", new{Controller="Admin",Area="Orchard.ContentTypes"}, new { @class = "button primaryAction" })
@Html.ActionLink(T("Create new part").Text, "CreatePart", new { Controller = "Admin", Area = "Orchard.ContentTypes" }, new { @class = "button primaryAction" })
</div>
<fieldset class="bulk-actions">
<label for="search-box">@T("Filter:")</label>
<input id="search-box" class="text" type="text" autofocus="autofocus" />
</fieldset>
<ul class="contentItems">
@foreach (var type in Model.Parts) {
<li data-record-text="@type.DisplayName">
@Html.DisplayFor(m => type)
</li>
<li data-record-text="@type.DisplayName">
@Html.DisplayFor(m => type)
</li>
}
</ul>

View File

@@ -1,7 +1,8 @@
@model Orchard.ContentTypes.ViewModels.RemoveFieldViewModel
@{
Style.Require("ContentTypesAdmin");
Layout.Title = T("Remove the \"{0}\" part from \"{1}\"", Model.Name, Model.Part.DisplayName).ToString();
Layout.Title = T("Remove the \"{0}\" Content Field from \"{1}\"", Model.Name, Html.Raw(Model.Part.DisplayName)).Text;
}
@using (Html.BeginFormAntiForgeryPost()) {

View File

@@ -1,7 +1,8 @@
@model Orchard.ContentTypes.ViewModels.RemovePartViewModel
@{
Style.Require("ContentTypesAdmin");
Layout.Title = T("Remove the \"{0}\" part from \"{1}\"", Model.Name, Model.Type.DisplayName).ToString();
Layout.Title = T("Remove the \"{0}\" Content Part from \"{1}\"", Model.Name, Html.Raw(Model.Type.DisplayName)).Text;
}
@using (Html.BeginFormAntiForgeryPost()) {

View File

@@ -211,9 +211,10 @@ namespace Orchard.Users.Controllers {
siteUrl = HttpContext.Request.ToRootUrlString();
}
_userService.SendLostPasswordEmail(username, nonce => Url.MakeAbsolute(Url.Action("LostPassword", "Account", new { Area = "Orchard.Users", nonce = nonce }), siteUrl));
_userService.SendLostPasswordEmail(username, nonce =>
Url.MakeAbsolute(Url.Action("LostPassword", "Account", new { Area = "Orchard.Users", nonce }), siteUrl));
_orchardServices.Notifier.Information(T("Check your e-mail for the confirmation link."));
_orchardServices.Notifier.Information(T("If your username or email is correct, we will send you an email with a link to reset your password."));
return RedirectToAction("LogOn");
}