Group template helper functions, remove Printf, improve template error messages (#23982)

Follow #23328 


Major changes:

* Group the function in `templates/help.go` by their purposes. It could
make future work easier.
* Remove the `Printf` helper function, there is already a builtin
`printf`.
* Remove `DiffStatsWidth`, replace with `Eval` in template
* Rename the `NewTextFuncMap` to `mailSubjectTextFuncMap`, it's for
subject text template only, no need to make it support HTML functions.


----

And fine tune template error messages, to make it more friendly to
developers and users.


![image](https://user-images.githubusercontent.com/2114189/230714245-4fd202d1-2b25-41b2-8be5-03c5fee45091.png)


![image](https://user-images.githubusercontent.com/2114189/230714277-66783577-2a03-49d5-8e8c-ceba5e07a2d4.png)

---------

Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
wxiaoguang 2023-04-08 21:15:22 +08:00 committed by GitHub
parent cf5a281fdc
commit fdbd646113
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 307 additions and 295 deletions

View file

@ -6,6 +6,7 @@ package templates
import (
"bytes"
"context"
"errors"
"fmt"
"html/template"
"io"
@ -15,9 +16,11 @@ import (
"strconv"
"strings"
"sync/atomic"
texttemplate "text/template"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/watcher"
)
@ -34,6 +37,8 @@ type HTMLRender struct {
templates atomic.Pointer[template.Template]
}
var ErrTemplateNotInitialized = errors.New("template system is not initialized, check your log for errors")
func (h *HTMLRender) HTML(w io.Writer, status int, name string, data interface{}) error {
if respWriter, ok := w.(http.ResponseWriter); ok {
if respWriter.Header().Get("Content-Type") == "" {
@ -41,11 +46,23 @@ func (h *HTMLRender) HTML(w io.Writer, status int, name string, data interface{}
}
respWriter.WriteHeader(status)
}
return h.templates.Load().ExecuteTemplate(w, name, data)
t, err := h.TemplateLookup(name)
if err != nil {
return texttemplate.ExecError{Name: name, Err: err}
}
return t.Execute(w, data)
}
func (h *HTMLRender) TemplateLookup(t string) *template.Template {
return h.templates.Load().Lookup(t)
func (h *HTMLRender) TemplateLookup(name string) (*template.Template, error) {
tmpls := h.templates.Load()
if tmpls == nil {
return nil, ErrTemplateNotInitialized
}
tmpl := tmpls.Lookup(name)
if tmpl == nil {
return nil, util.ErrNotExist
}
return tmpl, nil
}
func (h *HTMLRender) CompileTemplates() error {
@ -237,6 +254,12 @@ func GetLineFromTemplate(templateName string, targetLineNum int, target string,
}
}
// FIXME: this algorithm could provide incorrect results and mislead the developers.
// For example: Undefined function "file" in template .....
// {{Func .file.Addition file.Deletion .file.Addition}}
// ^^^^ ^(the real error is here)
// The pointer is added to the first one, but the second one is the real incorrect one.
//
// If there is a provided target to look for in the line add a pointer to it
// e.g. ^^^^^^^
if target != "" {