|
- {{ language.cultureDisplayName }}
+ {{ language.name }}
- {{vm.labels.general}}
|
{{vm.labels.mandatory}} |
@@ -55,4 +55,4 @@
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js
index 8b326db4f5..266bc3264b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.controller.js
@@ -249,7 +249,7 @@
function init() {
//we need to load this somewhere, for now its here.
- assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
+ assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
if ($routeParams.create) {
@@ -355,4 +355,4 @@
}
angular.module("umbraco").controller("Umbraco.Editors.PartialViewMacros.EditController", partialViewMacrosEditController);
-})();
\ No newline at end of file
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.controller.js
index d10c0e23be..960549aabf 100644
--- a/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.controller.js
@@ -242,7 +242,7 @@
function init() {
//we need to load this somewhere, for now its here.
- assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
+ assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
if ($routeParams.create) {
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js
index dd25741aeb..98e649729c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js
@@ -105,5 +105,5 @@
};
//load the separate css for the editor to avoid it blocking our js loading
- assetsService.loadCss("lib/spectrum/spectrum.css");
+ assetsService.loadCss("lib/spectrum/spectrum.css", $scope);
});
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js
index 6c1e596014..1e0493e8f1 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/datepicker/datepicker.controller.js
@@ -112,7 +112,7 @@ function dateTimePickerController($scope, notificationsService, assetsService, a
//get the current user to see if we can localize this picker
userService.getCurrentUser().then(function (user) {
- assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css').then(function() {
+ assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css', $scope).then(function() {
var filesToLoad = ["lib/datetimepicker/bootstrap-datetimepicker.js"];
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js
index 1d6261c10a..f32c188d63 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js
@@ -2,7 +2,7 @@ angular.module("umbraco")
.controller("Umbraco.PropertyEditors.GoogleMapsController",
function ($element, $rootScope, $scope, notificationsService, dialogService, assetsService, $log, $timeout) {
- assetsService.loadJs('https://www.google.com/jsapi')
+ assetsService.loadJs('https://www.google.com/jsapi', $scope)
.then(function () {
google.load("maps", "3",
{
@@ -94,4 +94,4 @@ angular.module("umbraco")
//update the display val again if it has changed from the server
initMap();
};
- });
\ No newline at end of file
+ });
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js
index 7a3abdd0e6..155fa3d854 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js
@@ -74,7 +74,7 @@ function MarkdownEditorController($scope, $element, assetsService, dialogService
});
//load the seperat css for the editor to avoid it blocking our js loading TEMP HACK
- assetsService.loadCss("lib/markdown/markdown.css");
+ assetsService.loadCss("lib/markdown/markdown.css", $scope);
})
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js
index 65a62f599c..e1c9ce9ba2 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js
@@ -117,5 +117,5 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
});
// load TinyMCE skin which contains css for font-icons
- assetsService.loadCss("lib/tinymce/skins/umbraco/skin.min.css");
- });
\ No newline at end of file
+ assetsService.loadCss("lib/tinymce/skins/umbraco/skin.min.css", $scope);
+ });
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/slider.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/slider.controller.js
index 321ac13555..95b74a2ced 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/slider.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/slider/slider.controller.js
@@ -211,7 +211,7 @@
});
//load the separate css for the editor to avoid it blocking our js loading
- assetsService.loadCss("lib/slider/bootstrap-slider.css");
- assetsService.loadCss("lib/slider/bootstrap-slider-custom.css");
+ assetsService.loadCss("lib/slider/bootstrap-slider.css", $scope);
+ assetsService.loadCss("lib/slider/bootstrap-slider-custom.css", $scope);
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.SliderController", sliderController);
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
index 7ca067f9ca..b2ac308249 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
@@ -7,7 +7,7 @@ angular.module("umbraco")
$scope.isLoading = true;
$scope.tagToAdd = "";
- assetsService.loadJs("lib/typeahead.js/typeahead.bundle.min.js").then(function () {
+ assetsService.loadJs("lib/typeahead.js/typeahead.bundle.min.js", $scope).then(function () {
$scope.isLoading = false;
diff --git a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js
index c284100cb2..68fd2d0107 100644
--- a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.controller.js
@@ -92,7 +92,7 @@
function init() {
//we need to load this somewhere, for now its here.
- assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
+ assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
if ($routeParams.create) {
codefileResource.getScaffold("scripts", $routeParams.id).then(function (script) {
@@ -199,4 +199,4 @@
}
angular.module("umbraco").controller("Umbraco.Editors.Scripts.EditController", ScriptsEditController);
-})();
\ No newline at end of file
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js
index 5d2129668e..36f64c11ee 100644
--- a/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js
@@ -105,7 +105,7 @@
vm.init = function () {
//we need to load this somewhere, for now its here.
- assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css");
+ assetsService.loadCss("lib/ace-razor-mode/theme/razor_chrome.css", $scope);
//load templates - used in the master template picker
templateResource.getAll()
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index f16ad10645..a07112b36e 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -91,7 +91,7 @@
-
+
@@ -175,6 +175,231 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ All
+
+ -->
+
+
+
+
+
+
+ ../packages/log4net.2.0.8/lib/net45-full/log4net.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.Mvc.5.2.3/lib/net45/System.Web.Mvc.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.WebApi.Core.5.2.3/lib/net45/System.Web.Http.dll
+ True
+
+
+ ../packages/ClientDependency-Mvc5.1.8.0.0/lib/net45/ClientDependency.Core.Mvc.dll
+ True
+
+
+ ../packages/SharpZipLib.0.86.0/lib/20/ICSharpCode.SharpZipLib.dll
+ True
+
+
+ ../packages/ImageProcessor.2.5.4/lib/net45/ImageProcessor.dll
+ True
+
+
+ ..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Analyzers.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Core.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.FastVectorHighlighter.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Highlighter.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Memory.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Queries.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Regex.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.SimpleFacetedSearch.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.Snowball.dll
+ True
+
+
+ ..\packages\Lucene.Net.Contrib.3.0.3\lib\net40\Lucene.Net.Contrib.SpellChecker.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.Identity.Core.2.2.1/lib/net45/Microsoft.AspNet.Identity.Core.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.Identity.Owin.2.2.1/lib/net45/Microsoft.AspNet.Identity.Owin.dll
+ True
+
+
+ ../packages/Microsoft.Owin.3.1.0/lib/net45/Microsoft.Owin.dll
+ True
+
+
+ ../packages/Microsoft.Owin.Host.SystemWeb.3.1.0/lib/net45/Microsoft.Owin.Host.SystemWeb.dll
+ True
+
+
+ ../packages/Microsoft.Owin.Security.3.1.0/lib/net45/Microsoft.Owin.Security.dll
+ True
+
+
+ ../packages/Microsoft.Owin.Security.Cookies.3.1.0/lib/net45/Microsoft.Owin.Security.Cookies.dll
+ True
+
+
+ ../packages/Microsoft.Owin.Security.OAuth.3.1.0/lib/net45/Microsoft.Owin.Security.OAuth.dll
+ True
+
+
+ ../packages/MiniProfiler.3.2.0.157/lib/net40/MiniProfiler.dll
+ True
+
+
+ ../packages/MySql.Data.6.9.9/lib/net45/MySql.Data.dll
+ True
+
+
+ ../packages/Owin.1.0/lib/net40/Owin.dll
+ True
+
+
+ ../packages/System.Collections.Immutable.1.3.1/lib/netstandard1.0/System.Collections.Immutable.dll
+ True
+
+
+ ../packages/SqlServerCE.4.0.0.1/lib/System.Data.SqlServerCe.dll
+ True
+
+
+ ../packages/SqlServerCE.4.0.0.1/lib/System.Data.SqlServerCe.Entity.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.WebApi.Client.5.2.3/lib/net45/System.Net.Http.Formatting.dll
+ True
+
+
+ ../packages/System.Reflection.Metadata.1.4.1/lib/portable-net45+win8/System.Reflection.Metadata.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.WebPages.3.2.3/lib/net45/System.Web.Helpers.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.WebApi.WebHost.5.2.3/lib/net45/System.Web.Http.WebHost.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.Razor.3.2.3/lib/net45/System.Web.Razor.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.WebPages.3.2.3/lib/net45/System.Web.WebPages.dll
+ True
+
+
+ ../packages/Microsoft.Web.Infrastructure.1.0.0.0/lib/net40/Microsoft.Web.Infrastructure.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.WebPages.3.2.3/lib/net45/System.Web.WebPages.Deployment.dll
+ True
+
+
+ ../packages/Microsoft.AspNet.WebPages.3.2.3/lib/net45/System.Web.WebPages.Razor.dll
+ True
+
+
+ ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll
+
+
+ ..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll
+ True
+
+
+ ..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll
+ True
+
+
+ ../packages/System.Xml.XPath.XDocument.4.3.0/lib/net46/System.Xml.XPath.XDocument.dll
+ True
+
@@ -736,6 +961,8 @@
+
+
11.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0
diff --git a/src/Umbraco.Web/Composing/CompositionRoots/WebMappingProfilesCompositionRoot.cs b/src/Umbraco.Web/Composing/CompositionRoots/WebMappingProfilesCompositionRoot.cs
index 77ded444b6..0c73e64ff2 100644
--- a/src/Umbraco.Web/Composing/CompositionRoots/WebMappingProfilesCompositionRoot.cs
+++ b/src/Umbraco.Web/Composing/CompositionRoots/WebMappingProfilesCompositionRoot.cs
@@ -23,6 +23,7 @@ namespace Umbraco.Web.Composing.CompositionRoots
container.Register();
container.Register();
container.Register();
+ container.Register();
}
}
}
diff --git a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs
index 713d386140..a0cf6c3767 100644
--- a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs
+++ b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs
@@ -285,6 +285,10 @@ namespace Umbraco.Web.Editors
{
"backOfficeAssetsApiBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl(
controller => controller.GetSupportedMomentLocales())
+ },
+ {
+ "languageApiBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl(
+ controller => controller.GetAllLanguages())
}
}
},
diff --git a/src/Umbraco.Web/Editors/LanguageController.cs b/src/Umbraco.Web/Editors/LanguageController.cs
index 20932f6bf9..e2439e0afc 100644
--- a/src/Umbraco.Web/Editors/LanguageController.cs
+++ b/src/Umbraco.Web/Editors/LanguageController.cs
@@ -1,10 +1,17 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Net;
+using System.Net.Http;
using System.Web.Http;
+using AutoMapper;
+using Umbraco.Core;
using Umbraco.Core.Persistence;
using Umbraco.Web.Models;
+using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
+using Umbraco.Web.WebApi;
namespace Umbraco.Web.Editors
{
@@ -12,6 +19,7 @@ namespace Umbraco.Web.Editors
/// Backoffice controller supporting the dashboard for language administration.
///
[PluginController("UmbracoApi")]
+ [PrefixlessBodyModelValidator]
public class LanguageController : UmbracoAuthorizedJsonController
{
///
@@ -19,10 +27,12 @@ namespace Umbraco.Web.Editors
///
///
[HttpGet]
- public IEnumerable GetAllCultures()
+ public IDictionary GetAllCultures()
{
- return CultureInfo.GetCultures(CultureTypes.AllCultures)
- .Select(x => new Culture {IsoCode = x.Name, Name = x.DisplayName});
+ return
+ CultureInfo.GetCultures(CultureTypes.AllCultures)
+ .Where(x => !x.Name.IsNullOrWhiteSpace())
+ .OrderBy(x => x.DisplayName).ToDictionary(x => x.Name, x => x.DisplayName);
}
///
@@ -32,52 +42,125 @@ namespace Umbraco.Web.Editors
[HttpGet]
public IEnumerable GetAllLanguages()
{
- var allLanguages = Services.LocalizationService.GetAllLanguages();
+ var allLanguages = Services.LocalizationService.GetAllLanguages().OrderBy(x => x.Id).ToList();
+ var langs = Mapper.Map>(allLanguages).ToList();
- return allLanguages.Select(x => new Language
+ //if there's only one language, by default it is the default
+ if (langs.Count == 1)
{
- Id = x.Id,
- IsoCode = x.IsoCode,
- Name = x.CultureInfo.DisplayName,
- IsDefaultVariantLanguage = x.IsDefaultVariantLanguage,
- Mandatory = x.Mandatory
- });
+ langs[0].IsDefaultVariantLanguage = true;
+ langs[0].Mandatory = true;
+ }
+ else if (allLanguages.All(x => !x.IsDefaultVariantLanguage))
+ {
+ //if no language has the default flag, then the defaul language is the one with the lowest id
+ langs[0].IsDefaultVariantLanguage = true;
+ langs[0].Mandatory = true;
+ }
+
+ return langs.OrderBy(x => x.Name);
}
-
+
+ [HttpGet]
+ public Language GetLanguage(int id)
+ {
+ var lang = Services.LocalizationService.GetLanguageById(id);
+ if (lang == null)
+ throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
+
+ var model = Mapper.Map(lang);
+
+ //if there's only one language, by default it is the default
+ var allLangs = Services.LocalizationService.GetAllLanguages().OrderBy(x => x.Id).ToList();
+ if (!lang.IsDefaultVariantLanguage)
+ {
+ if (allLangs.Count == 1)
+ {
+ model.IsDefaultVariantLanguage = true;
+ model.Mandatory = true;
+ }
+ else if (allLangs.All(x => !x.IsDefaultVariantLanguage))
+ {
+ //if no language has the default flag, then the defaul language is the one with the lowest id
+ model.IsDefaultVariantLanguage = allLangs[0].Id == lang.Id;
+ model.Mandatory = allLangs[0].Id == lang.Id;
+ }
+ }
+
+
+ return model;
+ }
+
///
/// Deletes a language with a given ID
///
[HttpDelete]
[HttpPost]
- public void DeleteLanguage(int id)
+ public IHttpActionResult DeleteLanguage(int id)
{
var language = Services.LocalizationService.GetLanguageById(id);
- if (language == null)
+ if (language == null) return NotFound();
+
+ var totalLangs = Services.LocalizationService.GetAllLanguages().Count();
+
+ if (language.IsDefaultVariantLanguage || totalLangs == 1)
{
- throw new EntityNotFoundException(id, $"Could not find language by id: '{id}'.");
+ var message = $"Language '{language.IsoCode}' is currently set to 'default' or it is the only installed language and can not be deleted.";
+ throw new HttpResponseException(Request.CreateNotificationValidationErrorResponse(message));
}
+
Services.LocalizationService.Delete(language);
+
+ return Ok();
}
///
- /// Saves a bulk set of languages with default/mandatory settings and returns the full set of languages configured.
+ /// Creates or saves a language
///
[HttpPost]
- public IEnumerable SaveLanguages(IEnumerable languages)
+ public Language SaveLanguage(Language language)
{
- foreach (var l in languages)
+ if (!ModelState.IsValid)
+ throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState));
+
+ var found = Services.LocalizationService.GetLanguageByIsoCode(language.IsoCode);
+
+ if (found != null && language.Id != found.Id)
{
- var language = Services.LocalizationService.GetLanguageByIsoCode(l.IsoCode);
- if (language == null)
- {
- language = new Core.Models.Language(l.IsoCode);
- }
- language.Mandatory = l.Mandatory;
- language.IsDefaultVariantLanguage = l.IsDefaultVariantLanguage;
- Services.LocalizationService.Save(language);
+ //someone is trying to create a language that alraedy exist
+ ModelState.AddModelError("IsoCode", "The language " + language.IsoCode + " already exists");
+ throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState));
}
- return GetAllLanguages();
+ if (found == null)
+ {
+ CultureInfo culture;
+ try
+ {
+ culture = CultureInfo.GetCultureInfo(language.IsoCode);
+ }
+ catch (CultureNotFoundException)
+ {
+ ModelState.AddModelError("IsoCode", "No Culture found with name " + language.IsoCode);
+ throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState));
+ }
+
+ //create it
+ var newLang = new Umbraco.Core.Models.Language(culture.Name)
+ {
+ CultureName = culture.DisplayName,
+ IsDefaultVariantLanguage = language.IsDefaultVariantLanguage,
+ Mandatory = language.Mandatory
+ };
+ Services.LocalizationService.Save(newLang);
+ return Mapper.Map(newLang);
+ }
+
+ found.Mandatory = language.Mandatory;
+ found.IsDefaultVariantLanguage = language.IsDefaultVariantLanguage;
+ Services.LocalizationService.Save(found);
+ return Mapper.Map(found);
}
+
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Models/ContentEditing/Language.cs b/src/Umbraco.Web/Models/ContentEditing/Language.cs
new file mode 100644
index 0000000000..f78d2bd28f
--- /dev/null
+++ b/src/Umbraco.Web/Models/ContentEditing/Language.cs
@@ -0,0 +1,28 @@
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+
+namespace Umbraco.Web.Models.ContentEditing
+{
+ [DataContract(Name = "language", Namespace = "")]
+ public class Language
+ {
+ [DataMember(Name = "id")]
+ public int Id { get; set; }
+
+ [DataMember(Name = "culture", IsRequired = true)]
+ [Required(AllowEmptyStrings = false)]
+ public string IsoCode { get; set; }
+
+ [DataMember(Name = "name")]
+ [ReadOnly(true)]
+ public string Name { get; set; }
+
+ [DataMember(Name = "isDefault")]
+ public bool IsDefaultVariantLanguage { get; set; }
+
+ [DataMember(Name = "isMandatory")]
+ public bool Mandatory { get; set; }
+ }
+}
diff --git a/src/Umbraco.Web/Models/Culture.cs b/src/Umbraco.Web/Models/Culture.cs
deleted file mode 100644
index 16ebc6bc2a..0000000000
--- a/src/Umbraco.Web/Models/Culture.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Umbraco.Web.Models
-{
- public class Culture
- {
- public string IsoCode { get; set; }
- public string Name { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Models/Language.cs b/src/Umbraco.Web/Models/Language.cs
deleted file mode 100644
index 4fdf418eef..0000000000
--- a/src/Umbraco.Web/Models/Language.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Globalization;
-
-namespace Umbraco.Web.Models
-{
- public class Language
- {
- public int Id { get; set; }
- public string IsoCode { get; set; }
- public string Name { get; set; }
- public bool IsDefaultVariantLanguage { get; set; }
- public bool Mandatory { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs
new file mode 100644
index 0000000000..6b9a64d60a
--- /dev/null
+++ b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs
@@ -0,0 +1,17 @@
+using System.Globalization;
+using AutoMapper;
+using Umbraco.Core.Models;
+using Umbraco.Web.Models.ContentEditing;
+using Language = Umbraco.Web.Models.ContentEditing.Language;
+
+namespace Umbraco.Web.Models.Mapping
+{
+ internal class LanguageMapperProfile : Profile
+ {
+ public LanguageMapperProfile()
+ {
+ CreateMap()
+ .ForMember(l => l.Name, expression => expression.MapFrom(x => x.CultureInfo.DisplayName));
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Trees/LanguageTreeController.cs b/src/Umbraco.Web/Trees/LanguageTreeController.cs
index 0e547fea6a..9a9f32128c 100644
--- a/src/Umbraco.Web/Trees/LanguageTreeController.cs
+++ b/src/Umbraco.Web/Trees/LanguageTreeController.cs
@@ -34,7 +34,7 @@ namespace Umbraco.Web.Trees
//this will load in a custom UI instead of the dashboard for the root node
root.RoutePath = string.Format("{0}/{1}/{2}", Constants.Applications.Settings, Constants.Trees.Languages, "overview");
- root.Icon = "icon-flag-alt";
+ root.Icon = "icon-globe";
root.HasChildren = false;
root.MenuUrl = null;
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index fec49a09d3..86c72c51d3 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -72,6 +72,9 @@
+
+
+
@@ -216,6 +219,7 @@
+
@@ -239,14 +243,14 @@
-
-
+
+