feat: 可配置站点 URL 风格
- 新增 urlStyle 工具与测试:postPath/userPath/sitePagePath 统一生成链接 - 管理端新增 UrlStylePanel 设置面板,settings 服务与 handler 适配 - 全站路由链接与 JSON-LD/sitemap 切换为统一 URL 生成 - middleware 与相关组件适配
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { createContext, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
||||
import { apiGetSettings, type PublicSettings } from "@/lib/api";
|
||||
import { siteDocumentTitle, normalizeBrandLogoFit, normalizeBrandLogoSize, normalizeBrandMark, normalizeFooterLinks } from "@/lib/brand";
|
||||
import { normalizeUrlStyle, type UrlStyle } from "@/lib/urlStyle";
|
||||
import { realtime, RT_SETTINGS_CHANGED, type RtSettingsData } from "@/lib/realtime";
|
||||
import { onDocumentVisible, VISIBLE_RECONCILE_GAP_MS } from "@/lib/visibilityReconcile";
|
||||
|
||||
@@ -17,11 +18,12 @@ export type SiteBrand = {
|
||||
brand_logo_size: PublicSettings["brand_logo_size"];
|
||||
brand_logo_fit: PublicSettings["brand_logo_fit"];
|
||||
footer_links: PublicSettings["footer_links"];
|
||||
url_style: UrlStyle;
|
||||
};
|
||||
|
||||
const SiteBrandContext = createContext<SiteBrand | null>(null);
|
||||
|
||||
function fromSettings(s: Pick<PublicSettings, keyof SiteBrand>): SiteBrand {
|
||||
function fromSettings(s: PublicSettings): SiteBrand {
|
||||
return {
|
||||
site_name: s.site_name,
|
||||
site_wordmark: s.site_wordmark,
|
||||
@@ -33,6 +35,7 @@ function fromSettings(s: Pick<PublicSettings, keyof SiteBrand>): SiteBrand {
|
||||
brand_logo_size: s.brand_logo_size,
|
||||
brand_logo_fit: s.brand_logo_fit,
|
||||
footer_links: s.footer_links,
|
||||
url_style: s.url_style,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -47,6 +50,7 @@ function sameBrand(a: SiteBrand, b: SiteBrand): boolean {
|
||||
a.brand_mark === b.brand_mark &&
|
||||
a.brand_logo_size === b.brand_logo_size &&
|
||||
a.brand_logo_fit === b.brand_logo_fit &&
|
||||
a.url_style === b.url_style &&
|
||||
JSON.stringify(a.footer_links) === JSON.stringify(b.footer_links)
|
||||
);
|
||||
}
|
||||
@@ -97,11 +101,17 @@ export function useSiteBrand(): SiteBrand {
|
||||
brand_logo_size: "sq",
|
||||
brand_logo_fit: "contain",
|
||||
footer_links: [],
|
||||
url_style: "default",
|
||||
};
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/** 详情页伪静态风格(SSR 初值与水合一致,设置保存后 realtime 热更) */
|
||||
export function useUrlStyle(): UrlStyle {
|
||||
return useSiteBrand().url_style;
|
||||
}
|
||||
|
||||
/** SSR 初值 + settings:changed:页眉/页脚/标题/favicon 不必整页刷新 */
|
||||
export default function SiteBrandProvider({
|
||||
initial,
|
||||
@@ -142,6 +152,7 @@ export default function SiteBrandProvider({
|
||||
footer_links: Array.isArray(raw.footer_links)
|
||||
? normalizeFooterLinks(raw.footer_links)
|
||||
: prev.footer_links,
|
||||
url_style: raw.url_style !== undefined ? normalizeUrlStyle(raw.url_style) : prev.url_style,
|
||||
};
|
||||
if (sameBrand(prev, next)) return;
|
||||
retitle(prev, next);
|
||||
|
||||
Reference in New Issue
Block a user