feat(ui): custom HTML content in predefined locations (#2621)

pull/2693/head
Aaron Liu 2025-07-15 10:44:51 +08:00
parent ca57ca1ba0
commit 000124f6c7
5 changed files with 22 additions and 1 deletions

2
assets

@ -1 +1 @@
Subproject commit d4819eeaf4ed3d443165def69cb89267d31b81da Subproject commit aa80ca5bb2609d75fc9706d12edd5c6e9a0c76b7

View File

@ -518,6 +518,9 @@ var DefaultSettings = map[string]string{
"qq_login_config": `{"direct_sign_in":false}`, "qq_login_config": `{"direct_sign_in":false}`,
"license": "", "license": "",
"custom_nav_items": "[]", "custom_nav_items": "[]",
"headless_footer_html": "",
"headless_bottom_html": "",
"sidebar_bottom_html": "",
} }
func init() { func init() {

View File

@ -200,6 +200,8 @@ type (
CustomProps(ctx context.Context) []types.CustomProps CustomProps(ctx context.Context) []types.CustomProps
// CustomNavItems returns the custom nav items settings. // CustomNavItems returns the custom nav items settings.
CustomNavItems(ctx context.Context) []CustomNavItem CustomNavItems(ctx context.Context) []CustomNavItem
// CustomHTML returns the custom HTML settings.
CustomHTML(ctx context.Context) *CustomHTML
} }
UseFirstSiteUrlCtxKey = struct{} UseFirstSiteUrlCtxKey = struct{}
) )
@ -227,6 +229,13 @@ type (
} }
) )
func (s *settingProvider) CustomHTML(ctx context.Context) *CustomHTML {
return &CustomHTML{
HeadlessFooter: s.getString(ctx, "headless_footer_html", ""),
HeadlessBody: s.getString(ctx, "headless_bottom_html", ""),
SidebarBottom: s.getString(ctx, "sidebar_bottom_html", ""),
}
}
func (s *settingProvider) CustomNavItems(ctx context.Context) []CustomNavItem { func (s *settingProvider) CustomNavItems(ctx context.Context) []CustomNavItem {
raw := s.getString(ctx, "custom_nav_items", "[]") raw := s.getString(ctx, "custom_nav_items", "[]")
var items []CustomNavItem var items []CustomNavItem

View File

@ -215,3 +215,9 @@ type CustomNavItem struct {
Name string `json:"name"` Name string `json:"name"`
URL string `json:"url"` URL string `json:"url"`
} }
type CustomHTML struct {
HeadlessFooter string `json:"headless_footer,omitempty"`
HeadlessBody string `json:"headless_bottom,omitempty"`
SidebarBottom string `json:"sidebar_bottom,omitempty"`
}

View File

@ -21,6 +21,7 @@ type SiteConfig struct {
Logo string `json:"logo,omitempty"` Logo string `json:"logo,omitempty"`
LogoLight string `json:"logo_light,omitempty"` LogoLight string `json:"logo_light,omitempty"`
CustomNavItems []setting.CustomNavItem `json:"custom_nav_items,omitempty"` CustomNavItems []setting.CustomNavItem `json:"custom_nav_items,omitempty"`
CustomHTML *setting.CustomHTML `json:"custom_html,omitempty"`
// Login Section // Login Section
LoginCaptcha bool `json:"login_captcha,omitempty"` LoginCaptcha bool `json:"login_captcha,omitempty"`
@ -130,6 +131,7 @@ func (s *GetSettingService) GetSiteConfig(c *gin.Context) (*SiteConfig, error) {
capCaptcha := settings.CapCaptcha(c) capCaptcha := settings.CapCaptcha(c)
appSetting := settings.AppSetting(c) appSetting := settings.AppSetting(c)
customNavItems := settings.CustomNavItems(c) customNavItems := settings.CustomNavItems(c)
customHTML := settings.CustomHTML(c)
return &SiteConfig{ return &SiteConfig{
InstanceID: siteBasic.ID, InstanceID: siteBasic.ID,
SiteName: siteBasic.Name, SiteName: siteBasic.Name,
@ -146,6 +148,7 @@ func (s *GetSettingService) GetSiteConfig(c *gin.Context) (*SiteConfig, error) {
CapAssetServer: capCaptcha.AssetServer, CapAssetServer: capCaptcha.AssetServer,
AppPromotion: appSetting.Promotion, AppPromotion: appSetting.Promotion,
CustomNavItems: customNavItems, CustomNavItems: customNavItems,
CustomHTML: customHTML,
}, nil }, nil
} }