WebClient: allow to set a list of default CSS

The new WIP WebClient requires 2 CSS files

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino
2023-11-05 12:24:26 +01:00
parent b872c423ee
commit 010c36cab5
13 changed files with 47 additions and 27 deletions

View File

@@ -357,7 +357,7 @@ The configuration file contains the following sections:
- `login_image_path`, string. Path to a custom image to show on the login screen relative to `static_files_path`. The preferred image size is 900x900 pixel - `login_image_path`, string. Path to a custom image to show on the login screen relative to `static_files_path`. The preferred image size is 900x900 pixel
- `disclaimer_name`, string. Name for your optional disclaimer - `disclaimer_name`, string. Name for your optional disclaimer
- `disclaimer_path`, string. Path to the HTML page with the disclaimer relative to `static_files_path` - `disclaimer_path`, string. Path to the HTML page with the disclaimer relative to `static_files_path`
- `default_css`, string. Optional path to a custom CSS file, relative to `static_files_path`, which replaces the SB Admin2 default CSS - `default_css`, list of strings. Optional path to custom CSS files, relative to `static_files_path`, which replaces the default CSS
- `extra_css`, list of strings. Defines the paths, relative to `static_files_path`, to additional CSS files - `extra_css`, list of strings. Defines the paths, relative to `static_files_path`, to additional CSS files
- `templates_path`, string. Path to the HTML web templates. This can be an absolute path or a path relative to the config dir - `templates_path`, string. Path to the HTML web templates. This can be an absolute path or a path relative to the config dir
- `static_files_path`, string. Path to the static files for the web interface. This can be an absolute path or a path relative to the config dir. If both `templates_path` and `static_files_path` are empty the built-in web interface will be disabled - `static_files_path`, string. Path to the static files for the web interface. This can be an absolute path or a path relative to the config dir. If both `templates_path` and `static_files_path` are empty the built-in web interface will be disabled

View File

