mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-21 08:31:27 -05:00
Add slogan config (#3752)
This is a PR for #3616 Currently added a new optional config `SLOGAN` in ini file. When this config is set title page is modified in APP_NAME [ - SLOGAN] Example in image below ![Selezione_075.png](/attachments/7a72171e-e730-4e57-8c97-ffc94258e00f) Add the new config value in the admin settings page (readonly) ![Screenshot 2024-05-13 at 18-04-13 My Forgejo.png](/attachments/dad00fc2-29fa-4371-a7b9-5233eadeac13) ## TODO * [x] Add the possibility to add the `SLOGAN` config from the installation form * [ ] Update https://forgejo.org/docs/next/admin/config-cheat-sheet Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/3752 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Co-authored-by: mirko <mirko.perillo@gmail.com> Co-committed-by: mirko <mirko.perillo@gmail.com>
This commit is contained in:
parent
dedcd6c647
commit
f015846c11
19 changed files with 138 additions and 13 deletions
|
@ -1,10 +1,10 @@
|
|||
; This file lists the default values used by Gitea
|
||||
; This file lists the default values used by Forgejo
|
||||
;; Copy required sections to your own app.ini (default is custom/conf/app.ini)
|
||||
;; and modify as needed.
|
||||
;; Do not copy the whole file as-is, as it contains some invalid sections for illustrative purposes.
|
||||
;; If you don't know what a setting is you should not set it.
|
||||
;;
|
||||
;; see https://docs.gitea.com/administration/config-cheat-sheet for additional documentation.
|
||||
;; see https://forgejo.org/docs/next/admin/config-cheat-sheet for additional documentation.
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -41,7 +41,14 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; App name that shows in every page title
|
||||
APP_NAME = ; Gitea: Git with a cup of tea
|
||||
APP_NAME = ; Forgejo: Beyond coding. We Forge.
|
||||
;;
|
||||
;; APP_SLOGAN shows a slogan near the App name in every page title.
|
||||
;APP_SLOGAN =
|
||||
;;
|
||||
;; APP_DISPLAY_NAME_FORMAT defines how the AppDisplayName should be presented
|
||||
;; It is used only if APP_SLOGAN is set.
|
||||
;APP_DISPLAY_NAME_FORMAT = {APP_NAME}: {APP_SLOGAN}
|
||||
;;
|
||||
;; RUN_USER will automatically detect the current user - but you can set it here change it if you run locally
|
||||
RUN_USER = ; git
|
||||
|
|
|
@ -45,6 +45,14 @@ var (
|
|||
// AppName is the Application name, used in the page title.
|
||||
// It maps to ini:"APP_NAME"
|
||||
AppName string
|
||||
// AppSlogan is the Application slogan.
|
||||
// It maps to ini:"APP_SLOGAN"
|
||||
AppSlogan string
|
||||
// AppDisplayNameFormat defines how the AppDisplayName should be presented
|
||||
// It maps to ini:"APP_DISPLAY_NAME_FORMAT"
|
||||
AppDisplayNameFormat string
|
||||
// AppDisplayName is the display name for the application, defined following AppDisplayNameFormat
|
||||
AppDisplayName string
|
||||
// AppURL is the Application ROOT_URL. It always has a '/' suffix
|
||||
// It maps to ini:"ROOT_URL"
|
||||
AppURL string
|
||||
|
@ -164,10 +172,21 @@ func MakeAbsoluteAssetURL(appURL, staticURLPrefix string) string {
|
|||
return strings.TrimSuffix(staticURLPrefix, "/")
|
||||
}
|
||||
|
||||
func generateDisplayName() string {
|
||||
appDisplayName := AppName
|
||||
if AppSlogan != "" {
|
||||
appDisplayName = strings.Replace(AppDisplayNameFormat, "{APP_NAME}", AppName, 1)
|
||||
appDisplayName = strings.Replace(appDisplayName, "{APP_SLOGAN}", AppSlogan, 1)
|
||||
}
|
||||
return appDisplayName
|
||||
}
|
||||
|
||||
func loadServerFrom(rootCfg ConfigProvider) {
|
||||
sec := rootCfg.Section("server")
|
||||
AppName = rootCfg.Section("").Key("APP_NAME").MustString("Forgejo: Beyond coding. We Forge.")
|
||||
|
||||
AppSlogan = rootCfg.Section("").Key("APP_SLOGAN").MustString("")
|
||||
AppDisplayNameFormat = rootCfg.Section("").Key("APP_DISPLAY_NAME_FORMAT").MustString("{APP_NAME}: {APP_SLOGAN}")
|
||||
AppDisplayName = generateDisplayName()
|
||||
Domain = sec.Key("DOMAIN").MustString("localhost")
|
||||
HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
|
||||
HTTPPort = sec.Key("HTTP_PORT").MustString("3000")
|
||||
|
|
36
modules/setting/server_test.go
Normal file
36
modules/setting/server_test.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package setting
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDisplayNameDefault(t *testing.T) {
|
||||
defer test.MockVariableValue(&AppName, "Forgejo")()
|
||||
defer test.MockVariableValue(&AppSlogan, "Beyond coding. We Forge.")()
|
||||
defer test.MockVariableValue(&AppDisplayNameFormat, "{APP_NAME}: {APP_SLOGAN}")()
|
||||
displayName := generateDisplayName()
|
||||
assert.Equal(t, "Forgejo: Beyond coding. We Forge.", displayName)
|
||||
}
|
||||
|
||||
func TestDisplayNameEmptySlogan(t *testing.T) {
|
||||
defer test.MockVariableValue(&AppName, "Forgejo")()
|
||||
defer test.MockVariableValue(&AppSlogan, "")()
|
||||
defer test.MockVariableValue(&AppDisplayNameFormat, "{APP_NAME}: {APP_SLOGAN}")()
|
||||
displayName := generateDisplayName()
|
||||
assert.Equal(t, "Forgejo", displayName)
|
||||
}
|
||||
|
||||
func TestDisplayNameCustomFormat(t *testing.T) {
|
||||
defer test.MockVariableValue(&AppName, "Forgejo")()
|
||||
defer test.MockVariableValue(&AppSlogan, "Beyond coding. We Forge.")()
|
||||
defer test.MockVariableValue(&AppDisplayNameFormat, "{APP_NAME} - {APP_SLOGAN}")()
|
||||
displayName := generateDisplayName()
|
||||
assert.Equal(t, "Forgejo - Beyond coding. We Forge.", displayName)
|
||||
}
|
|
@ -79,6 +79,12 @@ func NewFuncMap() template.FuncMap {
|
|||
"AppName": func() string {
|
||||
return setting.AppName
|
||||
},
|
||||
"AppSlogan": func() string {
|
||||
return setting.AppSlogan
|
||||
},
|
||||
"AppDisplayName": func() string {
|
||||
return setting.AppDisplayName
|
||||
},
|
||||
"AppSubUrl": func() string {
|
||||
return setting.AppSubURL
|
||||
},
|
||||
|
|
|
@ -28,6 +28,12 @@ func mailSubjectTextFuncMap() texttmpl.FuncMap {
|
|||
"AppName": func() string {
|
||||
return setting.AppName
|
||||
},
|
||||
"AppSlogan": func() string {
|
||||
return setting.AppSlogan
|
||||
},
|
||||
"AppDisplayName": func() string {
|
||||
return setting.AppDisplayName
|
||||
},
|
||||
"AppDomain": func() string { // documented in mail-templates.md
|
||||
return setting.Domain
|
||||
},
|
||||
|
|
|
@ -267,6 +267,8 @@ err_admin_name_is_invalid = Administrator Username is invalid
|
|||
general_title = General settings
|
||||
app_name = Instance title
|
||||
app_name_helper = You can enter your company name here.
|
||||
app_slogan = Instance slogan
|
||||
app_slogan_helper = Enter your instance slogan here. Leave empty to disable.
|
||||
repo_path = Repository root path
|
||||
repo_path_helper = Remote Git repositories will be saved to this directory.
|
||||
lfs_path = Git LFS root path
|
||||
|
@ -3207,6 +3209,7 @@ auths.invalid_openIdConnectAutoDiscoveryURL = Invalid Auto Discovery URL (this m
|
|||
|
||||
config.server_config = Server configuration
|
||||
config.app_name = Instance title
|
||||
config.app_slogan = Instance slogan
|
||||
config.app_ver = Forgejo version
|
||||
config.app_url = Base URL
|
||||
config.custom_conf = Configuration file path
|
||||
|
|
10
release-notes/8.0.0/3616.md
Normal file
10
release-notes/8.0.0/3616.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
There are a couple of new configs to define the name of the instance.
|
||||
The more important is `APP_SLOGAN`. It permits to configure a slogan for the site and it is optional.
|
||||
The other is `APP_DISPLAY_NAME_FORMAT` and permits to customize the aspect of the full display name for the instance used in some parts of the UI as:
|
||||
|
||||
- Title page.
|
||||
- Homepage head title.
|
||||
- Open Graph site and title meta tags.
|
||||
|
||||
Its default value is `APP_NAME: APP_SLOGAN`.
|
||||
The config `APP_DISPLAY_NAME_FORMAT` is used only if `APP_SLOGAN` is set otherwise the full display name shows only `APP_NAME` value.
|
|
@ -115,7 +115,8 @@ func Install(ctx *context.Context) {
|
|||
ctx.Data["CurDbType"] = curDBType
|
||||
|
||||
// Application general settings
|
||||
form.AppName = setting.AppName
|
||||
form.AppName = "Forgejo"
|
||||
form.AppSlogan = "Beyond coding. We Forge."
|
||||
form.RepoRootPath = setting.RepoRootPath
|
||||
form.LFSRootPath = setting.LFS.Storage.Path
|
||||
|
||||
|
@ -383,6 +384,7 @@ func SubmitInstall(ctx *context.Context) {
|
|||
}
|
||||
|
||||
cfg.Section("").Key("APP_NAME").SetValue(form.AppName)
|
||||
cfg.Section("").Key("APP_SLOGAN").SetValue(form.AppSlogan)
|
||||
cfg.Section("").Key("RUN_USER").SetValue(form.RunUser)
|
||||
cfg.Section("").Key("WORK_PATH").SetValue(setting.AppWorkPath)
|
||||
cfg.Section("").Key("RUN_MODE").SetValue("prod")
|
||||
|
|
|
@ -31,6 +31,7 @@ type InstallForm struct {
|
|||
DbSchema string
|
||||
|
||||
AppName string `binding:"Required" locale:"install.app_name"`
|
||||
AppSlogan string
|
||||
RepoRootPath string `binding:"Required"`
|
||||
LFSRootPath string
|
||||
RunUser string `binding:"Required"`
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<dl class="admin-dl-horizontal">
|
||||
<dt>{{ctx.Locale.Tr "admin.config.app_name"}}</dt>
|
||||
<dd>{{AppName}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.app_slogan"}}</dt>
|
||||
<dd>{{AppSlogan}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.app_ver"}}</dt>
|
||||
<dd>{{AppVer}}{{.AppBuiltWith}}</dd>
|
||||
<dt>{{ctx.Locale.Tr "admin.config.custom_conf"}}</dt>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{{/* Display `- .Repository.FullName` only if `.Title` does not already start with that. */}}
|
||||
<title>{{if .Title}}{{.Title}} - {{end}}{{if and (.Repository.Name) (not (StringUtils.HasPrefix .Title .Repository.FullName))}}{{.Repository.FullName}} - {{end}}{{AppName}}</title>
|
||||
<title>{{if .Title}}{{.Title}} - {{end}}{{if and (.Repository.Name) (not (StringUtils.HasPrefix .Title .Repository.FullName))}}{{.Repository.FullName}} - {{end}}{{AppDisplayName}}</title>
|
||||
{{if .ManifestData}}<link rel="manifest" href="data:{{.ManifestData}}">{{end}}
|
||||
<meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}">
|
||||
<meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}">
|
||||
|
|
|
@ -38,10 +38,10 @@
|
|||
<meta property="og:image" content="{{.Repository.Owner.AvatarLink ctx}}">
|
||||
{{end}}
|
||||
{{else}}
|
||||
<meta property="og:title" content="{{AppName}}">
|
||||
<meta property="og:title" content="{{AppDisplayName}}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:image" content="{{AssetUrlPrefix}}/img/logo.png">
|
||||
<meta property="og:url" content="{{AppUrl}}">
|
||||
<meta property="og:description" content="{{MetaDescription}}">
|
||||
{{end}}
|
||||
<meta property="og:site_name" content="{{AppName}}">
|
||||
<meta property="og:site_name" content="{{AppDisplayName}}">
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<img class="logo" width="220" height="220" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}">
|
||||
<div class="hero">
|
||||
<h1 class="ui icon header title">
|
||||
{{AppName}}
|
||||
{{AppDisplayName}}
|
||||
</h1>
|
||||
<h2>{{ctx.Locale.Tr "startpage.app_desc"}}</h2>
|
||||
</div>
|
||||
|
|
|
@ -107,6 +107,11 @@
|
|||
<input id="app_name" name="app_name" value="{{.app_name}}" required>
|
||||
<span class="help">{{ctx.Locale.Tr "install.app_name_helper"}}</span>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<label for="app_slogan">{{ctx.Locale.Tr "install.app_slogan"}}</label>
|
||||
<input id="app_slogan" name="app_slogan" value="{{.app_slogan}}">
|
||||
<span class="help">{{ctx.Locale.Tr "install.app_slogan_helper"}}</span>
|
||||
</div>
|
||||
<div class="inline required field {{if .Err_RepoRootPath}}error{{end}}">
|
||||
<label for="repo_root_path">{{ctx.Locale.Tr "install.repo_path"}}</label>
|
||||
<input id="repo_root_path" name="repo_root_path" value="{{.repo_root_path}}" required>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<html lang="{{ctx.Locale.Lang}}" data-theme="{{ThemeName .SignedUser}}">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ctx.Locale.Tr "error.server_internal"}} - {{AppName}}</title>
|
||||
<title>{{ctx.Locale.Tr "error.server_internal"}} - {{AppDisplayName}}</title>
|
||||
<link rel="icon" href="{{AssetUrlPrefix}}/img/favicon.svg" type="image/svg+xml">
|
||||
<link rel="alternate icon" href="{{AssetUrlPrefix}}/img/favicon.png" type="image/png">
|
||||
{{template "base/head_style" .}}
|
||||
|
|
|
@ -185,3 +185,28 @@ func TestInHistoryButton(t *testing.T) {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestTitleDisplayName(t *testing.T) {
|
||||
session := emptyTestSession(t)
|
||||
title := GetHTMLTitle(t, session, "/")
|
||||
assert.Equal(t, "Gitea: Git with a cup of tea", title)
|
||||
}
|
||||
|
||||
func TestHomeDisplayName(t *testing.T) {
|
||||
session := emptyTestSession(t)
|
||||
req := NewRequest(t, "GET", "/")
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
assert.Equal(t, "Gitea: Git with a cup of tea", strings.TrimSpace(htmlDoc.Find("h1.title").Text()))
|
||||
}
|
||||
|
||||
func TestOpenGraphDisplayName(t *testing.T) {
|
||||
session := emptyTestSession(t)
|
||||
req := NewRequest(t, "GET", "/")
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
ogTitle, _ := htmlDoc.Find("meta[property='og:title']").Attr("content")
|
||||
assert.Equal(t, "Gitea: Git with a cup of tea", ogTitle)
|
||||
ogSiteName, _ := htmlDoc.Find("meta[property='og:site_name']").Attr("content")
|
||||
assert.Equal(t, "Gitea: Git with a cup of tea", ogSiteName)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
APP_NAME = Gitea: Git with a cup of tea
|
||||
APP_NAME = Gitea
|
||||
APP_SLOGAN = Git with a cup of tea
|
||||
RUN_MODE = prod
|
||||
|
||||
[database]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
APP_NAME = Gitea: Git with a cup of tea
|
||||
APP_NAME = Gitea
|
||||
APP_SLOGAN = Git with a cup of tea
|
||||
RUN_MODE = prod
|
||||
|
||||
[database]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
APP_NAME = Gitea: Git with a cup of tea
|
||||
APP_NAME = Gitea
|
||||
APP_SLOGAN = Git with a cup of tea
|
||||
RUN_MODE = prod
|
||||
|
||||
[database]
|
||||
|
|
Loading…
Reference in a new issue