• Mike Samuel's avatar
    exp/template/html: escape {{template}} calls and sets of templates · 4c6454ae
    Mike Samuel authored
    This adds support for {{template "callee"}} calls.
    It recognizes that calls can appear in many contexts.
    
    {{if .ImageURL}}
        <img src="{{.ImageURL}}" alt="{{template "description"}}">
    {{else}}
        <p>{{template "description"}}</p>
    {{end}}
    
    calls a template in two different contexts, first in an HTML attribute
    context, and second in an HTML text context.
    
    Those two contexts aren't very different, but when linking text
    to search terms, the escaping context can be materially different:
    
    <a href="/search?q={{template "tags"}}">{{template "tags"}}</a>
    
    This adds API:
    EscapeSet(*template.Set, names ...string) os.Error
    
    takes a set of templates and the names of those which might be called
    in the default context as starting points.
    
    It changes the escape* functions to be methods of an object which
    maintains a conceptual mapping of
    (template names*input context) -> output context.
    
    The actual mapping uses as key a mangled name which combines the
    template name with the input context.
    
    The mangled name when the input context is the default context is the
    same as the unmangled name.
    
    When a template is called in multiple contexts, we clone the template.
    
    {{define "tagLink"}}
      <a href="/search?q={{template "tags"}}">{{template "tags"}}</a>
    {{end}}
    {{define "tags"}}
      {{range .Tags}}{{.}},{{end}}
    {{end}}
    
    given []string{ "foo", "O'Reilly", "bar" } produces
    
      <a href="/search?q=foo,O%27Reilly,bar">foo,O&#39;Reilly,bar</a>
    
    This involves rewriting the above to something like
    
    {{define "tagLink"}}
      <a href="/search?q={{template "tags$1"}}">{{template "tags"}}</a>
    {{end}}
    {{define "tags"}}
      {{range .Tags}}{{. | html}},{{end}}
    {{end}}
    {{define "tags$1"}}
      {{range .Tags}}{{. | urlquery}},{{end}}
    {{end}}
    
    clone.go provides a mechanism for cloning template "tags" to produce
    "tags$1".
    
    changes to escape.go implement the new API and context propagation
    around the call graph.
    
    context.go includes minor changes to support name mangling and
    context_test.go tests those.
    
    js.go contains a bug-fix.
    
    R=nigeltao, r
    CC=golang-dev
    https://golang.org/cl/4969072
    4c6454ae
escape_test.go 27.6 KB