mirror of
https://github.com/golang/go
synced 2024-11-24 22:27:57 -07:00
doc: update codelab/wiki to Go 1.
R=golang-dev, r, adg CC=golang-dev https://golang.org/cl/5683076
This commit is contained in:
parent
27e07a2666
commit
52cd4c8610
@ -2,13 +2,9 @@
|
|||||||
# Use of this source code is governed by a BSD-style
|
# Use of this source code is governed by a BSD-style
|
||||||
# license that can be found in the LICENSE file.
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
include ../../../src/Make.inc
|
|
||||||
|
|
||||||
all: index.html
|
all: index.html
|
||||||
|
|
||||||
include ../../../src/Make.common
|
CLEANFILES:=srcextract.bin htmlify.bin get.bin
|
||||||
|
|
||||||
CLEANFILES+=srcextract.bin htmlify.bin get.bin
|
|
||||||
|
|
||||||
index.html: wiki.html srcextract.bin htmlify.bin
|
index.html: wiki.html srcextract.bin htmlify.bin
|
||||||
PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html
|
PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html
|
||||||
@ -17,9 +13,8 @@ test: get.bin
|
|||||||
bash ./test.sh
|
bash ./test.sh
|
||||||
rm -f get.6 get.bin
|
rm -f get.6 get.bin
|
||||||
|
|
||||||
%.bin: %.$O
|
%.bin: %.go
|
||||||
$(LD) -o $@ $<
|
go build -o $@ $^
|
||||||
|
|
||||||
%.$O: %.go
|
|
||||||
$(GC) $(GCFLAGS) $(GCIMPORTS) $*.go
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(CLEANFILES)
|
||||||
|
@ -6,10 +6,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"text/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"text/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"text/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
@ -59,7 +59,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
||||||
t, err := template.ParseFiles(tmpl+".html", nil)
|
t, err := template.ParseFiles(tmpl + ".html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"text/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
@ -55,7 +55,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
||||||
t, _ := template.ParseFiles(tmpl+".html", nil)
|
t, _ := template.ParseFiles(tmpl + ".html")
|
||||||
t.Execute(w, p)
|
t.Execute(w, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"text/template"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
|
@ -6,8 +6,8 @@ Covered in this codelab:
|
|||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Creating a data structure with load and save methods</li>
|
<li>Creating a data structure with load and save methods</li>
|
||||||
<li>Using the <code>http</code> package to build web applications
|
<li>Using the <code>net/http</code> package to build web applications
|
||||||
<li>Using the <code>template</code> package to process HTML templates</li>
|
<li>Using the <code>html/template</code> package to process HTML templates</li>
|
||||||
<li>Using the <code>regexp</code> package to validate user input</li>
|
<li>Using the <code>regexp</code> package to validate user input</li>
|
||||||
<li>Using closures</li>
|
<li>Using closures</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -18,21 +18,18 @@ Assumed knowledge:
|
|||||||
<ul>
|
<ul>
|
||||||
<li>Programming experience</li>
|
<li>Programming experience</li>
|
||||||
<li>Understanding of basic web technologies (HTTP, HTML)</li>
|
<li>Understanding of basic web technologies (HTTP, HTML)</li>
|
||||||
<li>Some UNIX command-line knowledge</li>
|
<li>Some UNIX/DOS command-line knowledge</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Getting Started</h2>
|
<h2>Getting Started</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
At present, you need to have a Linux, OS X, or FreeBSD machine to run Go. If
|
At present, you need to have a FreeBSD, Linux, OS X, or Windows machine to run Go.
|
||||||
you don't have access to one, you could set up a Linux Virtual Machine (using
|
We will use <code>$</code> to represent the command prompt.
|
||||||
<a href="http://www.virtualbox.org/">VirtualBox</a> or similar) or a
|
|
||||||
<a href="http://www.google.com/search?q=virtual+private+server">Virtual
|
|
||||||
Private Server</a>.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Install Go (see the <a href="http://golang.org/doc/install.html">Installation Instructions</a>).
|
Install Go (see the <a href="/doc/install.html">Installation Instructions</a>).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -40,8 +37,8 @@ Make a new directory for this codelab and cd to it:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ mkdir ~/gowiki
|
$ mkdir gowiki
|
||||||
$ cd ~/gowiki
|
$ cd gowiki
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -55,15 +52,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
We import the <code>fmt</code>, <code>ioutil</code> and <code>os</code>
|
We import the <code>fmt</code> and <code>ioutil</code> packages from the Go
|
||||||
packages from the Go standard library. Later, as we implement additional
|
standard library. Later, as we implement additional functionality, we will
|
||||||
functionality, we will add more packages to this <code>import</code>
|
add more packages to this <code>import</code> declaration.
|
||||||
declaration.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Data Structures</h2>
|
<h2>Data Structures</h2>
|
||||||
@ -84,8 +79,8 @@ type Page struct {
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The type <code>[]byte</code> means "a <code>byte</code> slice".
|
The type <code>[]byte</code> means "a <code>byte</code> slice".
|
||||||
(See <a href="http://golang.org/doc/effective_go.html#slices">Effective Go</a>
|
(See <a href="/doc/articles/slices_usage_and_internals.html">Slices: usage and
|
||||||
for more on slices.)
|
internals</a> for more on slices.)
|
||||||
The <code>Body</code> element is a <code>[]byte</code> rather than
|
The <code>Body</code> element is a <code>[]byte</code> rather than
|
||||||
<code>string</code> because that is the type expected by the <code>io</code>
|
<code>string</code> because that is the type expected by the <code>io</code>
|
||||||
libraries we will use, as you'll see below.
|
libraries we will use, as you'll see below.
|
||||||
@ -178,9 +173,8 @@ func loadPage(title string) (*Page, error) {
|
|||||||
<p>
|
<p>
|
||||||
Callers of this function can now check the second parameter; if it is
|
Callers of this function can now check the second parameter; if it is
|
||||||
<code>nil</code> then it has successfully loaded a Page. If not, it will be an
|
<code>nil</code> then it has successfully loaded a Page. If not, it will be an
|
||||||
<code>error</code> that can be handled by the caller (see the <a
|
<code>error</code> that can be handled by the caller (see the
|
||||||
href="http://golang.org/pkg/os/#Error">os package documentation</a> for
|
<a href="/doc/go_spec.html#Errors">language specification</a> for details).
|
||||||
details).
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -210,23 +204,21 @@ You can compile and run the program like this:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ 8g wiki.go
|
$ go build wiki.go
|
||||||
$ 8l wiki.8
|
$ ./wiki
|
||||||
$ ./8.out
|
|
||||||
This is a sample page.
|
This is a sample page.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
(The <code>8g</code> and <code>8l</code> commands are applicable to
|
(If you're using Windows you must type "<code>wiki</code>" without the
|
||||||
<code>GOARCH=386</code>. If you're on an <code>amd64</code> system,
|
"<code>./</code>" to run the program.)
|
||||||
substitute 6's for the 8's.)
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="part1.go">Click here to view the code we've written so far.</a>
|
<a href="part1.go">Click here to view the code we've written so far.</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Introducing the <code>http</code> package (an interlude)</h2>
|
<h2>Introducing the <code>net/http</code> package (an interlude)</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Here's a full working example of a simple web server:
|
Here's a full working example of a simple web server:
|
||||||
@ -292,18 +284,17 @@ the program would present a page containing:
|
|||||||
</p>
|
</p>
|
||||||
<pre>Hi there, I love monkeys!</pre>
|
<pre>Hi there, I love monkeys!</pre>
|
||||||
|
|
||||||
<h2>Using <code>http</code> to serve wiki pages</h2>
|
<h2>Using <code>net/http</code> to serve wiki pages</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To use the <code>http</code> package, it must be imported:
|
To use the <code>net/http</code> package, it must be imported:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
<b>"http"</b>
|
<b>"net/http"</b>
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -361,14 +352,17 @@ func main() {
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
Let's create some page data (as <code>test.txt</code>), compile our code, and
|
Let's create some page data (as <code>test.txt</code>), compile our code, and
|
||||||
try serving a wiki page:
|
try serving a wiki page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Open <code>test.txt</code> file in your editor, and save the string "Hello world" (without quotes)
|
||||||
|
in it.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ echo "Hello world" > test.txt
|
$ go build wiki.go
|
||||||
$ 8g wiki.go
|
$ ./wiki
|
||||||
$ 8l wiki.8
|
|
||||||
$ ./8.out
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -426,19 +420,17 @@ This function will work fine, but all that hard-coded HTML is ugly.
|
|||||||
Of course, there is a better way.
|
Of course, there is a better way.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>The <code>template</code> package</h2>
|
<h2>The <code>html/template</code> package</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <code>template</code> package is part of the Go standard library.
|
The <code>html/template</code> package is part of the Go standard library.
|
||||||
(A new template package is coming; this code lab will be updated soon.)
|
We can use <code>html/template</code> to keep the HTML in a separate file,
|
||||||
We can
|
allowing us to change the layout of our edit page without modifying the
|
||||||
use <code>template</code> to keep the HTML in a separate file, allowing
|
underlying Go code.
|
||||||
us to change the layout of our edit page without modifying the underlying Go
|
|
||||||
code.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
First, we must add <code>template</code> to the list of imports:
|
First, we must add <code>html/template</code> to the list of imports:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@ -446,7 +438,7 @@ import (
|
|||||||
"http"
|
"http"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
<b>"template"</b>
|
<b>"html/template"</b>
|
||||||
)
|
)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -482,7 +474,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The function <code>template.ParseFile</code> will read the contents of
|
The function <code>template.ParseFiles</code> will read the contents of
|
||||||
<code>edit.html</code> and return a <code>*template.Template</code>.
|
<code>edit.html</code> and return a <code>*template.Template</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -558,7 +550,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
||||||
t, _ := template.ParseFiles(tmpl+".html", nil)
|
t, _ := template.ParseFiles(tmpl + ".html")
|
||||||
t.Execute(w, p)
|
t.Execute(w, p)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
@ -570,10 +562,11 @@ The handlers are now shorter and simpler.
|
|||||||
<h2>Handling non-existent pages</h2>
|
<h2>Handling non-existent pages</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
What if you visit <code>/view/APageThatDoesntExist</code>? The program will
|
What if you visit <a href="http://localhost:8080/view/APageThatDoesntExist">
|
||||||
crash. This is because it ignores the error return value from
|
<code>/view/APageThatDoesntExist</code></a>? The program will crash. This is
|
||||||
<code>loadPage</code>. Instead, if the requested Page doesn't exist, it should
|
because it ignores the error return value from <code>loadPage</code>. Instead,
|
||||||
redirect the client to the edit Page so the content may be created:
|
if the requested Page doesn't exist, it should redirect the client to the edit
|
||||||
|
Page so the content may be created:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@ -643,7 +636,7 @@ First, let's handle the errors in <code>renderTemplate</code>:
|
|||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
||||||
t, err := template.ParseFiles(tmpl+".html", nil)
|
t, err := template.ParseFiles(tmpl + ".html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -976,9 +969,8 @@ Recompile the code, and run the app:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ 8g wiki.go
|
$ go build wiki.go
|
||||||
$ 8l wiki.8
|
$ ./wiki
|
||||||
$ ./8.out
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -8,10 +8,10 @@ cleanup() {
|
|||||||
}
|
}
|
||||||
trap cleanup 0 INT
|
trap cleanup 0 INT
|
||||||
|
|
||||||
gomake get.bin
|
make get.bin
|
||||||
addr=$(./get.bin -addr)
|
addr=$(./get.bin -addr)
|
||||||
sed s/:8080/$addr/ < final.go > final-test.go
|
sed s/:8080/$addr/ < final.go > final-test.go
|
||||||
gomake final-test.bin
|
make final-test.bin
|
||||||
(./final-test.bin) &
|
(./final-test.bin) &
|
||||||
wiki_pid=$!
|
wiki_pid=$!
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ Covered in this codelab:
|
|||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Creating a data structure with load and save methods</li>
|
<li>Creating a data structure with load and save methods</li>
|
||||||
<li>Using the <code>http</code> package to build web applications
|
<li>Using the <code>net/http</code> package to build web applications
|
||||||
<li>Using the <code>template</code> package to process HTML templates</li>
|
<li>Using the <code>html/template</code> package to process HTML templates</li>
|
||||||
<li>Using the <code>regexp</code> package to validate user input</li>
|
<li>Using the <code>regexp</code> package to validate user input</li>
|
||||||
<li>Using closures</li>
|
<li>Using closures</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -18,21 +18,18 @@ Assumed knowledge:
|
|||||||
<ul>
|
<ul>
|
||||||
<li>Programming experience</li>
|
<li>Programming experience</li>
|
||||||
<li>Understanding of basic web technologies (HTTP, HTML)</li>
|
<li>Understanding of basic web technologies (HTTP, HTML)</li>
|
||||||
<li>Some UNIX command-line knowledge</li>
|
<li>Some UNIX/DOS command-line knowledge</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Getting Started</h2>
|
<h2>Getting Started</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
At present, you need to have a Linux, OS X, or FreeBSD machine to run Go. If
|
At present, you need to have a FreeBSD, Linux, OS X, or Windows machine to run Go.
|
||||||
you don't have access to one, you could set up a Linux Virtual Machine (using
|
We will use <code>$</code> to represent the command prompt.
|
||||||
<a href="http://www.virtualbox.org/">VirtualBox</a> or similar) or a
|
|
||||||
<a href="http://www.google.com/search?q=virtual+private+server">Virtual
|
|
||||||
Private Server</a>.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Install Go (see the <a href="http://golang.org/doc/install.html">Installation Instructions</a>).
|
Install Go (see the <a href="/doc/install.html">Installation Instructions</a>).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -40,8 +37,8 @@ Make a new directory for this codelab and cd to it:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ mkdir ~/gowiki
|
$ mkdir gowiki
|
||||||
$ cd ~/gowiki
|
$ cd gowiki
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -55,15 +52,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
We import the <code>fmt</code>, <code>ioutil</code> and <code>os</code>
|
We import the <code>fmt</code> and <code>ioutil</code> packages from the Go
|
||||||
packages from the Go standard library. Later, as we implement additional
|
standard library. Later, as we implement additional functionality, we will
|
||||||
functionality, we will add more packages to this <code>import</code>
|
add more packages to this <code>import</code> declaration.
|
||||||
declaration.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Data Structures</h2>
|
<h2>Data Structures</h2>
|
||||||
@ -81,8 +76,8 @@ the title and body.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The type <code>[]byte</code> means "a <code>byte</code> slice".
|
The type <code>[]byte</code> means "a <code>byte</code> slice".
|
||||||
(See <a href="http://golang.org/doc/effective_go.html#slices">Effective Go</a>
|
(See <a href="/doc/articles/slices_usage_and_internals.html">Slices: usage and
|
||||||
for more on slices.)
|
internals</a> for more on slices.)
|
||||||
The <code>Body</code> element is a <code>[]byte</code> rather than
|
The <code>Body</code> element is a <code>[]byte</code> rather than
|
||||||
<code>string</code> because that is the type expected by the <code>io</code>
|
<code>string</code> because that is the type expected by the <code>io</code>
|
||||||
libraries we will use, as you'll see below.
|
libraries we will use, as you'll see below.
|
||||||
@ -161,9 +156,8 @@ function to return <code>*Page</code> and <code>error</code>.
|
|||||||
<p>
|
<p>
|
||||||
Callers of this function can now check the second parameter; if it is
|
Callers of this function can now check the second parameter; if it is
|
||||||
<code>nil</code> then it has successfully loaded a Page. If not, it will be an
|
<code>nil</code> then it has successfully loaded a Page. If not, it will be an
|
||||||
<code>error</code> that can be handled by the caller (see the <a
|
<code>error</code> that can be handled by the caller (see the
|
||||||
href="http://golang.org/pkg/os/#Error">os package documentation</a> for
|
<a href="/doc/go_spec.html#Errors">language specification</a> for details).
|
||||||
details).
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -188,23 +182,21 @@ You can compile and run the program like this:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ 8g wiki.go
|
$ go build wiki.go
|
||||||
$ 8l wiki.8
|
$ ./wiki
|
||||||
$ ./8.out
|
|
||||||
This is a sample page.
|
This is a sample page.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
(The <code>8g</code> and <code>8l</code> commands are applicable to
|
(If you're using Windows you must type "<code>wiki</code>" without the
|
||||||
<code>GOARCH=386</code>. If you're on an <code>amd64</code> system,
|
"<code>./</code>" to run the program.)
|
||||||
substitute 6's for the 8's.)
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="part1.go">Click here to view the code we've written so far.</a>
|
<a href="part1.go">Click here to view the code we've written so far.</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Introducing the <code>http</code> package (an interlude)</h2>
|
<h2>Introducing the <code>net/http</code> package (an interlude)</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Here's a full working example of a simple web server:
|
Here's a full working example of a simple web server:
|
||||||
@ -256,18 +248,17 @@ the program would present a page containing:
|
|||||||
</p>
|
</p>
|
||||||
<pre>Hi there, I love monkeys!</pre>
|
<pre>Hi there, I love monkeys!</pre>
|
||||||
|
|
||||||
<h2>Using <code>http</code> to serve wiki pages</h2>
|
<h2>Using <code>net/http</code> to serve wiki pages</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To use the <code>http</code> package, it must be imported:
|
To use the <code>net/http</code> package, it must be imported:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
<b>"http"</b>
|
<b>"net/http"</b>
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -318,14 +309,17 @@ any requests under the path <code>/view/</code>.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
Let's create some page data (as <code>test.txt</code>), compile our code, and
|
Let's create some page data (as <code>test.txt</code>), compile our code, and
|
||||||
try serving a wiki page:
|
try serving a wiki page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Open <code>test.txt</code> file in your editor, and save the string "Hello world" (without quotes)
|
||||||
|
in it.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ echo "Hello world" > test.txt
|
$ go build wiki.go
|
||||||
$ 8g wiki.go
|
$ ./wiki
|
||||||
$ 8l wiki.8
|
|
||||||
$ ./8.out
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -366,19 +360,17 @@ This function will work fine, but all that hard-coded HTML is ugly.
|
|||||||
Of course, there is a better way.
|
Of course, there is a better way.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>The <code>template</code> package</h2>
|
<h2>The <code>html/template</code> package</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <code>template</code> package is part of the Go standard library.
|
The <code>html/template</code> package is part of the Go standard library.
|
||||||
(A new template package is coming; this code lab will be updated soon.)
|
We can use <code>html/template</code> to keep the HTML in a separate file,
|
||||||
We can
|
allowing us to change the layout of our edit page without modifying the
|
||||||
use <code>template</code> to keep the HTML in a separate file, allowing
|
underlying Go code.
|
||||||
us to change the layout of our edit page without modifying the underlying Go
|
|
||||||
code.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
First, we must add <code>template</code> to the list of imports:
|
First, we must add <code>html/template</code> to the list of imports:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@ -386,7 +378,7 @@ import (
|
|||||||
"http"
|
"http"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
<b>"template"</b>
|
<b>"html/template"</b>
|
||||||
)
|
)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@ -409,7 +401,7 @@ HTML:
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The function <code>template.ParseFile</code> will read the contents of
|
The function <code>template.ParseFiles</code> will read the contents of
|
||||||
<code>edit.html</code> and return a <code>*template.Template</code>.
|
<code>edit.html</code> and return a <code>*template.Template</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -474,10 +466,11 @@ The handlers are now shorter and simpler.
|
|||||||
<h2>Handling non-existent pages</h2>
|
<h2>Handling non-existent pages</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
What if you visit <code>/view/APageThatDoesntExist</code>? The program will
|
What if you visit <a href="http://localhost:8080/view/APageThatDoesntExist">
|
||||||
crash. This is because it ignores the error return value from
|
<code>/view/APageThatDoesntExist</code></a>? The program will crash. This is
|
||||||
<code>loadPage</code>. Instead, if the requested Page doesn't exist, it should
|
because it ignores the error return value from <code>loadPage</code>. Instead,
|
||||||
redirect the client to the edit Page so the content may be created:
|
if the requested Page doesn't exist, it should redirect the client to the edit
|
||||||
|
Page so the content may be created:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@ -753,9 +746,8 @@ Recompile the code, and run the app:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
$ 8g wiki.go
|
$ go build wiki.go
|
||||||
$ 8l wiki.8
|
$ ./wiki
|
||||||
$ ./8.out
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
Loading…
Reference in New Issue
Block a user