Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with gin template rendering #912

Open
5455230 opened this issue Jan 22, 2025 · 7 comments
Open

Problems with gin template rendering #912

5455230 opened this issue Jan 22, 2025 · 7 comments
Labels
bug Something isn't working

Comments

@5455230
Copy link

5455230 commented Jan 22, 2025

What version of Garble and Go are you using?

garble version:
mvdan.cc/garble v0.13.0
Build settings:
      -buildmode exe
       -compiler gc
     CGO_ENABLED 1
          GOARCH amd64
            GOOS windows
         GOAMD64 v1

go version:
go version go1.22.5 windows/amd64

What did you do?
[]Item list,iii cannot be printed.

        {{range $value := .iii}}
            value: {{$value.Size}}
        {{end}}

garble build -mod=vendor -o bin/go_go.exe main.go

/main.go

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

type Item struct {
	Page int
	Size int
}

func main() {
	r := gin.Default()
	r.LoadHTMLGlob("templates/*")
	r.GET("/index", func(c *gin.Context) {
		a := gin.H{
			"title": "titleAA",
			"ce":    "123456",
			"iii": []Item{
				{Page: 1, Size: 11},
				{Page: 2, Size: 12},
				{Page: 3, Size: 13},
			},
		}
		c.HTML(http.StatusOK, "index.html", a)
	})
	r.Run()
}

/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>{{.title}}</title>
</head>
    <body>
        iii:
        {{range $value := .iii}}
            value: {{$value.Size}}
        {{end}}
    </body>
</html>

GET:http://127.0.0.1:8080/index
Error #01: template: index.html:9:27: executing "index.html" at <$value.Size>: can't evaluate field Size in type main.B0aMZmq6

@5455230
Copy link
Author

5455230 commented Jan 22, 2025

/main.go

"iii": Item{Page: 1, Size: 11}

/templates/index.html

{{.iii.Size}}

struct{} writing methods can be rendered successfully.

Error with []struct{} type in gin template rendering.

@lu4p
Copy link
Member

lu4p commented Jan 22, 2025

This is likely fixed in master:

go install mvdan.cc/garble@master

@5455230
Copy link
Author

5455230 commented Jan 23, 2025

This is likely fixed in master:

go install mvdan.cc/garble@master

go install mvdan.cc/garble@master
OR
go get -u mvdan.cc/garble@master

What version of Garble and Go are you using?

garble version:
mvdan.cc/garble v0.13.1-0.20250119141355-97833204f8f2
Build settings:
      -buildmode exe
       -compiler gc
     CGO_ENABLED 1
          GOARCH amd64
            GOOS windows
         GOAMD64 v1

go version:
go version go1.23.5 windows/amd64

go.mod:
mvdan.cc/garble v0.13.1-0.20250119141355-97833204f8f2
go.sum:

mvdan.cc/garble v0.13.1-0.20250119141355-97833204f8f2 h1:KbpHDqitrM8UW68FcQ3ehobmldqmyLjmuZkwO82xva0=
mvdan.cc/garble v0.13.1-0.20250119141355-97833204f8f2/go.mod h1:QOG7wThB5kAQhih4m93Sk1kjiGT8pgcEvWi/+VTWEn0=

Go->cmd:
SET CGO_ENABLED=0 && SET GOOS=windows && SET GOARCH=amd64 && garble build -o bin/go_go.exe main.go

GET:http://127.0.0.1:8080/index
Error #1: template: index.html:9:27: executing "index.html" at <$value.Size>: can't evaluate field Size in type main.ORh2JaE4Gpg8


I seem to have found some clues (not sure).

iii := map[string]interface{}{"Page": 1, "Size": "11"}
fmt.Println(fmt.Printf("%+v", iii)) //map[Page:1 Size:11]

OR

iii := []map[string]interface{}{
	{"Page": 1, "Size": "11"},
	{"Page": 2, "Size": "12"},
	{"Page": 3, "Size": "13"},
}
fmt.Println(fmt.Printf("%+v", iii)) //[map[Page:1 Size:11] map[Page:2 Size:12] map[Page:3 Size:13]]

any and interface{} Obfuscation was not successfully performed.

