From 9d2242d33191ac258ea0eef51b78fde39e0ad165 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 22 Nov 2025 13:42:13 +0800 Subject: [PATCH] :lipstick: Hosted page SEO optimization --- DysonNetwork.Zone/Pages/About.cshtml | 67 +++++++++++++++++++ DysonNetwork.Zone/Pages/Index.cshtml | 1 + DysonNetwork.Zone/Pages/Posts.cshtml | 42 ++++++++++++ DysonNetwork.Zone/Pages/Posts/Details.cshtml | 67 +++++++++++++++++++ DysonNetwork.Zone/Pages/Shared/_Layout.cshtml | 2 + .../Pages/Shared/_LayoutContained.cshtml | 57 +++++++++------- 6 files changed, 213 insertions(+), 23 deletions(-) diff --git a/DysonNetwork.Zone/Pages/About.cshtml b/DysonNetwork.Zone/Pages/About.cshtml index bc00c9a..a6a307e 100644 --- a/DysonNetwork.Zone/Pages/About.cshtml +++ b/DysonNetwork.Zone/Pages/About.cshtml @@ -4,8 +4,75 @@ @{ Layout = "_LayoutContained"; + + var pageTitle = "About"; + var pageDescription = "Information page."; + var ogType = "website"; + string? ogImageUrl = null; + var canonicalUrl = $"{Request.Scheme}://{Request.Host}{Request.Path}{Request.QueryString}"; + var siteName = Model.Site?.Name ?? "Solar Network"; + + if (Model.UserAccount != null) + { + pageTitle = $"About {Model.UserAccount.Nick ?? Model.UserAccount.Name}"; + if (!string.IsNullOrWhiteSpace(Model.UserAccount.Profile?.Bio)) + { + pageDescription = Model.UserAccount.Profile.Bio; + } + else + { + pageDescription = $"Profile of {Model.UserAccount.Nick ?? Model.UserAccount.Name} on {siteName}"; + } + + ogType = "profile"; + ogImageUrl = Model.UserPictureUrl; + if(!string.IsNullOrEmpty(ogImageUrl) && !ogImageUrl.StartsWith("http")) + { + ogImageUrl = $"{Request.Scheme}://{Request.Host}{ogImageUrl}"; + } + } + else if (Model.Site != null) + { + pageTitle = $"About {Model.Site.Name}"; + if(!string.IsNullOrWhiteSpace(Model.Site.Description)) + { + pageDescription = Model.Site.Description; + } + ogType = "website"; + ogImageUrl = null; + } + + if (!string.IsNullOrWhiteSpace(pageDescription) && pageDescription.Length > 160) + { + pageDescription = pageDescription.Substring(0, 157) + "..."; + } } +@section Head { + @pageTitle - @siteName + + + + + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } + + + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } +} + + @if (Model.UserAccount != null) { @if (!string.IsNullOrEmpty(Model.UserBackgroundUrl)) diff --git a/DysonNetwork.Zone/Pages/Index.cshtml b/DysonNetwork.Zone/Pages/Index.cshtml index 235c908..e2ad447 100644 --- a/DysonNetwork.Zone/Pages/Index.cshtml +++ b/DysonNetwork.Zone/Pages/Index.cshtml @@ -11,5 +11,6 @@ Logo

Hello World 👋

Here are the Solar Network Pages

+

为什么这个首页长这样呢?因为羊不知道该放什么,所以如果你有想法欢迎跟羊讲!

diff --git a/DysonNetwork.Zone/Pages/Posts.cshtml b/DysonNetwork.Zone/Pages/Posts.cshtml index da4f5f3..ff8488f 100644 --- a/DysonNetwork.Zone/Pages/Posts.cshtml +++ b/DysonNetwork.Zone/Pages/Posts.cshtml @@ -3,8 +3,50 @@ @{ Layout = "_LayoutContained"; const string defaultAvatar = "https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp"; + + var pageTitle = "Posts"; + var pageDescription = "A collection of posts."; + string? ogImageUrl = null; + var canonicalUrl = $"{Request.Scheme}://{Request.Host}{Request.Path}{Request.QueryString}"; + var siteName = Model.Publisher?.Nick ?? Model.Publisher?.Name ?? "Solar Network"; + + if (Model.Publisher != null) + { + pageTitle = $"Posts by {Model.Publisher.Nick ?? Model.Publisher.Name}"; + pageDescription = $"Browse posts written by {Model.Publisher.Nick ?? Model.Publisher.Name}."; + if (Model.Publisher.Background != null) + { + ogImageUrl = $"{Request.Scheme}://{Request.Host}/drive/files/{Model.Publisher.Background.Id}"; + } + } } +@section Head { + @pageTitle - @siteName + + + + + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } + + + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } +} + + +

