gobuffalo / plush

The powerful template system that Go needs
MIT License
900 stars 56 forks source link

how to access struct variable? #11

Closed ghost closed 6 years ago

ghost commented 7 years ago

How to access a struct variable field in plush tempalte?

type authAdapter struct {
   k string
   v string
}
    m := make([]authAdapter, 0)
    m = append(m, authAdapter{k: "amazon", v: "Amazon"})
    m = append(m, authAdapter{"bitbucket", "Bitbucket"})
    m = append(m, authAdapter{"facebook", "facebook"})
    m = append(m, authAdapter{"github", "github"})
    m = append(m, authAdapter{"gitlab", "gitlab"})
    m = append(m, authAdapter{"twitter", "twitter"})
    m = append(m, authAdapter{"google", "google"})
    c.Set("Providers", m)
    return c.Render(200, r.HTML("index.html"))
majorcode commented 7 years ago

Here's a solution that uses custom template helpers

// Add template helpers here:
Helpers: render.Helpers{
  "authK": func(v interface{}) (string, error) {
    aa, ok := v.(authAdapter)
    if !ok {
      return "", errors.New("authK helper: unable to convert argument to an authAdapter")
    }
    return aa.k, nil
  },
  "authV": func(v interface{}) (string, error) {
    aa, ok := v.(authAdapter)
    if !ok {
      return "", errors.New("authV helper: unable to convert argument to an authAdapter")
    }
    return aa.v, nil
  },
},

In the template:

<pre>
<%= for (i, p) in Providers { %>
Providers[<%= authK(p) %>] = <%= authV(p) %>
<% } %>
</pre>

Prints:

Providers[amazon] = Amazon
Providers[bitbucket] = Bitbucket
Providers[facebook] = facebook
Providers[github] = github
Providers[gitlab] = gitlab
Providers[twitter] = twitter
Providers[google] = google

Maybe you could make a more generic struct-member-accessor helper with some reflection? I don't know how structure member access (with dot-syntax, ideally) would be implemented directly in plush.

I hope this helps.

markbates commented 7 years ago

An alternate solution would be to us exported attributes instead of non-exported. k and v cant be accessed outside of the package. However, if they’re named K and V they can be accessed in the template. Standard Go exporting rules apply.

majorcode commented 7 years ago

Well. Duh! Of course this works when you change the struct:

<%= for (i, p) in Providers { %>
Providers[<%= p.K %>] = <%= p.V %>
<% } %>

Reflection FTW, I suppose.

ghost commented 7 years ago

Thanks for your help. thanks.