2023-08-08 09:22:47 +08:00
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package context
import (
"context"
2026-04-04 01:56:31 +08:00
"html/template"
2025-10-28 18:25:00 +08:00
"net/http"
2026-02-26 16:16:11 +01:00
"strconv"
2026-04-04 01:56:31 +08:00
"strings"
2023-08-08 09:22:47 +08:00
"time"
2025-10-28 18:25:00 +08:00
2026-04-04 01:56:31 +08:00
"code.gitea.io/gitea/modules/httplib"
2026-02-26 16:16:11 +01:00
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/web/middleware"
2025-10-28 18:25:00 +08:00
"code.gitea.io/gitea/services/webtheme"
2023-08-08 09:22:47 +08:00
)
var _ context . Context = TemplateContext ( nil )
2025-10-28 18:25:00 +08:00
func NewTemplateContext ( ctx context . Context , req * http . Request ) TemplateContext {
return TemplateContext { "_ctx" : ctx , "_req" : req }
2023-08-08 09:22:47 +08:00
}
2026-02-26 16:16:11 +01:00
func ( c TemplateContext ) req ( ) * http . Request {
return c [ "_req" ] . ( * http . Request )
}
2023-08-08 09:22:47 +08:00
func ( c TemplateContext ) parentContext ( ) context . Context {
return c [ "_ctx" ] . ( context . Context )
}
func ( c TemplateContext ) Deadline ( ) ( deadline time . Time , ok bool ) {
return c . parentContext ( ) . Deadline ( )
}
func ( c TemplateContext ) Done ( ) <- chan struct { } {
return c . parentContext ( ) . Done ( )
}
func ( c TemplateContext ) Err ( ) error {
return c . parentContext ( ) . Err ( )
}
func ( c TemplateContext ) Value ( key any ) any {
return c . parentContext ( ) . Value ( key )
}
2025-10-28 18:25:00 +08:00
func ( c TemplateContext ) CurrentWebTheme ( ) * webtheme . ThemeMetaInfo {
var themeName string
if webCtx := GetWebContext ( c ) ; webCtx != nil {
if webCtx . Doer != nil {
themeName = webCtx . Doer . Theme
}
}
if themeName == "" {
2026-02-26 16:16:11 +01:00
themeName = middleware . GetSiteCookie ( c . req ( ) , middleware . CookieTheme )
2025-10-28 18:25:00 +08:00
}
return webtheme . GuaranteeGetThemeMetaInfo ( themeName )
}
2026-02-26 16:16:11 +01:00
func ( c TemplateContext ) CurrentWebBanner ( ) * setting . WebBannerType {
// Using revision as a simple approach to determine if the banner has been changed after the user dismissed it.
// There could be some false-positives because revision can be changed even if the banner isn't.
// While it should be still good enough (no admin would keep changing the settings) and doesn't really harm end users (just a few more times to see the banner)
// So it doesn't need to make it more complicated by allocating unique IDs or using hashes.
dismissedBannerRevision , _ := strconv . Atoi ( middleware . GetSiteCookie ( c . req ( ) , middleware . CookieWebBannerDismissed ) )
banner , revision , _ := setting . Config ( ) . Instance . WebBanner . ValueRevision ( c )
if banner . ShouldDisplay ( ) && dismissedBannerRevision != revision {
return & banner
}
return nil
}
2026-04-04 01:56:31 +08:00
// AppFullLink returns a full URL link with AppSubURL for the given app link (no AppSubURL)
// If no link is given, it returns the current app full URL with sub-path but without trailing slash (that's why it is not named as AppURL)
func ( c TemplateContext ) AppFullLink ( link ... string ) template . URL {
s := httplib . GuessCurrentAppURL ( c . parentContext ( ) )
s = strings . TrimSuffix ( s , "/" )
if len ( link ) == 0 {
return template . URL ( s )
}
2026-04-21 10:04:01 +08:00
return template . URL ( s + "/" + strings . TrimPrefix ( link [ 0 ] , "/" ) )
2026-04-04 01:56:31 +08:00
}