Hacker News new | past | comments | ask | show | jobs | submit login
Using Go Templates (gopheracademy.com)
120 points by bketelsen on Dec 27, 2017 | hide | past | favorite | 20 comments



An additional tip. Template actions don't necessarily have to be delimited by '{{' and '}}'.

Before parsing, you can call Delims to use custom delimiters.

  func (t *Template) Delims(left, right string) *Template
https://golang.org/pkg/text/template/#Template.Delims


Especially useful if, for example, you'll be doing additional js templating that also use the mustache tag eg with Vuejs (can also be changed)


You've given me a fantastic Christmas present! Now I just have to lobby the projects which use the defaults to make the delims configurable, saving their users keystrokes and horrible "how do I escape golang template delims" anxiety


I really want to love templates, but I find many aspects to be quite confusing.

(1): I just want to deploy a binary file. This does not seem possible with templates (unless they're defined inside .go files, but never seen anyone do that).. also rather annoying that the tmpl files must be located in a specific directory rather than located among their components.. but I guess it wouldn't make much sense anyway since they won't be a part of the binary file.

(2): it's really difficult to find good and medium-large scale projects that are using templates

(3): I have no idea what's the right way to initialize and execute templates, this includes when the same template will be called in multiple funcs. I know how I can do it, but I don't feel confident that I'm doing it correctly..

(4): it's really exhausting to keep template code clean. With Go (and various JS frameworks) the code is automatically formatted/linted/whatever, but with templates nada.. can't even figure out how to minimize it for production.

(5): no idea what to do with css/js.. sometimes use inline, other times call a static file. Static files obviously benefit from being cached.. not sure how I'm supposed to cache the templates

I can't really tell if there are any speed gains to using templates, so it feels like a lot of sacrifices for no obvious gain. I do think templates would be godlike if they featured vue-like structure with "template/script/style" syntax, and was easily minified and compiled into the binary. But I guess I can keep dreaming about the last part :)


1) The first example in the blog post shows an inline template:

    t, err := template.New("todos").Parse("You have a task named \"{{ .Name}}\" with description: \"{{ .Description}}\"")
If you have a lot of templates and don't want to declare them in-line but also want to ship just an executable, you could use a project like https://github.com/GeertJohan/go.rice which allows you to pack multiple files into a go executable and then reference them like files.

2) I'm not very familiar with the project but gogs https://github.com/gogits/gogs/tree/master/templates has a lot

3) Hard to comment without seeing an approach

4) Agree

5) Generally templates should be parsed at start time, not re-parsed for every request. I'm not sure if I'm responding to what you are saying. Do you have link to some code you would like comments on?


You might want to look into resource packers. I believe a few projects will pack files into the binary in a fashion something akin to resources in .Net/Java. Go-bindata is one such project; that or something else may suit your needs.


Regarding (1), os.Executable function introduced relatively recently could make things better for you. https://golang.org/pkg/os/#Executable


Regarding (1) that is why I love resource handling in .NET, Java, Android, and the executable file formats on Windows and OS X derived OSes.

Sadly UNIX never got to agree how to handle resources.



I love Hugo, but I was thinking more in the lines of a "standard" website, like Hacker News, Twitter, the official gohugo.io website (rather than their generator), etc.


