You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
forgejo/modules
wxiaoguang 722dab5286
Make HTML template functions support context (#24056)
# Background

Golang template is not friendly for large projects, and Golang template
team is quite slow, related:
* `https://github.com/golang/go/issues/54450`

Without upstream support, we can also have our solution to make HTML
template functions support context.

It helps a lot, the above Golang template issue `#54450` explains a lot:

1. It makes `{{Locale.Tr}}` could be used in any template, without
passing unclear `(dict "root" . )` anymore.
2. More and more functions need `context`, like `avatar`, etc, we do not
need to do `(dict "Context" $.Context)` anymore.
3. Many request-related functions could be shared by parent&children
templates, like "user setting" / "system setting"

See the test `TestScopedTemplateSetFuncMap`, one template set, two
`Execute` calls with different `CtxFunc`.

# The Solution

Instead of waiting for upstream, this PR re-uses the escaped HTML
template trees, use `AddParseTree` to add related templates/trees to a
new template instance, then the new template instance can have its own
FuncMap , the function calls in the template trees will always use the
new template's FuncMap.

`template.New` / `template.AddParseTree` / `adding-FuncMap` are all
quite fast, so the performance is not affected.

The details:

1. Make a new `html/template/Template` for `all` templates
2. Add template code to the `all` template
3. Freeze the `all` template, reset its exec func map, it shouldn't
execute any template.
4. When a router wants to render a template by its `name`
    1. Find the `name` in `all`
    2. Find all its related sub templates
3. Escape all related templates (just like what the html template
package does)
4. Add the escaped parse-trees of related templates into a new (scoped)
`text/template/Template`
    5. Add context-related func map into the new (scoped) text template
    6. Execute the new (scoped) text template
7. To improve performance, the escaped templates are cached to `template
sets`

# FAQ

## There is a `unsafe` call, is this PR unsafe?

This PR is safe. Golang has strict language definition, it's safe to do
so: https://pkg.go.dev/unsafe#Pointer (1) Conversion of a *T1 to Pointer
to *T2


## What if Golang template supports such feature in the future?

The public structs/interfaces/functions introduced by this PR is quite
simple, the code of `HTMLRender` is not changed too much. It's very easy
to switch to the official mechanism if there would be one.

## Does this PR change the template execution behavior?

No, see the tests (welcome to design more tests if it's necessary)

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Giteabot <teabot@gitea.io>
1 year ago
..
actions Support triggering workflows by wiki related events (#24119) 1 year ago
activitypub Add Chef package registry (#22554) 1 year ago
analyze Implement FSFE REUSE for golang files (#21840) 2 years ago
assetfs Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
auth Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
avatar Use minio/sha256-simd for accelerated SHA256 (#23052) 1 year ago
base Use a general Eval function for expressions in templates. (#23927) 1 year ago
cache Update redis library to support redis v7 (#24114) 1 year ago
charset Refactor locale number (#24134) 1 year ago
container Implement FSFE REUSE for golang files (#21840) 2 years ago
context Make HTML template functions support context (#24056) 1 year ago
csv Refactor locale number (#24134) 1 year ago
doctor Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
emoji Fix unstable emoji sort (#22346) 2 years ago
eventsource Move `convert` package to services (#22264) 2 years ago
generate Implement FSFE REUSE for golang files (#21840) 2 years ago
git Make wiki title supports dashes and improve wiki name related features (#24143) 1 year ago
gitgraph Add context cache as a request level cache (#22294) 1 year ago
graceful Remove most path-based golangci exclusions (#24214) 1 year ago
hcaptcha Consume hcaptcha and pwn deps (#22610) 1 year ago
highlight test_env: hardcode major go version in use (#23464) 1 year ago
hostmatcher Implement FSFE REUSE for golang files (#21840) 2 years ago
html Implement FSFE REUSE for golang files (#21840) 2 years ago
httpcache Set `X-Gitea-Debug` header once (#23361) 1 year ago
httplib Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687) 1 year ago
indexer Allow adding new files to an empty repo (#24164) 1 year ago
issue/template Allow issue templates to not render title (#22589) 2 years ago
json Update gitea-vet to check FSFE REUSE (#22004) 2 years ago
label Make label templates have consistent behavior and priority (#23749) 1 year ago
lfs Make minio package support legacy MD5 checksum (#23768) 1 year ago
log Remove most path-based golangci exclusions (#24214) 1 year ago
markup Improve Wiki TOC (#24137) 1 year ago
mcaptcha Implement FSFE REUSE for golang files (#21840) 2 years ago
metrics include build info in Prometheus metrics (#22819) 1 year ago
migration Scoped labels (#22585) 1 year ago
mirror Implement FSFE REUSE for golang files (#21840) 2 years ago
nosql Update redis library to support redis v7 (#24114) 1 year ago
notification Implement actions (#21937) 1 year ago
options Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
packages Display image size for multiarch container images (#23821) 1 year ago
paginator Update gitea-vet to check FSFE REUSE (#22004) 2 years ago
pprof Implement FSFE REUSE for golang files (#21840) 2 years ago
private Fix incorrect internal response type (#24173) 1 year ago
process Improve trace logging for pulls and processes (#22633) 1 year ago
proxy Use proxy for pull mirror (#22771) 1 year ago
proxyprotocol Implement FSFE REUSE for golang files (#21840) 2 years ago
public Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
queue Update redis library to support redis v7 (#24114) 1 year ago
recaptcha Implement FSFE REUSE for golang files (#21840) 2 years ago
references Use correct captured group range when parsing cross-reference (#22672) 1 year ago
regexplru Implement FSFE REUSE for golang files (#21840) 2 years ago
repository Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
secret Use minio/sha256-simd for accelerated SHA256 (#23052) 1 year ago
session Update redis library to support redis v7 (#24114) 1 year ago
setting Fix incorrect CORS default values (#24206) 1 year ago
sitemap Fix sitemap (#22272) 2 years ago
ssh Implement FSFE REUSE for golang files (#21840) 2 years ago
storage Make minio package support legacy MD5 checksum (#23768) 1 year ago
structs Fix Org edit page bugs: renaming detection, maxlength (#24161) 1 year ago
svg Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
sync Implement FSFE REUSE for golang files (#21840) 2 years ago
system Implement FSFE REUSE for golang files (#21840) 2 years ago
templates Make HTML template functions support context (#24056) 1 year ago
test Make HTML template functions support context (#24056) 1 year ago
timeutil Remove untranslatable `on_date` key (#24106) 1 year ago
translation Refactor locale number (#24134) 1 year ago
turnstile Add new captcha: cloudflare turnstile (#22369) 1 year ago
typesniffer Do not recognize text files as audio (#23355) 1 year ago
updatechecker Implement FSFE REUSE for golang files (#21840) 2 years ago
upload Implement FSFE REUSE for golang files (#21840) 2 years ago
uri Implement FSFE REUSE for golang files (#21840) 2 years ago
user Implement FSFE REUSE for golang files (#21840) 2 years ago
util Use a general approach to access custom/static/builtin assets (#24022) 1 year ago
validation Map OIDC groups to Orgs/Teams (#21441) 1 year ago
web Refactor cookie (#24107) 1 year ago
webhook Restructure `webhook` module (#22256) 2 years ago