SHA256
Link-Fixes: Sprachumschalter, Canonical, og:locale, Legal-Platzhalter, serve-Fallback
- Builder.cs: Sprachumschalter-Links verwenden /{lang}/{slug}.html statt
/{lang}/{slug}/ (Dateien liegen flach als lang/slug.html)
- Builder.cs: Canonical/OG-URL enthält jetzt /{lang}/-Präfix
- Builder.cs: Legal-Seiten ersetzen {{intro}}, {{positioning}}, {{publisher}}
mit leerem String (waren zuvor als Artefakte im HTML sichtbar)
- Builder.cs: Sitemap-URLs enthalten Sprach-Präfix + .html
- BuildConfig.cs: JsonNamingPolicy.SnakeCaseLower für korrekte Deserialisierung
von snake_case JSON-Properties (og_locale → OgLocale, base_url → BaseUrl)
- Program.cs: webstatic serve hat .html-Fallback ( /de/slug → de/slug.html)
This commit is contained in:
+20
-9
@@ -105,8 +105,10 @@ public static class Builder
|
||||
? bannerHtml + htmlContent
|
||||
: htmlContent;
|
||||
|
||||
var canonical = page.Href.StartsWith("/") ? page.Href : $"/{page.Href}";
|
||||
if (!canonical.EndsWith("/")) canonical += "/";
|
||||
var slug = page.Href.Trim('/');
|
||||
var canonical = string.IsNullOrEmpty(slug)
|
||||
? $"/{lang}/"
|
||||
: $"/{lang}/{slug}.html";
|
||||
|
||||
var defaultTitle = cfg.Site.Title.TryGetValue(lang, out var dt) ? dt : cfg.Site.Name;
|
||||
var defaultDesc = cfg.Site.Description.TryGetValue(lang, out var dd) ? dd : "";
|
||||
@@ -157,8 +159,8 @@ public static class Builder
|
||||
var ldir = Path.Combine(Directories.DistDir, lang);
|
||||
Directory.CreateDirectory(ldir);
|
||||
|
||||
var slug = page.Href.Trim('/');
|
||||
var outputFile = string.IsNullOrEmpty(slug) ? "index.html" : $"{slug}.html";
|
||||
var fileSlug = page.Href.Trim('/');
|
||||
var outputFile = string.IsNullOrEmpty(fileSlug) ? "index.html" : $"{fileSlug}.html";
|
||||
var outputPath = Path.Combine(ldir, outputFile);
|
||||
File.WriteAllText(outputPath, pageHtml);
|
||||
|
||||
@@ -248,7 +250,7 @@ public static class Builder
|
||||
var code = (li.HrefLang ?? lang).ToUpperInvariant();
|
||||
string slug = "";
|
||||
if (langSlug != null && langSlug.TryGetValue(lang, out var h)) slug = h.Trim('/');
|
||||
var href = string.IsNullOrEmpty(slug) ? $"/{lang}/" : $"/{lang}/{slug}/";
|
||||
var href = string.IsNullOrEmpty(slug) ? $"/{lang}/" : $"/{lang}/{slug}.html";
|
||||
sb.AppendLine($" <li><a href=\"{href}\" hreflang=\"{li.HrefLang ?? lang}\"><span>{HtmlEncode(label)}</span> <span class=\"lang-dropdown__code\">{code}</span></a></li>");
|
||||
}
|
||||
return sb.ToString().Trim();
|
||||
@@ -403,14 +405,15 @@ public static class Builder
|
||||
htmlContent = MarkdownProcessor.TablePostprocess(htmlContent);
|
||||
|
||||
var baseName = Regex.Replace(bn, @"\.(de|en|vi)\.md$", ".html").Replace(".md", ".html");
|
||||
var canonical = $"/{Path.GetFileNameWithoutExtension(baseName)}/";
|
||||
var legalFileName = Path.GetFileNameWithoutExtension(baseName);
|
||||
var canonical = $"/{lang}/{legalFileName}.html";
|
||||
var defaultTitle = cfg.Site.Title.TryGetValue(lang, out var dt) ? dt : cfg.Site.Name;
|
||||
var defaultDesc = cfg.Site.Description.TryGetValue(lang, out var dd) ? dd : "";
|
||||
var seoHead = SeoHelper.RenderSeoHead(lang, title, "", $"{env.BaseUrl}{canonical}",
|
||||
env.Cdn, defaultTitle, defaultDesc);
|
||||
var sidebarTocHtml = BuildSidebarTocHtml(content);
|
||||
var legalSlug = $"/{Path.GetFileNameWithoutExtension(baseName)}/";
|
||||
var legalLangSlug = cfg.LanguageCodes().ToDictionary(l => l, l => legalSlug);
|
||||
var legalSlug = $"{legalFileName}.html";
|
||||
var legalLangSlug = cfg.LanguageCodes().ToDictionary(l => l, l => $"{l}/{legalFileName}.html");
|
||||
var langLinksHtml = BuildLangLinksHtml(legalLangSlug);
|
||||
|
||||
var pageHtml = layout
|
||||
@@ -425,6 +428,9 @@ public static class Builder
|
||||
.Replace("{{lang_links}}", langLinksHtml).Replace("{{ lang_links }}", langLinksHtml)
|
||||
.Replace("{{glossary_href}}", GlossaryHref(lang)).Replace("{{ glossary_href }}", GlossaryHref(lang))
|
||||
.Replace("{{glossary_label}}", GlossaryLabel(lang)).Replace("{{ glossary_label }}", GlossaryLabel(lang))
|
||||
.Replace("{{intro}}", "").Replace("{{ intro }}", "")
|
||||
.Replace("{{positioning}}", "").Replace("{{ positioning }}", "")
|
||||
.Replace("{{publisher}}", "").Replace("{{ publisher }}", "")
|
||||
.Replace("{{content}}", htmlContent).Replace("{{ content }}", htmlContent)
|
||||
.Replace("{{body}}", htmlContent).Replace("{{ body }}", htmlContent);
|
||||
pageHtml = I18n.Substitute(pageHtml, lang);
|
||||
@@ -452,7 +458,12 @@ public static class Builder
|
||||
urls.Add($"{baseUrl}/{lang}/");
|
||||
var contents = ContentLoader.LoadContent(Directories.ContentDir, lang);
|
||||
foreach (var page in contents)
|
||||
if (page.Meta.Render) urls.Add($"{baseUrl}{page.Href}");
|
||||
{
|
||||
if (!page.Meta.Render) continue;
|
||||
var slug = page.Href.Trim('/');
|
||||
if (!string.IsNullOrEmpty(slug))
|
||||
urls.Add($"{baseUrl}/{lang}/{slug}.html");
|
||||
}
|
||||
}
|
||||
var sitemap = @"<?xml version=""1.0"" encoding=""UTF-8""?>
|
||||
<urlset xmlns=""http://www.sitemaps.org/schemas/sitemap/0.9"">
|
||||
|
||||
Reference in New Issue
Block a user