Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
b67b72da
Commit
b67b72da
authored
Aug 18, 2011
by
Andrew Gerrand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
doc/codelab: use new template package
R=golang-dev, r CC=golang-dev
https://golang.org/cl/4897048
parent
0f801ff8
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
77 additions
and
73 deletions
+77
-73
doc/codelab/wiki/edit.html
doc/codelab/wiki/edit.html
+3
-3
doc/codelab/wiki/final-noclosure.go
doc/codelab/wiki/final-noclosure.go
+2
-2
doc/codelab/wiki/final-noerror.go
doc/codelab/wiki/final-noerror.go
+3
-3
doc/codelab/wiki/final.go
doc/codelab/wiki/final.go
+3
-2
doc/codelab/wiki/htmlify.go
doc/codelab/wiki/htmlify.go
+2
-2
doc/codelab/wiki/index.html
doc/codelab/wiki/index.html
+35
-33
doc/codelab/wiki/srcextract.go
doc/codelab/wiki/srcextract.go
+1
-1
doc/codelab/wiki/view.html
doc/codelab/wiki/view.html
+3
-3
doc/codelab/wiki/wiki.html
doc/codelab/wiki/wiki.html
+25
-24
No files found.
doc/codelab/wiki/edit.html
View file @
b67b72da
<h1>
Editing {
Title
}
</h1>
<h1>
Editing {
{.Title |html}
}
</h1>
<form
action=
"/save/{
Title
}"
method=
"POST"
>
<div><textarea
name=
"body"
rows=
"20"
cols=
"80"
>
{
Body|html
}
</textarea></div>
<form
action=
"/save/{
{.Title |html}
}"
method=
"POST"
>
<div><textarea
name=
"body"
rows=
"20"
cols=
"80"
>
{
{printf "%s" .Body |html}
}
</textarea></div>
<div><input
type=
"submit"
value=
"Save"
></div>
</form>
doc/codelab/wiki/final-noclosure.go
View file @
b67b72da
...
...
@@ -3,9 +3,9 @@ package main
import
(
"http"
"io/ioutil"
"old/template"
"os"
"regexp"
"template"
)
type
Page
struct
{
...
...
@@ -68,7 +68,7 @@ func saveHandler(w http.ResponseWriter, r *http.Request) {
}
func
renderTemplate
(
w
http
.
ResponseWriter
,
tmpl
string
,
p
*
Page
)
{
t
,
err
:=
template
.
ParseFile
(
tmpl
+
".html"
,
nil
)
t
,
err
:=
template
.
ParseFile
(
tmpl
+
".html"
)
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
String
(),
http
.
StatusInternalServerError
)
return
...
...
doc/codelab/wiki/final-noerror.go
View file @
b67b72da
...
...
@@ -3,8 +3,8 @@ package main
import
(
"http"
"io/ioutil"
"old/template"
"os"
"template"
)
type
Page
struct
{
...
...
@@ -34,14 +34,14 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
if
err
!=
nil
{
p
=
&
Page
{
Title
:
title
}
}
t
,
_
:=
template
.
ParseFile
(
"edit.html"
,
nil
)
t
,
_
:=
template
.
ParseFile
(
"edit.html"
)
t
.
Execute
(
w
,
p
)
}
func
viewHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
title
:=
r
.
URL
.
Path
[
lenPath
:
]
p
,
_
:=
loadPage
(
title
)
t
,
_
:=
template
.
ParseFile
(
"view.html"
,
nil
)
t
,
_
:=
template
.
ParseFile
(
"view.html"
)
t
.
Execute
(
w
,
p
)
}
...
...
doc/codelab/wiki/final.go
View file @
b67b72da
...
...
@@ -3,9 +3,9 @@ package main
import
(
"http"
"io/ioutil"
"old/template"
"os"
"regexp"
"template"
)
type
Page
struct
{
...
...
@@ -59,7 +59,8 @@ var templates = make(map[string]*template.Template)
func
init
()
{
for
_
,
tmpl
:=
range
[]
string
{
"edit"
,
"view"
}
{
templates
[
tmpl
]
=
template
.
MustParseFile
(
tmpl
+
".html"
,
nil
)
t
:=
template
.
Must
(
template
.
ParseFile
(
tmpl
+
".html"
))
templates
[
tmpl
]
=
t
}
}
...
...
doc/codelab/wiki/htmlify.go
View file @
b67b72da
package
main
import
(
"
old/
template"
"template"
"os"
"io/ioutil"
)
func
main
()
{
b
,
_
:=
ioutil
.
ReadAll
(
os
.
Stdin
)
template
.
HTML
Formatter
(
os
.
Stdout
,
""
,
b
)
template
.
HTML
Escape
(
os
.
Stdout
,
b
)
}
doc/codelab/wiki/index.html
View file @
b67b72da
...
...
@@ -7,7 +7,7 @@ Covered in this codelab:
<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>
old/
template
</code>
package to process HTML templates
</li>
<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>
...
...
@@ -426,27 +426,27 @@ This function will work fine, but all that hard-coded HTML is ugly.
Of course, there is a better way.
</p>
<h2>
The
<code>
old/
template
</code>
package
</h2>
<h2>
The
<code>
template
</code>
package
</h2>
<p>
The
<code>
old/
template
</code>
package is part of the Go standard library.
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>
old/
template
</code>
to keep the HTML in a separate file, allowing
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>
old/
template
</code>
to the list of imports:
First, we must add
<code>
template
</code>
to the list of imports:
</p>
<pre>
import (
"http"
"io/ioutil"
<b>
"old/template"
</b>
"os"
<b>
"template"
</b>
)
</pre>
...
...
@@ -456,10 +456,10 @@ Open a new file named <code>edit.html</code>, and add the following lines:
</p>
<pre>
<
h1
>
Editing {
Title
}
<
/h1
>
<
h1
>
Editing {
{.Title |html}
}
<
/h1
>
<
form action=
"
/save/{
Title
}
"
method=
"
POST
">
<
div
><
textarea name=
"
body
"
rows=
"
20
"
cols=
"
80
">
{
Body|html
}
<
/textarea
><
/div
>
<
form action=
"
/save/{
{.Title |html}
}
"
method=
"
POST
">
<
div
><
textarea name=
"
body
"
rows=
"
20
"
cols=
"
80
">
{
{printf
"
%s
"
.Body |html}
}
<
/textarea
><
/div
>
<
div
><
input type=
"
submit
"
value=
"
Save
"><
/div
>
<
/form
>
</pre>
...
...
@@ -476,7 +476,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
if err != nil {
p =
&
Page{Title: title}
}
t, _ := template.ParseFile(
"
edit.html
"
, nil
)
t, _ := template.ParseFile(
"
edit.html
"
)
t.Execute(w, p)
}
</pre>
...
...
@@ -487,19 +487,21 @@ The function <code>template.ParseFile</code> will read the contents of
</p>
<p>
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.ResponseWriter
</code>
.
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>
Note that we've used
<code>
{Body|html}
</code>
in the above template.
The
<code>
|html
</code>
part asks the template engine to pass the value
<code>
Body
</code>
through the
<code>
html
</code>
formatter before outputting it,
which escapes HTML characters (such as replacing
<code>
>
</code>
with
<code>
&
gt;
</code>
).
This will prevent user data from corrupting the form HTML.
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>
>
</code>
with
<code>
&
gt;
</code>
),
preventing user data from corrupting the form HTML.
</p>
<p>
...
...
@@ -513,11 +515,11 @@ While we're working with templates, let's create a template for our
</p>
<pre>
<
h1
>
{
Title
}
<
/h1
>
<
h1
>
{
{.Title |html}
}
<
/h1
>
<
p
>
[
<
a href=
"
/edit/{
Title
}
">
edit
<
/a
>
]
<
/p
>
<
p
>
[
<
a href=
"
/edit/{
{.Title |html}
}
">
edit
<
/a
>
]
<
/p
>
<
div
>
{
Body
}
<
/div
>
<
div
>
{
{printf
"
%s
"
.Body |html}
}
<
/div
>
</pre>
<p>
...
...
@@ -528,7 +530,7 @@ Modify <code>viewHandler</code> accordingly:
func viewHandler(w http.ResponseWriter, r *http.Request) {
title := r.URL.Path[lenPath:]
p, _ := loadPage(title)
t, _ := template.ParseFile(
"
view.html
"
, nil
)
t, _ := template.ParseFile(
"
view.html
"
)
t.Execute(w, p)
}
</pre>
...
...
@@ -708,16 +710,17 @@ var templates = make(map[string]*template.Template)
<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
ParseFile
</code>
is a convenience wrapper around
<code>
ParseFile
</code>
that does not return an error code; instead, it panics
if an error is encountered. A panic is appropriate here; if the templates can't
be loaded the only sensible thing to do is exit the program.
<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{
"
edit
"
,
"
view
"
} {
templates[tmpl] = template.MustParseFile(tmpl+
"
.html
"
, nil)
t := template.Must(template.ParseFile(tmpl +
"
.html
"
))
templates[tmpl] = t
}
}
</pre>
...
...
@@ -763,10 +766,9 @@ var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")
<p>
The function
<code>
regexp.MustCompile
</code>
will parse and compile the
regular expression, and return a
<code>
regexp.Regexp
</code>
.
<code>
MustCompile
</code>
, like
<code>
template.MustParseFile
</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.
<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>
...
...
doc/codelab/wiki/srcextract.go
View file @
b67b72da
...
...
@@ -8,7 +8,7 @@ import (
"go/ast"
"go/token"
"log"
"
old/
template"
"template"
"os"
)
...
...
doc/codelab/wiki/view.html
View file @
b67b72da
<h1>
{
Title
}
</h1>
<h1>
{
{.Title |html}
}
</h1>
<p>
[
<a
href=
"/edit/{
Title
}"
>
edit
</a>
]
</p>
<p>
[
<a
href=
"/edit/{
{.Title |html}
}"
>
edit
</a>
]
</p>
<div>
{
Body
}
</div>
<div>
{
{printf "%s" .Body |html}
}
</div>
doc/codelab/wiki/wiki.html
View file @
b67b72da
...
...
@@ -7,7 +7,7 @@ Covered in this codelab:
<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>
old/
template
</code>
package to process HTML templates
</li>
<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>
...
...
@@ -366,27 +366,27 @@ This function will work fine, but all that hard-coded HTML is ugly.
Of course, there is a better way.
</p>
<h2>
The
<code>
old/
template
</code>
package
</h2>
<h2>
The
<code>
template
</code>
package
</h2>
<p>
The
<code>
old/
template
</code>
package is part of the Go standard library.
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>
old/
template
</code>
to keep the HTML in a separate file, allowing
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>
old/
template
</code>
to the list of imports:
First, we must add
<code>
template
</code>
to the list of imports:
</p>
<pre>
import (
"http"
"io/ioutil"
<b>
"old/template"
</b>
"os"
<b>
"template"
</b>
)
</pre>
...
...
@@ -414,19 +414,21 @@ The function <code>template.ParseFile</code> will read the contents of
</p>
<p>
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.ResponseWriter
</code>
.
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>
Note that we've used
<code>
{Body|html}
</code>
in the above template.
The
<code>
|html
</code>
part asks the template engine to pass the value
<code>
Body
</code>
through the
<code>
html
</code>
formatter before outputting it,
which escapes HTML characters (such as replacing
<code>
>
</code>
with
<code>
&
gt;
</code>
).
This will prevent user data from corrupting the form HTML.
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>
>
</code>
with
<code>
&
gt;
</code>
),
preventing user data from corrupting the form HTML.
</p>
<p>
...
...
@@ -572,10 +574,10 @@ our <code>*Template</code> values, keyed by <code>string</code>
<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
ParseFile
</code>
is a convenience wrapper around
<code>
ParseFile
</code>
that does not return an error code; instead, it panics
if an error is encountered. A panic is appropriate here; if the templates can't
be loaded the only sensible thing to do is exit the program.
<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>
...
...
@@ -618,10 +620,9 @@ Then we can create a global variable to store our validation regexp:
<p>
The function
<code>
regexp.MustCompile
</code>
will parse and compile the
regular expression, and return a
<code>
regexp.Regexp
</code>
.
<code>
MustCompile
</code>
, like
<code>
template.MustParseFile
</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.
<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>
...
...
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