Posts diff --git a/DysonNetwork.Zone/Pages/Posts/Details.cshtml b/DysonNetwork.Zone/Pages/Posts/Details.cshtml index e9bf302..bb80ad7 100644 --- a/DysonNetwork.Zone/Pages/Posts/Details.cshtml +++ b/DysonNetwork.Zone/Pages/Posts/Details.cshtml @@ -1,9 +1,76 @@ @page "/p/{slug}" +@using NodaTime @model DysonNetwork.Zone.Pages.Posts.DetailsModel @{ Layout = "_LayoutContained"; + + var post = Model.Post; + var pageTitle = post?.Title ?? "Post"; + var pageDescription = post?.Description; + string? ogImageUrl = null; + var canonicalUrl = $"{Request.Scheme}://{Request.Host}{Request.Path}{Request.QueryString}"; + + if (post != null) + { + if (string.IsNullOrWhiteSpace(pageDescription) && !string.IsNullOrWhiteSpace(post.Content)) + { + var plainText = System.Text.RegularExpressions.Regex.Replace(post.Content, "<.*?>", string.Empty); + pageDescription = plainText.Length > 160 ? plainText.Substring(0, 157) + "..." : plainText; + } + + var imageAttachment = post.Attachments.FirstOrDefault(a => a.MimeType != null && a.MimeType.StartsWith("image")); + if (imageAttachment != null) + { + ogImageUrl = $"{Request.Scheme}://{Request.Host}/drive/files/{imageAttachment.Id}"; + } + } } +@section Head { + @pageTitle + @if (!string.IsNullOrWhiteSpace(pageDescription)) + { + + + + } + + + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } + + @if(post != null) + { + + @if (post.EditedAt.HasValue) + { + + } + + @foreach (var tag in post.Tags) + { + var tagName = !string.IsNullOrEmpty(tag.Name) ? tag.Name : tag.Slug; + if(!string.IsNullOrEmpty(tagName)) + { + + } + } + } + + + + @if (!string.IsNullOrEmpty(ogImageUrl)) + { + + } +} + +
@if (Model.Post != null) diff --git a/DysonNetwork.Zone/Pages/Shared/_Layout.cshtml b/DysonNetwork.Zone/Pages/Shared/_Layout.cshtml index 8128592..d403cc4 100644 --- a/DysonNetwork.Zone/Pages/Shared/_Layout.cshtml +++ b/DysonNetwork.Zone/Pages/Shared/_Layout.cshtml @@ -15,6 +15,8 @@ + + @await RenderSectionAsync("Head", required: false) diff --git a/DysonNetwork.Zone/Pages/Shared/_LayoutContained.cshtml b/DysonNetwork.Zone/Pages/Shared/_LayoutContained.cshtml index 125ff74..698a744 100644 --- a/DysonNetwork.Zone/Pages/Shared/_LayoutContained.cshtml +++ b/DysonNetwork.Zone/Pages/Shared/_LayoutContained.cshtml @@ -7,32 +7,43 @@ }
@RenderBody()
- +@section Scripts +{ + @await RenderSectionAsync("Scripts", required: false) +} + +@section Head +{ + @await RenderSectionAsync("Head", required: false) + + +}