Error #01: template: index.html:9:27: executing "index.html" at <$value.Size>: can't evaluate field Size in type main.B0aMZmq6

The reason for the error is that []Item{} liststruct has successfully executed the code confusion, but template: index.html:9:27 fails to correspond to the variable name after confusion.
(But I personally have no ability to repair this problem,sorry)

@lu4p
Copy link
Member

lu4p commented Jan 23, 2025

Can you share a full example to reproduce this?

@5455230
Copy link
Author

5455230 commented Jan 23, 2025

Can you share a full example to reproduce this?

The complete file example is at the beginning of the post, with only two files (/main.go and /templates/index.html)

@5455230
Copy link
Author

5455230 commented Jan 30, 2025

package main

import (
	"fmt"
	"html/template"

	"github.com/gin-gonic/gin"
)

// SET CGO_ENABLED=0&&SET GOOS=windows&&SET GOARCH=amd64&&garble build -o bin/go_build_main_go.exe main.go
func main() {
	r := gin.Default()
	// r.LoadHTMLGlob("templates/*")
	tmpl := template.Must(template.New("index.html").Parse(`
		<!DOCTYPE html>
		<html lang="en">
		<head>
			<title>{{.title}}</title>
		</head>
			<body>
				iii:
				{{range $value := .iii}}
					value: {{$value.Size}}
				{{end}}
			</body>
		</html>
	`))
	r.SetHTMLTemplate(tmpl)
	r.GET("/index", func(c *gin.Context) {
		type Item struct {
			Page int
			Size string
		}
		aaa := []Item{
			{Page: 1, Size: "11"},
			{Page: 2, Size: "12"},
			{Page: 3, Size: "13"},
		}
		a := gin.H{
			"title": "titleAA",
			"ce":    "123456",
			"iii":   aaa,
			"aaa": []Item{
				{Page: 1, Size: "11"},
				{Page: 2, Size: "12"},
				{Page: 3, Size: "13"},
			},
		}
		c.HTML(200, "index.html", a)
	})
	r.Run()
}

This example(main.go) has the same error prompt as the example above.

@Xiol
Copy link

Xiol commented Feb 4, 2025

I am having a similar problem, although my use case is different. I can replicate my issue with this code, which replicates what I'm doing in my application:

package main

import (
	"embed"
	"fmt"
	"os"
	"strings"
	"text/template"
)

//go:embed templates
var templateFS embed.FS

type TemplateData struct {
	Name  string
	Value string
	Port  int
}

func RenderTemplate[T any](src string, dest string, data T) error {
	content, err := templateFS.ReadFile(src)
	if err != nil {
		return fmt.Errorf("failed to read template: %w", err)
	}

	tmpl, err := template.New(src).Parse(string(content))
	if err != nil {
		return fmt.Errorf("failed to parse template: %w", err)
	}

	var buf strings.Builder
	if err := tmpl.Execute(&buf, data); err != nil {
		return fmt.Errorf("failed to execute template: %w", err)
	}

	return os.WriteFile(dest, []byte(buf.String()), 0644)
}

func main() {
	data := TemplateData{
		Name:  "test",
		Value: "example",
		Port:  8080,
	}

	if err := RenderTemplate("templates/config.yaml.tmpl", "config.yaml", data); err != nil {
		fmt.Printf("Error rendering template: %v\n", err)
		os.Exit(1)
	}
}

In the same directory, create another directory called templates and add this as config.yaml.tmpl:

name: {{.Name}}
value: {{.Value}}
port: {{.Port}}

Directory structure should then match:

.
├── main.go
└── templates/
    └── config.yaml.tmpl

Running this with go run main.go results in the template being rendered correctly:

❯ go run main.go
❯ cat config.yaml
name: test
value: example
port: 8080

Running it with garble run main.go results in the error as reported by others:

❯ garble run main.go
Error rendering template: failed to execute template: template: templates/config.yaml.tmpl:1:8: executing "templates/config.yaml.tmpl" at <.Name>: can't evaluate field Name in type main.BuHbPeMsq
exit status 1
exit status 1

@lu4p lu4p added the bug Something isn't working label Feb 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

3 participants