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