Model, retrieval, mapping and display for fall back language editing
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a new, self-joined field to umbracoLanguages to hold the fall-back language for
|
||||
/// a given language.
|
||||
/// </summary>
|
||||
public class FallbackLanguage : MigrationBase
|
||||
{
|
||||
public FallbackLanguage(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.Language) && x.ColumnName.InvariantEquals("fallbackLanguageId")) == false)
|
||||
AddColumn<LanguageDto>("fallbackLanguageId");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,5 +33,11 @@ namespace Umbraco.Core.Models
|
||||
/// If true, a variant node cannot be published unless this language variant is created
|
||||
/// </summary>
|
||||
bool Mandatory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the fallback language that can be used in multi-lingual scenarios to provide
|
||||
/// content if the requested language does not have it published.
|
||||
/// </summary>
|
||||
ILanguage FallbackLanguage { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Umbraco.Core.Models
|
||||
private string _cultureName;
|
||||
private bool _isDefaultVariantLanguage;
|
||||
private bool _mandatory;
|
||||
private ILanguage _fallbackLanguage;
|
||||
|
||||
public Language(string isoCode)
|
||||
{
|
||||
@@ -32,6 +33,7 @@ namespace Umbraco.Core.Models
|
||||
public readonly PropertyInfo CultureNameSelector = ExpressionHelper.GetPropertyInfo<Language, string>(x => x.CultureName);
|
||||
public readonly PropertyInfo IsDefaultVariantLanguageSelector = ExpressionHelper.GetPropertyInfo<Language, bool>(x => x.IsDefaultVariantLanguage);
|
||||
public readonly PropertyInfo MandatorySelector = ExpressionHelper.GetPropertyInfo<Language, bool>(x => x.Mandatory);
|
||||
public readonly PropertyInfo FallbackLanguageSelector = ExpressionHelper.GetPropertyInfo<Language, ILanguage>(x => x.FallbackLanguage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -71,5 +73,11 @@ namespace Umbraco.Core.Models
|
||||
get => _mandatory;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _mandatory, Ps.Value.MandatorySelector);
|
||||
}
|
||||
|
||||
public ILanguage FallbackLanguage
|
||||
{
|
||||
get => _fallbackLanguage;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _fallbackLanguage, Ps.Value.FallbackLanguageSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,5 +38,14 @@ namespace Umbraco.Core.Persistence.Dtos
|
||||
[Column("mandatory")]
|
||||
[Constraint(Default = "0")]
|
||||
public bool Mandatory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the fallback language that can be used in multi-lingual scenarios to provide
|
||||
/// content if the requested language does not have it published.
|
||||
/// </summary>
|
||||
[Column("fallbackLanguageId")]
|
||||
[ForeignKey(typeof(LanguageDto), Column = "id")]
|
||||
[Index(IndexTypes.NonClustered)]
|
||||
public int? FallbackLanguageId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
sql.OrderBy<LanguageDto>(dto => dto.Id);
|
||||
|
||||
// get languages
|
||||
var languages = Database.Fetch<LanguageDto>(sql).Select(ConvertFromDto).ToList();
|
||||
var dtos = Database.Fetch<LanguageDto>(sql);
|
||||
var languages = dtos.Select(ConvertFromDto).ToList();
|
||||
PopulateFallbackLanguages(dtos, languages);
|
||||
|
||||
// initialize the code-id map
|
||||
lock (_codeIdMap)
|
||||
@@ -74,7 +76,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<ILanguage>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
return Database.Fetch<LanguageDto>(sql).Select(ConvertFromDto);
|
||||
var dtos = Database.Fetch<LanguageDto>(sql);
|
||||
var languages = dtos.Select(ConvertFromDto).ToList();
|
||||
PopulateFallbackLanguages(dtos, languages);
|
||||
return languages;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -199,7 +204,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var entity = LanguageFactory.BuildEntity(dto);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
private static void PopulateFallbackLanguages(List<LanguageDto> dtos, IList<ILanguage> languages)
|
||||
{
|
||||
foreach (var dto in dtos.Where(x => x.FallbackLanguageId.HasValue))
|
||||
{
|
||||
var language = languages.Single(x => x.Id == dto.Id);
|
||||
// ReSharper disable once PossibleInvalidOperationException (DTOs with fallback languages have already been filtered in the loop condition)
|
||||
language.FallbackLanguage = languages.Single(x => x.Id == dto.FallbackLanguageId.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public ILanguage GetByIsoCode(string isoCode)
|
||||
{
|
||||
TypedCachePolicy.GetAllCached(PerformGetAll); // ensure cache is populated, in a non-expensive way
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RefactorMacroColumns.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\SuperZero.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\TagsMigration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\FallbackLanguage.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\UserForeignKeys.cs" />
|
||||
<Compile Include="Models\AuditEntry.cs" />
|
||||
<Compile Include="Models\Consent.cs" />
|
||||
|
||||
@@ -56,6 +56,20 @@
|
||||
|
||||
});
|
||||
|
||||
$scope.properties = {
|
||||
fallbackLanguage: {
|
||||
alias: "fallbackLanguage",
|
||||
description: "To allow multi-lingual content to fall back to another language if not present in the requested language, select it here.",
|
||||
label: "Fall back language"
|
||||
}
|
||||
};
|
||||
|
||||
vm.loading = true;
|
||||
languageResource.getAll().then(function (languages) {
|
||||
vm.availableLanguages = languages;
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
if(!$routeParams.create) {
|
||||
|
||||
vm.loading = true;
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
hide-alias="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
<umb-editor-container class="form-horizontal">
|
||||
|
||||
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
|
||||
|
||||
<umb-box ng-if="!vm.loading" class="block-form">
|
||||
<umb-box ng-if="!vm.loading">
|
||||
<umb-box-content>
|
||||
|
||||
<umb-control-group label="@general_language" ng-if="vm.availableCultures">
|
||||
@@ -64,6 +64,17 @@
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-property property="properties.fallbackLanguage">
|
||||
<div>
|
||||
<select name="fallbackLanguage"
|
||||
ng-model="vm.language.fallbackLanguage.id"
|
||||
required
|
||||
ng-options="l.id as l.name for l in vm.availableLanguages">
|
||||
<option value="">No fall back language</option>
|
||||
</select>
|
||||
</div>
|
||||
</umb-property>
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
"treeHeaders_languages",
|
||||
"general_mandatory",
|
||||
"general_default",
|
||||
"languages_fallsbackToLabel"
|
||||
];
|
||||
|
||||
localizationService.localizeMany(labelKeys).then(function (values) {
|
||||
vm.labels.languages = values[0];
|
||||
vm.labels.mandatory = values[1];
|
||||
vm.labels.general = values[2];
|
||||
vm.labels.fallsbackTo = values[3];
|
||||
// set page name
|
||||
vm.page.name = vm.labels.languages;
|
||||
});
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<span ng-if="language.isDefault">- {{vm.labels.general}}</span>
|
||||
</td>
|
||||
<td><span ng-if="language.isMandatory">{{vm.labels.mandatory}}</span></td>
|
||||
<td><span ng-if="language.fallbackLanguage">{{vm.labels.fallsbackTo}}: {{language.fallbackLanguage.name}}</span></td>
|
||||
<td style="text-align: right;">
|
||||
<umb-button
|
||||
ng-if="!language.isDefault"
|
||||
|
||||
@@ -1661,6 +1661,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="defaultLanguage">Default language</key>
|
||||
<key alias="defaultLanguageHelp">An Umbraco site can only have one default langugae set.</key>
|
||||
<key alias="changingDefaultLanguageWarning">Switching default language may result in default content missing.</key>
|
||||
<key alias="fallsbackToLabel">Falls back to</key>
|
||||
</area>
|
||||
|
||||
<area alias="modelsBuilder">
|
||||
|
||||
@@ -24,5 +24,8 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
|
||||
[DataMember(Name = "isMandatory")]
|
||||
public bool Mandatory { get; set; }
|
||||
|
||||
[DataMember(Name = "fallbackLanguage")]
|
||||
public Language FallbackLanguage { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user