Config: Prefer SiteName for app name and site title

AppName() resolves to an explicit AppName, then SiteName (SITE_NAME), then SiteTitle. SiteTitle() falls back to SiteName when neither a SiteTitle nor an AppName is set, so an instance branded only via SITE_NAME stays consistent.
This commit is contained in:
Michael Mayer 2026-06-10 14:28:33 +00:00
parent a10de3b616
commit 245ecc565e
4 changed files with 54 additions and 7 deletions

View file

@ -14,10 +14,15 @@ import (
// DefaultAppColor specifies the default app background and splash screen color.
var DefaultAppColor = "#19191a"
// AppName returns the app name when installed on a device.
// AppName returns the app name shown when installed as a PWA, preferring an explicit
// AppName, then the distinctive SiteName (SITE_NAME), then the SiteTitle.
func (c *Config) AppName() string {
name := strings.TrimSpace(c.options.AppName)
if name == "" {
name = c.SiteName()
}
if name == "" {
name = c.SiteTitle()
}

View file

@ -11,8 +11,32 @@ import (
func TestConfig_AppName(t *testing.T) {
c := NewConfig(CliTestContext())
assert.Equal(t, "PhotoPrism", c.AppName())
t.Run("ExplicitAppNameWins", func(t *testing.T) {
c.options.AppName = "My App"
c.options.SiteName = "Acme Media"
c.options.SiteTitle = "Our Trip"
assert.Equal(t, "My App", c.AppName())
})
t.Run("PrefersSiteNameOverSiteTitle", func(t *testing.T) {
c.options.AppName = ""
c.options.SiteName = "Acme Media"
c.options.SiteTitle = "Our Trip"
assert.Equal(t, "Acme Media", c.AppName())
})
t.Run("FallsBackToSiteTitle", func(t *testing.T) {
c.options.AppName = ""
c.options.SiteName = ""
c.options.SiteTitle = "Our Trip"
assert.Equal(t, "Our Trip", c.AppName())
})
t.Run("StripsQuotesAndClips", func(t *testing.T) {
c.options.AppName = `A'B"C`
assert.Equal(t, "ABC", c.AppName())
})
c.options.AppName = ""
c.options.SiteName = ""
c.options.SiteTitle = ""
}
func TestConfig_AppMode(t *testing.T) {

View file

@ -178,11 +178,20 @@ func (c *Config) SiteName() string {
// SiteTitle returns the main site title (default is application name).
func (c *Config) SiteTitle() string {
if c.options.SiteTitle == "" {
return c.Name()
if c.options.SiteTitle != "" {
return c.options.SiteTitle
}
return c.options.SiteTitle
// With no SiteTitle and no AppName configured, fall back to the distinctive
// SiteName (SITE_NAME) before the product Name so an instance branded only via
// SITE_NAME shows that name as its title.
if c.options.AppName == "" {
if name := clean.TypeUnicode(c.options.SiteName); name != "" {
return name
}
}
return c.Name()
}
// SiteCaption returns a short site caption.

View file

@ -241,6 +241,15 @@ func TestConfig_SiteTitle(t *testing.T) {
assert.Equal(t, "Cats", c.SiteTitle())
c.options.SiteTitle = "PhotoPrism"
assert.Equal(t, "PhotoPrism", c.SiteTitle())
// With no SiteTitle and no AppName, the distinctive SiteName is used as the title.
c.options.SiteTitle = ""
c.options.SiteName = "Acme Media"
assert.Equal(t, "Acme Media", c.SiteTitle())
// A configured AppName suppresses the SiteName-as-title fallback.
c.options.AppName = "My App"
assert.Equal(t, "PhotoPrism", c.SiteTitle())
c.options.AppName = ""
c.options.SiteName = ""
}
func TestConfig_SiteName(t *testing.T) {
@ -253,8 +262,8 @@ func TestConfig_SiteName(t *testing.T) {
c.options.AppName = "Kitten"
assert.Equal(t, "Kitten", c.SiteName())
// SiteName takes precedence when explicitly configured.
c.options.SiteName = "Sharjah Media"
assert.Equal(t, "Sharjah Media", c.SiteName())
c.options.SiteName = "Acme Media"
assert.Equal(t, "Acme Media", c.SiteName())
// Empty when nothing distinctive is configured (no product Name fallback).
c.options.SiteName = ""
c.options.AppName = ""