mirror of
https://github.com/golang/go
synced 2024-11-23 17:10:03 -07:00
effective_go: convert to use tmpltohtml.
Also update the big example to the new template system. There are a number of other examples that should be extracted; this CL serves as an introduction to the approach. R=golang-dev, adg CC=golang-dev https://golang.org/cl/4923043
This commit is contained in:
parent
1446ffc265
commit
d1a3edaee7
@ -8,4 +8,11 @@ TARG=tmpltohtml
|
||||
GOFILES=\
|
||||
tmpltohtml.go\
|
||||
|
||||
go_tutorial.html: go_tutorial.tmpl tmpltohtml
|
||||
makehtml go_tutorial.tmpl
|
||||
|
||||
effective_go.html: effective_go.tmpl tmpltohtml
|
||||
makehtml effective_go.tmpl
|
||||
|
||||
|
||||
include ../src/Make.cmd
|
||||
|
@ -793,7 +793,7 @@ func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
|
||||
var nr int
|
||||
nr, err = r.Read(buf)
|
||||
n += nr
|
||||
buf = buf[nr:len(buf)]
|
||||
buf = buf[nr:]
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -954,8 +954,9 @@ In Go terminology, it returns a pointer to a newly allocated zero value of type
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Since the memory returned by <code>new</code> is zeroed, it's helpful to arrange that the
|
||||
zeroed object can be used without further initialization. This means a user of
|
||||
Since the memory returned by <code>new</code> is zeroed, it's helpful to arrange
|
||||
when designing your data structures that the
|
||||
zero value of each type can be used without further initialization. This means a user of
|
||||
the data structure can create one with <code>new</code> and get right to
|
||||
work.
|
||||
For example, the documentation for <code>bytes.Buffer</code> states that
|
||||
@ -1075,8 +1076,9 @@ m := map[int]string{Enone: "no error", Eio: "Eio", Einval: "invalid argument"}
|
||||
Back to allocation.
|
||||
The built-in function <code>make(T, </code><i>args</i><code>)</code> serves
|
||||
a purpose different from <code>new(T)</code>.
|
||||
It creates slices, maps, and channels only, and it returns an initialized (not zero)
|
||||
value of type <code>T</code>, not <code>*T</code>.
|
||||
It creates slices, maps, and channels only, and it returns an <em>initialized</em>
|
||||
(not <em>zeroed</em>)
|
||||
value of type <code>T</code> (not <code>*T</code>).
|
||||
The reason for the distinction
|
||||
is that these three types are, under the covers, references to data structures that
|
||||
must be initialized before use.
|
||||
@ -2917,66 +2919,55 @@ for instance, a URL, saving you typing the URL into the phone's tiny keyboard.
|
||||
Here's the complete program.
|
||||
An explanation follows.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
package main
|
||||
<pre><!--{{code "progs/eff_qr.go"}}
|
||||
-->package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"http"
|
||||
"io"
|
||||
"log"
|
||||
"old/template" // New template package coming soon...
|
||||
"flag"
|
||||
"http"
|
||||
"log"
|
||||
"template"
|
||||
)
|
||||
|
||||
var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
|
||||
var fmap = template.FormatterMap{
|
||||
"html": template.HTMLFormatter,
|
||||
"url+html": UrlHtmlFormatter,
|
||||
}
|
||||
var templ = template.MustParse(templateStr, fmap)
|
||||
var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
|
||||
|
||||
var templ = template.Must(template.New("qr").Parse(templateStr))
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
http.Handle("/", http.HandlerFunc(QR))
|
||||
http.Handle("/", http.HandlerFunc(QR))
|
||||
err := http.ListenAndServe(*addr, nil)
|
||||
if err != nil {
|
||||
log.Fatal("ListenAndServe:", err)
|
||||
log.Fatal("ListenAndServe:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func QR(w http.ResponseWriter, req *http.Request) {
|
||||
templ.Execute(w, req.FormValue("s"))
|
||||
templ.Execute(w, req.FormValue("s"))
|
||||
}
|
||||
|
||||
func UrlHtmlFormatter(w io.Writer, fmt string, v ...interface{}) {
|
||||
template.HTMLEscape(w, []byte(http.URLEscape(v[0].(string))))
|
||||
}
|
||||
|
||||
|
||||
const templateStr = `
|
||||
<html>
|
||||
<head>
|
||||
<title>QR Link Generator</title>
|
||||
</head>
|
||||
<body>
|
||||
{.section @}
|
||||
<img src="http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF-8&chl={@|url+html}"
|
||||
{{if .}}
|
||||
<img src="http://chart.apis.google.com/chart?chs=300x300&amp;cht=qr&amp;choe=UTF-8&amp;chl={{urlquery .}}"
|
||||
/>
|
||||
<br>
|
||||
{@|html}
|
||||
{{html .}}
|
||||
<br>
|
||||
<br>
|
||||
{.end}
|
||||
<form action="/" name=f method="GET"><input maxLength=1024 size=70
|
||||
name=s value="" title="Text to QR Encode"><input type=submit
|
||||
value="Show QR" name=qr>
|
||||
{{end}}
|
||||
<form action="/" name=f method="GET"><input maxLength=1024 size=70
|
||||
name=s value="" title="Text to QR Encode"><input type=submit
|
||||
value="Show QR" name=qr>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The pieces up to <code>main</code> should be easy to follow.
|
||||
The one flag sets a default HTTP port for our server. The template
|
||||
@ -2995,25 +2986,20 @@ server; it blocks while the server runs.
|
||||
executes the template on the data in the form value named <code>s</code>.
|
||||
</p>
|
||||
<p>
|
||||
The template package, inspired by <a
|
||||
href="http://code.google.com/p/json-template">json-template</a>, is
|
||||
powerful;
|
||||
The template package is powerful;
|
||||
this program just touches on its capabilities.
|
||||
In essence, it rewrites a piece of text on the fly by substituting elements derived
|
||||
from data items passed to <code>templ.Execute</code>, in this case the
|
||||
form value.
|
||||
Within the template text (<code>templateStr</code>),
|
||||
brace-delimited pieces denote template actions.
|
||||
The piece from the <code>{.section @}</code>
|
||||
to <code>{.end}</code> executes with the value of the data item <code>@</code>,
|
||||
which is a shorthand for “the current item”, which is the form value.
|
||||
(When the string is empty, this piece of the template is suppressed.)
|
||||
double-brace-delimited pieces denote template actions.
|
||||
The piece from the <code></code> executes only if the value of the current data item, called <code>.</code>,
|
||||
is non-empty.
|
||||
That is, when the string is empty, this piece of the template is suppressed.
|
||||
</p>
|
||||
<p>
|
||||
The snippet <code>{@|url+html}</code> says to run the data through the formatter
|
||||
installed in the formatter map (<code>fmap</code>)
|
||||
under the name <code>"url+html"</code>.
|
||||
That is the function <code>UrlHtmlFormatter</code>, which sanitizes the string
|
||||
The snippet <code>0</code> says to process the data with the function
|
||||
<code>urlquery</code>, which sanitizes the query string
|
||||
for safe display on the web page.
|
||||
</p>
|
||||
<p>
|
||||
|
2980
doc/effective_go.tmpl
Normal file
2980
doc/effective_go.tmpl
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,4 +14,4 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make && ./tmpltohtml $TMPL > $HTML
|
||||
make tmpltohtml && ./tmpltohtml $TMPL > $HTML
|
||||
|
47
doc/progs/eff_qr.go
Normal file
47
doc/progs/eff_qr.go
Normal file
@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"http"
|
||||
"log"
|
||||
"template"
|
||||
)
|
||||
|
||||
var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
|
||||
|
||||
var templ = template.Must(template.New("qr").Parse(templateStr))
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
http.Handle("/", http.HandlerFunc(QR))
|
||||
err := http.ListenAndServe(*addr, nil)
|
||||
if err != nil {
|
||||
log.Fatal("ListenAndServe:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func QR(w http.ResponseWriter, req *http.Request) {
|
||||
templ.Execute(w, req.FormValue("s"))
|
||||
}
|
||||
|
||||
const templateStr = `
|
||||
<html>
|
||||
<head>
|
||||
<title>QR Link Generator</title>
|
||||
</head>
|
||||
<body>
|
||||
{{if .}}
|
||||
<img src="http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF-8&chl={{urlquery .}}"
|
||||
/>
|
||||
<br>
|
||||
{{html .}}
|
||||
<br>
|
||||
<br>
|
||||
{{end}}
|
||||
<form action="/" name=f method="GET"><input maxLength=1024 size=70
|
||||
name=s value="" title="Text to QR Encode"><input type=submit
|
||||
value="Show QR" name=qr>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`
|
@ -35,6 +35,7 @@ for i in \
|
||||
sieve1.go \
|
||||
server1.go \
|
||||
strings.go \
|
||||
eff_qr.go \
|
||||
; do
|
||||
$GC $i
|
||||
done
|
||||
|
Loading…
Reference in New Issue
Block a user