优化cms

This commit is contained in:
biss committed 2026-08-29 16:50:01 +08:00
1 parent f56a63d4ce
commit 1f7603923e
9 files changed
+183 -42

No files matched your search

@@ -13,7 +13,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"launchUrl": "",
"applicationUrl": "http://localhost:5037",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -23,7 +23,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"launchUrl": "",
"applicationUrl": "https://localhost:7053;http://localhost:5037",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -0,0 +1,43 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Localization;
using OrchardCore.Contents;
using OrchardCore.Navigation;
using OrchardCore.Security.Permissions;
namespace ElectionSystem.Cms.PublicContent;
/// <summary>
/// Makes the fixed election disclosure sections visible in the CMS administration menu.
/// </summary>
public sealed class AdminMenu(IStringLocalizer<AdminMenu> stringLocalizer) : AdminNavigationProvider
{
private readonly IStringLocalizer _stringLocalizer = stringLocalizer;
protected override ValueTask BuildAsync(NavigationBuilder builder)
{
builder.Add(_stringLocalizer["Content"], content => content
.Add(_stringLocalizer["Information Disclosure"], "10", disclosure => disclosure
.AddClass("election-public-content")
.Id("election-public-content")
.LinkToFirstChild(true)
.Add(_stringLocalizer["Election Notices"], "1", item => AddContentList(item, "ElectionNotice"))
.Add(_stringLocalizer["Rules and Policies"], "2", item => AddContentList(item, "PolicyDocument"))
.Add(_stringLocalizer["Candidate Disclosures"], "3", item => AddContentList(item, "CandidateDisclosure"))
.Add(_stringLocalizer["Voter Guides"], "4", item => AddContentList(item, "VoterGuide"))
.Add(_stringLocalizer["Result Announcements"], "5", item => AddContentList(item, "ResultAnnouncement"))
.Add(_stringLocalizer["Frequently Asked Questions"], "6", item => AddContentList(item, "PublicFaq"))
.Add(_stringLocalizer["Downloads"], "7", item => AddContentList(item, "DownloadAsset"))
.Add(_stringLocalizer["Archives"], "8", item => AddContentList(item, "ArchiveRecord"))));
return ValueTask.CompletedTask;
}
private static NavigationItemBuilder AddContentList(NavigationItemBuilder item, string contentType) => item
.Action("List", "Admin", new RouteValueDictionary
{
["area"] = "OrchardCore.Contents",
["contentTypeId"] = contentType
})
.Permission(CommonPermissions.ListContent)
.LocalNav();
}
@@ -81,7 +81,31 @@ public sealed class PublicContentController(ISession session) : ControllerBase
ReadString(item.Content, "ElectionPublicMetadataPart", "EffectiveToUtc"));
private static string? ReadString(JsonObject content, string partName, string fieldName) =>
content[partName]?[fieldName]?.GetValue<string>();
ReadScalar(content[partName]?[fieldName]);
private static string? ReadScalar(JsonNode? node, int depth = 0)
{
if (node is JsonValue value)
{
return value.TryGetValue<string>(out var text) ? text : value.ToString();
}
// Content fields can be represented as objects depending on the Orchard editor/field type.
// Only expose a conventional scalar child; never serialize an arbitrary CMS object into the public response.
if (node is JsonObject obj && depth < 2)
{
foreach (var propertyName in new[] { "Text", "Html", "Value", "Url", "Path" })
{
var text = ReadScalar(obj[propertyName], depth + 1);
if (!string.IsNullOrWhiteSpace(text))
{
return text;
}
}
}
return null;
}
}
public sealed record PublicContentSummary(
Loaded 3 of 9 files, more files were not shown because too many files have changed in this diff. Show more