Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
a2332a32
Commit
a2332a32
authored
Sep 30, 2010
by
Stephen Ma
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
doc: update http handler usage for new signature
R=adg, r2 CC=golang-dev
https://golang.org/cl/2302041
parent
763cb8ad
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
152 additions
and
152 deletions
+152
-152
final-noclosure.go
doc/codelab/wiki/final-noclosure.go
+17
-17
final-noerror.go
doc/codelab/wiki/final-noerror.go
+4
-4
final-parsetemplate.go
doc/codelab/wiki/final-parsetemplate.go
+16
-16
final-template.go
doc/codelab/wiki/final-template.go
+8
-8
final.go
doc/codelab/wiki/final.go
+15
-15
http-sample.go
doc/codelab/wiki/http-sample.go
+2
-2
index.html
doc/codelab/wiki/index.html
+70
-70
notemplate.go
doc/codelab/wiki/notemplate.go
+4
-4
part2.go
doc/codelab/wiki/part2.go
+2
-2
wiki.html
doc/codelab/wiki/wiki.html
+14
-14
No files found.
doc/codelab/wiki/final-noclosure.go
View file @
a2332a32
...
...
@@ -27,21 +27,21 @@ func loadPage(title string) (*page, os.Error) {
return
&
page
{
title
:
title
,
body
:
body
},
nil
}
func
viewHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
title
,
err
:=
getTitle
(
c
,
r
)
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
(
c
,
"/edit/"
+
title
,
http
.
StatusFound
)
http
.
Redirect
(
w
,
r
,
"/edit/"
+
title
,
http
.
StatusFound
)
return
}
renderTemplate
(
c
,
"view"
,
p
)
renderTemplate
(
w
,
"view"
,
p
)
}
func
editHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
title
,
err
:=
getTitle
(
c
,
r
)
func
editHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
,
err
:=
getTitle
(
w
,
r
)
if
err
!=
nil
{
return
}
...
...
@@ -49,11 +49,11 @@ func editHandler(c *http.Conn, r *http.Request) {
if
err
!=
nil
{
p
=
&
page
{
title
:
title
}
}
renderTemplate
(
c
,
"edit"
,
p
)
renderTemplate
(
w
,
"edit"
,
p
)
}
func
saveHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
title
,
err
:=
getTitle
(
c
,
r
)
func
saveHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
,
err
:=
getTitle
(
w
,
r
)
if
err
!=
nil
{
return
}
...
...
@@ -61,21 +61,21 @@ func saveHandler(c *http.Conn, r *http.Request) {
p
:=
&
page
{
title
:
title
,
body
:
[]
byte
(
body
)}
err
=
p
.
save
()
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
return
}
http
.
Redirect
(
c
,
"/view/"
+
title
,
http
.
StatusFound
)
http
.
Redirect
(
w
,
r
,
"/view/"
+
title
,
http
.
StatusFound
)
}
func
renderTemplate
(
c
*
http
.
Conn
,
tmpl
string
,
p
*
page
)
{
func
renderTemplate
(
w
http
.
ResponseWriter
,
tmpl
string
,
p
*
page
)
{
t
,
err
:=
template
.
ParseFile
(
tmpl
+
".html"
,
nil
)
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
return
}
err
=
t
.
Execute
(
p
,
c
)
err
=
t
.
Execute
(
p
,
w
)
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
}
}
...
...
@@ -83,10 +83,10 @@ const lenPath = len("/view/")
var
titleValidator
=
regexp
.
MustCompile
(
"^[a-zA-Z0-9]+$"
)
func
getTitle
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
(
title
string
,
err
os
.
Error
)
{
func
getTitle
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
title
string
,
err
os
.
Error
)
{
title
=
r
.
URL
.
Path
[
lenPath
:
]
if
!
titleValidator
.
MatchString
(
title
)
{
http
.
NotFound
(
c
,
r
)
http
.
NotFound
(
w
,
r
)
err
=
os
.
NewError
(
"Invalid Page Title"
)
}
return
...
...
doc/codelab/wiki/final-noerror.go
View file @
a2332a32
...
...
@@ -28,21 +28,21 @@ func loadPage(title string) (*page, os.Error) {
const
lenPath
=
len
(
"/view/"
)
func
editHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
editHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
err
:=
loadPage
(
title
)
if
err
!=
nil
{
p
=
&
page
{
title
:
title
}
}
t
,
_
:=
template
.
ParseFile
(
"edit.html"
,
nil
)
t
.
Execute
(
p
,
c
)
t
.
Execute
(
p
,
w
)
}
func
viewHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
viewHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
_
:=
loadPage
(
title
)
t
,
_
:=
template
.
ParseFile
(
"view.html"
,
nil
)
t
.
Execute
(
p
,
c
)
t
.
Execute
(
p
,
w
)
}
func
main
()
{
...
...
doc/codelab/wiki/final-parsetemplate.go
View file @
a2332a32
...
...
@@ -27,43 +27,43 @@ func loadPage(title string) (*page, os.Error) {
return
&
page
{
title
:
title
,
body
:
body
},
nil
}
func
viewHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
title
string
)
{
func
viewHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
title
string
)
{
p
,
err
:=
loadPage
(
title
)
if
err
!=
nil
{
http
.
Redirect
(
c
,
"/edit/"
+
title
,
http
.
StatusFound
)
http
.
Redirect
(
w
,
r
,
"/edit/"
+
title
,
http
.
StatusFound
)
return
}
renderTemplate
(
c
,
"view"
,
p
)
renderTemplate
(
w
,
"view"
,
p
)
}
func
editHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
title
string
)
{
func
editHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
title
string
)
{
p
,
err
:=
loadPage
(
title
)
if
err
!=
nil
{
p
=
&
page
{
title
:
title
}
}
renderTemplate
(
c
,
"edit"
,
p
)
renderTemplate
(
w
,
"edit"
,
p
)
}
func
saveHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
title
string
)
{
func
saveHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
title
string
)
{
body
:=
r
.
FormValue
(
"body"
)
p
:=
&
page
{
title
:
title
,
body
:
[]
byte
(
body
)}
err
:=
p
.
save
()
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
return
}
http
.
Redirect
(
c
,
"/view/"
+
title
,
http
.
StatusFound
)
http
.
Redirect
(
w
,
r
,
"/view/"
+
title
,
http
.
StatusFound
)
}
func
renderTemplate
(
c
*
http
.
Conn
,
tmpl
string
,
p
*
page
)
{
func
renderTemplate
(
w
http
.
ResponseWriter
,
tmpl
string
,
p
*
page
)
{
t
,
err
:=
template
.
ParseFile
(
tmpl
+
".html"
,
nil
)
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
return
}
err
=
t
.
Execute
(
p
,
c
)
err
=
t
.
Execute
(
p
,
w
)
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
}
}
...
...
@@ -71,14 +71,14 @@ const lenPath = len("/view/")
var
titleValidator
=
regexp
.
MustCompile
(
"^[a-zA-Z0-9]+$"
)
func
makeHandler
(
fn
func
(
*
http
.
Conn
,
*
http
.
Request
,
string
))
http
.
HandlerFunc
{
return
func
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
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
(
c
,
r
)
http
.
NotFound
(
w
,
r
)
return
}
fn
(
c
,
r
,
title
)
fn
(
w
,
r
,
title
)
}
}
...
...
doc/codelab/wiki/final-template.go
View file @
a2332a32
...
...
@@ -28,32 +28,32 @@ func loadPage(title string) (*page, os.Error) {
const
lenPath
=
len
(
"/view/"
)
func
editHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
editHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
err
:=
loadPage
(
title
)
if
err
!=
nil
{
p
=
&
page
{
title
:
title
}
}
renderTemplate
(
c
,
"edit"
,
p
)
renderTemplate
(
w
,
"edit"
,
p
)
}
func
viewHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
viewHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
_
:=
loadPage
(
title
)
renderTemplate
(
c
,
"view"
,
p
)
renderTemplate
(
w
,
"view"
,
p
)
}
func
saveHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
saveHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
body
:=
r
.
FormValue
(
"body"
)
p
:=
&
page
{
title
:
title
,
body
:
[]
byte
(
body
)}
p
.
save
()
http
.
Redirect
(
c
,
"/view/"
+
title
,
http
.
StatusFound
)
http
.
Redirect
(
w
,
r
,
"/view/"
+
title
,
http
.
StatusFound
)
}
func
renderTemplate
(
c
*
http
.
Conn
,
tmpl
string
,
p
*
page
)
{
func
renderTemplate
(
w
http
.
ResponseWriter
,
tmpl
string
,
p
*
page
)
{
t
,
_
:=
template
.
ParseFile
(
tmpl
+
".html"
,
nil
)
t
.
Execute
(
p
,
c
)
t
.
Execute
(
p
,
w
)
}
func
main
()
{
...
...
doc/codelab/wiki/final.go
View file @
a2332a32
...
...
@@ -27,32 +27,32 @@ func loadPage(title string) (*page, os.Error) {
return
&
page
{
title
:
title
,
body
:
body
},
nil
}
func
viewHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
title
string
)
{
func
viewHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
title
string
)
{
p
,
err
:=
loadPage
(
title
)
if
err
!=
nil
{
http
.
Redirect
(
c
,
"/edit/"
+
title
,
http
.
StatusFound
)
http
.
Redirect
(
w
,
r
,
"/edit/"
+
title
,
http
.
StatusFound
)
return
}
renderTemplate
(
c
,
"view"
,
p
)
renderTemplate
(
w
,
"view"
,
p
)
}
func
editHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
title
string
)
{
func
editHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
title
string
)
{
p
,
err
:=
loadPage
(
title
)
if
err
!=
nil
{
p
=
&
page
{
title
:
title
}
}
renderTemplate
(
c
,
"edit"
,
p
)
renderTemplate
(
w
,
"edit"
,
p
)
}
func
saveHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
,
title
string
)
{
func
saveHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
title
string
)
{
body
:=
r
.
FormValue
(
"body"
)
p
:=
&
page
{
title
:
title
,
body
:
[]
byte
(
body
)}
err
:=
p
.
save
()
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
return
}
http
.
Redirect
(
c
,
"/view/"
+
title
,
http
.
StatusFound
)
http
.
Redirect
(
w
,
r
,
"/view/"
+
title
,
http
.
StatusFound
)
}
var
templates
=
make
(
map
[
string
]
*
template
.
Template
)
...
...
@@ -63,10 +63,10 @@ func init() {
}
}
func
renderTemplate
(
c
*
http
.
Conn
,
tmpl
string
,
p
*
page
)
{
err
:=
templates
[
tmpl
]
.
Execute
(
p
,
c
)
func
renderTemplate
(
w
http
.
ResponseWriter
,
tmpl
string
,
p
*
page
)
{
err
:=
templates
[
tmpl
]
.
Execute
(
p
,
w
)
if
err
!=
nil
{
http
.
Error
(
c
,
err
.
String
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
}
}
...
...
@@ -74,14 +74,14 @@ const lenPath = len("/view/")
var
titleValidator
=
regexp
.
MustCompile
(
"^[a-zA-Z0-9]+$"
)
func
makeHandler
(
fn
func
(
*
http
.
Conn
,
*
http
.
Request
,
string
))
http
.
HandlerFunc
{
return
func
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
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
(
c
,
r
)
http
.
NotFound
(
w
,
r
)
return
}
fn
(
c
,
r
,
title
)
fn
(
w
,
r
,
title
)
}
}
...
...
doc/codelab/wiki/http-sample.go
View file @
a2332a32
...
...
@@ -5,8 +5,8 @@ import (
"http"
)
func
handler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
fmt
.
Fprintf
(
c
,
"Hi there, I love %s!"
,
r
.
URL
.
Path
[
1
:
])
func
handler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
fmt
.
Fprintf
(
w
,
"Hi there, I love %s!"
,
r
.
URL
.
Path
[
1
:
])
}
func
main
()
{
...
...
doc/codelab/wiki/index.html
View file @
a2332a32
...
...
@@ -240,8 +240,8 @@ import (
"
http
"
)
func handler(
c *http.Conn
, r *http.Request) {
fmt.Fprintf(
c
,
"
Hi there, I love %s!
"
, r.URL.Path[1:])
func handler(
w http.ResponseWriter
, r *http.Request) {
fmt.Fprintf(
w
,
"
Hi there, I love %s!
"
, r.URL.Path[1:])
}
func main() {
...
...
@@ -266,12 +266,12 @@ This function will block until the program is terminated.
<p>
The function
<code>
handler
</code>
is of the type
<code>
http.HandlerFunc
</code>
.
It takes an
<code>
http.
Conn
</code>
and
<code>
http.Request
</code>
as its
arguments.
It takes an
<code>
http.
ResponseWriter
</code>
and an
<code>
http.Request
</code>
as
its
arguments.
</p>
<p>
An
<code>
http.
Conn
</code>
is the server end of an HTTP connection
; by writing
An
<code>
http.
ResponseWriter
</code>
value assembles the HTTP server's response
; by writing
to it, we send data to the HTTP client.
</p>
...
...
@@ -314,10 +314,10 @@ Let's create a handler to view a wiki page:
<pre>
const lenPath = len(
"
/view/
"
)
func viewHandler(
c *http.Conn
, r *http.Request) {
func viewHandler(
w http.ResponseWriter
, r *http.Request) {
title := r.URL.Path[lenPath:]
p, _ := loadPage(title)
fmt.Fprintf(
c
,
"<
h1
>
%s
<
/h1
><
div
>
%s
<
/div
>"
, p.title, p.body)
fmt.Fprintf(
w
,
"<
h1
>
%s
<
/h1
><
div
>
%s
<
/div
>"
, p.title, p.body)
}
</pre>
...
...
@@ -333,7 +333,7 @@ begin with <code>"/view/"</code>, which is not part of the page title.
<p>
The function then loads the page data, formats the page with a string of simple
HTML, and writes it to
<code>
c
</code>
, the
<code>
http.Conn
</code>
.
HTML, and writes it to
<code>
w
</code>
, the
<code>
http.ResponseWriter
</code>
.
</p>
<p>
...
...
@@ -406,13 +406,13 @@ and displays an HTML form.
</p>
<pre>
func editHandler(
c *http.Conn
, r *http.Request) {
func editHandler(
w http.ResponseWriter
, r *http.Request) {
title := r.URL.Path[lenPath:]
p, err := loadPage(title)
if err != nil {
p =
&
page{title: title}
}
fmt.Fprintf(
c
,
"<
h1
>
Editing %s
<
/h1
>"
+
fmt.Fprintf(
w
,
"<
h1
>
Editing %s
<
/h1
>"
+
"<
form action=\
"
/save/%s\
"
method=\
"
POST\
">"
+
"<
textarea name=\
"
body\
">
%s
<
/textarea
><
br
>"
+
"<
input type=\
"
submit\
"
value=\
"
Save\
">"
+
...
...
@@ -468,14 +468,14 @@ HTML:
</p>
<pre>
func editHandler(
c *http.Conn
, r *http.Request) {
func editHandler(
w http.ResponseWriter
, r *http.Request) {
title := r.URL.Path[lenPath:]
p, err := loadPage(title)
if err != nil {
p =
&
page{title: title}
}
t, _ := template.ParseFile(
"
edit.html
"
, nil)
t.Execute(p,
c
)
t.Execute(p,
w
)
}
</pre>
...
...
@@ -488,7 +488,7 @@ The function <code>template.ParseFile</code> will read the contents of
The method
<code>
t.Execute
</code>
replaces all occurrences of
<code>
{title}
</code>
and
<code>
{body}
</code>
with the values of
<code>
p.title
</code>
and
<code>
p.body
</code>
, and writes the resultant
HTML to the
<code>
http.
Conn
</code>
.
HTML to the
<code>
http.
ResponseWriter
</code>
.
</p>
<p>
...
...
@@ -523,11 +523,11 @@ Modify <code>viewHandler</code> accordingly:
</p>
<pre>
func viewHandler(
c *http.Conn
, r *http.Request) {
func viewHandler(
w http.ResponseWriter
, r *http.Request) {
title := r.URL.Path[lenPath:]
p, _ := loadPage(title)
t, _ := template.ParseFile(
"
view.html
"
, nil)
t.Execute(p,
c
)
t.Execute(p,
w
)
}
</pre>
...
...
@@ -538,24 +538,24 @@ to its own function:
</p>
<pre>
func viewHandler(
c *http.Conn
, r *http.Request) {
func viewHandler(
w http.ResponseWriter
, r *http.Request) {
title := r.URL.Path[lenPath:]
p, _ := loadPage(title)
renderTemplate(
c
,
"
view
"
, p)
renderTemplate(
w
,
"
view
"
, p)
}
func editHandler(
c *http.Conn
, r *http.Request) {
func editHandler(
w http.ResponseWriter
, r *http.Request) {
title := r.URL.Path[lenPath:]
p, err := loadPage(title)
if err != nil {
p =
&
page{title: title}
}
renderTemplate(
c
,
"
edit
"
, p)
renderTemplate(
w
,
"
edit
"
, p)
}
func renderTemplate(
c *http.Conn
, tmpl string, p *page) {
func renderTemplate(
w http.ResponseWriter
, tmpl string, p *page) {
t, _ := template.ParseFile(tmpl+
"
.html
"
, nil)
t.Execute(p,
c
)
t.Execute(p,
w
)
}
</pre>
...
...
@@ -573,13 +573,13 @@ redirect the client to the edit page so the content may be created:
</p>
<pre>
func viewHandler(
c *http.Conn
, r *http.Request, title string) {
func viewHandler(
w http.ResponseWriter
, r *http.Request, title string) {
p, err := loadPage(title)
if err != nil {
http.Redirect(
c
,
"
/edit/
"
+title, http.StatusFound)
http.Redirect(
w, r
,
"
/edit/
"
+title, http.StatusFound)
return
}
renderTemplate(
c
,
"
view
"
, p)
renderTemplate(
w
,
"
view
"
, p)
}
</pre>
...
...
@@ -596,12 +596,12 @@ The function <code>saveHandler</code> will handle the form submission.
</p>
<pre>
func saveHandler(
c *http.Conn
, r *http.Request) {
func saveHandler(
w http.ResponseWriter
, r *http.Request) {
title := r.URL.Path[lenPath:]
body := r.FormValue(
"
body
"
)
p :=
&
page{title: title, body: []byte(body)}
p.save()
http.Redirect(
c
,
"
/view/
"
+title, http.StatusFound)
http.Redirect(
w, r
,
"
/view/
"
+title, http.StatusFound)
}
</pre>
...
...
@@ -634,15 +634,15 @@ First, let's handle the errors in <code>renderTemplate</code>:
</p>
<pre>
func renderTemplate(
c *http.Conn
, tmpl string, p *page) {
func renderTemplate(
w http.ResponseWriter
, tmpl string, p *page) {
t, err := template.ParseFile(tmpl+
"
.html
"
, nil)
if err != nil {
http.Error(
c
, err.String(), http.StatusInternalServerError)
http.Error(
w
, err.String(), http.StatusInternalServerError)
return
}
err = t.Execute(p,
c
)
err = t.Execute(p,
w
)
if err != nil {
http.Error(
c
, err.String(), http.StatusInternalServerError)
http.Error(
w
, err.String(), http.StatusInternalServerError)
}
}
</pre>
...
...
@@ -658,15 +658,15 @@ Now let's fix up <code>saveHandler</code>:
</p>
<pre>
func saveHandler(
c *http.Conn
, r *http.Request, title string) {
func saveHandler(
w http.ResponseWriter
, r *http.Request, title string) {
body := r.FormValue(
"
body
"
)
p :=
&
page{title: title, body: []byte(body)}
err := p.save()
if err != nil {
http.Error(
c
, err.String(), http.StatusInternalServerError)
http.Error(
w
, err.String(), http.StatusInternalServerError)
return
}
http.Redirect(
c
,
"
/view/
"
+title, http.StatusFound)
http.Redirect(
w, r
,
"
/view/
"
+title, http.StatusFound)
}
</pre>
...
...
@@ -725,10 +725,10 @@ the <code>Execute</code> method on the appropriate <code>Template</code> from
<code>
templates
</code>
:
<pre>
func renderTemplate(
c *http.Conn
, tmpl string, p *page) {
err := templates[tmpl].Execute(p,
c
)
func renderTemplate(
w http.ResponseWriter
, tmpl string, p *page) {
err := templates[tmpl].Execute(p,
w
)
if err != nil {
http.Error(
c
, err.String(), http.StatusInternalServerError)
http.Error(
w
, err.String(), http.StatusInternalServerError)
}
}
</pre>
...
...
@@ -765,10 +765,10 @@ URL, and tests it against our <code>titleValidator</code> expression:
</p>
<pre>
func getTitle(
c *http.Conn
, r *http.Request) (title string, err os.Error) {
func getTitle(
w http.ResponseWriter
, r *http.Request) (title string, err os.Error) {
title = r.URL.Path[lenPath:]
if !titleValidator.MatchString(title) {
http.NotFound(
c
, r)
http.NotFound(
w
, r)
err = os.NewError(
"
Invalid Page Title
"
)
}
return
...
...
@@ -787,21 +787,21 @@ Let's put a call to <code>getTitle</code> in each of the handlers:
</p>
<pre>
func viewHandler(
c *http.Conn
, r *http.Request) {
title, err := getTitle(
c
, r)
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(
c
,
"
/edit/
"
+title, http.StatusFound)
http.Redirect(
w, r
,
"
/edit/
"
+title, http.StatusFound)
return
}
renderTemplate(
c
,
"
view
"
, p)
renderTemplate(
w
,
"
view
"
, p)
}
func editHandler(
c *http.Conn
, r *http.Request) {
title, err := getTitle(
c
, r)
func editHandler(
w http.ResponseWriter
, r *http.Request) {
title, err := getTitle(
w
, r)
if err != nil {
return
}
...
...
@@ -809,11 +809,11 @@ func editHandler(c *http.Conn, r *http.Request) {
if err != nil {
p =
&
page{title: title}
}
renderTemplate(
c
,
"
edit
"
, p)
renderTemplate(
w
,
"
edit
"
, p)
}
func saveHandler(
c *http.Conn
, r *http.Request) {
title, err := getTitle(
c
, r)
func saveHandler(
w http.ResponseWriter
, r *http.Request) {
title, err := getTitle(
w
, r)
if err != nil {
return
}
...
...
@@ -821,10 +821,10 @@ func saveHandler(c *http.Conn, r *http.Request) {
p :=
&
page{title: title, body: []byte(body)}
err = p.save()
if err != nil {
http.Error(
c
, err.String(), http.StatusInternalServerError)
http.Error(
w
, err.String(), http.StatusInternalServerError)
return
}
http.Redirect(
c
,
"
/view/
"
+title, http.StatusFound)
http.Redirect(
w, r
,
"
/view/
"
+title, http.StatusFound)
}
</pre>
...
...
@@ -845,9 +845,9 @@ a title string:
</p>
<pre>
func viewHandler(
c *http.Conn
, r *http.Request, title string)
func editHandler(
c *http.Conn
, r *http.Request, title string)
func saveHandler(
c *http.Conn
, r *http.Request, title string)
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>
...
...
@@ -857,8 +857,8 @@ type</i>, and returns a function of type <code>http.HandlerFunc</code>
</p>
<pre>
func makeHandler(fn func (
*http.Conn
, *http.Request, string)) http.HandlerFunc {
return func(
c *http.Conn
, r *http.Request) {
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'
}
...
...
@@ -878,28 +878,28 @@ Now we can take the code from <code>getTitle</code> and use it here
</p>
<pre>
func makeHandler(fn func(
*http.Conn
, *http.Request, string)) http.HandlerFunc {
return func(
c *http.Conn
, r *http.Request) {
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(
c
, r)
http.NotFound(
w
, r)
return
}
fn(
c
, r, title)
fn(
w
, r, title)
}
}
</pre>
<p>
The closure returned by
<code>
makeHandler
</code>
is a function that takes
an
<code>
http.
Conn
</code>
and
<code>
http.Request
</code>
(in other words,
an
<code>
http.HandlerFunc
</code>
).
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>
Conn
</code>
using the
<code>
http.NotFound
</code>
function.
<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>
Conn
</code>
,
<code>
fn
</code>
will be called with the
<code>
ResponseWriter
</code>
,
<code>
Request
</code>
, and
<code>
title
</code>
as arguments.
</p>
...
...
@@ -924,32 +924,32 @@ making them much simpler:
</p>
<pre>
func viewHandler(
c *http.Conn
, r *http.Request, title string) {
func viewHandler(
w http.ResponseWriter
, r *http.Request, title string) {
p, err := loadPage(title)
if err != nil {
http.Redirect(
c
,
"
/edit/
"
+title, http.StatusFound)
http.Redirect(
w, r
,
"
/edit/
"
+title, http.StatusFound)
return
}
renderTemplate(
c
,
"
view
"
, p)
renderTemplate(
w
,
"
view
"
, p)
}
func editHandler(
c *http.Conn
, r *http.Request, title string) {
func editHandler(
w http.ResponseWriter
, r *http.Request, title string) {
p, err := loadPage(title)
if err != nil {
p =
&
page{title: title}
}
renderTemplate(
c
,
"
edit
"
, p)
renderTemplate(
w
,
"
edit
"
, p)
}
func saveHandler(
c *http.Conn
, r *http.Request, title string) {
func saveHandler(
w http.ResponseWriter
, r *http.Request, title string) {
body := r.FormValue(
"
body
"
)
p :=
&
page{title: title, body: []byte(body)}
err := p.save()
if err != nil {
http.Error(
c
, err.String(), http.StatusInternalServerError)
http.Error(
w
, err.String(), http.StatusInternalServerError)
return
}
http.Redirect(
c
,
"
/view/
"
+title, http.StatusFound)
http.Redirect(
w, r
,
"
/view/
"
+title, http.StatusFound)
}
</pre>
...
...
doc/codelab/wiki/notemplate.go
View file @
a2332a32
...
...
@@ -28,19 +28,19 @@ func loadPage(title string) (*page, os.Error) {
const
lenPath
=
len
(
"/view/"
)
func
viewHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
viewHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
_
:=
loadPage
(
title
)
fmt
.
Fprintf
(
c
,
"<h1>%s</h1><div>%s</div>"
,
p
.
title
,
p
.
body
)
fmt
.
Fprintf
(
w
,
"<h1>%s</h1><div>%s</div>"
,
p
.
title
,
p
.
body
)
}
func
editHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
editHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
err
:=
loadPage
(
title
)
if
err
!=
nil
{
p
=
&
page
{
title
:
title
}
}
fmt
.
Fprintf
(
c
,
"<h1>Editing %s</h1>"
+
fmt
.
Fprintf
(
w
,
"<h1>Editing %s</h1>"
+
"<form action=
\"
/save/%s
\"
method=
\"
POST
\"
>"
+
"<textarea name=
\"
body
\"
>%s</textarea><br>"
+
"<input type=
\"
submit
\"
value=
\"
Save
\"
>"
+
...
...
doc/codelab/wiki/part2.go
View file @
a2332a32
...
...
@@ -28,10 +28,10 @@ func loadPage(title string) (*page, os.Error) {
const
lenPath
=
len
(
"/view/"
)
func
viewHandler
(
c
*
http
.
Conn
,
r
*
http
.
Request
)
{
func
viewHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
_
:=
loadPage
(
title
)
fmt
.
Fprintf
(
c
,
"<h1>%s</h1><div>%s</div>"
,
p
.
title
,
p
.
body
)
fmt
.
Fprintf
(
w
,
"<h1>%s</h1><div>%s</div>"
,
p
.
title
,
p
.
body
)
}
func
main
()
{
...
...
doc/codelab/wiki/wiki.html
View file @
a2332a32
...
...
@@ -230,12 +230,12 @@ This function will block until the program is terminated.
<p>
The function
<code>
handler
</code>
is of the type
<code>
http.HandlerFunc
</code>
.
It takes an
<code>
http.
Conn
</code>
and
<code>
http.Request
</code>
as its
arguments.
It takes an
<code>
http.
ResponseWriter
</code>
and an
<code>
http.Request
</code>
as
its
arguments.
</p>
<p>
An
<code>
http.
Conn
</code>
is the server end of an HTTP connection
; by writing
An
<code>
http.
ResponseWriter
</code>
value assembles the HTTP server's response
; by writing
to it, we send data to the HTTP client.
</p>
...
...
@@ -293,7 +293,7 @@ begin with <code>"/view/"</code>, which is not part of the page title.
<p>
The function then loads the page data, formats the page with a string of simple
HTML, and writes it to
<code>
c
</code>
, the
<code>
http.Conn
</code>
.
HTML, and writes it to
<code>
w
</code>
, the
<code>
http.ResponseWriter
</code>
.
</p>
<p>
...
...
@@ -415,7 +415,7 @@ The function <code>template.ParseFile</code> will read the contents of
The method
<code>
t.Execute
</code>
replaces all occurrences of
<code>
{title}
</code>
and
<code>
{body}
</code>
with the values of
<code>
p.title
</code>
and
<code>
p.body
</code>
, and writes the resultant
HTML to the
<code>
http.
Conn
</code>
.
HTML to the
<code>
http.
ResponseWriter
</code>
.
</p>
<p>
...
...
@@ -667,9 +667,9 @@ a title string:
</p>
<pre>
func viewHandler(
c *http.Conn
, r *http.Request, title string)
func editHandler(
c *http.Conn
, r *http.Request, title string)
func saveHandler(
c *http.Conn
, r *http.Request, title string)
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>
...
...
@@ -679,8 +679,8 @@ type</i>, and returns a function of type <code>http.HandlerFunc</code>
</p>
<pre>
func makeHandler(fn func (
*http.Conn
, *http.Request, string)) http.HandlerFunc {
return func(
c *http.Conn
, r *http.Request) {
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'
}
...
...
@@ -705,14 +705,14 @@ Now we can take the code from <code>getTitle</code> and use it here
<p>
The closure returned by
<code>
makeHandler
</code>
is a function that takes
an
<code>
http.
Conn
</code>
and
<code>
http.Request
</code>
(in other words,
an
<code>
http.HandlerFunc
</code>
).
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>
Conn
</code>
using the
<code>
http.NotFound
</code>
function.
<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>
Conn
</code>
,
<code>
fn
</code>
will be called with the
<code>
ResponseWriter
</code>
,
<code>
Request
</code>
, and
<code>
title
</code>
as arguments.
</p>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment