Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,60 @@
height = 100
};

// Culture-aware field selection for the Rule content-type.
// Mirrors FallacyExplorer (PR #490): cascade lang -> en -> fr on suffixed fields.
// ADDS a 4th fallback on the generic (unsuffixed) field: the Rule content-type
// currently exposes generic fields (Summary, Material, ...) holding the FR
// canonical value, with no language dimensions wired yet. Without the generic
// fallback, Loc() would return "" until the DB gains suffixed fields — breaking
// the current FR rendering. The generic fallback preserves FR during the
// DB-migration transition (gated on the 2sxc portal export, jsboige).
// See investigation PR #669 (RulesExplorer FR-only = cause of audit #662).
var lang = (CmsContext.Culture.CurrentCode ?? "fr-fr").Split(new[] { '-' })[0].ToLowerInvariant();
var supported = new HashSet<string> { "fr", "en", "ru", "pt", "es", "ar", "fa", "zh" };
if (!supported.Contains(lang)) { lang = "fr"; }

string Loc(dynamic entity, string field)
{
var dict = (IDictionary<string, object>)entity;
string pick(string key) => dict.ContainsKey(key) ? entity[key]?.ToString() ?? "" : "";
var primary = pick(field + "_" + lang);
if (!string.IsNullOrEmpty(primary)) return primary;
if (lang != "en") { var en = pick(field + "_en"); if (!string.IsNullOrEmpty(en)) return en; }
var fr = pick(field + "_fr");
if (!string.IsNullOrEmpty(fr)) return fr;
return pick(field); // generic fallback — current FR canonical value
}

}

<link rel="stylesheet" href="@App.Path/src/styles/argumentum.css" data-enableoptimizations="150" />

<div class="rule row mb-4 mb-md-5" @Edit.TagToolbar(ruleEntity)>
<div class="col-md-4 position-relative">
<h1>
@ruleEntity.EntityTitle
@Loc(ruleEntity, "EntityTitle")
</h1>
<h5>de @ruleEntity.MinNbPlayers &agrave; @ruleEntity.MaxNbPlayers joueurs </h5>
<h2>@Resources.RuleSummary</h2>
@Html.Raw(ruleEntity.Summary)
@Html.Raw(Loc(ruleEntity, "Summary"))
</div>
<div class="col-md-8 position-relative">
<h2>@Resources.RuleMaterial</h2>
@Html.Raw(ruleEntity.Material)
@Html.Raw(Loc(ruleEntity, "Material"))
<h2>@Resources.RuleInstallation</h2>
@Html.Raw(ruleEntity.Installation)
@Html.Raw(Loc(ruleEntity, "Installation"))
</div>
<div class="col-md-12 position-relative">
@Html.Raw(ruleEntity.Content)
@if (ruleEntity.Variants != "")
@Html.Raw(Loc(ruleEntity, "Content"))
@if (!string.IsNullOrEmpty(Loc(ruleEntity, "Variants")))
{
<h2>@Resources.RuleVariants</h2>
@Html.Raw(ruleEntity.Variants)
@Html.Raw(Loc(ruleEntity, "Variants"))
}

