Asymmetry of text/template and html/template definition

Given a collection of html/templates and a collection of text/templates that are read at program start

package main
import (
	ht "html/template"
	tt "text/template"

func ttNames(a []*tt.Template) []string {
	names := make([]string, len(a))
	for p := range a {
		names[p] = a[p].Name()
	return names
func htNames(a []*ht.Template) []string {
	names := make([]string, len(a))
	for p := range a {
		names[p] = a[p].Name()
	return names

func main() {
	html := ht.Must(ht.New("html").ParseGlob("page/*"))
	cmds := tt.Must(tt.New("cmds").ParseGlob("command/*"))

where the page and command contain one template file “test” each, I get

[test][test html]

as output. So html.Templates() returned the root template “html”, while the cmds.Templates() did not.
I can handle this, but it feels strange somehow. Shouldn’t a html/template Template.Templates() call behave the same as text/template Template.Templates()?

  1. The behaviour is documented.
  2. For my use case it would be simpler if html/template.Template would not return itself on call to Templates()

As I was also pondering about the similarities and differences,
and wanted to use both (html & text) in some agnostic way, I created

as a common umbrella. Hope it may help You as well to simplify Your code.

First I wanted to put both together too, but it doesn’t make too much sense in the end, for my project.

If there are more differences between both function sets, can you please outline them. I haven’t analyzed them in total, yet.

If there is some use case for a common handling of both template types, your package seems very useful.

1 Like

thx 4 Your honest answer! makes me feel happy & comfortable.

Just: Your re-stated question also reminds me: I got to admit:
I failed to think more deeply about Your specific code / problem.

Please accept my apologies.

Re-reading much more carefully makes me strongly feel:
You discovered a bug!

As I wrote, I first thought of a similar approach, handling html/template and text/template through a custom abstraction of the defined template functions. But in the end I found that it is better to keep the handling split as the packages and types are.
But still the Templates() return asymmetry does not feel natural and is error prone, though documented.

BTW: It is not a bug, it’s a feature, when documented:

BTW: It’s after midnight over here - so whatever You link to … I’ll read later.

Just, IMHO it cannot be a bug. Why? 'cause @rsc himself keeps re-iterating the intended equivalency of the API’s, (and very carefully details the differences, such as the default-set of TemplateFuncs …

BTW: I’ve read the godoc’s of this pair of pack’s a couple of times - monthes ago - and I am impressed about it’s style, completeness, eloquence and quality.

And I’m ready to accept a freshly drought ‘Alt’ beer for a bet :wink:

Hi @ikrabbe

Yes, You’re right! I was wrong!

Yes - the Templates() method has two different implementations!
(since 1.7 at least!)
Yes - only ʕ◔ϖ◔ʔ knows why! I simply don’t.

And - yes, You’re right again: it’s ‘documented’:

  • text: Templates returns a slice of defined templates associated with t.
  • html: Templates returns a slice of the templates associated with t, including t itself.

Cheers to You - shame on me, and blame onto whoever did this and/or failed to mention this discrepancy more clearly and prominently.

I think this is a bug. Either cmds should be returned in the first, or html should not be returned in the second. Please file an issue at Thanks.

1 Like

Ok I will file a bug here if not done already. Sorry for my late response:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.