<!-- Codelab: Writing Web Applications -->
<h2>Introduction</h2>

<p>
Covered in this codelab:
</p>
<ul>
<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>template</code> package to process HTML templates</li>
<li>Using the <code>regexp</code> package to validate user input</li>
<li>Using closures</li>
</ul>

<p>
Assumed knowledge:
</p>
<ul>
<li>Programming experience</li>
<li>Understanding of basic web technologies (HTTP, HTML)</li>
<li>Some UNIX command-line knowledge</li>
</ul>

<h2>Getting Started</h2>

<p>
At present, you need to have a Linux, OS X, or FreeBSD machine to run Go. If
you don't have access to one, you could set up a Linux Virtual Machine (using 
<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>
Install Go (see the <a href="http://golang.org/doc/install.html">Installation Instructions</a>).
</p>

<p>
Make a new directory for this codelab and cd to it:
</p>

<pre>
$ mkdir ~/gowiki
$ cd ~/gowiki
</pre>

<p>
Create a file named <code>wiki.go</code>, open it in your favorite editor, and 
add the following lines:
</p>

<pre>
package main

import (
	"fmt"
	"io/ioutil"
	"os"
)
</pre>

<p>
We import the <code>fmt</code>, <code>ioutil</code> and <code>os</code>
packages from the Go standard library. Later, as we implement additional
functionality, we will add more packages to this <code>import</code>
declaration.
</p>

<h2>Data Structures</h2>

<p>
Let's start by defining the data structures. A wiki consists of a series of
interconnected pages, each of which has a title and a body (the page content).
Here, we define <code>Page</code> as a struct with two fields representing
the title and body.
</p>

<pre>
type Page struct {
	Title	string
	Body	[]byte
}
</pre>

<p>
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> 
for more on slices.)  
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>
libraries we will use, as you'll see below.
</p>

<p>
The <code>Page</code> struct describes how page data will be stored in memory. 
But what about persistent storage? We can address that by creating a 
<code>save</code> method on <code>Page</code>:
</p>

<pre>
func (p *Page) save() os.Error {
	filename := p.Title + &#34;.txt&#34;
	return ioutil.WriteFile(filename, p.Body, 0600)
}
</pre>

<p>
This method's signature reads: "This is a method named <code>save</code> that
takes as its receiver <code>p</code>, a pointer to <code>Page</code> . It takes
no parameters, and returns a value of type <code>os.Error</code>." 
</p>

<p>
This method will save the <code>Page</code>'s <code>Body</code> to a text 
file. For simplicity, we will use the <code>Title</code> as the file name.
</p>

<p>
The <code>save</code> method returns an <code>os.Error</code> value because
that is the return type of <code>WriteFile</code> (a standard library function
that writes a byte slice to a file).  The <code>save</code> method returns the
error value, to let the application handle it should anything go wrong while
writing the file.  If all goes well, <code>Page.save()</code> will return
<code>nil</code> (the zero-value for pointers, interfaces, and some other 
types).
</p>

<p>
The octal integer constant <code>0600</code>, passed as the third parameter to
<code>WriteFile</code>, indicates that the file should be created with
read-write permissions for the current user only. (See the Unix man page
<code>open(2)</code> for details.)
</p>

<p>
We will want to load pages, too:
</p>

<pre>
func loadPage(title string) *Page {
	filename := title + &#34;.txt&#34;
	body, _ := ioutil.ReadFile(filename)
	return &amp;Page{Title: title, Body: body}
}
</pre>

<p>
The function <code>loadPage</code> constructs the file name from
<code>Title</code>, reads the file's contents into a new
<code>Page</code>, and returns a pointer to that new <code>page</code>.
</p>

<p>
Functions can return multiple values. The standard library function 
<code>io.ReadFile</code> returns <code>[]byte</code> and <code>os.Error</code>. 
In <code>loadPage</code>, error isn't being handled yet; the "blank identifier"
represented by the underscore (<code>_</code>) symbol is used to throw away the
error return value (in essence, assigning the value to nothing). 
</p>

