mirror of
https://github.com/golang/go
synced 2024-11-23 19:20: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=\
|
GOFILES=\
|
||||||
tmpltohtml.go\
|
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
|
include ../src/Make.cmd
|
||||||
|
@ -793,7 +793,7 @@ func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
|
|||||||
var nr int
|
var nr int
|
||||||
nr, err = r.Read(buf)
|
nr, err = r.Read(buf)
|
||||||
n += nr
|
n += nr
|
||||||
buf = buf[nr:len(buf)]
|
buf = buf[nr:]
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -954,8 +954,9 @@ In Go terminology, it returns a pointer to a newly allocated zero value of type
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Since the memory returned by <code>new</code> is zeroed, it's helpful to arrange that the
|
Since the memory returned by <code>new</code> is zeroed, it's helpful to arrange
|
||||||
zeroed object can be used without further initialization. This means a user of
|
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
|
the data structure can create one with <code>new</code> and get right to
|
||||||
work.
|
work.
|
||||||
For example, the documentation for <code>bytes.Buffer</code> states that
|
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.
|
Back to allocation.
|
||||||
The built-in function <code>make(T, </code><i>args</i><code>)</code> serves
|
The built-in function <code>make(T, </code><i>args</i><code>)</code> serves
|
||||||
a purpose different from <code>new(T)</code>.
|
a purpose different from <code>new(T)</code>.
|
||||||
It creates slices, maps, and channels only, and it returns an initialized (not zero)
|
It creates slices, maps, and channels only, and it returns an <em>initialized</em>
|
||||||
value of type <code>T</code>, not <code>*T</code>.
|
(not <em>zeroed</em>)
|
||||||
|
value of type <code>T</code> (not <code>*T</code>).
|
||||||
The reason for the distinction
|
The reason for the distinction
|
||||||
is that these three types are, under the covers, references to data structures that
|
is that these three types are, under the covers, references to data structures that
|
||||||
must be initialized before use.
|
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.
|
Here's the complete program.
|
||||||
An explanation follows.
|
An explanation follows.
|
||||||
</p>
|
</p>
|
||||||
|
<pre><!--{{code "progs/eff_qr.go"}}
|
||||||
<pre>
|
-->package main
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"http"
|
"http"
|
||||||
"io"
|
"log"
|
||||||
"log"
|
"template"
|
||||||
"old/template" // New template package coming soon...
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
|
var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
|
||||||
var fmap = template.FormatterMap{
|
|
||||||
"html": template.HTMLFormatter,
|
var templ = template.Must(template.New("qr").Parse(templateStr))
|
||||||
"url+html": UrlHtmlFormatter,
|
|
||||||
}
|
|
||||||
var templ = template.MustParse(templateStr, fmap)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
http.Handle("/", http.HandlerFunc(QR))
|
http.Handle("/", http.HandlerFunc(QR))
|
||||||
err := http.ListenAndServe(*addr, nil)
|
err := http.ListenAndServe(*addr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("ListenAndServe:", err)
|
log.Fatal("ListenAndServe:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func QR(w http.ResponseWriter, req *http.Request) {
|
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 = `
|
const templateStr = `
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>QR Link Generator</title>
|
<title>QR Link Generator</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{.section @}
|
{{if .}}
|
||||||
<img src="http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF-8&chl={@|url+html}"
|
<img src="http://chart.apis.google.com/chart?chs=300x300&amp;cht=qr&amp;choe=UTF-8&amp;chl={{urlquery .}}"
|
||||||
/>
|
/>
|
||||||
<br>
|
<br>
|
||||||
{@|html}
|
{{html .}}
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
{.end}
|
{{end}}
|
||||||
<form action="/" name=f method="GET"><input maxLength=1024 size=70
|
<form action="/" name=f method="GET"><input maxLength=1024 size=70
|
||||||
name=s value="" title="Text to QR Encode"><input type=submit
|
name=s value="" title="Text to QR Encode"><input type=submit
|
||||||
value="Show QR" name=qr>
|
value="Show QR" name=qr>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`
|
`
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The pieces up to <code>main</code> should be easy to follow.
|
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
|
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>.
|
executes the template on the data in the form value named <code>s</code>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The template package, inspired by <a
|
The template package is powerful;
|
||||||
href="http://code.google.com/p/json-template">json-template</a>, is
|
|
||||||
powerful;
|
|
||||||
this program just touches on its capabilities.
|
this program just touches on its capabilities.
|
||||||
In essence, it rewrites a piece of text on the fly by substituting elements derived
|
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
|
from data items passed to <code>templ.Execute</code>, in this case the
|
||||||
form value.
|
form value.
|
||||||
Within the template text (<code>templateStr</code>),
|
Within the template text (<code>templateStr</code>),
|
||||||
brace-delimited pieces denote template actions.
|
double-brace-delimited pieces denote template actions.
|
||||||
The piece from the <code>{.section @}</code>
|
The piece from the <code></code> executes only if the value of the current data item, called <code>.</code>,
|
||||||
to <code>{.end}</code> executes with the value of the data item <code>@</code>,
|
is non-empty.
|
||||||
which is a shorthand for “the current item”, which is the form value.
|
That is, when the string is empty, this piece of the template is suppressed.
|
||||||
(When the string is empty, this piece of the template is suppressed.)
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The snippet <code>{@|url+html}</code> says to run the data through the formatter
|
The snippet <code>0</code> says to process the data with the function
|
||||||
installed in the formatter map (<code>fmap</code>)
|
<code>urlquery</code>, which sanitizes the query string
|
||||||
under the name <code>"url+html"</code>.
|
|
||||||
That is the function <code>UrlHtmlFormatter</code>, which sanitizes the string
|
|
||||||
for safe display on the web page.
|
for safe display on the web page.
|
||||||
</p>
|
</p>
|
||||||
<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
|
exit 1
|
||||||
fi
|
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 \
|
sieve1.go \
|
||||||
server1.go \
|
server1.go \
|
||||||
strings.go \
|
strings.go \
|
||||||
|
eff_qr.go \
|
||||||
; do
|
; do
|
||||||
$GC $i
|
$GC $i
|
||||||
done
|
done
|
||||||
|
Loading…
Reference in New Issue
Block a user