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>
2023-04-20 04:08:58 -04:00
..
actions Support triggering workflows by wiki related events (#24119) 2023-04-17 13:49:47 -04:00
activitypub Add Chef package registry (#22554) 2023-02-06 09:49:21 +08:00
analyze Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
assetfs Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
auth Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
avatar Use minio/sha256-simd for accelerated SHA256 (#23052) 2023-02-22 14:21:46 -05:00
base Use a general Eval function for expressions in templates. (#23927) 2023-04-07 21:25:49 +08:00
cache Update redis library to support redis v7 (#24114) 2023-04-13 18:41:04 -04:00
charset Refactor locale number (#24134) 2023-04-17 11:37:23 +08:00
container Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
context Make HTML template functions support context (#24056) 2023-04-20 04:08:58 -04:00
csv Refactor locale number (#24134) 2023-04-17 11:37:23 +08:00
doctor Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
emoji Fix unstable emoji sort (#22346) 2023-01-05 13:58:51 +02:00
eventsource Move convert package to services (#22264) 2022-12-29 10:57:15 +08:00
generate Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
git Make wiki title supports dashes and improve wiki name related features (#24143) 2023-04-19 13:50:10 -04:00
gitgraph Add context cache as a request level cache (#22294) 2023-02-15 21:37:34 +08:00
graceful Remove most path-based golangci exclusions (#24214) 2023-04-19 22:08:01 -04:00
hcaptcha Consume hcaptcha and pwn deps (#22610) 2023-01-29 09:49:51 -06:00
highlight test_env: hardcode major go version in use (#23464) 2023-03-14 16:09:01 -04:00
hostmatcher Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
html Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
httpcache Set X-Gitea-Debug header once (#23361) 2023-03-08 15:40:04 -05:00
httplib Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687) 2023-03-29 14:32:26 +08:00
indexer Allow adding new files to an empty repo (#24164) 2023-04-19 21:40:42 +08:00
issue/template Allow issue templates to not render title (#22589) 2023-01-26 22:45:49 -06:00
json Update gitea-vet to check FSFE REUSE (#22004) 2022-12-02 22:14:57 +08:00
label Make label templates have consistent behavior and priority (#23749) 2023-04-10 16:44:02 +08:00
lfs Make minio package support legacy MD5 checksum (#23768) 2023-03-28 11:10:24 -04:00
log Remove most path-based golangci exclusions (#24214) 2023-04-19 22:08:01 -04:00
markup Improve Wiki TOC (#24137) 2023-04-17 15:05:19 -04:00
mcaptcha Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
metrics include build info in Prometheus metrics (#22819) 2023-02-08 19:54:01 +02:00
migration Scoped labels (#22585) 2023-02-18 21:17:39 +02:00
mirror Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
nosql Update redis library to support redis v7 (#24114) 2023-04-13 18:41:04 -04:00
notification Implement actions (#21937) 2023-01-31 09:45:19 +08:00
options Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
packages Display image size for multiarch container images (#23821) 2023-04-02 17:53:37 +08:00
paginator Update gitea-vet to check FSFE REUSE (#22004) 2022-12-02 22:14:57 +08:00
pprof Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
private Fix incorrect internal response type (#24173) 2023-04-17 23:10:40 -04:00
process Improve trace logging for pulls and processes (#22633) 2023-02-03 18:11:48 -05:00
proxy Use proxy for pull mirror (#22771) 2023-02-11 08:39:50 +08:00
proxyprotocol Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
public Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
queue Update redis library to support redis v7 (#24114) 2023-04-13 18:41:04 -04:00
recaptcha Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
references Use correct captured group range when parsing cross-reference (#22672) 2023-01-31 10:08:05 +01:00
regexplru Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
repository Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
secret Use minio/sha256-simd for accelerated SHA256 (#23052) 2023-02-22 14:21:46 -05:00
session Update redis library to support redis v7 (#24114) 2023-04-13 18:41:04 -04:00
setting Fix incorrect CORS default values (#24206) 2023-04-19 15:30:10 -04:00
sitemap Fix sitemap (#22272) 2022-12-30 23:31:00 +08:00
ssh Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
storage Make minio package support legacy MD5 checksum (#23768) 2023-03-28 11:10:24 -04:00
structs Fix Org edit page bugs: renaming detection, maxlength (#24161) 2023-04-17 11:35:57 -04:00
svg Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
sync Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
system Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
templates Make HTML template functions support context (#24056) 2023-04-20 04:08:58 -04:00
test Make HTML template functions support context (#24056) 2023-04-20 04:08:58 -04:00
timeutil Remove untranslatable on_date key (#24106) 2023-04-15 13:01:54 +02:00
translation Refactor locale number (#24134) 2023-04-17 11:37:23 +08:00
turnstile Add new captcha: cloudflare turnstile (#22369) 2023-02-05 15:29:03 +08:00
typesniffer Do not recognize text files as audio (#23355) 2023-03-07 22:40:41 -05:00
updatechecker Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
upload Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
uri Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
user Implement FSFE REUSE for golang files (#21840) 2022-11-27 18:20:29 +00:00
util Use a general approach to access custom/static/builtin assets (#24022) 2023-04-12 18:16:45 +08:00
validation Map OIDC groups to Orgs/Teams (#21441) 2023-02-08 14:44:42 +08:00
web Refactor cookie (#24107) 2023-04-13 15:45:33 -04:00
webhook Restructure webhook module (#22256) 2023-01-01 23:23:15 +08:00