<p>
But what happens if <code>ReadFile</code> encounters an error?  For example,
the file might not exist. We should not ignore such errors.  Let's modify the
function to return <code>*Page</code> and <code>os.Error</code>.
</p>

<pre>
func loadPage(title string) (*Page, os.Error) {
	filename := title + &#34;.txt&#34;
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &amp;Page{Title: title, Body: body}, nil
}
</pre>

<p>
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>os.Error</code> that can be handled by the caller (see the <a
href="http://golang.org/pkg/os/#Error">os package documentation</a> for 
details).
</p>

<p>
At this point we have a simple data structure and the ability to save to and
load from a file. Let's write a <code>main</code> function to test what we've
written:
</p>

<pre>
func main() {
	p1 := &amp;Page{Title: &#34;TestPage&#34;, Body: []byte(&#34;This is a sample Page.&#34;)}
	p1.save()
	p2, _ := loadPage(&#34;TestPage&#34;)
	fmt.Println(string(p2.Body))
}
</pre>

<p>
After compiling and executing this code, a file named <code>TestPage.txt</code>
would be created, containing the contents of <code>p1</code>. The file would
then be read into the struct <code>p2</code>, and its <code>Body</code> element
printed to the screen.
</p>

<p>
You can compile and run the program like this: 
</p>

<pre>
$ 8g wiki.go
$ 8l wiki.8
$ ./8.out
This is a sample page.
</pre>

<p>
(The <code>8g</code> and <code>8l</code> commands are applicable to
<code>GOARCH=386</code>. If you're on an <code>amd64</code> system,
substitute 6's for the 8's.)
</p>

<p>
<a href="part1.go">Click here to view the code we've written so far.</a>
</p>

<h2>Introducing the <code>http</code> package (an interlude)</h2>

<p>
Here's a full working example of a simple web server:
</p>

<pre>
package main

import (
	&#34;fmt&#34;
	&#34;http&#34;
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, &#34;Hi there, I love %s!&#34;, r.URL.Path[1:])
}

func main() {
	http.HandleFunc(&#34;/&#34;, handler)
	http.ListenAndServe(&#34;:8080&#34;, nil)
}
</pre>

<p>
The <code>main</code> function begins with a call to 
<code>http.HandleFunc</code>, which tells the <code>http</code> package to 
handle all requests to the web root (<code>"/"</code>) with 
<code>handler</code>. 
</p>

<p>
It then calls <code>http.ListenAndServe</code>, specifying that it should
listen on port 8080 on any interface (<code>":8080"</code>). (Don't
worry about its second parameter, <code>nil</code>, for now.)
This function will block until the program is terminated.
</p>

<p>
The function <code>handler</code> is of the type <code>http.HandlerFunc</code>.
It takes an <code>http.ResponseWriter</code> and an <code>http.Request</code> as
its arguments.
</p>

<p>
An <code>http.ResponseWriter</code> value assembles the HTTP server's response; by writing 
to it, we send data to the HTTP client.
</p>

<p>
An <code>http.Request</code> is a data structure that represents the client
HTTP request.  The string <code>r.URL.Path</code> is the path component
of the request URL.  The trailing <code>[1:]</code> means
"create a sub-slice of <code>Path</code> from the 1st character to the end." 
This drops the leading "/" from the path name.
</p>

<p>
If you run this program and access the URL: 
</p>
<pre>http://localhost:8080/monkeys</pre>
<p>
the program would present a page containing:
</p>
<pre>Hi there, I love monkeys!</pre>

<h2>Using <code>http</code> to serve wiki pages</h2>

<p>
To use the <code>http</code> package, it must be imported:
</p>

<pre>
import (
	"fmt"
	<b>"http"</b>
	"io/ioutil"
	"os"
)
</pre>

<p>
Let's create a handler to view a wiki page: 
</p>

<pre>
const lenPath = len(&#34;/view/&#34;)

func viewHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[lenPath:]
	p, _ := loadPage(title)
	fmt.Fprintf(w, &#34;&lt;h1&gt;%s&lt;/h1&gt;&lt;div&gt;%s&lt;/div&gt;&#34;, p.Title, p.Body)
}
</pre>

<p>
First, this function extracts the page title from <code>r.URL.Path</code>,
the path component of the request URL. The global constant 
<code>lenPath</code> is the length of the leading <code>"/view/"</code>
component of the request path.
The <code>Path</code> is re-sliced with <code>[lenPath:]</code> to drop the 
first 6 characters of the string. This is because the path will invariably 
begin with <code>"/view/"</code>, which is not part of the page title.
</p>

<p>
The function then loads the page data, formats the page with a string of simple 
HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. 
</p>

<p>
Again, note the use of <code>_</code> to ignore the <code>os.Error</code> 
return value from <code>loadPage</code>. This is done here for simplicity
and generally considered bad practice. We will attend to this later.
</p>

<p>
To use this handler, we create a <code>main</code> function that
initializes <code>http</code> using the <code>viewHandler</code> to handle
any requests under the path <code>/view/</code>.
</p>

<pre>
func main() {
	http.HandleFunc(&#34;/view/&#34;, viewHandler)
	http.ListenAndServe(&#34;:8080&#34;, nil)
}
</pre>

<p>
<a href="part2.go">Click here to view the code we've written so far.</a>
</p>

<p>
Let's create some page data (as <code>test.txt</code>), compile our code, and
try serving a wiki page:
</p>

<pre>
$ echo "Hello world" &gt; test.txt
$ 8g wiki.go
$ 8l wiki.8
$ ./8.out
</pre>

<p>
With this web server running, a visit to <code><a
href="http://localhost:8080/view/test">http://localhost:8080/view/test</a></code>
should show a page titled "test" containing the words "Hello world".
</p>

<h2>Editing Pages</h2>

<p>
A wiki is not a wiki without the ability to edit pages. Let's create two new
handlers: one named <code>editHandler</code> to display an 'edit page' form,
and the other named <code>saveHandler</code> to save the data entered via the
form.
</p>

<p>
First, we add them to <code>main()</code>: 
</p>

<pre>
func main() {
	http.HandleFunc(&#34;/view/&#34;, viewHandler)
	http.HandleFunc(&#34;/edit/&#34;, editHandler)
	http.HandleFunc(&#34;/save/&#34;, saveHandler)
	http.ListenAndServe(&#34;:8080&#34;, nil)
}
</pre>

<p>
The function <code>editHandler</code> loads the page 
(or, if it doesn't exist, create an empty <code>Page</code> struct), 
and displays an HTML form.
</p>

<pre>
func editHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[lenPath:]
	p, err := loadPage(title)
	if err != nil {
		p = &amp;Page{Title: title}
	}
	fmt.Fprintf(w, &#34;&lt;h1&gt;Editing %s&lt;/h1&gt;&#34;+
		&#34;&lt;form action=\&#34;/save/%s\&#34; method=\&#34;POST\&#34;&gt;&#34;+
		&#34;&lt;textarea name=\&#34;body\&#34;&gt;%s&lt;/textarea&gt;&lt;br&gt;&#34;+
		&#34;&lt;input type=\&#34;submit\&#34; value=\&#34;Save\&#34;&gt;&#34;+
		&#34;&lt;/form&gt;&#34;,
		p.Title, p.Title, p.Body)
}
</pre>

<p>
This function will work fine, but all that hard-coded HTML is ugly.
Of course, there is a better way.
</p>
 
<h2>The <code>template</code> package</h2>

<p>
The <code>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>template</code> to keep the HTML in a separate file, allowing
us to change the layout of our edit page without modifying the underlying Go
code.
</p>

<p>
First, we must add <code>template</code> to the list of imports:
</p>

<pre>
import (
	"http"
	"io/ioutil"
	"os"
	<b>"template"</b>
)
</pre>

<p>
Let's create a template file containing the HTML form. 
Open a new file named <code>edit.html</code>, and add the following lines:
</p>

<pre>
&lt;h1&gt;Editing {{.Title |html}}&lt;/h1&gt;

&lt;form action=&#34;/save/{{.Title |html}}&#34; method=&#34;POST&#34;&gt;
&lt;div&gt;&lt;textarea name=&#34;body&#34; rows=&#34;20&#34; cols=&#34;80&#34;&gt;{{printf &#34;%s&#34; .Body |html}}&lt;/textarea&gt;&lt;/div&gt;
&lt;div&gt;&lt;input type=&#34;submit&#34; value=&#34;Save&#34;&gt;&lt;/div&gt;
&lt;/form&gt;
</pre>

<p>
Modify <code>editHandler</code> to use the template, instead of the hard-coded
HTML:
</p>

<pre>
func editHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[lenPath:]
	p, err := loadPage(title)
	if err != nil {
		p = &amp;Page{Title: title}
	}
	t, _ := template.ParseFile(&#34;edit.html&#34;)
	t.Execute(w, p)
}
</pre>

<p>
The function <code>template.ParseFile</code> will read the contents of 
<code>edit.html</code> and return a <code>*template.Template</code>. 
</p>

<p>
The method <code>t.Execute</code> executes the template, writing the
generated HTML to the <code>http.ResponseWriter</code>.
The <code>.Title</code> and <code>.Body</code> dotted identifiers refer to
<code>p.Title</code> and <code>p.Body</code>.
</p>

<p>
Template directives are enclosed in double curly braces.
The <code>printf "%s" .Body</code> instruction is a function call
that outputs <code>.Body</code> as a string instead of a stream of bytes,
the same as a call to <code>fmt.Printf</code>.
The <code>|html</code> part of each directive pipes the value through the
<code>html</code> formatter before outputting it, which escapes HTML
characters (such as replacing <code>&gt;</code> with <code>&amp;gt;</code>),
preventing user data from corrupting the form HTML. 
</p>

<p>
Now that we've removed the <code>fmt.Fprintf</code> statement, we can remove
<code>"fmt"</code> from the <code>import</code> list.
</p>

<p>
While we're working with templates, let's create a template for our
<code>viewHandler</code> called <code>view.html</code>:
</p>

<pre>
&lt;h1&gt;{{.Title |html}}&lt;/h1&gt;

&lt;p&gt;[&lt;a href=&#34;/edit/{{.Title |html}}&#34;&gt;edit&lt;/a&gt;]&lt;/p&gt;

&lt;div&gt;{{printf &#34;%s&#34; .Body |html}}&lt;/div&gt;
</pre>

<p>
Modify <code>viewHandler</code> accordingly:
</p>

<pre>
func viewHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[lenPath:]
	p, _ := loadPage(title)
	t, _ := template.ParseFile(&#34;view.html&#34;)
	t.Execute(w, p)
}
</pre>

<p>
Notice that we've used almost exactly the same templating code in both
handlers. Let's remove this duplication by moving the templating code
to its own function:
</p>

<pre>
func viewHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[lenPath:]
	p, _ := loadPage(title)
	renderTemplate(w, &#34;view&#34;, p)
}

func editHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[lenPath:]
	p, err := loadPage(title)
	if err != nil {
		p = &amp;Page{Title: title}
	}
	renderTemplate(w, &#34;edit&#34;, p)
}

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	t, _ := template.ParseFile(tmpl+&#34;.html&#34;, nil)
	t.Execute(w, p)
}
</pre>

<p>
The handlers are now shorter and simpler. 
</p>

<h2>Handling non-existent pages</h2>

<p>
What if you visit <code>/view/APageThatDoesntExist</code>? The program will 
crash. This is because it ignores the error return value from
<code>loadPage</code>. Instead, if the requested Page doesn't exist, it should 
redirect the client to the edit Page so the content may be created:
</p>

<pre>
func viewHandler(w http.ResponseWriter, r *http.Request) {
	title, err := getTitle(w, r)
	if err != nil {
		return
	}
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, &#34;/edit/&#34;+title, http.StatusFound)
		return
	}
	renderTemplate(w, &#34;view&#34;, p)
}
</pre>

<p>
The <code>http.Redirect</code> function adds an HTTP status code of 
<code>http.StatusFound</code> (302) and a <code>Location</code>
header to the HTTP response.
</p>

<h2>Saving Pages</h2>

<p>
The function <code>saveHandler</code> will handle the form submission. 
</p>

<pre>
func saveHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[lenPath:]
	body := r.FormValue(&#34;body&#34;)
	p := &amp;Page{Title: title, Body: []byte(body)}
	p.save()
	http.Redirect(w, r, &#34;/view/&#34;+title, http.StatusFound)
}
</pre>

<p>
The page title (provided in the URL) and the form's only field, 
<code>Body</code>, are stored in a new <code>Page</code>. 
The <code>save()</code> method is then called to write the data to a file,
and the client is redirected to the <code>/view/</code> page.
</p>

<p>
The value returned by <code>FormValue</code> is of type <code>string</code>.
We must convert that value to <code>[]byte</code> before it will fit into 
the <code>Page</code> struct.  We use <code>[]byte(body)</code> to perform
the conversion.
</p>

<h2>Error handling</h2>

<p>
There are several places in our program where errors are being ignored.  This
is bad practice, not least because when an error does occur the program will
crash.  A better solution is to handle the errors and return an error message
to the user. That way if something does go wrong, the server will continue to
function and the user will be notified.
</p>

<p>
First, let's handle the errors in <code>renderTemplate</code>:
</p>

<pre>
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	t, err := template.ParseFile(tmpl+&#34;.html&#34;, nil)
	if err != nil {
		http.Error(w, err.String(), http.StatusInternalServerError)
		return
	}
	err = t.Execute(w, p)
	if err != nil {
		http.Error(w, err.String(), http.StatusInternalServerError)
	}
}
</pre>

<p>
The <code>http.Error</code> function sends a specified HTTP response code 
(in this case "Internal Server Error") and error message.
Already the decision to put this in a separate function is paying off.
</p>

<p>
Now let's fix up <code>saveHandler</code>:
</p>

<pre>
func saveHandler(w http.ResponseWriter, r *http.Request) {
	title, err := getTitle(w, r)
	if err != nil {
		return
	}
	body := r.FormValue(&#34;body&#34;)
	p := &amp;Page{Title: title, Body: []byte(body)}
	err = p.save()
	if err != nil {
		http.Error(w, err.String(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, &#34;/view/&#34;+title, http.StatusFound)
}
</pre>

<p>
Any errors that occur during <code>p.save()</code> will be reported 
to the user.
</p>

<h2>Template caching</h2>

<p>
There is an inefficiency in this code: <code>renderTemplate</code> calls 
<code>ParseFile</code> every time a page is rendered. 
A better approach would be to call <code>ParseFile</code> once for each 
template at program initialization, and store the resultant 
<code>*Template</code> values in a data structure for later use.
</p>

<p>
First we create a global map named <code>templates</code> in which to store 
our <code>*Template</code> values, keyed by <code>string</code> 
(the template name):
</p>

<pre>
var templates = make(map[string]*template.Template)
</pre>

<p>
Then we create an <code>init</code> function, which will be called before
<code>main</code> at program initialization. The function
<code>template.Must</code> is a convenience wrapper that panics when passed a
non-nil <code>os.Error</code> value, and otherwise returns the
<code>*Template</code> unaltered. A panic is appropriate here; if the templates
can't be loaded the only sensible thing to do is exit the program.
</p>

<pre>
func init() {
	for _, tmpl := range []string{&#34;edit&#34;, &#34;view&#34;} {
		t := template.Must(template.ParseFile(tmpl + &#34;.html&#34;))
		templates[tmpl] = t
	}
}
</pre>

<p>
A <code>for</code> loop is used with a <code>range</code> statement to iterate 
over an array constant containing the names of the templates we want parsed.
If we were to add more templates to our program, we would add their names to 
that array.
</p>

<p>
We then modify our <code>renderTemplate</code> function to call 
the <code>Execute</code> method on the appropriate <code>Template</code> from 
<code>templates</code>:

<pre>
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	err := templates[tmpl].Execute(w, p)
	if err != nil {
		http.Error(w, err.String(), http.StatusInternalServerError)
	}
}
</pre>

<h2>Validation</h2>

<p>
As you may have observed, this program has a serious security flaw: a user
can supply an arbitrary path to be read/written on the server. To mitigate
this, we can write a function to validate the title with a regular expression.
</p>

<p>
First, add <code>"regexp"</code> to the <code>import</code> list.
Then we can create a global variable to store our validation regexp:
</p>

<pre>
var titleValidator = regexp.MustCompile(&#34;^[a-zA-Z0-9]+$&#34;)
</pre>

<p>
The function <code>regexp.MustCompile</code> will parse and compile the 
regular expression, and return a <code>regexp.Regexp</code>. 
<code>MustCompile</code> is distinct from <code>Compile</code> in that it will
panic if the expression compilation fails, while <code>Compile</code> returns
an <code>os.Error</code> as a second parameter. 
</p>

<p>
Now, let's write a function that extracts the title string from the request 
URL, and tests it against our <code>TitleValidator</code> expression:
</p>

<pre>
func getTitle(w http.ResponseWriter, r *http.Request) (title string, err os.Error) {
	title = r.URL.Path[lenPath:]
	if !titleValidator.MatchString(title) {
		http.NotFound(w, r)
		err = os.NewError(&#34;Invalid Page Title&#34;)
	}
	return
}
</pre>

<p>
If the title is valid, it will be returned along with a <code>nil</code>
error value.  If the title is invalid, the function will write a 
"404 Not Found" error to the HTTP connection, and return an error to the 
handler. 
</p>

<p>
Let's put a call to <code>getTitle</code> in each of the handlers:
</p>

<pre>
func viewHandler(w http.ResponseWriter, r *http.Request) {
	title, err := getTitle(w, r)
	if err != nil {
		return
	}
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, &#34;/edit/&#34;+title, http.StatusFound)
		return
	}
	renderTemplate(w, &#34;view&#34;, p)
}

func editHandler(w http.ResponseWriter, r *http.Request) {
	title, err := getTitle(w, r)
	if err != nil {
		return
	}
	p, err := loadPage(title)
	if err != nil {
		p = &amp;Page{Title: title}
	}
	renderTemplate(w, &#34;edit&#34;, p)
}

func saveHandler(w http.ResponseWriter, r *http.Request) {
	title, err := getTitle(w, r)
	if err != nil {
		return
	}
	body := r.FormValue(&#34;body&#34;)
	p := &amp;Page{Title: title, Body: []byte(body)}
	err = p.save()
	if err != nil {
		http.Error(w, err.String(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, &#34;/view/&#34;+title, http.StatusFound)
}
</pre>

<h2>Introducing Function Literals and Closures</h2>

<p>
Catching the error condition in each handler introduces a lot of repeated code.
What if we could wrap each of the handlers in a function that does this 
validation and error checking? Go's 
<a href="http://golang.org/doc/go_spec.html#Function_declarations">function 
literals</a> provide a powerful means of abstracting functionality 
that can help us here.
</p>

<p>
First, we re-write the function definition of each of the handlers to accept
a title string:
</p>

<pre>
func viewHandler(w http.ResponseWriter, r *http.Request, title string)
func editHandler(w http.ResponseWriter, r *http.Request, title string)
func saveHandler(w http.ResponseWriter, r *http.Request, title string)
</pre>

<p>
Now let's define a wrapper function that <i>takes a function of the above
type</i>, and returns a function of type <code>http.HandlerFunc</code>
(suitable to be passed to the function <code>http.HandleFunc</code>):
</p>

<pre>
func makeHandler(fn func (http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Here we will extract the page title from the Request,
		// and call the provided handler 'fn'
	}
}
</pre>

<p>
The returned function is called a closure because it encloses values defined
outside of it. In this case, the variable <code>fn</code> (the single argument
to <code>makeHandler</code>) is enclosed by the closure. The variable
<code>fn</code> will be one of our save, edit, or view handlers.
</p>

<p>
Now we can take the code from <code>getTitle</code> and use it here
(with some minor modifications):
</p>

<pre>
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		title := r.URL.Path[lenPath:]
		if !titleValidator.MatchString(title) {
			http.NotFound(w, r)
			return
		}
		fn(w, r, title)
	}
}
</pre>

<p>
The closure returned by <code>makeHandler</code> is a function that takes
an <code>http.ResponseWriter</code> and <code>http.Request</code> (in other
words, an <code>http.HandlerFunc</code>). 
The closure extracts the <code>title</code> from the request path, and
validates it with the <code>TitleValidator</code> regexp. If the
<code>title</code> is invalid, an error will be written to the
<code>ResponseWriter</code> using the <code>http.NotFound</code> function. 
If the <code>title</code> is valid, the enclosed handler function
<code>fn</code> will be called with the <code>ResponseWriter</code>,
<code>Request</code>, and <code>title</code> as arguments.
</p>

<p>
Now we can wrap the handler functions with <code>makeHandler</code> in 
<code>main</code>, before they are registered with the <code>http</code> 
package:
</p>

<pre>
func main() {
	http.HandleFunc(&#34;/view/&#34;, makeHandler(viewHandler))
	http.HandleFunc(&#34;/edit/&#34;, makeHandler(editHandler))
	http.HandleFunc(&#34;/save/&#34;, makeHandler(saveHandler))
	http.ListenAndServe(&#34;:8080&#34;, nil)
}
</pre>

<p>
Finally we remove the calls to <code>getTitle</code> from the handler functions,
making them much simpler:
</p>

<pre>
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, &#34;/edit/&#34;+title, http.StatusFound)
		return
	}
	renderTemplate(w, &#34;view&#34;, p)
}

func editHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		p = &amp;Page{Title: title}
	}
	renderTemplate(w, &#34;edit&#34;, p)
}

func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
	body := r.FormValue(&#34;body&#34;)
	p := &amp;Page{Title: title, Body: []byte(body)}
	err := p.save()
	if err != nil {
		http.Error(w, err.String(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, &#34;/view/&#34;+title, http.StatusFound)
}
</pre>

<h2>Try it out!</h2>

<p>
<a href="final.go">Click here to view the final code listing.</a>
</p>

<p>
Recompile the code, and run the app:
</p>

<pre>
$ 8g wiki.go
$ 8l wiki.8
$ ./8.out
</pre>

<p>
Visiting <a href="http://localhost:8080/view/ANewPage">http://localhost:8080/view/ANewPage</a>
should present you with the page edit form. You should then be able to 
enter some text, click 'Save', and be redirected to the newly created page.
</p>

<h2>Other tasks</h2>

<p>
Here are some simple tasks you might want to tackle on your own:
</p>

<ul>
<li>Store templates in <code>tmpl/</code> and page data in <code>data/</code>.
<li>Add a handler to make the web root redirect to 
	<code>/view/FrontPage</code>.</li>
<li>Spruce up the page templates by making them valid HTML and adding some
	CSS rules.</li>
<li>Implement inter-page linking by converting instances of 
	<code>[PageName]</code> to <br>
	<code>&lt;a href="/view/PageName"&gt;PageName&lt;/a&gt;</code>.
	(hint: you could use <code>regexp.ReplaceAllFunc</code> to do this)
	</li>
</ul>