@@ -1667,7 +1667,7 @@ func getHTTPDUIBrandingFromEnv(prefix string, branding httpd.UIBranding) (httpd.
isSet = true isSet = true
} }
defaultCSSPath, ok := os.LookupEnv(fmt.Sprintf("%s__DEFAULT_CSS", prefix)) defaultCSSPath, ok := lookupStringListFromEnv(fmt.Sprintf("%s__DEFAULT_CSS", prefix))
if ok { if ok {
branding.DefaultCSS = defaultCSSPath branding.DefaultCSS = defaultCSSPath
isSet = true isSet = true

View File

@@ -1417,7 +1417,7 @@ func TestHTTPDBindingsFromEnv(t *testing.T) {
require.Equal(t, "login_image.png", bindings[2].Branding.WebAdmin.LoginImagePath) require.Equal(t, "login_image.png", bindings[2].Branding.WebAdmin.LoginImagePath)
require.Equal(t, "disclaimer", bindings[2].Branding.WebClient.DisclaimerName) require.Equal(t, "disclaimer", bindings[2].Branding.WebClient.DisclaimerName)
require.Equal(t, "disclaimer.html", bindings[2].Branding.WebAdmin.DisclaimerPath) require.Equal(t, "disclaimer.html", bindings[2].Branding.WebAdmin.DisclaimerPath)
require.Equal(t, "default.css", bindings[2].Branding.WebClient.DefaultCSS) require.Equal(t, []string{"default.css"}, bindings[2].Branding.WebClient.DefaultCSS)
require.Len(t, bindings[2].Branding.WebClient.ExtraCSS, 2) require.Len(t, bindings[2].Branding.WebClient.ExtraCSS, 2)
require.Equal(t, "1.css", bindings[2].Branding.WebClient.ExtraCSS[0]) require.Equal(t, "1.css", bindings[2].Branding.WebClient.ExtraCSS[0])
require.Equal(t, "2.css", bindings[2].Branding.WebClient.ExtraCSS[1]) require.Equal(t, "2.css", bindings[2].Branding.WebClient.ExtraCSS[1])

View File

@@ -405,15 +405,14 @@ type UIBranding struct {
DisclaimerName string `json:"disclaimer_name" mapstructure:"disclaimer_name"` DisclaimerName string `json:"disclaimer_name" mapstructure:"disclaimer_name"`
// Path to the HTML page for your disclaimer relative to "static_files_path". // Path to the HTML page for your disclaimer relative to "static_files_path".
DisclaimerPath string `json:"disclaimer_path" mapstructure:"disclaimer_path"` DisclaimerPath string `json:"disclaimer_path" mapstructure:"disclaimer_path"`
// Path to a custom CSS file, relative to "static_files_path", which replaces // Path to custom CSS files, relative to "static_files_path", which replaces
// the SB Admin2 default CSS. This is useful, for example, if you rebuild // the default CSS files
// SB Admin2 CSS to use custom colors DefaultCSS []string `json:"default_css" mapstructure:"default_css"`
DefaultCSS string `json:"default_css" mapstructure:"default_css"`
// Additional CSS file paths, relative to "static_files_path", to include // Additional CSS file paths, relative to "static_files_path", to include
ExtraCSS []string `json:"extra_css" mapstructure:"extra_css"` ExtraCSS []string `json:"extra_css" mapstructure:"extra_css"`
} }
func (b *UIBranding) check() { func (b *UIBranding) check(isWebClient bool) {
if b.LogoPath != "" { if b.LogoPath != "" {
b.LogoPath = util.CleanPath(b.LogoPath) b.LogoPath = util.CleanPath(b.LogoPath)
} else { } else {
@@ -432,10 +431,19 @@ func (b *UIBranding) check() {
if b.DisclaimerPath != "" { if b.DisclaimerPath != "" {
b.DisclaimerPath = util.CleanPath(b.DisclaimerPath) b.DisclaimerPath = util.CleanPath(b.DisclaimerPath)
} }
if b.DefaultCSS != "" { if len(b.DefaultCSS) > 0 {
b.DefaultCSS = util.CleanPath(b.DefaultCSS) for idx := range b.DefaultCSS {
b.DefaultCSS[idx] = util.CleanPath(b.DefaultCSS[idx])
}
} else { } else {
b.DefaultCSS = "/css/sb-admin-2.min.css" if isWebClient {
b.DefaultCSS = []string{
"/assets/plugins/global/plugins.bundle.css",
"/assets/css/style.bundle.css",
}
} else {
b.DefaultCSS = []string{"/css/sb-admin-2.min.css"}
}
} }
for idx := range b.ExtraCSS { for idx := range b.ExtraCSS {
b.ExtraCSS[idx] = util.CleanPath(b.ExtraCSS[idx]) b.ExtraCSS[idx] = util.CleanPath(b.ExtraCSS[idx])
@@ -534,8 +542,8 @@ type Binding struct {
} }
func (b *Binding) checkBranding() { func (b *Binding) checkBranding() {
b.Branding.WebAdmin.check() b.Branding.WebAdmin.check(false)
b.Branding.WebClient.check() b.Branding.WebClient.check(true)
if b.Branding.WebAdmin.Name == "" { if b.Branding.WebAdmin.Name == "" {
b.Branding.WebAdmin.Name = "SFTPGo WebAdmin" b.Branding.WebAdmin.Name = "SFTPGo WebAdmin"
} }

View File

@@ -331,7 +331,7 @@ func TestBrandingValidation(t *testing.T) {
WebAdmin: UIBranding{ WebAdmin: UIBranding{
LogoPath: "path1", LogoPath: "path1",
LoginImagePath: "login1.png", LoginImagePath: "login1.png",
DefaultCSS: "my.css", DefaultCSS: []string{"my.css"},
}, },
WebClient: UIBranding{ WebClient: UIBranding{
FaviconPath: "favicon1.ico", FaviconPath: "favicon1.ico",
@@ -344,7 +344,7 @@ func TestBrandingValidation(t *testing.T) {
assert.Equal(t, "/favicon.ico", b.Branding.WebAdmin.FaviconPath) assert.Equal(t, "/favicon.ico", b.Branding.WebAdmin.FaviconPath)
assert.Equal(t, "/path1", b.Branding.WebAdmin.LogoPath) assert.Equal(t, "/path1", b.Branding.WebAdmin.LogoPath)
assert.Equal(t, "/login1.png", b.Branding.WebAdmin.LoginImagePath) assert.Equal(t, "/login1.png", b.Branding.WebAdmin.LoginImagePath)
assert.Equal(t, "/my.css", b.Branding.WebAdmin.DefaultCSS) assert.Equal(t, []string{"/my.css"}, b.Branding.WebAdmin.DefaultCSS)
assert.Len(t, b.Branding.WebAdmin.ExtraCSS, 0) assert.Len(t, b.Branding.WebAdmin.ExtraCSS, 0)
assert.Equal(t, "/favicon1.ico", b.Branding.WebClient.FaviconPath) assert.Equal(t, "/favicon1.ico", b.Branding.WebClient.FaviconPath)
assert.Equal(t, "/path2", b.Branding.WebClient.DisclaimerPath) assert.Equal(t, "/path2", b.Branding.WebClient.DisclaimerPath)

View File

@@ -317,7 +317,7 @@
"login_image_path": "", "login_image_path": "",
"disclaimer_name": "", "disclaimer_name": "",
"disclaimer_path": "", "disclaimer_path": "",
"default_css": "", "default_css": [],
"extra_css": [] "extra_css": []
}, },
"web_client": { "web_client": {
@@ -328,7 +328,7 @@
"login_image_path": "", "login_image_path": "",
"disclaimer_name": "", "disclaimer_name": "",
"disclaimer_path": "", "disclaimer_path": "",
"default_css": "", "default_css": [],
"extra_css": [] "extra_css": []
} }
} }

View File

@@ -29,7 +29,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" /> <link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" />
<!-- Custom styles for this template--> <!-- Custom styles for this template-->
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet"> {{- range .Branding.DefaultCSS}}
<link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">
{{- end}}
<style> <style>
{{template "commoncss" .}} {{template "commoncss" .}}
</style> </style>

View File

@@ -29,7 +29,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" /> <link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" />
<!-- Custom styles for this template--> <!-- Custom styles for this template-->
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet"> {{- range .Branding.DefaultCSS}}
<link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">
{{- end}}
<style> <style>
{{template "commoncss" .}} {{template "commoncss" .}}
</style> </style>

View File

@@ -29,7 +29,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" /> <link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" />
<!-- Custom styles for this template--> <!-- Custom styles for this template-->
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet"> {{- range .Branding.DefaultCSS}}
<link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">
{{- end}}
<style> <style>
{{template "commoncss" .}} {{template "commoncss" .}}
</style> </style>

View File

@@ -35,7 +35,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<link href="{{.StaticURL}}/vendor/fontawesome-free/css/regular.min.css" rel="stylesheet" type="text/css"> <link href="{{.StaticURL}}/vendor/fontawesome-free/css/regular.min.css" rel="stylesheet" type="text/css">
<!-- Custom styles for this template--> <!-- Custom styles for this template-->
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet"> {{- range .Branding.DefaultCSS}}
<link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">
{{- end}}
<style> <style>
{{template "commoncss" .}} {{template "commoncss" .}}
</style> </style>

View File

@@ -30,7 +30,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" /> <link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" />
<!-- Custom styles for this template--> <!-- Custom styles for this template-->
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet"> {{- range .Branding.DefaultCSS}}
<link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">
{{- end}}
<style> <style>
{{template "commoncss" .}} {{template "commoncss" .}}
</style> </style>

View File

@@ -23,9 +23,10 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" /> <link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" />
{{- template "fonts" .StaticURL }} {{- template "fonts" .StaticURL }}
<link href="{{.StaticURL}}/assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css" /> {{- range .Branding.DefaultCSS}}
<link href="{{.StaticURL}}/assets/css/style.bundle.css" rel="stylesheet" type="text/css" /> <link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">
{{- template "globalstyle" }} {{- end}}
{{- template "globalstyle" }}
{{- block "extra_css" .}}{{- end}} {{- block "extra_css" .}}{{- end}}
{{- range .Branding.ExtraCSS}} {{- range .Branding.ExtraCSS}}
<link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css"> <link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">

View File

@@ -23,8 +23,9 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" /> <link rel="shortcut icon" href="{{.StaticURL}}{{.Branding.FaviconPath}}" />
{{- template "fonts" .StaticURL }} {{- template "fonts" .StaticURL }}
<link href="{{.StaticURL}}/assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css" /> {{- range .Branding.DefaultCSS}}
<link href="{{.StaticURL}}/assets/css/style.bundle.css" rel="stylesheet" type="text/css" /> <link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">
{{- end}}
{{- template "globalstyle" }} {{- template "globalstyle" }}
{{- range .Branding.ExtraCSS}} {{- range .Branding.ExtraCSS}}
<link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css"> <link href="{{$.StaticURL}}{{.}}" rel="stylesheet" type="text/css">