web UIs: allow to replace the default CSS
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
751946f47a
commit
0ecaa862bd
13 changed files with 31 additions and 8 deletions
|
@ -1353,6 +1353,12 @@ func getHTTPDUIBrandingFromEnv(prefix string) (httpd.UIBranding, bool) {
|
||||||
isSet = true
|
isSet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultCSSPath, ok := os.LookupEnv(fmt.Sprintf("%s__DEFAULT_CSS", prefix))
|
||||||
|
if ok {
|
||||||
|
result.DefaultCSS = defaultCSSPath
|
||||||
|
isSet = true
|
||||||
|
}
|
||||||
|
|
||||||
extraCSS, ok := lookupStringListFromEnv(fmt.Sprintf("%s__EXTRA_CSS", prefix))
|
extraCSS, ok := lookupStringListFromEnv(fmt.Sprintf("%s__EXTRA_CSS", prefix))
|
||||||
if ok {
|
if ok {
|
||||||
result.ExtraCSS = extraCSS
|
result.ExtraCSS = extraCSS
|
||||||
|
|
|
@ -939,6 +939,7 @@ func TestHTTPDBindingsFromEnv(t *testing.T) {
|
||||||
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__LOGIN_IMAGE_PATH", "login_image.png")
|
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__LOGIN_IMAGE_PATH", "login_image.png")
|
||||||
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__DISCLAIMER_NAME", "disclaimer")
|
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__DISCLAIMER_NAME", "disclaimer")
|
||||||
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__DISCLAIMER_PATH", "disclaimer.html")
|
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__DISCLAIMER_PATH", "disclaimer.html")
|
||||||
|
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__DEFAULT_CSS", "default.css")
|
||||||
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__EXTRA_CSS", "1.css,2.css")
|
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__EXTRA_CSS", "1.css,2.css")
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__ADDRESS")
|
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__ADDRESS")
|
||||||
|
@ -996,6 +997,7 @@ func TestHTTPDBindingsFromEnv(t *testing.T) {
|
||||||
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__LOGIN_IMAGE_PATH")
|
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__LOGIN_IMAGE_PATH")
|
||||||
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__DISCLAIMER_NAME")
|
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__DISCLAIMER_NAME")
|
||||||
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__DISCLAIMER_PATH")
|
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_ADMIN__DISCLAIMER_PATH")
|
||||||
|
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__DEFAULT_CSS")
|
||||||
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__EXTRA_CSS")
|
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__BRANDING__WEB_CLIENT__EXTRA_CSS")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1081,6 +1083,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.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])
|
||||||
|
|
|
@ -280,6 +280,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
|
||||||
- `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
|
||||||
|
@ -327,7 +328,7 @@ The configuration file contains the following sections:
|
||||||
- `url`, string, optional. If not empty, the header will be added only if the request URL starts with the one specified here
|
- `url`, string, optional. If not empty, the header will be added only if the request URL starts with the one specified here
|
||||||
- **command**, configuration for external commands such as program based hooks
|
- **command**, configuration for external commands such as program based hooks
|
||||||
- `timeout`, integer. Timeout specifies a time limit, in seconds, to execute external commands. Valid range: `1-300`. Default: `30`
|
- `timeout`, integer. Timeout specifies a time limit, in seconds, to execute external commands. Valid range: `1-300`. Default: `30`
|
||||||
- `env`, list of strings. Additional environment variable to pass to all the external commands. Each entry is of the form `key=value`. Default: empty
|
- `env`, list of strings. Additional environment variable to pass to all the external commands. Each entry is of the form `key=value`. Do not use environment variables prefixed with `SFTPGO_` to avoid conflicts with environment variables that SFTPGo hooks can set. Default: empty
|
||||||
- `commands`, list of structs. Allow to customize configuration per-command. Each struct has the following fields:
|
- `commands`, list of structs. Allow to customize configuration per-command. Each struct has the following fields:
|
||||||
- `path`, string. Define the command path as defined in the hook configuration
|
- `path`, string. Define the command path as defined in the hook configuration
|
||||||
- `timeout`, integer. This value overrides the global timeout if set
|
- `timeout`, integer. This value overrides the global timeout if set
|
||||||
|
|
|
@ -332,6 +332,10 @@ 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
|
||||||
|
// the SB Admin2 default CSS. This is useful, for example, if you rebuild
|
||||||
|
// SB Admin2 CSS to use custom colors
|
||||||
|
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"`
|
||||||
}
|
}
|
||||||
|
@ -355,6 +359,11 @@ 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 != "" {
|
||||||
|
b.DefaultCSS = util.CleanPath(b.DefaultCSS)
|
||||||
|
} else {
|
||||||
|
b.DefaultCSS = "/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])
|
||||||
}
|
}
|
||||||
|
|
|
@ -308,6 +308,7 @@ func TestBrandingValidation(t *testing.T) {
|
||||||
WebAdmin: UIBranding{
|
WebAdmin: UIBranding{
|
||||||
LogoPath: "path1",
|
LogoPath: "path1",
|
||||||
LoginImagePath: "login1.png",
|
LoginImagePath: "login1.png",
|
||||||
|
DefaultCSS: "my.css",
|
||||||
},
|
},
|
||||||
WebClient: UIBranding{
|
WebClient: UIBranding{
|
||||||
FaviconPath: "favicon1.ico",
|
FaviconPath: "favicon1.ico",
|
||||||
|
@ -320,6 +321,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.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)
|
||||||
|
|
|
@ -267,6 +267,7 @@
|
||||||
"login_image_path": "",
|
"login_image_path": "",
|
||||||
"disclaimer_name": "",
|
"disclaimer_name": "",
|
||||||
"disclaimer_path": "",
|
"disclaimer_path": "",
|
||||||
|
"default_css": "",
|
||||||
"extra_css": []
|
"extra_css": []
|
||||||
},
|
},
|
||||||
"web_client": {
|
"web_client": {
|
||||||
|
@ -277,6 +278,7 @@
|
||||||
"login_image_path": "",
|
"login_image_path": "",
|
||||||
"disclaimer_name": "",
|
"disclaimer_name": "",
|
||||||
"disclaimer_path": "",
|
"disclaimer_path": "",
|
||||||
|
"default_css": "",
|
||||||
"extra_css": []
|
"extra_css": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<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}}/css/sb-admin-2.min.css" rel="stylesheet">
|
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
{{template "commoncss" .}}
|
{{template "commoncss" .}}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<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}}/css/sb-admin-2.min.css" rel="stylesheet">
|
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
{{template "commoncss" .}}
|
{{template "commoncss" .}}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<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}}/css/sb-admin-2.min.css" rel="stylesheet">
|
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
{{template "commoncss" .}}
|
{{template "commoncss" .}}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<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}}/css/sb-admin-2.min.css" rel="stylesheet">
|
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
{{template "commoncss" .}}
|
{{template "commoncss" .}}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<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}}/css/sb-admin-2.min.css" rel="stylesheet">
|
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
{{template "commoncss" .}}
|
{{template "commoncss" .}}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<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}}/css/sb-admin-2.min.css" rel="stylesheet">
|
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
{{template "commoncss" .}}
|
{{template "commoncss" .}}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<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}}/css/sb-admin-2.min.css" rel="stylesheet">
|
<link href="{{.StaticURL}}{{.Branding.DefaultCSS}}" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
{{template "commoncss" .}}
|
{{template "commoncss" .}}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue