diff --git a/src/Umbraco.Core/Persistence/Factories/DictionaryItemFactory.cs b/src/Umbraco.Core/Persistence/Factories/DictionaryItemFactory.cs
index 8994026ccb..4236195402 100644
--- a/src/Umbraco.Core/Persistence/Factories/DictionaryItemFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/DictionaryItemFactory.cs
@@ -1,66 +1,66 @@
-using System.Collections.Generic;
-using Umbraco.Core.Models;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Persistence.Factories
-{
- internal static class DictionaryItemFactory
- {
- #region Implementation of IEntityFactory
-
- public static IDictionaryItem BuildEntity(DictionaryDto dto)
- {
- var item = new DictionaryItem(dto.Parent, dto.Key);
-
- try
- {
- item.DisableChangeTracking();
-
- item.Id = dto.PrimaryKey;
- item.Key = dto.UniqueId;
-
- // reset dirty initial properties (U4-1946)
- item.ResetDirtyProperties(false);
- return item;
- }
- finally
- {
- item.EnableChangeTracking();
- }
- }
-
- public static DictionaryDto BuildDto(IDictionaryItem entity)
- {
- return new DictionaryDto
- {
- UniqueId = entity.Key,
- Key = entity.ItemKey,
- Parent = entity.ParentId,
- PrimaryKey = entity.Id,
- LanguageTextDtos = BuildLanguageTextDtos(entity)
- };
- }
-
- #endregion
-
- private static List BuildLanguageTextDtos(IDictionaryItem entity)
- {
- var list = new List();
- foreach (var translation in entity.Translations)
- {
- var text = new LanguageTextDto
- {
- LanguageId = translation.LanguageId,
- UniqueId = translation.Key,
- Value = translation.Value
- };
-
- if (translation.HasIdentity)
- text.PrimaryKey = translation.Id;
-
- list.Add(text);
- }
- return list;
- }
- }
-}
+using System.Collections.Generic;
+using Umbraco.Core.Models;
+using Umbraco.Core.Persistence.Dtos;
+
+namespace Umbraco.Core.Persistence.Factories
+{
+ internal static class DictionaryItemFactory
+ {
+ #region Implementation of IEntityFactory
+
+ public static IDictionaryItem BuildEntity(DictionaryDto dto)
+ {
+ var item = new DictionaryItem(dto.Parent, dto.Key);
+
+ try
+ {
+ item.DisableChangeTracking();
+
+ item.Id = dto.PrimaryKey;
+ item.Key = dto.UniqueId;
+
+ // reset dirty initial properties (U4-1946)
+ item.ResetDirtyProperties(false);
+ return item;
+ }
+ finally
+ {
+ item.EnableChangeTracking();
+ }
+ }
+
+ public static DictionaryDto BuildDto(IDictionaryItem entity)
+ {
+ return new DictionaryDto
+ {
+ UniqueId = entity.Key,
+ Key = entity.ItemKey,
+ Parent = entity.ParentId,
+ PrimaryKey = entity.Id,
+ LanguageTextDtos = BuildLanguageTextDtos(entity)
+ };
+ }
+
+ #endregion
+
+ private static List BuildLanguageTextDtos(IDictionaryItem entity)
+ {
+ var list = new List();
+ foreach (var translation in entity.Translations)
+ {
+ var text = new LanguageTextDto
+ {
+ LanguageId = translation.LanguageId,
+ UniqueId = translation.Key,
+ Value = translation.Value
+ };
+
+ if (translation.HasIdentity)
+ text.PrimaryKey = translation.Id;
+
+ list.Add(text);
+ }
+ return list;
+ }
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js
index da4a53328d..30c2b493da 100644
--- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js
@@ -1,464 +1,464 @@
-/**
- * @ngdoc controller
- * @name Umbraco.Editors.DocumentType.EditController
- * @function
- *
- * @description
- * The controller for the content type editor
- */
-(function () {
- "use strict";
-
- function DocumentTypesEditController($scope, $routeParams, $injector, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
-
- var vm = this;
- var evts = [];
-
- var disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
- var documentTypeId = $routeParams.id;
- var create = $routeParams.create;
- var noTemplate = $routeParams.notemplate;
- var infiniteMode = $scope.model && $scope.model.infiniteMode;
-
- vm.save = save;
- vm.close = close;
-
- vm.currentNode = null;
- vm.contentType = {};
- vm.labels = {};
- vm.submitButtonKey = "buttons_save";
- vm.generateModelsKey = "buttons_saveAndGenerateModels";
-
- vm.page = {};
- vm.page.loading = false;
- vm.page.saveButtonState = "init";
- vm.page.navigation = [];
-
- var labelKeys = [
- "general_design",
- "general_listView",
- "general_rights",
- "treeHeaders_templates",
- "main_sections",
- "shortcuts_navigateSections",
- "shortcuts_addTab",
- "shortcuts_addProperty",
- "shortcuts_addEditor",
- "shortcuts_editDataType",
- "shortcuts_toggleListView",
- "shortcuts_toggleAllowAsRoot",
- "shortcuts_addChildNode",
- "shortcuts_addTemplate"
- ];
-
- onInit();
-
- function onInit() {
- // get init values from model when in infinite mode
- if(infiniteMode) {
- documentTypeId = $scope.model.id;
- create = $scope.model.create;
- noTemplate = $scope.model.notemplate;
- vm.submitButtonKey = "buttons_saveAndClose";
- vm.generateModelsKey = "buttons_generateModelsAndClose";
- }
- }
-
- localizationService.localizeMany(labelKeys).then(function (values) {
- // navigation
- vm.labels.design = values[0];
- vm.labels.listview = values[1];
- vm.labels.permissions = values[2];
- vm.labels.templates = values[3];
- // keyboard shortcuts
- vm.labels.sections = values[4];
- vm.labels.navigateSections = values[5];
- vm.labels.addTab = values[6];
- vm.labels.addProperty = values[7];
- vm.labels.addEditor = values[8];
- vm.labels.editDataType = values[9];
- vm.labels.toggleListView = values[10];
- vm.labels.allowAsRoot = values[11];
- vm.labels.addChildNode = values[12];
- vm.labels.addTemplate = values[13];
-
- var buttons = [
- {
- "name": vm.labels.design,
- "alias": "design",
- "icon": "icon-document-dashed-line",
- "view": "views/documenttypes/views/design/design.html",
- "active": true
- },
- {
- "name": vm.labels.listview,
- "alias": "listView",
- "icon": "icon-list",
- "view": "views/documenttypes/views/listview/listview.html"
- },
- {
- "name": vm.labels.permissions,
- "alias": "permissions",
- "icon": "icon-keychain",
- "view": "views/documenttypes/views/permissions/permissions.html"
- },
- {
- "name": vm.labels.templates,
- "alias": "templates",
- "icon": "icon-layout",
- "view": "views/documenttypes/views/templates/templates.html"
- }
- ];
-
- vm.page.keyboardShortcutsOverview = [
- {
- "name": vm.labels.sections,
- "shortcuts": [
- {
- "description": vm.labels.navigateSections,
- "keys": [{ "key": "1" }, { "key": "4" }],
- "keyRange": true
- }
- ]
- },
- {
- "name": vm.labels.design,
- "shortcuts": [
- {
- "description": vm.labels.addTab,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
- },
- {
- "description": vm.labels.addProperty,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
- },
- {
- "description": vm.labels.addEditor,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
- },
- {
- "description": vm.labels.editDataType,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
- }
- ]
- },
- {
- "name": vm.labels.listview,
- "shortcuts": [
- {
- "description": vm.labels.toggleListView,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
- }
- ]
- },
- {
- "name": vm.labels.permissions,
- "shortcuts": [
- {
- "description": vm.labels.allowAsRoot,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
- },
- {
- "description": vm.labels.addChildNode,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
- }
- ]
- },
- {
- "name": vm.labels.templates,
- "shortcuts": [
- {
- "description": vm.labels.addTemplate,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
- }
- ]
- }
- ];
-
- loadButtons(buttons);
-
- });
-
- contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
- vm.page.modelsBuilder = result;
- if (result) {
- //Models builder mode:
- vm.page.defaultButton = {
- alias: "save",
- hotKey: "ctrl+s",
- hotKeyWhenHidden: true,
- labelKey: vm.submitButtonKey,
- letter: "S",
- type: "submit",
- handler: function () { vm.save(); }
- };
- vm.page.subButtons = [{
- alias: "saveAndGenerateModels",
- hotKey: "ctrl+g",
- hotKeyWhenHidden: true,
- labelKey: vm.generateModelsKey,
- letter: "G",
- handler: function () {
-
- vm.page.saveButtonState = "busy";
-
- saveInternal().then(function (result) {
-
- vm.page.saveButtonState = "busy";
-
- localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
- localizationService.localize("modelsBuilder_waitingMessage").then(function (msgValue) {
- notificationsService.info(headerValue, msgValue);
- });
- });
-
- contentTypeHelper.generateModels().then(function (result) {
-
- // generateModels() returns the dashboard content
- if (!result.lastError) {
-
- //re-check model status
- contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
- vm.page.modelsBuilder = statusResult;
- });
-
- //clear and add success
- vm.page.saveButtonState = "init";
- localizationService.localize("modelsBuilder_modelsGenerated").then(function (value) {
- notificationsService.success(value);
- });
-
- } else {
- vm.page.saveButtonState = "error";
- localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function (value) {
- notificationsService.error(value);
- });
- }
-
- }, function () {
- vm.page.saveButtonState = "error";
- localizationService.localize("modelsBuilder_modelsGeneratedError").then(function (value) {
- notificationsService.error(value);
- });
- });
- });
- }
- }];
- }
- });
-
- if (create) {
- vm.page.loading = true;
-
- //we are creating so get an empty data type item
- contentTypeResource.getScaffold(documentTypeId)
- .then(function (dt) {
- init(dt);
- vm.page.loading = false;
- });
- }
- else {
- loadDocumentType();
- }
-
- function loadDocumentType() {
- vm.page.loading = true;
- contentTypeResource.getById(documentTypeId).then(function (dt) {
- init(dt);
- // we don't need to sync the tree in infinite mode
- if(!infiniteMode) {
- syncTreeNode(vm.contentType, dt.path, true);
- }
- vm.page.loading = false;
- });
- }
-
- function loadButtons(buttons) {
-
- angular.forEach(buttons,
- function (val, index) {
-
- if (disableTemplates === true && val.alias === "templates") {
- buttons.splice(index, 1);
- }
-
- });
-
- vm.page.navigation = buttons;
- }
-
- /* ---------- SAVE ---------- */
-
- function save() {
- //return the saveInternal method but catch rejections since this is the upper most caller
- return saveInternal().catch(angular.noop);
- }
-
- /** This internal save method performs the actual saving and returns a promise, not to be bound to any buttons but used by other bound methods */
- function saveInternal() {
-
- // only save if there is no overlays open
- if (overlayHelper.getNumberOfOverlays() === 0) {
-
- vm.page.saveButtonState = "busy";
-
- // reformat allowed content types to array if id's
- vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
-
- return contentEditingHelper.contentEditorPerformSave({
- saveMethod: contentTypeResource.save,
- scope: $scope,
- content: vm.contentType,
- //We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
- // type when server side validation fails - as opposed to content where we are capable of saving the content
- // item if server side validation fails
- redirectOnFailure: false,
- // we need to rebind... the IDs that have been created!
- rebindCallback: function (origContentType, savedContentType) {
- vm.contentType.id = savedContentType.id;
- vm.contentType.groups.forEach(function (group) {
- if (!group.name) return;
- var k = 0;
- while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
- k++;
- if (k == savedContentType.groups.length) {
- group.id = 0;
- return;
- }
- var savedGroup = savedContentType.groups[k];
- if (!group.id) group.id = savedGroup.id;
-
- group.properties.forEach(function (property) {
- if (property.id || !property.alias) return;
- k = 0;
- while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
- k++;
- if (k == savedGroup.properties.length) {
- property.id = 0;
- return;
- }
- var savedProperty = savedGroup.properties[k];
- property.id = savedProperty.id;
- });
- });
- }
- }).then(function (data) {
- //success
- // we don't need to sync the tree in infinite mode
- if(!infiniteMode) {
- syncTreeNode(vm.contentType, data.path);
- }
-
- // emit event
- var args = { documentType: vm.contentType };
- eventsService.emit("editors.documentType.saved", args);
-
- vm.page.saveButtonState = "success";
-
- if(infiniteMode && $scope.model.submit) {
- $scope.model.documentTypeAlias = vm.contentType.alias;
- $scope.model.submit($scope.model);
- }
-
- return $q.resolve(data);
- }, function (err) {
- //error
- if (err) {
- editorState.set($scope.content);
- }
- else {
- localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
- localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
- notificationsService.error(headerValue, msgValue);
- });
- });
- }
- vm.page.saveButtonState = "error";
- return $q.reject(err);
- });
- }
- else {
- return $q.reject();
- }
- }
-
- function init(contentType) {
-
- // set all tab to inactive
- if (contentType.groups.length !== 0) {
- angular.forEach(contentType.groups, function (group) {
-
- angular.forEach(group.properties, function (property) {
- // get data type details for each property
- getDataTypeDetails(property);
- });
-
- });
- }
-
- // insert template on new doc types
- if (!noTemplate && contentType.id === 0) {
- contentType.defaultTemplate = contentTypeHelper.insertDefaultTemplatePlaceholder(contentType.defaultTemplate);
- contentType.allowedTemplates = contentTypeHelper.insertTemplatePlaceholder(contentType.allowedTemplates);
- }
-
- // convert icons for content type
- convertLegacyIcons(contentType);
-
- //set a shared state
- editorState.set(contentType);
-
- vm.contentType = contentType;
- }
-
- function convertLegacyIcons(contentType) {
- // make array to store contentType icon
- var contentTypeArray = [];
-
- // push icon to array
- contentTypeArray.push({ "icon": contentType.icon });
-
- // run through icon method
- iconHelper.formatContentTypeIcons(contentTypeArray);
-
- // set icon back on contentType
- contentType.icon = contentTypeArray[0].icon;
- }
-
- function getDataTypeDetails(property) {
- if (property.propertyState !== "init") {
- dataTypeResource.getById(property.dataTypeId)
- .then(function (dataType) {
- property.dataTypeIcon = dataType.icon;
- property.dataTypeName = dataType.name;
- });
- }
- }
-
- /** Syncs the content type to it's tree node - this occurs on first load and after saving */
- function syncTreeNode(dt, path, initialLoad) {
- navigationService.syncTree({ tree: "documenttypes", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
- vm.currentNode = syncArgs.node;
- });
- }
-
- function close() {
- if($scope.model.close) {
- $scope.model.close($scope.model);
- }
- }
-
- evts.push(eventsService.on("app.refreshEditor", function (name, error) {
- loadDocumentType();
- }));
-
- //ensure to unregister from all events!
- $scope.$on('$destroy', function () {
- for (var e in evts) {
- eventsService.unsubscribe(evts[e]);
- }
- });
- }
-
- angular.module("umbraco").controller("Umbraco.Editors.DocumentTypes.EditController", DocumentTypesEditController);
-})();
+/**
+ * @ngdoc controller
+ * @name Umbraco.Editors.DocumentType.EditController
+ * @function
+ *
+ * @description
+ * The controller for the content type editor
+ */
+(function () {
+ "use strict";
+
+ function DocumentTypesEditController($scope, $routeParams, $injector, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
+
+ var vm = this;
+ var evts = [];
+
+ var disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
+ var documentTypeId = $routeParams.id;
+ var create = $routeParams.create;
+ var noTemplate = $routeParams.notemplate;
+ var infiniteMode = $scope.model && $scope.model.infiniteMode;
+
+ vm.save = save;
+ vm.close = close;
+
+ vm.currentNode = null;
+ vm.contentType = {};
+ vm.labels = {};
+ vm.submitButtonKey = "buttons_save";
+ vm.generateModelsKey = "buttons_saveAndGenerateModels";
+
+ vm.page = {};
+ vm.page.loading = false;
+ vm.page.saveButtonState = "init";
+ vm.page.navigation = [];
+
+ var labelKeys = [
+ "general_design",
+ "general_listView",
+ "general_rights",
+ "treeHeaders_templates",
+ "main_sections",
+ "shortcuts_navigateSections",
+ "shortcuts_addTab",
+ "shortcuts_addProperty",
+ "shortcuts_addEditor",
+ "shortcuts_editDataType",
+ "shortcuts_toggleListView",
+ "shortcuts_toggleAllowAsRoot",
+ "shortcuts_addChildNode",
+ "shortcuts_addTemplate"
+ ];
+
+ onInit();
+
+ function onInit() {
+ // get init values from model when in infinite mode
+ if(infiniteMode) {
+ documentTypeId = $scope.model.id;
+ create = $scope.model.create;
+ noTemplate = $scope.model.notemplate;
+ vm.submitButtonKey = "buttons_saveAndClose";
+ vm.generateModelsKey = "buttons_generateModelsAndClose";
+ }
+ }
+
+ localizationService.localizeMany(labelKeys).then(function (values) {
+ // navigation
+ vm.labels.design = values[0];
+ vm.labels.listview = values[1];
+ vm.labels.permissions = values[2];
+ vm.labels.templates = values[3];
+ // keyboard shortcuts
+ vm.labels.sections = values[4];
+ vm.labels.navigateSections = values[5];
+ vm.labels.addTab = values[6];
+ vm.labels.addProperty = values[7];
+ vm.labels.addEditor = values[8];
+ vm.labels.editDataType = values[9];
+ vm.labels.toggleListView = values[10];
+ vm.labels.allowAsRoot = values[11];
+ vm.labels.addChildNode = values[12];
+ vm.labels.addTemplate = values[13];
+
+ var buttons = [
+ {
+ "name": vm.labels.design,
+ "alias": "design",
+ "icon": "icon-document-dashed-line",
+ "view": "views/documenttypes/views/design/design.html",
+ "active": true
+ },
+ {
+ "name": vm.labels.listview,
+ "alias": "listView",
+ "icon": "icon-list",
+ "view": "views/documenttypes/views/listview/listview.html"
+ },
+ {
+ "name": vm.labels.permissions,
+ "alias": "permissions",
+ "icon": "icon-keychain",
+ "view": "views/documenttypes/views/permissions/permissions.html"
+ },
+ {
+ "name": vm.labels.templates,
+ "alias": "templates",
+ "icon": "icon-layout",
+ "view": "views/documenttypes/views/templates/templates.html"
+ }
+ ];
+
+ vm.page.keyboardShortcutsOverview = [
+ {
+ "name": vm.labels.sections,
+ "shortcuts": [
+ {
+ "description": vm.labels.navigateSections,
+ "keys": [{ "key": "1" }, { "key": "4" }],
+ "keyRange": true
+ }
+ ]
+ },
+ {
+ "name": vm.labels.design,
+ "shortcuts": [
+ {
+ "description": vm.labels.addTab,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
+ },
+ {
+ "description": vm.labels.addProperty,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
+ },
+ {
+ "description": vm.labels.addEditor,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
+ },
+ {
+ "description": vm.labels.editDataType,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
+ }
+ ]
+ },
+ {
+ "name": vm.labels.listview,
+ "shortcuts": [
+ {
+ "description": vm.labels.toggleListView,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
+ }
+ ]
+ },
+ {
+ "name": vm.labels.permissions,
+ "shortcuts": [
+ {
+ "description": vm.labels.allowAsRoot,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
+ },
+ {
+ "description": vm.labels.addChildNode,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
+ }
+ ]
+ },
+ {
+ "name": vm.labels.templates,
+ "shortcuts": [
+ {
+ "description": vm.labels.addTemplate,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
+ }
+ ]
+ }
+ ];
+
+ loadButtons(buttons);
+
+ });
+
+ contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
+ vm.page.modelsBuilder = result;
+ if (result) {
+ //Models builder mode:
+ vm.page.defaultButton = {
+ alias: "save",
+ hotKey: "ctrl+s",
+ hotKeyWhenHidden: true,
+ labelKey: vm.submitButtonKey,
+ letter: "S",
+ type: "submit",
+ handler: function () { vm.save(); }
+ };
+ vm.page.subButtons = [{
+ alias: "saveAndGenerateModels",
+ hotKey: "ctrl+g",
+ hotKeyWhenHidden: true,
+ labelKey: vm.generateModelsKey,
+ letter: "G",
+ handler: function () {
+
+ vm.page.saveButtonState = "busy";
+
+ saveInternal().then(function (result) {
+
+ vm.page.saveButtonState = "busy";
+
+ localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
+ localizationService.localize("modelsBuilder_waitingMessage").then(function (msgValue) {
+ notificationsService.info(headerValue, msgValue);
+ });
+ });
+
+ contentTypeHelper.generateModels().then(function (result) {
+
+ // generateModels() returns the dashboard content
+ if (!result.lastError) {
+
+ //re-check model status
+ contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
+ vm.page.modelsBuilder = statusResult;
+ });
+
+ //clear and add success
+ vm.page.saveButtonState = "init";
+ localizationService.localize("modelsBuilder_modelsGenerated").then(function (value) {
+ notificationsService.success(value);
+ });
+
+ } else {
+ vm.page.saveButtonState = "error";
+ localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function (value) {
+ notificationsService.error(value);
+ });
+ }
+
+ }, function () {
+ vm.page.saveButtonState = "error";
+ localizationService.localize("modelsBuilder_modelsGeneratedError").then(function (value) {
+ notificationsService.error(value);
+ });
+ });
+ });
+ }
+ }];
+ }
+ });
+
+ if (create) {
+ vm.page.loading = true;
+
+ //we are creating so get an empty data type item
+ contentTypeResource.getScaffold(documentTypeId)
+ .then(function (dt) {
+ init(dt);
+ vm.page.loading = false;
+ });
+ }
+ else {
+ loadDocumentType();
+ }
+
+ function loadDocumentType() {
+ vm.page.loading = true;
+ contentTypeResource.getById(documentTypeId).then(function (dt) {
+ init(dt);
+ // we don't need to sync the tree in infinite mode
+ if(!infiniteMode) {
+ syncTreeNode(vm.contentType, dt.path, true);
+ }
+ vm.page.loading = false;
+ });
+ }
+
+ function loadButtons(buttons) {
+
+ angular.forEach(buttons,
+ function (val, index) {
+
+ if (disableTemplates === true && val.alias === "templates") {
+ buttons.splice(index, 1);
+ }
+
+ });
+
+ vm.page.navigation = buttons;
+ }
+
+ /* ---------- SAVE ---------- */
+
+ function save() {
+ //return the saveInternal method but catch rejections since this is the upper most caller
+ return saveInternal().catch(angular.noop);
+ }
+
+ /** This internal save method performs the actual saving and returns a promise, not to be bound to any buttons but used by other bound methods */
+ function saveInternal() {
+
+ // only save if there is no overlays open
+ if (overlayHelper.getNumberOfOverlays() === 0) {
+
+ vm.page.saveButtonState = "busy";
+
+ // reformat allowed content types to array if id's
+ vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
+
+ return contentEditingHelper.contentEditorPerformSave({
+ saveMethod: contentTypeResource.save,
+ scope: $scope,
+ content: vm.contentType,
+ //We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
+ // type when server side validation fails - as opposed to content where we are capable of saving the content
+ // item if server side validation fails
+ redirectOnFailure: false,
+ // we need to rebind... the IDs that have been created!
+ rebindCallback: function (origContentType, savedContentType) {
+ vm.contentType.id = savedContentType.id;
+ vm.contentType.groups.forEach(function (group) {
+ if (!group.name) return;
+ var k = 0;
+ while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
+ k++;
+ if (k == savedContentType.groups.length) {
+ group.id = 0;
+ return;
+ }
+ var savedGroup = savedContentType.groups[k];
+ if (!group.id) group.id = savedGroup.id;
+
+ group.properties.forEach(function (property) {
+ if (property.id || !property.alias) return;
+ k = 0;
+ while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
+ k++;
+ if (k == savedGroup.properties.length) {
+ property.id = 0;
+ return;
+ }
+ var savedProperty = savedGroup.properties[k];
+ property.id = savedProperty.id;
+ });
+ });
+ }
+ }).then(function (data) {
+ //success
+ // we don't need to sync the tree in infinite mode
+ if(!infiniteMode) {
+ syncTreeNode(vm.contentType, data.path);
+ }
+
+ // emit event
+ var args = { documentType: vm.contentType };
+ eventsService.emit("editors.documentType.saved", args);
+
+ vm.page.saveButtonState = "success";
+
+ if(infiniteMode && $scope.model.submit) {
+ $scope.model.documentTypeAlias = vm.contentType.alias;
+ $scope.model.submit($scope.model);
+ }
+
+ return $q.resolve(data);
+ }, function (err) {
+ //error
+ if (err) {
+ editorState.set($scope.content);
+ }
+ else {
+ localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
+ localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
+ notificationsService.error(headerValue, msgValue);
+ });
+ });
+ }
+ vm.page.saveButtonState = "error";
+ return $q.reject(err);
+ });
+ }
+ else {
+ return $q.reject();
+ }
+ }
+
+ function init(contentType) {
+
+ // set all tab to inactive
+ if (contentType.groups.length !== 0) {
+ angular.forEach(contentType.groups, function (group) {
+
+ angular.forEach(group.properties, function (property) {
+ // get data type details for each property
+ getDataTypeDetails(property);
+ });
+
+ });
+ }
+
+ // insert template on new doc types
+ if (!noTemplate && contentType.id === 0) {
+ contentType.defaultTemplate = contentTypeHelper.insertDefaultTemplatePlaceholder(contentType.defaultTemplate);
+ contentType.allowedTemplates = contentTypeHelper.insertTemplatePlaceholder(contentType.allowedTemplates);
+ }
+
+ // convert icons for content type
+ convertLegacyIcons(contentType);
+
+ //set a shared state
+ editorState.set(contentType);
+
+ vm.contentType = contentType;
+ }
+
+ function convertLegacyIcons(contentType) {
+ // make array to store contentType icon
+ var contentTypeArray = [];
+
+ // push icon to array
+ contentTypeArray.push({ "icon": contentType.icon });
+
+ // run through icon method
+ iconHelper.formatContentTypeIcons(contentTypeArray);
+
+ // set icon back on contentType
+ contentType.icon = contentTypeArray[0].icon;
+ }
+
+ function getDataTypeDetails(property) {
+ if (property.propertyState !== "init") {
+ dataTypeResource.getById(property.dataTypeId)
+ .then(function (dataType) {
+ property.dataTypeIcon = dataType.icon;
+ property.dataTypeName = dataType.name;
+ });
+ }
+ }
+
+ /** Syncs the content type to it's tree node - this occurs on first load and after saving */
+ function syncTreeNode(dt, path, initialLoad) {
+ navigationService.syncTree({ tree: "documenttypes", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
+ vm.currentNode = syncArgs.node;
+ });
+ }
+
+ function close() {
+ if($scope.model.close) {
+ $scope.model.close($scope.model);
+ }
+ }
+
+ evts.push(eventsService.on("app.refreshEditor", function (name, error) {
+ loadDocumentType();
+ }));
+
+ //ensure to unregister from all events!
+ $scope.$on('$destroy', function () {
+ for (var e in evts) {
+ eventsService.unsubscribe(evts[e]);
+ }
+ });
+ }
+
+ angular.module("umbraco").controller("Umbraco.Editors.DocumentTypes.EditController", DocumentTypesEditController);
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js
index e26facc880..8c171af2f0 100644
--- a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js
@@ -1,272 +1,272 @@
-/**
- * @ngdoc controller
- * @name Umbraco.Editors.Media.EditController
- * @function
- *
- * @description
- * The controller for the media editor
- */
-function mediaEditController($scope, $routeParams, $q, appState, mediaResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, treeService, formHelper, umbModelMapper, editorState, umbRequestHelper, $http, eventsService) {
-
- var evts = [];
- var nodeId = null;
- var create = false;
- var infiniteMode = $scope.model && $scope.model.infiniteMode;
-
- // when opening the editor through infinite editing get the
- // node id from the model instead of the route param
- if(infiniteMode && $scope.model.id) {
- nodeId = $scope.model.id;
- } else {
- nodeId = $routeParams.id;
- }
-
- // when opening the editor through infinite editing get the
- // create option from the model instead of the route param
- if(infiniteMode) {
- create = $scope.model.create;
- } else {
- create = $routeParams.create;
- }
-
- //setup scope vars
- $scope.currentSection = appState.getSectionState("currentSection");
- $scope.currentNode = null; //the editors affiliated node
-
- $scope.page = {};
- $scope.page.loading = false;
- $scope.page.menu = {};
- $scope.page.menu.currentSection = appState.getSectionState("currentSection");
- $scope.page.menu.currentNode = null; //the editors affiliated node
- $scope.page.listViewPath = null;
- $scope.page.saveButtonState = "init";
- $scope.page.submitButtonLabel = "Save";
-
- /** Syncs the content item to it's tree node - this occurs on first load and after saving */
- function syncTreeNode(content, path, initialLoad) {
-
- if (!$scope.content.isChildOfListView) {
- navigationService.syncTree({ tree: "media", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
- $scope.page.menu.currentNode = syncArgs.node;
- });
- }
- else if (initialLoad === true) {
-
- //it's a child item, just sync the ui node to the parent
- navigationService.syncTree({ tree: "media", path: path.substring(0, path.lastIndexOf(",")).split(","), forceReload: initialLoad !== true });
-
- //if this is a child of a list view and it's the initial load of the editor, we need to get the tree node
- // from the server so that we can load in the actions menu.
- umbRequestHelper.resourcePromise(
- $http.get(content.treeNodeUrl),
- 'Failed to retrieve data for child node ' + content.id).then(function (node) {
- $scope.page.menu.currentNode = node;
- });
- }
- }
-
- if (create) {
-
- $scope.page.loading = true;
-
- mediaResource.getScaffold(nodeId, $routeParams.doctype)
- .then(function (data) {
- $scope.content = data;
-
- editorState.set($scope.content);
-
- // We don't get the info tab from the server from version 7.8 so we need to manually add it
- //contentEditingHelper.addInfoTab($scope.content.tabs);
-
- init($scope.content);
-
- $scope.page.loading = false;
-
- });
- }
- else {
- $scope.page.loading = true;
- loadMedia()
- .then(function(){
- $scope.page.loading = false;
- });
- }
-
- function init(content) {
-
- // prototype content and info apps
- var contentApp = {
- "name": "Content",
- "alias": "content",
- "icon": "icon-document",
- "view": "views/media/apps/content/content.html"
- };
-
- var infoApp = {
- "name": "Info",
- "alias": "info",
- "icon": "icon-info",
- "view": "views/media/apps/info/info.html"
- };
-
- var listview = {
- "name": "Child items",
- "alias": "childItems",
- "icon": "icon-list",
- "view": "views/media/apps/listview/listview.html"
- };
-
- $scope.content.apps = [];
-
- if($scope.content.contentTypeAlias === "Folder") {
- // add list view app
- $scope.content.apps.push(listview);
-
- // remove the list view tab
- angular.forEach($scope.content.tabs, function(tab, index){
- if(tab.alias === "Contents") {
- tab.hide = true;
- }
- });
-
- } else {
- $scope.content.apps.push(contentApp);
- }
-
- $scope.content.apps.push(infoApp);
-
- // set first app to active
- $scope.content.apps[0].active = true;
-
- // setup infinite mode
- if(infiniteMode) {
- $scope.page.submitButtonLabel = "Save and Close";
- }
-
- }
-
- $scope.save = function () {
-
- if (!$scope.busy && formHelper.submitForm({ scope: $scope })) {
-
- $scope.busy = true;
- $scope.page.saveButtonState = "busy";
-
- mediaResource.save($scope.content, create, fileManager.getFiles())
- .then(function(data) {
-
- formHelper.resetForm({ scope: $scope });
-
- contentEditingHelper.handleSuccessfulSave({
- scope: $scope,
- savedContent: data,
- redirectOnSuccess: !infiniteMode,
- rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
- });
-
- editorState.set($scope.content);
- $scope.busy = false;
-
- // when don't want to sync the tree when the editor is open in infinite mode
- if(!infiniteMode) {
- syncTreeNode($scope.content, data.path);
- }
-
- init($scope.content);
-
- $scope.page.saveButtonState = "success";
-
- // close the editor if it's infinite mode
- if(infiniteMode && $scope.model.submit) {
- $scope.model.mediaNode = $scope.content;
- $scope.model.submit($scope.model);
- }
-
- }, function(err) {
-
- contentEditingHelper.handleSaveError({
- err: err,
- redirectOnError: !infiniteMode,
- rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
- });
-
- editorState.set($scope.content);
- $scope.busy = false;
- $scope.page.saveButtonState = "error";
-
- });
- }else{
- $scope.busy = false;
- }
-
- };
-
- function loadMedia() {
-
- return mediaResource.getById(nodeId)
- .then(function (data) {
-
- $scope.content = data;
-
- if (data.isChildOfListView && data.trashed === false) {
- $scope.page.listViewPath = ($routeParams.page)
- ? "/media/media/edit/" + data.parentId + "?page=" + $routeParams.page
- : "/media/media/edit/" + data.parentId;
- }
-
- editorState.set($scope.content);
-
- //in one particular special case, after we've created a new item we redirect back to the edit
- // route but there might be server validation errors in the collection which we need to display
- // after the redirect, so we will bind all subscriptions which will show the server validation errors
- // if there are any and then clear them so the collection no longer persists them.
- serverValidationManager.executeAndClearAllSubscriptions();
-
- if(!infiniteMode) {
- syncTreeNode($scope.content, data.path, true);
- }
-
- if ($scope.content.parentId && $scope.content.parentId != -1) {
- //We fetch all ancestors of the node to generate the footer breadcrump navigation
- entityResource.getAncestors(nodeId, "media")
- .then(function (anc) {
- $scope.ancestors = anc;
- });
- }
-
- // We don't get the info tab from the server from version 7.8 so we need to manually add it
- //contentEditingHelper.addInfoTab($scope.content.tabs);
-
- init($scope.content);
-
- $scope.page.loading = false;
-
- $q.resolve($scope.content);
-
- });
-
- }
-
- $scope.close = function() {
- if($scope.model.close) {
- $scope.model.close($scope.model);
- }
- };
-
- evts.push(eventsService.on("editors.mediaType.saved", function(name, args) {
- // if this media item uses the updated media type we need to reload the media item
- if(args && args.mediaType && args.mediaType.key === $scope.content.contentType.key) {
- loadMedia();
- }
- }));
-
- //ensure to unregister from all events!
- $scope.$on('$destroy', function () {
- for (var e in evts) {
- eventsService.unsubscribe(evts[e]);
- }
- });
-
-}
-
-angular.module("umbraco").controller("Umbraco.Editors.Media.EditController", mediaEditController);
+/**
+ * @ngdoc controller
+ * @name Umbraco.Editors.Media.EditController
+ * @function
+ *
+ * @description
+ * The controller for the media editor
+ */
+function mediaEditController($scope, $routeParams, $q, appState, mediaResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, treeService, formHelper, umbModelMapper, editorState, umbRequestHelper, $http, eventsService) {
+
+ var evts = [];
+ var nodeId = null;
+ var create = false;
+ var infiniteMode = $scope.model && $scope.model.infiniteMode;
+
+ // when opening the editor through infinite editing get the
+ // node id from the model instead of the route param
+ if(infiniteMode && $scope.model.id) {
+ nodeId = $scope.model.id;
+ } else {
+ nodeId = $routeParams.id;
+ }
+
+ // when opening the editor through infinite editing get the
+ // create option from the model instead of the route param
+ if(infiniteMode) {
+ create = $scope.model.create;
+ } else {
+ create = $routeParams.create;
+ }
+
+ //setup scope vars
+ $scope.currentSection = appState.getSectionState("currentSection");
+ $scope.currentNode = null; //the editors affiliated node
+
+ $scope.page = {};
+ $scope.page.loading = false;
+ $scope.page.menu = {};
+ $scope.page.menu.currentSection = appState.getSectionState("currentSection");
+ $scope.page.menu.currentNode = null; //the editors affiliated node
+ $scope.page.listViewPath = null;
+ $scope.page.saveButtonState = "init";
+ $scope.page.submitButtonLabel = "Save";
+
+ /** Syncs the content item to it's tree node - this occurs on first load and after saving */
+ function syncTreeNode(content, path, initialLoad) {
+
+ if (!$scope.content.isChildOfListView) {
+ navigationService.syncTree({ tree: "media", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
+ $scope.page.menu.currentNode = syncArgs.node;
+ });
+ }
+ else if (initialLoad === true) {
+
+ //it's a child item, just sync the ui node to the parent
+ navigationService.syncTree({ tree: "media", path: path.substring(0, path.lastIndexOf(",")).split(","), forceReload: initialLoad !== true });
+
+ //if this is a child of a list view and it's the initial load of the editor, we need to get the tree node
+ // from the server so that we can load in the actions menu.
+ umbRequestHelper.resourcePromise(
+ $http.get(content.treeNodeUrl),
+ 'Failed to retrieve data for child node ' + content.id).then(function (node) {
+ $scope.page.menu.currentNode = node;
+ });
+ }
+ }
+
+ if (create) {
+
+ $scope.page.loading = true;
+
+ mediaResource.getScaffold(nodeId, $routeParams.doctype)
+ .then(function (data) {
+ $scope.content = data;
+
+ editorState.set($scope.content);
+
+ // We don't get the info tab from the server from version 7.8 so we need to manually add it
+ //contentEditingHelper.addInfoTab($scope.content.tabs);
+
+ init($scope.content);
+
+ $scope.page.loading = false;
+
+ });
+ }
+ else {
+ $scope.page.loading = true;
+ loadMedia()
+ .then(function(){
+ $scope.page.loading = false;
+ });
+ }
+
+ function init(content) {
+
+ // prototype content and info apps
+ var contentApp = {
+ "name": "Content",
+ "alias": "content",
+ "icon": "icon-document",
+ "view": "views/media/apps/content/content.html"
+ };
+
+ var infoApp = {
+ "name": "Info",
+ "alias": "info",
+ "icon": "icon-info",
+ "view": "views/media/apps/info/info.html"
+ };
+
+ var listview = {
+ "name": "Child items",
+ "alias": "childItems",
+ "icon": "icon-list",
+ "view": "views/media/apps/listview/listview.html"
+ };
+
+ $scope.content.apps = [];
+
+ if($scope.content.contentTypeAlias === "Folder") {
+ // add list view app
+ $scope.content.apps.push(listview);
+
+ // remove the list view tab
+ angular.forEach($scope.content.tabs, function(tab, index){
+ if(tab.alias === "Contents") {
+ tab.hide = true;
+ }
+ });
+
+ } else {
+ $scope.content.apps.push(contentApp);
+ }
+
+ $scope.content.apps.push(infoApp);
+
+ // set first app to active
+ $scope.content.apps[0].active = true;
+
+ // setup infinite mode
+ if(infiniteMode) {
+ $scope.page.submitButtonLabel = "Save and Close";
+ }
+
+ }
+
+ $scope.save = function () {
+
+ if (!$scope.busy && formHelper.submitForm({ scope: $scope })) {
+
+ $scope.busy = true;
+ $scope.page.saveButtonState = "busy";
+
+ mediaResource.save($scope.content, create, fileManager.getFiles())
+ .then(function(data) {
+
+ formHelper.resetForm({ scope: $scope });
+
+ contentEditingHelper.handleSuccessfulSave({
+ scope: $scope,
+ savedContent: data,
+ redirectOnSuccess: !infiniteMode,
+ rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
+ });
+
+ editorState.set($scope.content);
+ $scope.busy = false;
+
+ // when don't want to sync the tree when the editor is open in infinite mode
+ if(!infiniteMode) {
+ syncTreeNode($scope.content, data.path);
+ }
+
+ init($scope.content);
+
+ $scope.page.saveButtonState = "success";
+
+ // close the editor if it's infinite mode
+ if(infiniteMode && $scope.model.submit) {
+ $scope.model.mediaNode = $scope.content;
+ $scope.model.submit($scope.model);
+ }
+
+ }, function(err) {
+
+ contentEditingHelper.handleSaveError({
+ err: err,
+ redirectOnError: !infiniteMode,
+ rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
+ });
+
+ editorState.set($scope.content);
+ $scope.busy = false;
+ $scope.page.saveButtonState = "error";
+
+ });
+ }else{
+ $scope.busy = false;
+ }
+
+ };
+
+ function loadMedia() {
+
+ return mediaResource.getById(nodeId)
+ .then(function (data) {
+
+ $scope.content = data;
+
+ if (data.isChildOfListView && data.trashed === false) {
+ $scope.page.listViewPath = ($routeParams.page)
+ ? "/media/media/edit/" + data.parentId + "?page=" + $routeParams.page
+ : "/media/media/edit/" + data.parentId;
+ }
+
+ editorState.set($scope.content);
+
+ //in one particular special case, after we've created a new item we redirect back to the edit
+ // route but there might be server validation errors in the collection which we need to display
+ // after the redirect, so we will bind all subscriptions which will show the server validation errors
+ // if there are any and then clear them so the collection no longer persists them.
+ serverValidationManager.executeAndClearAllSubscriptions();
+
+ if(!infiniteMode) {
+ syncTreeNode($scope.content, data.path, true);
+ }
+
+ if ($scope.content.parentId && $scope.content.parentId != -1) {
+ //We fetch all ancestors of the node to generate the footer breadcrump navigation
+ entityResource.getAncestors(nodeId, "media")
+ .then(function (anc) {
+ $scope.ancestors = anc;
+ });
+ }
+
+ // We don't get the info tab from the server from version 7.8 so we need to manually add it
+ //contentEditingHelper.addInfoTab($scope.content.tabs);
+
+ init($scope.content);
+
+ $scope.page.loading = false;
+
+ $q.resolve($scope.content);
+
+ });
+
+ }
+
+ $scope.close = function() {
+ if($scope.model.close) {
+ $scope.model.close($scope.model);
+ }
+ };
+
+ evts.push(eventsService.on("editors.mediaType.saved", function(name, args) {
+ // if this media item uses the updated media type we need to reload the media item
+ if(args && args.mediaType && args.mediaType.key === $scope.content.contentType.key) {
+ loadMedia();
+ }
+ }));
+
+ //ensure to unregister from all events!
+ $scope.$on('$destroy', function () {
+ for (var e in evts) {
+ eventsService.unsubscribe(evts[e]);
+ }
+ });
+
+}
+
+angular.module("umbraco").controller("Umbraco.Editors.Media.EditController", mediaEditController);
diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js
index 0918a43188..2608ddf300 100644
--- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/edit.controller.js
@@ -1,419 +1,419 @@
-/**
- * @ngdoc controller
- * @name Umbraco.Editors.MediaType.EditController
- * @function
- *
- * @description
- * The controller for the media type editor
- */
-(function () {
- "use strict";
-
- function MediaTypesEditController($scope, $routeParams, mediaTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
-
- var vm = this;
- var evts = [];
- var mediaTypeId = $routeParams.id;
- var create = $routeParams.create;
- var infiniteMode = $scope.model && $scope.model.infiniteMode;
-
- vm.save = save;
- vm.close = close;
-
- vm.currentNode = null;
- vm.contentType = {};
- vm.page = {};
- vm.page.loading = false;
- vm.page.saveButtonState = "init";
- vm.labels = {};
- vm.saveButtonKey = "buttons_save";
- vm.generateModelsKey = "buttons_saveAndGenerateModels";
-
- onInit();
-
- function onInit() {
- // get init values from model when in infinite mode
- if(infiniteMode) {
- mediaTypeId = $scope.model.id;
- create = $scope.model.create;
- vm.saveButtonKey = "buttons_saveAndClose";
- vm.generateModelsKey = "buttons_generateModelsAndClose";
- }
- }
-
- var labelKeys = [
- "general_design",
- "general_listView",
- "general_rights",
-
- "main_sections",
- "shortcuts_navigateSections",
- "shortcuts_addTab",
- "shortcuts_addProperty",
- "shortcuts_addEditor",
- "shortcuts_editDataType",
- "shortcuts_toggleListView",
- "shortcuts_toggleAllowAsRoot",
- "shortcuts_addChildNode"
- ];
-
- localizationService.localizeMany(labelKeys).then(function (values) {
- // navigation
- vm.labels.design = values[0];
- vm.labels.listview = values[1];
- vm.labels.permissions = values[2];
- // keyboard shortcuts
- vm.labels.sections = values[3];
- vm.labels.navigateSections = values[4];
- vm.labels.addTab = values[5];
- vm.labels.addProperty = values[6];
- vm.labels.addEditor = values[7];
- vm.labels.editDataType = values[8];
- vm.labels.toggleListView = values[9];
- vm.labels.allowAsRoot = values[10];
- vm.labels.addChildNode = values[11];
-
- vm.page.navigation = [
- {
- "name": vm.labels.design,
- "icon": "icon-document-dashed-line",
- "view": "views/mediatypes/views/design/design.html",
- "active": true
- },
- {
- "name": vm.labels.listview,
- "icon": "icon-list",
- "view": "views/mediatypes/views/listview/listview.html"
- },
- {
- "name": vm.labels.permissions,
- "icon": "icon-keychain",
- "view": "views/mediatypes/views/permissions/permissions.html"
- }
- ];
-
- vm.page.keyboardShortcutsOverview = [
- {
- "name": vm.labels.sections,
- "shortcuts": [
- {
- "description": vm.labels.navigateSections,
- "keys": [{ "key": "1" }, { "key": "3" }],
- "keyRange": true
- }
- ]
- },
- {
- "name": vm.labels.design,
- "shortcuts": [
- {
- "description": vm.labels.addTab,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
- },
- {
- "description": vm.labels.addProperty,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
- },
- {
- "description": vm.labels.addEditor,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
- },
- {
- "description": vm.labels.editDataType,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
- }
- ]
- },
- {
- "name": vm.labels.listview,
- "shortcuts": [
- {
- "description": vm.labels.toggleListView,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
- }
- ]
- },
- {
- "name": vm.labels.permissions,
- "shortcuts": [
- {
- "description": vm.labels.allowAsRoot,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
- },
- {
- "description": vm.labels.addChildNode,
- "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
- }
- ]
- }
- ];
- });
-
- contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
- vm.page.modelsBuilder = result;
- if (result) {
- //Models builder mode:
- vm.page.defaultButton = {
- hotKey: "ctrl+s",
- hotKeyWhenHidden: true,
- labelKey: vm.saveButtonKey,
- letter: "S",
- type: "submit",
- handler: function () { vm.save(); }
- };
- vm.page.subButtons = [{
- hotKey: "ctrl+g",
- hotKeyWhenHidden: true,
- labelKey: vm.generateModelsKey,
- letter: "G",
- handler: function () {
-
- vm.page.saveButtonState = "busy";
-
- vm.save().then(function (result) {
-
- vm.page.saveButtonState = "busy";
-
- localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
- localizationService.localize("modelsBuilder_waitingMessage").then(function(msgValue) {
- notificationsService.info(headerValue, msgValue);
- });
- });
-
- contentTypeHelper.generateModels().then(function (result) {
-
- if (result.success) {
-
- //re-check model status
- contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
- vm.page.modelsBuilder = statusResult;
- });
-
- //clear and add success
- vm.page.saveButtonState = "init";
- localizationService.localize("modelsBuilder_modelsGenerated").then(function(value) {
- notificationsService.success(value);
- });
-
- } else {
- vm.page.saveButtonState = "error";
- localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function(value) {
- notificationsService.error(value);
- });
- }
-
- }, function () {
- vm.page.saveButtonState = "error";
- localizationService.localize("modelsBuilder_modelsGeneratedError").then(function(value) {
- notificationsService.error(value);
- });
- });
-
- });
-
- }
- }];
- }
- });
-
- if (create) {
- vm.page.loading = true;
-
- //we are creating so get an empty data type item
- mediaTypeResource.getScaffold(mediaTypeId)
- .then(function(dt) {
- init(dt);
-
- vm.page.loading = false;
- });
- }
- else {
- loadMediaType();
- }
-
- function loadMediaType() {
- vm.page.loading = true;
-
- mediaTypeResource.getById(mediaTypeId).then(function(dt) {
- init(dt);
-
- if(!infiniteMode) {
- syncTreeNode(vm.contentType, dt.path, true);
- }
-
- vm.page.loading = false;
- });
- }
-
- /* ---------- SAVE ---------- */
-
- function save() {
-
- // only save if there is no overlays open
- if(overlayHelper.getNumberOfOverlays() === 0) {
-
- var deferred = $q.defer();
-
- vm.page.saveButtonState = "busy";
-
- // reformat allowed content types to array if id's
- vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
-
- contentEditingHelper.contentEditorPerformSave({
- saveMethod: mediaTypeResource.save,
- scope: $scope,
- content: vm.contentType,
- //We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
- // type when server side validation fails - as opposed to content where we are capable of saving the content
- // item if server side validation fails
- redirectOnFailure: false,
- // we need to rebind... the IDs that have been created!
- rebindCallback: function (origContentType, savedContentType) {
- vm.contentType.id = savedContentType.id;
- vm.contentType.groups.forEach(function (group) {
- if (!group.name) return;
-
- var k = 0;
- while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
- k++;
- if (k == savedContentType.groups.length) {
- group.id = 0;
- return;
- }
-
- var savedGroup = savedContentType.groups[k];
- if (!group.id) group.id = savedGroup.id;
-
- group.properties.forEach(function (property) {
- if (property.id || !property.alias) return;
-
- k = 0;
- while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
- k++;
- if (k == savedGroup.properties.length) {
- property.id = 0;
- return;
- }
-
- var savedProperty = savedGroup.properties[k];
- property.id = savedProperty.id;
- });
- });
- }
- }).then(function (data) {
- //success
-
- if(!infiniteMode) {
- syncTreeNode(vm.contentType, data.path);
- }
-
- // emit event
- var args = { mediaType: vm.contentType };
- eventsService.emit("editors.mediaType.saved", args);
-
- vm.page.saveButtonState = "success";
-
- if(infiniteMode && $scope.model.submit) {
- $scope.model.submit();
- }
-
- deferred.resolve(data);
-
- }, function (err) {
- //error
- if (err) {
- editorState.set($scope.content);
- }
- else {
- localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
- localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
- notificationsService.error(headerValue, msgValue);
- });
- });
- }
-
- vm.page.saveButtonState = "error";
-
- deferred.reject(err);
- });
-
- return deferred.promise;
- }
- }
-
- function init(contentType) {
-
- // set all tab to inactive
- if (contentType.groups.length !== 0) {
- angular.forEach(contentType.groups, function (group) {
-
- angular.forEach(group.properties, function (property) {
- // get data type details for each property
- getDataTypeDetails(property);
- });
-
- });
- }
-
- // convert icons for content type
- convertLegacyIcons(contentType);
-
- //set a shared state
- editorState.set(contentType);
-
- vm.contentType = contentType;
- }
-
- function convertLegacyIcons(contentType) {
- // make array to store contentType icon
- var contentTypeArray = [];
-
- // push icon to array
- contentTypeArray.push({ "icon": contentType.icon });
-
- // run through icon method
- iconHelper.formatContentTypeIcons(contentTypeArray);
-
- // set icon back on contentType
- contentType.icon = contentTypeArray[0].icon;
- }
-
- function getDataTypeDetails(property) {
- if (property.propertyState !== "init") {
-
- dataTypeResource.getById(property.dataTypeId)
- .then(function(dataType) {
- property.dataTypeIcon = dataType.icon;
- property.dataTypeName = dataType.name;
- });
- }
- }
-
-
- /** Syncs the content type to it's tree node - this occurs on first load and after saving */
- function syncTreeNode(dt, path, initialLoad) {
- navigationService.syncTree({ tree: "mediatypes", path: path.split(","), forceReload: initialLoad !== true }).then(function(syncArgs) {
- vm.currentNode = syncArgs.node;
- });
- }
-
- function close() {
- if(infiniteMode && $scope.model.close) {
- $scope.model.close();
- }
- }
-
- evts.push(eventsService.on("app.refreshEditor", function(name, error) {
- loadMediaType();
- }));
-
- //ensure to unregister from all events!
- $scope.$on('$destroy', function () {
- for (var e in evts) {
- eventsService.unsubscribe(evts[e]);
- }
- });
- }
-
- angular.module("umbraco").controller("Umbraco.Editors.MediaTypes.EditController", MediaTypesEditController);
-})();
+/**
+ * @ngdoc controller
+ * @name Umbraco.Editors.MediaType.EditController
+ * @function
+ *
+ * @description
+ * The controller for the media type editor
+ */
+(function () {
+ "use strict";
+
+ function MediaTypesEditController($scope, $routeParams, mediaTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
+
+ var vm = this;
+ var evts = [];
+ var mediaTypeId = $routeParams.id;
+ var create = $routeParams.create;
+ var infiniteMode = $scope.model && $scope.model.infiniteMode;
+
+ vm.save = save;
+ vm.close = close;
+
+ vm.currentNode = null;
+ vm.contentType = {};
+ vm.page = {};
+ vm.page.loading = false;
+ vm.page.saveButtonState = "init";
+ vm.labels = {};
+ vm.saveButtonKey = "buttons_save";
+ vm.generateModelsKey = "buttons_saveAndGenerateModels";
+
+ onInit();
+
+ function onInit() {
+ // get init values from model when in infinite mode
+ if(infiniteMode) {
+ mediaTypeId = $scope.model.id;
+ create = $scope.model.create;
+ vm.saveButtonKey = "buttons_saveAndClose";
+ vm.generateModelsKey = "buttons_generateModelsAndClose";
+ }
+ }
+
+ var labelKeys = [
+ "general_design",
+ "general_listView",
+ "general_rights",
+
+ "main_sections",
+ "shortcuts_navigateSections",
+ "shortcuts_addTab",
+ "shortcuts_addProperty",
+ "shortcuts_addEditor",
+ "shortcuts_editDataType",
+ "shortcuts_toggleListView",
+ "shortcuts_toggleAllowAsRoot",
+ "shortcuts_addChildNode"
+ ];
+
+ localizationService.localizeMany(labelKeys).then(function (values) {
+ // navigation
+ vm.labels.design = values[0];
+ vm.labels.listview = values[1];
+ vm.labels.permissions = values[2];
+ // keyboard shortcuts
+ vm.labels.sections = values[3];
+ vm.labels.navigateSections = values[4];
+ vm.labels.addTab = values[5];
+ vm.labels.addProperty = values[6];
+ vm.labels.addEditor = values[7];
+ vm.labels.editDataType = values[8];
+ vm.labels.toggleListView = values[9];
+ vm.labels.allowAsRoot = values[10];
+ vm.labels.addChildNode = values[11];
+
+ vm.page.navigation = [
+ {
+ "name": vm.labels.design,
+ "icon": "icon-document-dashed-line",
+ "view": "views/mediatypes/views/design/design.html",
+ "active": true
+ },
+ {
+ "name": vm.labels.listview,
+ "icon": "icon-list",
+ "view": "views/mediatypes/views/listview/listview.html"
+ },
+ {
+ "name": vm.labels.permissions,
+ "icon": "icon-keychain",
+ "view": "views/mediatypes/views/permissions/permissions.html"
+ }
+ ];
+
+ vm.page.keyboardShortcutsOverview = [
+ {
+ "name": vm.labels.sections,
+ "shortcuts": [
+ {
+ "description": vm.labels.navigateSections,
+ "keys": [{ "key": "1" }, { "key": "3" }],
+ "keyRange": true
+ }
+ ]
+ },
+ {
+ "name": vm.labels.design,
+ "shortcuts": [
+ {
+ "description": vm.labels.addTab,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
+ },
+ {
+ "description": vm.labels.addProperty,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
+ },
+ {
+ "description": vm.labels.addEditor,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
+ },
+ {
+ "description": vm.labels.editDataType,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
+ }
+ ]
+ },
+ {
+ "name": vm.labels.listview,
+ "shortcuts": [
+ {
+ "description": vm.labels.toggleListView,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
+ }
+ ]
+ },
+ {
+ "name": vm.labels.permissions,
+ "shortcuts": [
+ {
+ "description": vm.labels.allowAsRoot,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
+ },
+ {
+ "description": vm.labels.addChildNode,
+ "keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
+ }
+ ]
+ }
+ ];
+ });
+
+ contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
+ vm.page.modelsBuilder = result;
+ if (result) {
+ //Models builder mode:
+ vm.page.defaultButton = {
+ hotKey: "ctrl+s",
+ hotKeyWhenHidden: true,
+ labelKey: vm.saveButtonKey,
+ letter: "S",
+ type: "submit",
+ handler: function () { vm.save(); }
+ };
+ vm.page.subButtons = [{
+ hotKey: "ctrl+g",
+ hotKeyWhenHidden: true,
+ labelKey: vm.generateModelsKey,
+ letter: "G",
+ handler: function () {
+
+ vm.page.saveButtonState = "busy";
+
+ vm.save().then(function (result) {
+
+ vm.page.saveButtonState = "busy";
+
+ localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
+ localizationService.localize("modelsBuilder_waitingMessage").then(function(msgValue) {
+ notificationsService.info(headerValue, msgValue);
+ });
+ });
+
+ contentTypeHelper.generateModels().then(function (result) {
+
+ if (result.success) {
+
+ //re-check model status
+ contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
+ vm.page.modelsBuilder = statusResult;
+ });
+
+ //clear and add success
+ vm.page.saveButtonState = "init";
+ localizationService.localize("modelsBuilder_modelsGenerated").then(function(value) {
+ notificationsService.success(value);
+ });
+
+ } else {
+ vm.page.saveButtonState = "error";
+ localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function(value) {
+ notificationsService.error(value);
+ });
+ }
+
+ }, function () {
+ vm.page.saveButtonState = "error";
+ localizationService.localize("modelsBuilder_modelsGeneratedError").then(function(value) {
+ notificationsService.error(value);
+ });
+ });
+
+ });
+
+ }
+ }];
+ }
+ });
+
+ if (create) {
+ vm.page.loading = true;
+
+ //we are creating so get an empty data type item
+ mediaTypeResource.getScaffold(mediaTypeId)
+ .then(function(dt) {
+ init(dt);
+
+ vm.page.loading = false;
+ });
+ }
+ else {
+ loadMediaType();
+ }
+
+ function loadMediaType() {
+ vm.page.loading = true;
+
+ mediaTypeResource.getById(mediaTypeId).then(function(dt) {
+ init(dt);
+
+ if(!infiniteMode) {
+ syncTreeNode(vm.contentType, dt.path, true);
+ }
+
+ vm.page.loading = false;
+ });
+ }
+
+ /* ---------- SAVE ---------- */
+
+ function save() {
+
+ // only save if there is no overlays open
+ if(overlayHelper.getNumberOfOverlays() === 0) {
+
+ var deferred = $q.defer();
+
+ vm.page.saveButtonState = "busy";
+
+ // reformat allowed content types to array if id's
+ vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
+
+ contentEditingHelper.contentEditorPerformSave({
+ saveMethod: mediaTypeResource.save,
+ scope: $scope,
+ content: vm.contentType,
+ //We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
+ // type when server side validation fails - as opposed to content where we are capable of saving the content
+ // item if server side validation fails
+ redirectOnFailure: false,
+ // we need to rebind... the IDs that have been created!
+ rebindCallback: function (origContentType, savedContentType) {
+ vm.contentType.id = savedContentType.id;
+ vm.contentType.groups.forEach(function (group) {
+ if (!group.name) return;
+
+ var k = 0;
+ while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
+ k++;
+ if (k == savedContentType.groups.length) {
+ group.id = 0;
+ return;
+ }
+
+ var savedGroup = savedContentType.groups[k];
+ if (!group.id) group.id = savedGroup.id;
+
+ group.properties.forEach(function (property) {
+ if (property.id || !property.alias) return;
+
+ k = 0;
+ while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
+ k++;
+ if (k == savedGroup.properties.length) {
+ property.id = 0;
+ return;
+ }
+
+ var savedProperty = savedGroup.properties[k];
+ property.id = savedProperty.id;
+ });
+ });
+ }
+ }).then(function (data) {
+ //success
+
+ if(!infiniteMode) {
+ syncTreeNode(vm.contentType, data.path);
+ }
+
+ // emit event
+ var args = { mediaType: vm.contentType };
+ eventsService.emit("editors.mediaType.saved", args);
+
+ vm.page.saveButtonState = "success";
+
+ if(infiniteMode && $scope.model.submit) {
+ $scope.model.submit();
+ }
+
+ deferred.resolve(data);
+
+ }, function (err) {
+ //error
+ if (err) {
+ editorState.set($scope.content);
+ }
+ else {
+ localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
+ localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
+ notificationsService.error(headerValue, msgValue);
+ });
+ });
+ }
+
+ vm.page.saveButtonState = "error";
+
+ deferred.reject(err);
+ });
+
+ return deferred.promise;
+ }
+ }
+
+ function init(contentType) {
+
+ // set all tab to inactive
+ if (contentType.groups.length !== 0) {
+ angular.forEach(contentType.groups, function (group) {
+
+ angular.forEach(group.properties, function (property) {
+ // get data type details for each property
+ getDataTypeDetails(property);
+ });
+
+ });
+ }
+
+ // convert icons for content type
+ convertLegacyIcons(contentType);
+
+ //set a shared state
+ editorState.set(contentType);
+
+ vm.contentType = contentType;
+ }
+
+ function convertLegacyIcons(contentType) {
+ // make array to store contentType icon
+ var contentTypeArray = [];
+
+ // push icon to array
+ contentTypeArray.push({ "icon": contentType.icon });
+
+ // run through icon method
+ iconHelper.formatContentTypeIcons(contentTypeArray);
+
+ // set icon back on contentType
+ contentType.icon = contentTypeArray[0].icon;
+ }
+
+ function getDataTypeDetails(property) {
+ if (property.propertyState !== "init") {
+
+ dataTypeResource.getById(property.dataTypeId)
+ .then(function(dataType) {
+ property.dataTypeIcon = dataType.icon;
+ property.dataTypeName = dataType.name;
+ });
+ }
+ }
+
+
+ /** Syncs the content type to it's tree node - this occurs on first load and after saving */
+ function syncTreeNode(dt, path, initialLoad) {
+ navigationService.syncTree({ tree: "mediatypes", path: path.split(","), forceReload: initialLoad !== true }).then(function(syncArgs) {
+ vm.currentNode = syncArgs.node;
+ });
+ }
+
+ function close() {
+ if(infiniteMode && $scope.model.close) {
+ $scope.model.close();
+ }
+ }
+
+ evts.push(eventsService.on("app.refreshEditor", function(name, error) {
+ loadMediaType();
+ }));
+
+ //ensure to unregister from all events!
+ $scope.$on('$destroy', function () {
+ for (var e in evts) {
+ eventsService.unsubscribe(evts[e]);
+ }
+ });
+ }
+
+ angular.module("umbraco").controller("Umbraco.Editors.MediaTypes.EditController", MediaTypesEditController);
+})();
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index 3b3d5b4b6e..711280ea4c 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -1,2170 +1,2170 @@
-
-
-
- The Umbraco community
- http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files
-
-
- Culture and Hostnames
- Audit Trail
- Browse Node
- Change Document Type
- Copy
- Create
- Export
- Create Package
- Create group
- Delete
- Disable
- Empty recycle bin
- Enable
- Export Document Type
- Import Document Type
- Import Package
- Edit in Canvas
- Exit
- Move
- Notifications
- Public access
- Publish
- Unpublish
- Reload
- Republish entire site
- Rename
- Restore
- Set permissions for the page %0%
- Choose where to move
- In the tree structure below
- Permissions
- Rollback
- Send To Publish
- Send To Translation
- Set group
- Sort
- Translate
- Update
- Set permissions
- Unlock
- Create Content Template
-
-
- Content
- Administration
- Structure
- Other
-
-
- Allow access to assign culture and hostnames
- Allow access to view a node's history log
- Allow access to view a node
- Allow access to change document type for a node
- Allow access to copy a node
- Allow access to create nodes
- Allow access to delete nodes
- Allow access to move a node
- Allow access to set and change public access for a node
- Allow access to publish a node
- Allow access to change permissions for a node
- Allow access to roll back a node to a previous state
- Allow access to send a node for approval before publishing
- Allow access to send a node for translation
- Allow access to change the sort order for nodes
- Allow access to translate a node
- Allow access to save a node
- Allow access to create a Content Template
-
-
- Permission denied.
- Add new Domain
- remove
- Invalid node.
- Invalid domain format.
- Domain has already been assigned.
- Language
- Domain
- New domain '%0%' has been created
- Domain '%0%' is deleted
- Domain '%0%' has already been assigned
- Domain '%0%' has been updated
- Edit Current Domains
-
-
-
- Inherit
- Culture
-
- or inherit culture from parent nodes. Will also apply
- to the current node, unless a domain below applies too.]]>
-
- Domains
-
-
- Viewing for
-
-
- Clear selection
- Select
- Select current folder
- Do something else
- Bold
- Cancel Paragraph Indent
- Insert form field
- Insert graphic headline
- Edit Html
- Indent Paragraph
- Italic
- Center
- Justify Left
- Justify Right
- Insert Link
- Insert local link (anchor)
- Bullet List
- Numeric List
- Insert macro
- Insert picture
- Edit relations
- Return to list
- Save
- Save and close
- Publish
- Publish…
- Save and schedule
- Save and send for approval
- Save list view
- Preview
- Preview is disabled because there's no template assigned
- Choose style
- Show styles
- Insert table
- Generate models
- Generate models and close
- Save and generate models
- Undo
- Redo
-
-
- To change the document type for the selected content, first select from the list of valid types for this location.
- Then confirm and/or amend the mapping of properties from the current type to the new, and click Save.
- The content has been re-published.
- Current Property
- Current type
- The document type cannot be changed, as there are no alternatives valid for this location. An alternative will be valid if it is allowed under the parent of the selected content item and that all existing child content items are allowed to be created under it.
- Document Type Changed
- Map Properties
- Map to Property
- New Template
- New Type
- none
- Content
- Select New Document Type
- The document type of the selected content has been successfully changed to [new type] and the following properties mapped:
- to
- Could not complete property mapping as one or more properties have more than one mapping defined.
- Only alternate types valid for the current location are displayed.
-
-
- Is Published
- About this page
- Alias
- (how would you describe the picture over the phone)
- Alternative Links
- Click to edit this item
- Created by
- Original author
- Updated by
- Created
- Date/time this document was created
- Document Type
- Editing
- Remove at
- This item has been changed after publication
- This item is not published
- Culture '%0%' for this item is not published
- Culture '%0%' for this item is not available
- Last published
- There are no items to show
- There are no items to show in the list.
- No content has been added
- No members have been added
- Media Type
- Link to media item(s)
- Member Group
- Role
- Member Type
- No changes have been made
- No date chosen
- Page title
- This media item has no link
- Properties
- This document is published but is not visible because the parent '%0%' is unpublished
- This document is published but is not in the cache
- Could not get the url
- This document is published but its url would collide with content %0%
- Publish
- Published
- Published (pending changes)
- Unpublished (pending changes)
- Publication Status
- Publish at
- Unpublish at
- Clear Date
- Set date
- Sortorder is updated
- To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting
- Statistics
- Title (optional)
- Alternative text (optional)
- Type
- Unpublish
- Unpublished
- Last edited
- Date/time this document was edited
- Remove file(s)
- Link to document
- Member of group(s)
- Not a member of group(s)
- Child items
- Target
- This translates to the following time on the server:
- What does this mean?]]>
- Are you sure you want to delete this item?
- Property %0% uses editor %1% which is not supported by Nested Content.
- Add another text box
- Remove this text box
- Content root
- This value is hidden. If you need access to view this value please contact your website administrator.
- This value is hidden.
- What languages would you like to publish?
- Published Languages.
- Ready to Publish?
-
-
- Create a new Content Template from '%0%'
- Blank
- Select a Content Template
- Content Template created
- A Content Template was created from '%0%'
- Another Content Template with the same name already exists
- A Content Template is pre-defined content that an editor can select to use as the basis for creating new content
-
-
- Click to upload
- Drop your files here...
- Link to media
- or click here to choose files
- Only allowed file types are
- Cannot upload this file, it does not have an approved file type
- Max file size is
- Media root
-
-
- Create a new member
- All Members
-
-
- Where do you want to create the new %0%
- Create an item under
- Select the document type you want to make a content template for
- Choose a type and a title
- "document types".]]>
- "media types".]]>
- Document Type without a template
- New folder
- New data type
- New javascript file
- New empty partial view
- New partial view macro
- New partial view from snippet
- New empty partial view macro
- New partial view macro from snippet
- New partial view macro (without macro)
-
-
- Browse your website
- - Hide
- If Umbraco isn't opening, you might need to allow popups from this site
- has opened in a new window
- Restart
- Visit
- Welcome
-
-
- Stay
- Discard changes
- You have unsaved changes
- Are you sure you want to navigate away from this page? - you have unsaved changes
-
-
- Done
-
- Deleted %0% item
- Deleted %0% items
- Deleted %0% out of %1% item
- Deleted %0% out of %1% items
-
- Published %0% item
- Published %0% items
- Published %0% out of %1% item
- Published %0% out of %1% items
-
- Unpublished %0% item
- Unpublished %0% items
- Unpublished %0% out of %1% item
- Unpublished %0% out of %1% items
-
- Moved %0% item
- Moved %0% items
- Moved %0% out of %1% item
- Moved %0% out of %1% items
-
- Copied %0% item
- Copied %0% items
- Copied %0% out of %1% item
- Copied %0% out of %1% items
-
-
- Link title
- Link
- Name
- Close this window
- Are you sure you want to delete
- Are you sure you want to disable
- Please check this box to confirm deletion of %0% item(s)
- Are you sure?
- Are you sure?
- Cut
- Edit Dictionary Item
- Edit Language
- Insert local link
- Insert character
- Insert graphic headline
- Insert picture
- Insert link
- Click to add a Macro
- Insert table
- Last Edited
- Link
- Internal link:
- When using local links, insert "#" in front of link
- Open in new window?
- Macro Settings
- This macro does not contain any properties you can edit
- Paste
- Edit permissions for
- Set permissions for
- Set permissions for %0% for user group %1%
- Select the users groups you want to set permissions for
- The items in the recycle bin are now being deleted. Please do not close this window while this operation takes place
- The recycle bin is now empty
- When items are deleted from the recycle bin, they will be gone forever
- regexlib.com's webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]>
- Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url'
- Remove Macro
- Required Field
- Site is reindexed
- The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished
- The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished.
- Number of columns
- Number of rows
-
- Set a placeholder id by setting an ID on your placeholder you can inject content into this template from child templates,
- by referring this ID using a <asp:content /> element.]]>
-
-
- Select a placeholder id from the list below. You can only
- choose Id's from the current template's master.]]>
-
- Click on the image to see full size
- Pick item
- View Cache Item
- Create folder...
- Relate to original
- Include descendants
- The friendliest community
- Link to page
- Opens the linked document in a new window or tab
- Link to media
- Link to file
- Select content start node
- Select media
- Select icon
- Select item
- Select link
- Select macro
- Select content
- Select media start node
- Select member
- Select member group
- Select node
- Select sections
- Select users
- No icons were found
- There are no parameters for this macro
- There are no macros available to insert
- External login providers
- Exception Details
- Stacktrace
- Inner Exception
- Link your
- Un-link your
- account
- Select editor
- Select snippet
- This will delete the node and all its languages. If you only want to delete one language go and unpublish it instead.
-
-
-
- %0%' below You can add additional languages under the 'languages' in the menu on the left
- ]]>
-
- Culture Name
- Edit the key of the dictionary item.
-
-
-
-
-
- Enter your username
- Enter your password
- Confirm your password
- Name the %0%...
- Enter a name...
- Enter an email...
- Enter a username...
- Label...
- Enter a description...
- Type to search...
- Type to filter...
- Type to add tags (press enter after each tag)...
- Enter your email...
- Enter a message...
- Your username is usually your email
-
-
- Allow at root
- Only Content Types with this checked can be created at the root level of Content and Media trees
- Allowed child node types
- Document Type Compositions
- Create
- Delete tab
- Description
- New tab
- Tab
- Thumbnail
- Enable list view
- Configures the content item to show a sortable & searchable list of its children, the children will not be shown in the tree
- Current list view
- The active list view data type
- Create custom list view
- Remove custom list view
-
-
- Renamed
- Enter a new folder name here
- %0% was renamed to %1%
-
-
- Add prevalue
- Database datatype
- Property editor GUID
- Property editor
- Buttons
- Enable advanced settings for
- Enable context menu
- Maximum default size of inserted images
- Related stylesheets
- Show label
- Width and height
- All property types & property data
- using this data type will be deleted permanently, please confirm you want to delete these as well
- Yes, delete
- and all property types & property data using this data type
- Select the folder to move
- to in the tree structure below
- was moved underneath
-
-
- Your data has been saved, but before you can publish this page there are some errors you need to fix first:
- The current membership provider does not support changing password (EnablePasswordRetrieval need to be true)
- %0% already exists
- There were errors:
- There were errors:
- The password should be a minimum of %0% characters long and contain at least %1% non-alpha numeric character(s)
- %0% must be an integer
- The %0% field in the %1% tab is mandatory
- %0% is a mandatory field
- %0% at %1% is not in a correct format
- %0% is not in a correct format
-
-
- Received an error from the server
- The specified file type has been disallowed by the administrator
- NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough.
- Please fill both alias and name on the new property type!
- There is a problem with read/write access to a specific file or folder
- Error loading Partial View script (file: %0%)
- Error loading userControl '%0%'
- Error loading customControl (Assembly: %0%, Type: '%1%')
- Error loading MacroEngine script (file: %0%)
- Please enter a title
- Please choose a type
- You're about to make the picture larger than the original size. Are you sure that you want to proceed?
- Error in python script
- The python script has not been saved, because it contained error(s)
- Startnode deleted, please contact your administrator
- Please mark content before changing style
- No active styles available
- Please place cursor at the left of the two cells you wish to merge
- You cannot split a cell that hasn't been merged.
- There is a configuration error with the data type used for this property, please check the data type
-
-
- Options
- About
- Action
- Actions
- Add
- Alias
- All
- Are you sure?
- Back
- Border
- by
- Cancel
- Cell margin
- Choose
- Close
- Close Window
- Comment
- Confirm
- Constrain
- Constrain proportions
- Continue
- Copy
- Create
- Database
- Date
- Default
- Delete
- Deleted
- Deleting...
- Design
- Dictionary
- Dimensions
- Down
- Download
- Edit
- Edited
- Elements
- Email
- Error
- Find
- First
- General
- Groups
- Height
- Help
- Hide
- History
- Icon
- Import
- Info
- Inner margin
- Insert
- Install
- Invalid
- Justify
- Label
- Language
- Last
- Layout
- Links
- Loading
- Locked
- Login
- Log off
- Logout
- Macro
- Mandatory
- Message
- Move
- More
- Name
- New
- Next
- No
- of
- Off
- OK
- Open
- On
- or
- Order by
- Password
- Path
- Placeholder ID
- One moment please...
- Previous
- Properties
- Email to receive form data
- Recycle Bin
- Your recycle bin is empty
- Remaining
- Remove
- Rename
- Renew
- Required
- Retrieve
- Retry
- Permissions
- Scheduled Publishing
- Search
- Sorry, we can not find what you are looking for
- No items have been added
- Server
- Settings
- Show
- Show page on Send
- Size
- Sort
- Status
- Submit
- Type
- Type to search...
- Up
- Update
- Upgrade
- Upload
- Url
- User
- Username
- Value
- View
- Welcome...
- Width
- Yes
- Folder
- Search results
- Reorder
- I am done reordering
- Preview
- Change password
- to
- List view
- Saving...
- current
- Embed
- Retrieve
- selected
-
-
- Black
- Green
- Yellow
- Orange
- Blue
- Blue Grey
- Grey
- Brown
- Light Blue
- Cyan
- Light Green
- Lime
- Amber
- Deep Orange
- Red
- Pink
- Purple
- Deep Purple
- Indigo
-
-
- Add tab
- Add property
- Add editor
- Add template
- Add child node
- Add child
-
- Edit data type
-
- Navigate sections
-
- Shortcuts
- show shortcuts
-
- Toggle list view
- Toggle allow as root
-
- Comment/Uncomment lines
- Remove line
- Copy Lines Up
- Copy Lines Down
- Move Lines Up
- Move Lines Down
-
- General
- Editor
-
-
- Background color
- Bold
- Text color
- Font
- Text
-
-
- Page
-
-
- The installer cannot connect to the database.
- Could not save the web.config file. Please modify the connection string manually.
- Your database has been found and is identified as
- Database configuration
-
- install button to install the Umbraco %0% database
- ]]>
-
- Next to proceed.]]>
-
- Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.
-
To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file.
]]>
-
-
-
- Please contact your ISP if necessary.
- If you're installing on a local machine or server you might need information from your system administrator.]]>
-
-
-
- Press the upgrade button to upgrade your database to Umbraco %0%
-
- Don't worry - no content will be deleted and everything will continue working afterwards!
-
- ]]>
-
-
- Press Next to
- proceed. ]]>
-
- next to continue the configuration wizard]]>
- The Default users' password needs to be changed!]]>
- The Default user has been disabled or has no access to Umbraco!
No further actions needs to be taken. Click Next to proceed.]]>
- The Default user's password has been successfully changed since the installation!
No further actions needs to be taken. Click Next to proceed.]]>
- The password is changed!
- Get a great start, watch our introduction videos
- By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this Umbraco distribution consists of two different licenses, the open source MIT license for the framework and the Umbraco freeware license that covers the UI.
- Not installed yet.
- Affected files and folders
- More information on setting up permissions for Umbraco here
- You need to grant ASP.NET modify permissions to the following files/folders
-
- Your permission settings are almost perfect!
- You can run Umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of Umbraco.]]>
-
- How to Resolve
- Click here to read the text version
- video tutorial on setting up folder permissions for Umbraco or read the text version.]]>
-
- Your permission settings might be an issue!
-
- You can run Umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of Umbraco.]]>
-
-
- Your permission settings are not ready for Umbraco!
-
- In order to run Umbraco, you'll need to update your permission settings.]]>
-
-
- Your permission settings are perfect!
- You are ready to run Umbraco and install packages!]]>
-
- Resolving folder issue
- Follow this link for more information on problems with ASP.NET and creating folders
- Setting up folder permissions
-
-
-
- I want to start from scratch
-
- learn how)
- You can still choose to install Runway later on. Please go to the Developer section and choose Packages.
- ]]>
-
- You've just set up a clean Umbraco platform. What do you want to do next?
- Runway is installed
-
-
- This is our list of recommended modules, check off the ones you would like to install, or view the full list of modules
- ]]>
-
- Only recommended for experienced users
- I want to start with a simple website
-
-
- "Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically,
- but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However,
- Runway offers an easy foundation based on best practices to get you started faster than ever.
- If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages.
-
-
- Included with Runway: Home page, Getting Started page, Installing Modules page.
- Optional Modules: Top Navigation, Sitemap, Contact, Gallery.
-
- ]]>
-
- What is Runway
- Step 1/5 Accept license
- Step 2/5: Database configuration
- Step 3/5: Validating File Permissions
- Step 4/5: Check Umbraco security
- Step 5/5: Umbraco is ready to get you started
- Thank you for choosing Umbraco
-
- Browse your new site
-You installed Runway, so why not see how your new website looks.]]>
-
-
- Further help and information
-Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the Umbraco terminology]]>
-
- Umbraco %0% is installed and ready for use
-
- /web.config file and update the AppSetting key UmbracoConfigurationStatus in the bottom to the value of '%0%'.]]>
-
-
- started instantly by clicking the "Launch Umbraco" button below. If you are new to Umbraco,
-you can find plenty of resources on our getting started pages.]]>
-
-
- Launch Umbraco
-To manage your website, simply open the Umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]>
-
- Connection to database failed.
- Umbraco Version 3
- Umbraco Version 4
- Watch
-
- Umbraco %0% for a fresh install or upgrading from version 3.0.
-