To be honest I completely disagree with most of what you've put. That's not to say that I think Go's templates are an amazing "must use" feature, but rather that the problem points you've raised are really more to do with learning the tooling than shortcomings of tools themselves (unless you want to argue that web development - CSS, JS, HTML etc - on the whole is a backwards approach to writing applications, in which case I whole heartedly agree. But that's an argument for a different thread hehe)

1/ You can have templates defined within the executable if you wanted. But you can also trivially find out the working directory of the Go executable if you still wanted to work with absolute paths without having to hardcode the location of the Go binary

2/ I've not tried to look, but often you'll fine that larger projects will eventually fall into NIH (not invented here) syndrome where a standard package fits 90% of their criteria but they have the developer man power to write a competing solution that fits 100% of their criteria. Templating is a pretty easy problem to solve in that regard.

3/ That depends on whether you want to cache the precompiled template or the compiled template. Without knowing your code it would be hard to accurately advise. However if the abundant documentation isn't helping you then write two versions of the code, one precompiled and one after compilation; then unit test each - if passing the compiled template around doesn't introduce caching bugs then go with that. However generally I'd recommend passing the precompiled template around for 99% of typical use cases.

4/ I find that a weird complaint. If you understand front end development well enough then you shouldn't have any issues keeping the code clean. If you don't, then perhaps you're trying to run before you can walk? In any case, I wouldn't rely on linters to clean your code. Sure they are a fantastic productivity tool; but if you become too dependent on them then it will hamper your development skills in the long run.

5/ the first part of your statement is really a matter of learning front end development. Generally you should never inline CSS nor JS unless under specific use cases. But general web development should nearly always have the CSS and JS separate from the HTML document. The last part of your statement is a reiteration of question 3.

> I can't really tell if there are any speed gains to using templates, so it feels like a lot of sacrifices for no obvious gain. I do think templates would be godlike if they featured vue-like structure with "template/script/style" syntax, and was easily minified and compiled into the binary. But I guess I can keep dreaming about the last part :)

You're comparing front end development frameworks with back end frameworks, so they're obviously going to differ. Plus you can easily minify templates and embed them into the Go binary (the example in the article you're commenting on does just the latter).

-----

With the greatest of respect to yourself, I think the issues you are having here isn't so much with the design of Go's templates but more with your experience with Go and front end web development. A lot of the problems you've identified become pretty self explanatory once you spend a few years writing code. However that's not to say you're asking "dumb" questions - they're definitely problem pains with web development that all of us had to work through. I guess in this regard Go's documentation might be a little lacking as I've found it typically focuses on the expectation of the developers prior expertise. Stick with it though, you're asking the right questions so it will all make sense soon enough. And don't be afraid to make mistakes while experimenting :)


Really glad someone put this together. The official documentation is pretty good but somewhat lacking in terms of practical examples around templates.


This Django style template library is also quite slick: https://github.com/flosch/pongo2


I am also really glad someone has glued toghether major aspects of template/html std library. It is definetely a place where are some 'taboos', tricks or gotchas, i.e. re-usability of tmpl static variable to add multiple named templates and call them by name (re: question on disqus below article) or sharing parent scope to children variable when using range loop (stackoverflow popular question). I am bit sad I haven't found some free time to collect all known 'tricks' to me and try to list them somehow or send CR yet.


Totally agree, I'm also glad there is another resource for learning templating! The gotchas are frequent for me when it comes to templating in Go. Recently I found that html/template will strip tags when inserting into an attribute [1]. I did not realize that Go made a special template for attributes (template.HTMLAttr) which is what I needed to make it work. [2]

[1]: https://play.golang.org/p/nHG_F2a0t-4

[2]: https://play.golang.org/p/TU5CX9Kstj


That's not all! Try inserting a Go variable within a script tag, and Go will automatically convert it to JSON. Makes it possible to easily do this:

  let msgs = {{ .Messages }}
Where .Messages is any slice. Same is true for structs -> JS objects.


Have you tried to benchmark writing out a page with Go templates, vs GO producing a JSON API that prints out into static HTML pages with JQUERY/Handlebars? How many RPS can you get with either scenario? What is Time to First Paint and when does the page finish printing for the user?


Go templates are not particularly fast, but I would be astonished if the client-side way one that battle.

There are faster server-side template engines in go though. One approach I particularly like is https://github.com/bouk/statictemplate, which generates code from your standard go templates that makes them quite a bit faster.


Seeing this from the front page RSS feed I opened the comments page in shock thinking somehow Golang got templates a la C++...


Gopher Academy has been doing great content lately. Good examples for templates past the real docs. Good stuff.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: