mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 01:34:27 +00:00 
			
		
		
		
	Add global setting how timestamps should be rendered (#28657)
- Resolves https://github.com/go-gitea/gitea/issues/22493 - Related to https://github.com/go-gitea/gitea/issues/4520 Some admins prefer all timestamps to display the full date instead of relative time. They can do that now by setting ```ini [ui] PREFERRED_TIMESTAMP_TENSE = absolute ``` This setting is set to `mixed` by default, allowing dates to render as "5 hours ago". Here are some screenshots of the UI with this setting set to `absolute`:    --------- Signed-off-by: Yarden Shoham <git@yardenshoham.com> Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
		@@ -1244,6 +1244,10 @@ LEVEL = Info
 | 
			
		||||
;; Change the sort type of the explore pages.
 | 
			
		||||
;; Default is "recentupdate", but you also have "alphabetically", "reverselastlogin", "newest", "oldest".
 | 
			
		||||
;EXPLORE_PAGING_DEFAULT_SORT = recentupdate
 | 
			
		||||
;;
 | 
			
		||||
;; The tense all timestamps should be rendered in. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) and `mixed`.
 | 
			
		||||
;; `mixed` means most timestamps are rendered in relative time (i.e. 2 days ago).
 | 
			
		||||
;PREFERRED_TIMESTAMP_TENSE = mixed
 | 
			
		||||
 | 
			
		||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
 
 | 
			
		||||
@@ -231,6 +231,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
 | 
			
		||||
- `ONLY_SHOW_RELEVANT_REPOS`: **false**: Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used.
 | 
			
		||||
    A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic).
 | 
			
		||||
- `EXPLORE_PAGING_DEFAULT_SORT`: **recentupdate**: Change the sort type of the explore pages. Valid values are "recentupdate", "alphabetically", "reverselastlogin", "newest" and "oldest"
 | 
			
		||||
- `PREFERRED_TIMESTAMP_TENSE`: **mixed**: The tense all timestamps should be rendered in. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) and `mixed`. `mixed` means most timestamps are rendered in relative time (i.e. 2 days ago).
 | 
			
		||||
 | 
			
		||||
### UI - Admin (`ui.admin`)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/container"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// UI settings
 | 
			
		||||
@@ -34,6 +35,7 @@ var UI = struct {
 | 
			
		||||
	SearchRepoDescription   bool
 | 
			
		||||
	OnlyShowRelevantRepos   bool
 | 
			
		||||
	ExploreDefaultSort      string `ini:"EXPLORE_PAGING_DEFAULT_SORT"`
 | 
			
		||||
	PreferredTimestampTense string
 | 
			
		||||
 | 
			
		||||
	AmbiguousUnicodeDetection bool
 | 
			
		||||
 | 
			
		||||
@@ -84,6 +86,7 @@ var UI = struct {
 | 
			
		||||
	Reactions:               []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`},
 | 
			
		||||
	CustomEmojis:            []string{`git`, `gitea`, `codeberg`, `gitlab`, `github`, `gogs`},
 | 
			
		||||
	CustomEmojisMap:         map[string]string{"git": ":git:", "gitea": ":gitea:", "codeberg": ":codeberg:", "gitlab": ":gitlab:", "github": ":github:", "gogs": ":gogs:"},
 | 
			
		||||
	PreferredTimestampTense: "mixed",
 | 
			
		||||
 | 
			
		||||
	AmbiguousUnicodeDetection: true,
 | 
			
		||||
 | 
			
		||||
@@ -142,6 +145,10 @@ func loadUIFrom(rootCfg ConfigProvider) {
 | 
			
		||||
	UI.DefaultShowFullName = sec.Key("DEFAULT_SHOW_FULL_NAME").MustBool(false)
 | 
			
		||||
	UI.SearchRepoDescription = sec.Key("SEARCH_REPO_DESCRIPTION").MustBool(true)
 | 
			
		||||
 | 
			
		||||
	if UI.PreferredTimestampTense != "mixed" && UI.PreferredTimestampTense != "absolute" {
 | 
			
		||||
		log.Fatal("ui.PREFERRED_TIMESTAMP_TENSE must be either 'mixed' or 'absolute'")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// OnlyShowRelevantRepos=false is important for many private/enterprise instances,
 | 
			
		||||
	// because many private repositories do not have "description/topic", users just want to search by their names.
 | 
			
		||||
	UI.OnlyShowRelevantRepos = sec.Key("ONLY_SHOW_RELEVANT_REPOS").MustBool(false)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,12 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"html"
 | 
			
		||||
	"html/template"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DateTime renders an absolute time HTML element by datetime.
 | 
			
		||||
func DateTime(format string, datetime any) template.HTML {
 | 
			
		||||
func DateTime(format string, datetime any, attrs ...string) template.HTML {
 | 
			
		||||
	if p, ok := datetime.(*time.Time); ok {
 | 
			
		||||
		datetime = *p
 | 
			
		||||
	}
 | 
			
		||||
@@ -48,13 +49,15 @@ func DateTime(format string, datetime any) template.HTML {
 | 
			
		||||
		panic(fmt.Sprintf("Unsupported time type %T", datetime))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	extraAttrs := strings.Join(attrs, " ")
 | 
			
		||||
 | 
			
		||||
	switch format {
 | 
			
		||||
	case "short":
 | 
			
		||||
		return template.HTML(fmt.Sprintf(`<relative-time format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="%s">%s</relative-time>`, datetimeEscaped, textEscaped))
 | 
			
		||||
		return template.HTML(fmt.Sprintf(`<relative-time %s format="datetime" year="numeric" month="short" day="numeric" weekday="" datetime="%s">%s</relative-time>`, extraAttrs, datetimeEscaped, textEscaped))
 | 
			
		||||
	case "long":
 | 
			
		||||
		return template.HTML(fmt.Sprintf(`<relative-time format="datetime" year="numeric" month="long" day="numeric" weekday="" datetime="%s">%s</relative-time>`, datetimeEscaped, textEscaped))
 | 
			
		||||
		return template.HTML(fmt.Sprintf(`<relative-time %s format="datetime" year="numeric" month="long" day="numeric" weekday="" datetime="%s">%s</relative-time>`, extraAttrs, datetimeEscaped, textEscaped))
 | 
			
		||||
	case "full":
 | 
			
		||||
		return template.HTML(fmt.Sprintf(`<relative-time format="datetime" weekday="" year="numeric" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" datetime="%s">%s</relative-time>`, datetimeEscaped, textEscaped))
 | 
			
		||||
		return template.HTML(fmt.Sprintf(`<relative-time %s format="datetime" weekday="" year="numeric" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" datetime="%s">%s</relative-time>`, extraAttrs, datetimeEscaped, textEscaped))
 | 
			
		||||
	}
 | 
			
		||||
	panic(fmt.Sprintf("Unsupported format %s", format))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/translation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -132,6 +133,9 @@ func timeSinceUnix(then, now time.Time, lang translation.Locale) template.HTML {
 | 
			
		||||
 | 
			
		||||
// TimeSince renders relative time HTML given a time.Time
 | 
			
		||||
func TimeSince(then time.Time, lang translation.Locale) template.HTML {
 | 
			
		||||
	if setting.UI.PreferredTimestampTense == "absolute" {
 | 
			
		||||
		return DateTime("full", then, `class="time-since"`)
 | 
			
		||||
	}
 | 
			
		||||
	return timeSinceUnix(then, time.Now(), lang)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -247,6 +247,7 @@ export default {
 | 
			
		||||
            <div class="gt-ellipsis text light-2">
 | 
			
		||||
              {{ commit.committer_or_author_name }}
 | 
			
		||||
              <span class="text right">
 | 
			
		||||
                <!-- TODO: make this respect the PreferredTimestampTense setting -->
 | 
			
		||||
                <relative-time class="time-since" prefix="" :datetime="commit.time" data-tooltip-content data-tooltip-interactive="true">{{ commit.time }}</relative-time>
 | 
			
		||||
              </span>
 | 
			
		||||
            </div>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user