2
0
Files
gitcaddy-server/modules/setting/config.go
logikonline ddf87daa42
All checks were successful
Build and Release / Create Release (push) Successful in 0s
Build and Release / Unit Tests (push) Successful in 3m20s
Build and Release / Integration Tests (PostgreSQL) (push) Successful in 4m41s
Build and Release / Lint (push) Successful in 4m56s
Build and Release / Build Binaries (amd64, linux, linux-latest) (push) Successful in 2m49s
Build and Release / Build Binaries (amd64, windows, windows-latest) (push) Successful in 9h4m28s
Build and Release / Build Binaries (arm64, darwin, macos) (push) Successful in 6m39s
Build and Release / Build Binaries (amd64, darwin, macos) (push) Successful in 8m53s
Build and Release / Build Binary (linux/arm64) (push) Successful in 8m25s
feat(blog): add standalone blog view and top nav option
Adds standalone blog post view at /blog/:id with full content rendering, comments, reactions, and OpenGraph metadata. Implements optional "Blogs" link in site header navigation (configurable in admin settings). Enforces repository access permissions on standalone view. Loads repo owners for avatar fallback on explore page. Includes SEO-friendly URLs and social media sharing support.
2026-02-02 00:19:17 -05:00

138 lines
4.9 KiB
Go

// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package setting
import (
"strings"
"sync"
"code.gitcaddy.com/server/v3/modules/log"
"code.gitcaddy.com/server/v3/modules/setting/config"
)
type PictureStruct struct {
DisableGravatar *config.Value[bool]
EnableFederatedAvatar *config.Value[bool]
}
type OpenWithEditorApp struct {
DisplayName string
OpenURL string
}
type OpenWithEditorAppsType []OpenWithEditorApp
func (t OpenWithEditorAppsType) ToTextareaString() string {
var ret strings.Builder
for _, app := range t {
ret.WriteString(app.DisplayName + " = " + app.OpenURL + "\n")
}
return ret.String()
}
func DefaultOpenWithEditorApps() OpenWithEditorAppsType {
return OpenWithEditorAppsType{
{
DisplayName: "VS Code",
OpenURL: "vscode://vscode.git/clone?url={url}",
},
{
DisplayName: "VSCodium",
OpenURL: "vscodium://vscode.git/clone?url={url}",
},
{
DisplayName: "Intellij IDEA",
OpenURL: "jetbrains://idea/checkout/git?idea.required.plugins.id=Git4Idea&checkout.repo={url}",
},
}
}
type RepositoryStruct struct {
OpenWithEditorApps *config.Value[OpenWithEditorAppsType]
GitGuideRemoteName *config.Value[string]
}
type ThemeStruct struct {
DisableRegistration *config.Value[bool]
HideExploreUsers *config.Value[bool]
HideExploreButton *config.Value[bool]
EnableExplorePackages *config.Value[bool]
HelpURL *config.Value[string]
CustomSiteIconURL *config.Value[string]
CustomHomeLogoURL *config.Value[string]
CustomHomeHTML *config.Value[string]
APIHeaderURL *config.Value[string]
CustomHomeTitle *config.Value[string]
CustomHomeTagline *config.Value[string]
PinnedOrgDisplayFormat *config.Value[string]
ExploreOrgDisplayFormat *config.Value[string]
EnableBlogs *config.Value[bool]
BlogsInTopNav *config.Value[bool]
}
type ConfigStruct struct {
Picture *PictureStruct
Repository *RepositoryStruct
Theme *ThemeStruct
}
var (
defaultConfig *ConfigStruct
defaultConfigOnce sync.Once
)
func initDefaultConfig() {
config.SetCfgSecKeyGetter(&cfgSecKeyGetter{})
defaultConfig = &ConfigStruct{
Picture: &PictureStruct{
DisableGravatar: config.ValueJSON[bool]("picture.disable_gravatar").WithFileConfig(config.CfgSecKey{Sec: "picture", Key: "DISABLE_GRAVATAR"}),
EnableFederatedAvatar: config.ValueJSON[bool]("picture.enable_federated_avatar").WithFileConfig(config.CfgSecKey{Sec: "picture", Key: "ENABLE_FEDERATED_AVATAR"}),
},
Repository: &RepositoryStruct{
OpenWithEditorApps: config.ValueJSON[OpenWithEditorAppsType]("repository.open-with.editor-apps"),
GitGuideRemoteName: config.ValueJSON[string]("repository.git-guide-remote-name").WithDefault("origin"),
},
Theme: &ThemeStruct{
DisableRegistration: config.ValueJSON[bool]("theme.disable_registration").WithFileConfig(config.CfgSecKey{Sec: "service", Key: "DISABLE_REGISTRATION"}),
HideExploreUsers: config.ValueJSON[bool]("theme.hide_explore_users").WithDefault(false),
HideExploreButton: config.ValueJSON[bool]("theme.hide_explore_button").WithDefault(false),
EnableExplorePackages: config.ValueJSON[bool]("theme.enable_explore_packages").WithFileConfig(config.CfgSecKey{Sec: "service.explore", Key: "ENABLE_PACKAGES_PAGE"}),
HelpURL: config.ValueJSON[string]("theme.help_url").WithDefault(""),
CustomSiteIconURL: config.ValueJSON[string]("theme.custom_site_icon_url").WithDefault(""),
CustomHomeLogoURL: config.ValueJSON[string]("theme.custom_home_logo_url").WithDefault(""),
CustomHomeHTML: config.ValueJSON[string]("theme.custom_home_html").WithDefault(""),
APIHeaderURL: config.ValueJSON[string]("theme.api_header_url").WithDefault(""),
CustomHomeTitle: config.ValueJSON[string]("theme.custom_home_title").WithDefault(""),
CustomHomeTagline: config.ValueJSON[string]("theme.custom_home_tagline").WithDefault(""),
PinnedOrgDisplayFormat: config.ValueJSON[string]("theme.pinned_org_display_format").WithDefault("condensed"),
ExploreOrgDisplayFormat: config.ValueJSON[string]("theme.explore_org_display_format").WithDefault("list"),
EnableBlogs: config.ValueJSON[bool]("theme.enable_blogs").WithDefault(false),
BlogsInTopNav: config.ValueJSON[bool]("theme.blogs_in_top_nav").WithDefault(false),
},
}
}
func Config() *ConfigStruct {
defaultConfigOnce.Do(initDefaultConfig)
return defaultConfig
}
type cfgSecKeyGetter struct{}
func (c cfgSecKeyGetter) GetValue(sec, key string) (v string, has bool) {
if key == "" {
return "", false
}
cfgSec, err := CfgProvider.GetSection(sec)
if err != nil {
log.Error("Unable to get config section: %q", sec)
return "", false
}
cfgKey := ConfigSectionKey(cfgSec, key)
if cfgKey == nil {
return "", false
}
return cfgKey.Value(), true
}