<!-- 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() 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>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>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>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>error</code>.
</p>

<pre>
func loadPage(title string) (*Page, 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>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;net/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>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.ParseFiles(&#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.ParseFiles(&#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.ParseFiles(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.ParseFiles(tmpl+&#34;.html&#34;, nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	err = t.Execute(w, p)
	if err != nil {
		http.Error(w, err.Error(), 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.Error(), 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>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.ParseFiles(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.Error(), 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>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 error) {
	title = r.URL.Path[lenPath:]
	if !titleValidator.MatchString(title) {
		http.NotFound(w, r)
		err = errors.New(&#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.Error(), 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.Error(), 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>