</div>
@if (!string.IsNullOrEmpty(ruleEntity.Memo))
@if (!string.IsNullOrEmpty(Loc(ruleEntity, "Memo")))
{
<div class="col-md-12">
<h2>@Resources.RuleMemoCard</h2>
Expand All @@ -64,11 +89,11 @@
<bleed>
<cut>
<safe>
<div class="cardName">@Resources.RuleMemoCardFileNamePrefix - @ruleEntity.EntityTitle</div>
<div class="cardName">@Resources.RuleMemoCardFileNamePrefix - @Loc(ruleEntity, "EntityTitle")</div>
<div>
<p><em>@ruleEntity.EntityTitle</em></p>
<p><em>@Loc(ruleEntity, "EntityTitle")</em></p>
<p><a class="@qrDomId" href='@qrLink' target="_blank"></a></p>
@Html.Raw(ruleEntity.Memo)
@Html.Raw(Loc(ruleEntity, "Memo"))
</div>

<div class="colorPalette">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,53 @@
@inherits Custom.Hybrid.Razor14

<link rel="stylesheet" href="@App.Path/src/styles/argumentum.css" data-enableoptimizations="150" />
@foreach (var ruleEntity in AsList(Data))
{
var view1Parameters = "details=" + ruleEntity.UrlKey+ "&mid=" + CmsContext.Module.Id;

<div class="rule row mb-4 mb-md-5" @Edit.TagToolbar(ruleEntity)>
<div class="col-md-12 position-relative">
<h2>@ruleEntity.EntityTitle</h2>
<a class="link-overlay" href="@Link.To(parameters: view1Parameters)"></a>
<div class="col-md-12">
<div class="row">
<div class="nbPlayers mb-3 mb-md-0 col-12 col-md-6 col-lg-4">
<h6>de @ruleEntity.MinNbPlayers &agrave; @ruleEntity.MaxNbPlayers joueurs </h6>
</div>
<div class="col-12 col-md-6 col-lg-8">
@Html.Raw(ruleEntity.Summary)
</div>
</div>

</div>
</div>
</div>
}
@inherits Custom.Hybrid.Razor14
@using ToSic.Razor.Blade;

@{
// Culture-aware field selection for the Rule content-type.
// Mirrors FallacyExplorer (PR #490): cascade lang -> en -> fr on suffixed fields.
// ADDS a 4th fallback on the generic (unsuffixed) field: the Rule content-type
// currently exposes generic fields (Summary, Material, ...) holding the FR
// canonical value, with no language dimensions wired yet. Without the generic
// fallback, Loc() would return "" until the DB gains suffixed fields — breaking
// the current FR rendering. The generic fallback preserves FR during the
// DB-migration transition (gated on the 2sxc portal export, jsboige).
// See investigation PR #669 (RulesExplorer FR-only = cause of audit #662).
var lang = (CmsContext.Culture.CurrentCode ?? "fr-fr").Split(new[] { '-' })[0].ToLowerInvariant();
var supported = new HashSet<string> { "fr", "en", "ru", "pt", "es", "ar", "fa", "zh" };
if (!supported.Contains(lang)) { lang = "fr"; }

string Loc(dynamic entity, string field)
{
var dict = (IDictionary<string, object>)entity;
string pick(string key) => dict.ContainsKey(key) ? entity[key]?.ToString() ?? "" : "";
var primary = pick(field + "_" + lang);
if (!string.IsNullOrEmpty(primary)) return primary;
if (lang != "en") { var en = pick(field + "_en"); if (!string.IsNullOrEmpty(en)) return en; }
var fr = pick(field + "_fr");
if (!string.IsNullOrEmpty(fr)) return fr;
return pick(field); // generic fallback — current FR canonical value
}
}

<link rel="stylesheet" href="@App.Path/src/styles/argumentum.css" data-enableoptimizations="150" />
@foreach (var ruleEntity in AsList(Data))
{
var view1Parameters = "details=" + ruleEntity.UrlKey + "&mid=" + CmsContext.Module.Id;

<div class="rule row mb-4 mb-md-5" @Edit.TagToolbar(ruleEntity)>
<div class="col-md-12 position-relative">
<h2>@Loc(ruleEntity, "EntityTitle")</h2>
<a class="link-overlay" href="@Link.To(parameters: view1Parameters)"></a>
<div class="col-md-12">
<div class="row">
<div class="nbPlayers mb-3 mb-md-0 col-12 col-md-6 col-lg-4">
<h6>de @ruleEntity.MinNbPlayers &agrave; @ruleEntity.MaxNbPlayers joueurs </h6>
</div>
<div class="col-12 col-md-6 col-lg-8">
@Html.Raw(Loc(ruleEntity, "Summary"))
</div>
</div>

</div>
</div>
</div>
}
Loading