summaryrefslogtreecommitdiff
path: root/doc/effective_go.html
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-11-04 17:29:20 -0800
committerRob Pike <r@golang.org>2009-11-04 17:29:20 -0800
commit782c3f76d1c7af511daf0d44ba29737f3e1de655 (patch)
treeff38e1cde49e9ac4fd454fded354c48db692cabe /doc/effective_go.html
parent27bcbb99f0f520eee9462179e3b297b48e01e1ba (diff)
downloadgolang-782c3f76d1c7af511daf0d44ba29737f3e1de655.tar.gz
add a final section with a complete example
R=rsc CC=go-dev http://go/go-review/1017033
Diffstat (limited to 'doc/effective_go.html')
-rw-r--r--doc/effective_go.html131
1 files changed, 131 insertions, 0 deletions
diff --git a/doc/effective_go.html b/doc/effective_go.html
index f3f8020e6..103cc8249 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -2360,6 +2360,137 @@ for try := 0; try < 2; try++ {
}
</pre>
+<h2 id="web_server">A web server</h2>
+
+<p>
+Let's finish with a complete Go program, a web server.
+This one is actually a kind of web re-server.
+Google provides a service at
+<a href="http://chart.apis.google.com">http://chart.apis.google.com</a>
+that does automatic formatting of data into charts and graphs.
+It's hard to use interactively, though,
+because you need to put the data into the URL as a query.
+The program here provides a nicer interface to one form of data: given a short piece of text,
+it calls on the chart server to produce a QR code, a matrix of boxes that encode the
+text.
+That image can be grabbed with your cell phone's camera and interpreted as,
+for instance, a URL, saving you typing the URL into the phone's tiny keyboard.
+</p>
+<p>
+Here's the complete program.
+An explanation follows.
+</p>
+
+<pre>
+package main
+
+import (
+ "flag";
+ "http";
+ "io";
+ "log";
+ "strings";
+ "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)
+
+func main() {
+ flag.Parse();
+ http.Handle("/", http.HandlerFunc(QR));
+ err := http.ListenAndServe(*addr, nil);
+ if err != nil {
+ log.Exit("ListenAndServe:", err);
+ }
+}
+
+func QR(c *http.Conn, req *http.Request) {
+ templ.Execute(req.FormValue("s"), c);
+}
+
+func UrlHtmlFormatter(w io.Writer, v interface{}, fmt string) {
+ template.HtmlEscape(w, strings.Bytes(http.URLEscape(v.(string))));
+}
+
+
+const templateStr = `
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;QR Link Generator&lt;/title&gt;
+&lt;/head&gt;
+&lt;body&gt;
+{.section @}
+&lt;img src="http://chart.apis.google.com/chart?chs=300x300&amp;cht=qr&amp;choe=UTF-8&amp;chl={@|url+html}"
+/&gt;
+&lt;br&gt;
+{@|html}
+&lt;br&gt;
+&lt;br&gt;
+{.end}
+&lt;form action="/" name=f method="GET"&gt;&lt;input maxLength=1024 size=70
+name=s value="" title="Text to QR Encode"&gt;&lt;input type=submit
+value="Show QR" name=qr&gt;
+&lt;/form&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+`
+</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
+variable <code>templ</code> is where the fun happens. It builds an HTML template
+that will be executed by the server to display the page; more about
+that in a moment.
+</p>
+<p>
+The <code>main</code> function parses the flags and, using the mechanism
+we talked about above, binds the function <code>QR</code> to the root path
+for the server. Then <code>http.ListenAndServe</code> is called to start the
+server; it blocks while the server runs.
+</p>
+<p>
+<code>QR</code> just receives the request, which contains form data, and
+executes the template on the data in the field 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;
+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
+string in the form data.
+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 &ldquo;the current item&rdquo;, in this case the form data.
+(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
+for safe display on the web page.
+</p>
+<p>
+The rest of the template string is just the HTML to show when the page loads.
+If this is too quick an explanation, see the <a href="/pkg/template/">documentation</a>
+for the template package for a more thorough discussion.
+</p>
+<p>
+And there you have it: a useful webserver in a few lines of code plus some
+data-driven HTML text.
+Go is powerful enough to make a lot happen in a few lines.
+</p>
+
<!--
TODO
<pre>