рд▓реЗрдЦ
рдЧреЛ рд╕реЗ
рдХреЛрдбрд▓реИрдм рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВ, рдЖрдк рдХреНрд░рдорд╢рдГ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди, рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдЗрдирдкреБрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП http, рдЯреЗрдореНрдкрд▓реЗрдЯ, regexp рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧреЛ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ, рдбрд╛рдпрдиреЗрдорд┐рдХ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВред

рд▓реЗрдЦ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рди рдХрд┐ рдпреВрдирд┐рдХреНрд╕ рдФрд░ рд╡реЗрдм рдХреЗ рд╢рдмреНрджреЛрдВ рд╕реЗ рдбрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рднрд╛рд╖рд╛ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рд▓реЗрдЦ рдореЗрдВ рдмрддрд╛рдИ рдЬрд╛рдПрдВрдЧреАред
рд╕реНрдерд╛рдкрдирд╛ рдЬрд╛рдУ
рдЗрд╕рд▓рд┐рдП, рдЧреЛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд▓рд┐рдирдХреНрд╕, рдлреНрд░реАрдмреАрдПрд╕рдбреА (рдУрдПрд╕ рдПрдХреНрд╕) рдХреА рдЬрд░реВрд░рдд рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐
рдорд┐рдирдЧреАрдбрдмреНрд▓реВ рд╡рд┐рдВрдбреЛрдЬ рдкрд░ рднреА
рдХрд╛рдо рдХрд░реЗрдЧрд╛ ред
рдЧреЛ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдХреБрдЫ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ (dpkg рд╡рд╛рд▓реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢ рджрд┐рдП рдЧрдП рд╣реИрдВ):
$ sudo apt-get install bison ed gawk gcc libc6-dev make # build tools
$ sudo apt-get install рдЕрдЬрдЧрд░-рд╕реЗрдЯрдкреНрдЯреВрд▓рд╕ рдЕрдЬрдЧрд░-рджреЗрд╡ рдмрд┐рд▓реНрдб-рдПрд╕реЗрдВрд╢рд┐рдпрд▓ # рдмрд┐рд▓реНрдб рдФрд░ рдЗрдВрд╕реНрдЯреЙрд▓ рдЯреВрд▓реНрд╕
$ sudo easy_install mercurial # рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрднреА рддрдХ рдПрдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА (apt рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ) рд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдирд╣реАрдВ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ
$ hg рдХреНрд▓реЛрди -r рд░рд┐рд▓реАрдЬрд╝ https://go.googlecode.com/hg/ рдЬрд╛рдирд╛
$ cd go / src
$ ./all.bash
рдпрджрд┐ рд╕рдм рдареАрдХ рд╣реИ, рддреЛ рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ
~ / .bashrc рдпрд╛
~ / .profile :
GOROOT = $ HOME / go рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ
OS рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ GOARCH = 386 # рдпрд╛ amd64 рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ
GOOS = linux рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ
рдирд┐рд░реНрдпрд╛рдд GOBIN = $ GOROOT / рдмрд┐рди
рдкрде = $ рдкрд╛рде: $ рдЧреЛрдмрд┐рди
рдЬрдм рдЖрдк рд╢реЗрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ (i386 рдХреЗ рд▓рд┐рдП
8g рдпрд╛ amd64 рдХреЗ рд▓рд┐рдП
6g рдкрд░ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ
8g рд╣реЛрдЧрд╛) рд╣рдореЗрдВ рдПрдХ рдорджрдж рд╕рдВрджреЗрд╢ рдорд┐рд▓рддрд╛ рд╣реИ:
gc: рдЙрдкрдпреЛрдЧ 8g [рдЭрдВрдбреЗ] file.go ...
рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЧреЛ рд╕реНрдерд╛рдкрд┐рдд рд╣реИ рдФрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЖрдк рд╕реАрдзреЗ рдЖрд╡реЗрджрди рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рд╛рд░рдВрднред рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдВ
рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрдирд╛рдПрдБ:
$ mkdir ~ / рдЧреМрдХреА
$ cd ~ / рдЧреМрд┐рдХреА
рдЪрд▓реЛ
рдПрдХ рдкрд╛рда рд╕рдВрдкрд╛рджрдХ (
рд╡рд┐рдо рдФрд░ emacs рдХреЗ рд▓рд┐рдП рдмрд╛рдБрдзрдиреЗ )
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рдордЧреНрд░рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ
wiki.go рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ:
рдкреИрдХреЗрдЬ рдореБрдЦреНрдп
рдЖрдпрд╛рдд (
"FMT"
"рдЖрдИрдУ / рдЖрдИрдпреВрдЯрд┐рд▓"
"рдУрдПрд╕"
)
рдирд╛рдо рд╕реЗ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рдЖрд╡реЗрджрди рд╣рдореЗрдВ рдкреГрд╖реНрдареЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рд╣реЗрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред
рдпрд╣ рдХреЛрдб рдЧреЛ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реЗ
fmt, ioutil рдФрд░
os рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЖрдпрд╛рдд рдХрд░рддрд╛ рд╣реИред рдмрд╛рдж рдореЗрдВ рд╣рдо рдХреБрдЫ рдЕрдиреНрдп рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЬреЛрдбрд╝реЗрдВрдЧреЗред
рдХрдИ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред рдПрдХ рд╡рд┐рдХреА рдПрдХ рд╢рд░реАрд░ рдФрд░ рдПрдХ рд╢реАрд░реНрд╖рдХ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реЗ рдкреГрд╖реНрдареЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИред рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рджреЛ рдлрд╝реАрд▓реНрдб рд╣реЛрдВрдЧреЗ:
рдкреГрд╖реНрда рд╕рдВрд░рдЪрдирд╛ рдЯрд╛рдЗрдк рдХрд░реЗрдВ {
рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ
рд╢рд░реАрд░ [] рдмрд╛рдЗрдЯ
}
[] рдмрд╛рдЗрдЯ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░
рдмрд╛рдЗрдЯ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд╣реИ, рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд╕рд░рдгреА рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧ (рдЕрдзрд┐рдХ:
рдкреНрд░рднрд╛рд╡реА рдЧреЛ )ред рд▓реЗрдЦ рдХрд╛ рдореБрдЦреНрдп рднрд╛рдЧ
[] рдмрд╛рдЗрдЯ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛
рдЬрд╛рддрд╛ рд╣реИ , рдФрд░ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП
рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдирд╣реАрдВред
рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╡рд░реНрдгрди рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рдХреИрд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЖрдкрдХреЛ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдбреЗрдЯрд╛ рдмрдЪрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдбрд┐рд╕реНрдХ рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо
рд╕рд╣реЗрдЬрдиреЗ рдХреА рд╡рд┐рдзрд┐ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:
func (p * рдкреЗрдЬ) рд╕реЗрд╡ () os.Error {
рдлрд╝рд╛рдЗрд▓ рдирд╛рдо: = p.title + ".txt"
рд╡рд╛рдкрд╕реА ioutil.WriteFile (рдлрд╝рд╛рдЗрд▓ рдирд╛рдо, рдкреАред рд▓реЛ, 0600)
}
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдореЗрдВ рд▓рд┐рдЦрд╛ рд╣реИ: "рдпрд╣
рдмрдЪрдд рд╡рд┐рдзрд┐ рд╣реИ, рдЬреЛ рдкреЗрдЬ рдкреЙрдЗрдВрдЯрд░ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИ, рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд┐рдирд╛, рдкреНрд░рдХрд╛рд░ рдХрд╛ рдорд╛рди
рд▓реМрдЯрд╛рддреА рд╣реИ ред
Error ред"
рдпрд╣ рд╡рд┐рдзрд┐ рдкрд╛рда рдХреЛ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рд╣реЗрдЬреЗрдЧреАред рд╕рд░рд▓рддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рд╣реИред рдпрджрд┐ рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рддреЛ рдЖрдк
рдХреНрд░рд┐рдкреНрдЯреЛ / md5 рдЖрдпрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░
md5.New (рдлрд╝рд╛рдЗрд▓ рдирд╛рдо) рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╡рд╛рдкрд╕реА рдХрд╛ рдорд╛рди рдкреНрд░рдХрд╛рд░
os.Error рдХрд╛ рд╣реЛрдЧрд╛ , рдЬреЛ
WriteFile рдХреЙрд▓ рдХреЗ рд░рд┐рдЯрд░реНрди рдорд╛рди рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ (рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реНрд▓рд╛рдЗрд╕ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдлрд╝рдВрдХреНрд╢рди)ред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдХреА рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗред рдпрджрд┐ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ
page.save () рд╢реВрдиреНрдп рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреА (рд╕рдВрдХреЗрдд, рдЗрдВрдЯрд░рдлреЗрд╕ рдФрд░ рдХреБрдЫ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢реВрдиреНрдп рдорд╛рди)ред
рдСрдХреНрдЯреЗрд▓ рдирд┐рд░рдВрддрд░ 0600,
WriteFile рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рддреАрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░, рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓ рдХреЗрд╡рд▓ рд╡рд░реНрддрдорд╛рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╣реЗрдЬреА рдЧрдИ рд╣реИред
рдкреЗрдЬ рд▓реЛрдб рдХрд░рдирд╛ рднреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛:
func loadPage (рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ) * рдкреГрд╖реНрда {
рдлрд╝рд╛рдЗрд▓ рдирд╛рдо: = рд╢реАрд░реНрд╖рдХ + ".txt"
рд╢рд░реАрд░, _: = ioutil.ReadFile (рдлрд╝рд╛рдЗрд▓ рдирд╛рдо)
рд╡рд╛рдкрд╕реА рдФрд░ рдкреГрд╖реНрда {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ, рд╢рд░реАрд░: рд╢рд░реАрд░}
}
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╣реЗрдбрд░ рд╕реЗ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рдорд┐рд▓рддрд╛ рд╣реИ, рд╕рд╛рдордЧреНрд░реА рдХреЛ рдкреНрд░рдХрд╛рд░ рдкреГрд╖реНрда рдХреЗ рдПрдХ рдЪрд░ рдореЗрдВ рдкрдврд╝рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдПрдХ рд╕рдВрдХреЗрддрдХ рд▓реМрдЯрд╛рддрд╛ рд╣реИред
рдЧреЛ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрдИ рдорд╛рди рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
Io.ReadFile рдорд╛рдирдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА
рдлрд╝рдВрдХреНрд╢рди рд░рд┐рдЯрд░реНрди
[] рдмрд╛рдЗрдЯ рдФрд░
os.Error ред
рд▓реЛрдбрдкреЗрдЬ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдЕрднреА рддрдХ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реБрдИ рд╣реИрдВ: рдЕрдВрдбрд░рд╕реНрдХреЛрд░ рдХрд╛ рдЕрд░реНрде рд╣реИ "рдЗрд╕ рдореВрд▓реНрдп рдХреЛ рди рдмрдЪрд╛рдПрдВ"ред
рдпрджрд┐
ReadFile рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрд╕ рд╢реАрд░реНрд╖рдХ рдХреЗ рд╕рд╛рде рдХреЛрдИ рдкреГрд╖реНрда рдирд╣реАрдВ рд╣реИред рдпрд╣ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЧрд▓рддреА рд╣реИ; рдЗрд╕реЗ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЛ рдорд╛рди рднреА
рд▓реМрдЯрд╛рдПрдБ :
* рдкреГрд╖реНрда рдФрд░
os.Error ред
func loadPage (рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ) (* рдкреГрд╖реНрда, os.Error) {
рдлрд╝рд╛рдЗрд▓ рдирд╛рдо: = рд╢реАрд░реНрд╖рдХ + ".txt"
рдмреЙрдбреА, рдЗрд░реЗрдЯ: = ioutil.ReadFile (рдлрд╝рд╛рдЗрд▓ рдирд╛рдо)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
рдПрдирдЖрдИрдПрд▓, рдПрд░
}
рд╡рд╛рдкрд╕реА рдФрд░ рдкреГрд╖реНрда {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ, рд╢рд░реАрд░: рд╢рд░реАрд░}, рдиреАрд▓
}
рдЕрдм рдЖрдк рджреВрд╕рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдореВрд▓реНрдп рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рдпрджрд┐ рдпрд╣
рд╢реВрдиреНрдп рд╣реИ , рддреЛ рдкреГрд╖реНрда рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЕрдиреНрдпрдерд╛, рдпрд╣
os.Error рдкреНрд░рдХрд╛рд░ рдХрд╛ рдорд╛рди рд╣реЛрдЧрд╛ред
рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓реЛрдбрд┐рдВрдЧ рдФрд░ рдЕрдирд▓реЛрдбрд┐рдВрдЧ рдХреА рдПрдХ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдФрд░ рддрд░реАрдХреЗ рд╣реИрдВред рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
рджреБрд░реНрдЧрдВрдз рдореБрдЦреНрдп () {
p1: = & рдкреЗрдЬ {рд╢реАрд░реНрд╖рдХ: "рдЯреЗрд╕реНрдЯрдкреЗрдЬ", рдмреЙрдбреА: [] рдмрд╛рдЗрдЯ ("рдЯреЗрд╕реНрдЯ рдкреЗрдЬред")}
p1.save ()
P2, _: = loadPage ("рдЯреЗрд╕реНрдЯрдкреЗрдЬ")
fmt.Println (рд╕реНрдЯреНрд░рд┐рдВрдЧ (P2.body))
}
рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж,
TestPage.txt рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдорд╛рди
p1-> рдмреЙрдбреА рд╣реЛрдЧреА ред рдЙрд╕рдХреЗ рдмрд╛рдж, рдпрд╣ рдорд╛рди
P2 рдЪрд░ рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмрдирд╛рдиреЗ рдФрд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдп рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ:
$ 8g wiki.go
$ 8 рдПрд▓ рд╡рд┐рдХреА ред8
$ ./8.out
рдпрд╣ рдПрдХ рдирдореВрдирд╛ рдкреГрд╖реНрда рд╣реИред
Http рд▓рд╛рдЗрдмреНрд░реЗрд░реА
рдЧреЛ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
рдкреИрдХреЗрдЬ рдореБрдЦреНрдп
рдЖрдпрд╛рдд (
"FMT"
"Http"
)
func handler (w http.ResponseWriter, r * http.Request) {
fmt.Fprintf (w, "рд╣реИрд▓реЛ% s!", r.URL.Path [1:])
}
рджреБрд░реНрдЧрдВрдз рдореБрдЦреНрдп () {
http.andleFunc ("/", рд╣реИрдВрдбрд▓рд░)
http.ListenAndServe (": 8080", рдиреАрд▓)
}
рдореБрдЦреНрдп рдлрд╝рдВрдХреНрд╢рди
http.HandleFunc рдХреЛ рдХреЙрд▓
рдХрд░рддрд╛ рд╣реИ , рдЬреЛ
http рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд░реЛрдз (
"/" )
рд╣реИрдВрдбрд▓рд░ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
Http.ListenAndServe рдХреА рдЕрдЧрд▓реА рдХреЙрд▓ рдХреЗ
рджреНрд╡рд╛рд░рд╛ , рд╣рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдкреЛрд░реНрдЯ 8080 (
": 8080" ) рдкрд░ рд╕рднреА рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд░ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рджреВрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрднреА рддрдХ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рдХрд╛рд░реНрдпрдХреНрд░рдо рдЬрдмрд░рди рд╕рдорд╛рдкреНрддрд┐ рддрдХ рдЗрд╕ рдореЛрдб рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
рд╣реИрдВрдбрд▓рд░ рдлрд╝рдВрдХреНрд╢рди
http.andlerFunc рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реИред рдпрд╣
http.esponseWriter рдФрд░ рдПрдХ рд╕реВрдЪрдХ рдХреЛ
http.equest рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИред
Http.ResponseWriter рдкреНрд░рдХрд╛рд░ рдХрд╛ рдорд╛рди
http рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ; рд╡рд╣рд╛рдВ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдирд╛ (
Fprintf рдХреЛ рдХреЙрд▓
рдХрд░рдХреЗ ) рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреГрд╖реНрда рдХреА рд╕рд╛рдордЧреНрд░реА рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред
Http.Request рдбреЗрдЯрд╛
рд╕рдВрд░рдЪрдирд╛ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдиреБрд░реЛрдз рд╣реИред рд╕реНрдЯреНрд░рд┐рдВрдЧ
r.URL.Path рдкрде рд╣реИред рдкреНрд░рддреНрдпрдп
[1:] рдХрд╛ рдЕрд░реНрде рд╣реИ "рдкрд╣рд▓реЗ рдЪрд░рд┐рддреНрд░ рд╕реЗ рдЕрдВрдд рддрдХ
рдкрде рд╕реНрд▓рд╛рдЗрд╕ (рд╡рд┐рдХрд▓реНрдк) рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ", рдЕрд░реНрдерд╛рдд рдЕрдЧреНрд░рдгреА рд╕реНрд▓реИрд╢ рдХреЛ рд╣рдЯрд╛ рджреЗрдВред
рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд▓реЙрдиреНрдЪ рдХрд░рдХреЗ рдФрд░ URL
http: // localhost: 8080 / habrahabr рдЦреЛрд▓рдХрд░, рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рдкреГрд╖реНрда рджреЗрдЦреЗрдВрдЧреЗ:
рд╣рд╛рдп рд╣рдмреНрдмрд░!
рдкреГрд╖реНрда рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП http рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
Http рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЖрдпрд╛рдд рдХрд░реЗрдВ:
рдЖрдпрд╛рдд (
"FMT"
"Http"
"рдЖрдИрдУ / рдЖрдИрдпреВрдЯрд┐рд▓"
"рдУрдПрд╕"
)
рд▓реЗрдЦ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реИрдВрдбрд▓рд░ рдмрдирд╛рдПрдВ:
const lenPath = len ("/ view /")
func viewHandler (рдбрдмреНрд▓реНрдпреВ http.esponseWriter, рдЖрд░ * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
рдкреА, _: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
fmt.Fprintf (w, "<h1>% s </ h1> <div>% s </ div>", p.title, p.body)
}
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдлрд╝рдВрдХреНрд╢рди
r.URL.Path рд╕реЗ рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдХреЛ рджрд┐рдП рдЧрдП URL рдХреЗ рдкрде рдШрдЯрдХреЛрдВ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рд╡реИрд╢реНрд╡рд┐рдХ рдирд┐рд░рдВрддрд░
рд▓реЗрдирдкрд╛рда рдкрде рдХреА рд▓рдВрдмрд╛рдИ
"/ рджреГрд╢реНрдп /" рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд▓реЗрдЦ рдХреЗ рдкрд╛рда рдХреЛ рджреЗрдЦрдиреЗ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИред
рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди [lenPath:] рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рд╛ рдЧрдпрд╛ рд╣реИ ,
рдЕрд░реНрдерд╛рддреН , рд▓реЗрдЦ рдХрд╛ рд╢реАрд░реНрд╖рдХ, рдЙрдкрд╕рд░реНрдЧ рдХреЛ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред
рдлрд╝рдВрдХреНрд╢рди рдбреЗрдЯрд╛ рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рд╕рд░рд▓ рдПрдЪрдЯреАрдПрдордПрд▓ рдЯреИрдЧ рдХреЗ рд╕рд╛рде рдкреВрд░рдХ рдХрд░рддрд╛ рд╣реИ рдФрд░
рдбрдмреНрд▓реНрдпреВ , рдЯрд╛рдЗрдк
http.esponseWriter рдХреЗ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ
рд▓рд┐рдЦрддрд╛ рд╣реИ ред
рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП _ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░рд┐рдЯрд░реНрди рдорд╛рди рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
os.Errorред рдпрд╣ рд╕рд░рд▓рддрд╛ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрдо рддреМрд░ рдкрд░ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдиреАрдЪреЗ рдЖрдк рдкрд╛рдПрдВрдЧреЗ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рдирд╛ рд╣реИред
рдЗрд╕ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо
рдореБрдЦреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ
http рдХреЛ рдкрде
/ рджреГрд╢реНрдп рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд
рд╡реНрдпреВрд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдЖрд░рдВрдн рдХрд░рддрд╛ рд╣реИред
рджреБрд░реНрдЧрдВрдз рдореБрдЦреНрдп () {
http.andleFunc ("/ view /", viewHandler)
http.ListenAndServe (": 8080", рдиреАрд▓)
}
рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкреГрд╖реНрда рдмрдирд╛рдПрдБ (рдлрд╝рд╛рдЗрд▓
test.txt рдореЗрдВ ), рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ рдФрд░ рдкреГрд╖реНрда
рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:
$ рдЧреВрдВрдЬ "рдирдорд╕реНрддреЗ рджреБрдирд┐рдпрд╛"> test.txt
$ 8g wiki.go
$ 8 рдПрд▓ рд╡рд┐рдХреА ред8
$ ./8.out
рдЬрдмрдХрд┐ рд╣рдорд╛рд░рд╛ рд╕рд░реНрд╡рд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рд╢реАрд░реНрд╖рдХ "рдкрд░реАрдХреНрд╖рдг" рд╡рд╛рд▓рд╛ рдПрдХ рдкреГрд╖реНрда рдЬрд┐рд╕рдореЗрдВ "рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб" рд╢рдмреНрдж
http: // localhost: 8080 / view / test рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛ ред
рдкреЗрдЬ рдмрджрд▓реЗрдВ
рдкреГрд╖реНрдареЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЗ рдмрд┐рдирд╛ рдпрд╣ рдХрд┐рд╕ рддрд░рд╣ рдХрд╛ рд╡рд┐рдХреА рд╣реИ? рдЖрдЗрдП рджреЛ рдирдП рд╣реИрдВрдбрд▓рд░ рдмрдирд╛рдПрдВ:
рдПрдбрд╣реИрдВрдбрд▓рд░ рдХреЛ рдПрдбрд┐рдЯ рдлреЙрд░реНрдо рдФрд░
рд╕реЗрд╡рд╣реИрдВрдбрд▓рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рд╕реЗрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЙрдиреНрд╣реЗрдВ
рдореБрдЦреНрдп () рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
рджреБрд░реНрдЧрдВрдз рдореБрдЦреНрдп () {
http.andleFunc ("/ view /", viewHandler)
http.HandleFunc ("/ edit /", editHandler)
http.andleFunc ("/ save /", saveHandler)
http.ListenAndServe (": 8080", рдиреАрд▓)
}
EditHandler рдлрд╝рдВрдХреНрд╢рди рдкреГрд╖реНрда рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ (рдпрд╛ рдРрд╕рд╛ рдХреЛрдИ рдкреГрд╖реНрда рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдПрдХ рдЦрд╛рд▓реА рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рддрд╛ рд╣реИ), рдФрд░ рдлрд╝реЙрд░реНрдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:
func editHandler (w http.ResponseWriter, r * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
p = & рдкреГрд╖реНрда {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ}
}
fmt.Fprintf (w, "<h1> рд╕рдВрдкрд╛рджрди% s </ h1>" +
"<рдлрд╝реЙрд░реНрдо рдХрд╛рд░реНрд░рд╡рд╛рдИ = \" / рд╕рд╣реЗрдЬреЗрдВ /% s \ "рд╡рд┐рдзрд┐ = \" POST \ ">" +
"<рдкрд╛рда рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдирд╛рдо = \" рд╢рд░реАрд░ \ ">% s </ рдкрд╛рда рдХреНрд╖реЗрддреНрд░>" +
"<рдЗрдирдкреБрдЯ рдкреНрд░рдХрд╛рд░ = \" рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВ \ "рдореВрд▓реНрдп = \" рд╕рд╣реЗрдЬреЗрдВ \ ">" +
"</ рдлрд╛рд░реНрдо>",
p.title, p.title, p.body)
}
рдлрд╝рдВрдХреНрд╢рди рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдФрд░ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрджрд╕реВрд░рдд рджрд┐рдЦрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдХрд╛рд░рдг html рд╣рд╛рд░реНрдбрдХреЛрдб рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдареАрдХ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред
рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЦрд╛рдХрд╛
рдЯреЗрдореНрдкрд▓реЗрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдорд╛рдирдХ рдЧреЛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рд╣рдо рдХреЛрдб рдХреЗ рдмрд╛рд╣рд░ html рдорд╛рд░реНрдХрдЕрдк рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдорд╛рд░реНрдХрдЕрдк рдХреЛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд┐рдирд╛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХреЗред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ,
рдЯреЗрдореНрдкрд▓реЗрдЯ рдЖрдпрд╛рдд рдХрд░реЗрдВ:
рдЖрдпрд╛рдд (
"Http"
"рдЖрдИрдУ / рдЖрдИрдпреВрдЯрд┐рд▓"
"рдУрдПрд╕"
"рдЦрд╛рдХрд╛"
)
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде
edit.html рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдПрдХ рдкреНрд░рдкрддреНрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдмрдирд╛рдПрдБ:
<h1> рд╕рдВрдкрд╛рджрди {рд╢реАрд░реНрд╖рдХ} </ h1>
<рдлрд╝реЙрд░реНрдо рдХрд╛рд░реНрд░рд╡рд╛рдИ = "/ рд╕рд╣реЗрдЬреЗрдВ / {рд╢реАрд░реНрд╖рдХ}" рд╡рд┐рдзрд┐ = "POST">
<div> <text рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдирд╛рдо = "рд╢рд░реАрд░" рдкрдВрдХреНрддрд┐рдпрд╛рдБ = "20" рдмрдЫрдбрд╝реЗ = "80"> {рд╢рд░реАрд░ | html} </ рдкрд╛рда рдХреНрд╖реЗрддреНрд░> </ div>
<div> <рдЗрдирдкреБрдЯ рдкреНрд░рдХрд╛рд░ = "рд╕рдмрдорд┐рдЯ" рдореВрд▓реНрдп = "рд╕рд╣реЗрдЬреЗрдВ"> </ div>
</ рдлрд╛рд░реНрдо>
рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
editHandler рдмрджрд▓реЗрдВ:
func editHandler (w http.ResponseWriter, r * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
p = & рдкреГрд╖реНрда {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ}
}
t, _: = template.ParseFile ("edit.html", nil)
t.Execute (рдкреА, рдбрдмреНрд▓реНрдпреВ)
}
Template.ParseFile рд╡рд┐рдзрд┐
edit.html рдлрд╝рд╛рдЗрд▓ рдХреЛ
рдкрдврд╝реЗрдЧреА рдФрд░ рдЯрд╛рдЗрдк
* value.Template рдХрд╛ рдорд╛рди
рд▓реМрдЯрд╛рдПрдЧреА ред
T.Execute рдкрджреНрдзрддрд┐
p.title рдФрд░
p.body рдХреЗ рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде
{title} рдФрд░
{body} рдХреА рд╕рднреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд
рдХрд░рддреА рд╣реИ , рдФрд░ рдкрд░рд┐рдгрд╛рдореА HTML рдХреЛ http.esponseWriter рдХреЗ рдПрдХ рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддреА рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ
{body | html} рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╕рд╛рдордиреЗ рдЖрдпрд╛
рдерд╛ ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ HTML рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд░реВрдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЕрд░реНрдерд╛рддред рдмрдЪ рдЬрд╛рдПрдЧрд╛ рдФрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
> рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
& gt; ред рдпрд╣ рдлрд╝реЙрд░реНрдо рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред
рдЕрдм рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ
fmt.Sprintf рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдХреЙрд▓ рдирд╣реАрдВ рд╣реИ, рдЖрдк рдЖрдпрд╛рдд рд╕реЗ
fmt рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдо рдкреГрд╖реНрда рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЦрд╛рдХрд╛ рднреА рдмрдирд╛рддреЗ рд╣реИрдВред
<h1> {рд╢реАрд░реНрд╖рдХ} </ h1>
<p> [<a href="/edit/unningtitlele""> рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ </a>] </ p>
<div> {body} </ div>
рддрджрдиреБрд╕рд╛рд░
рд╡реНрдпреВрд╣рд▓рд░ рдмрджрд▓реЗрдВ:
func viewHandler (рдбрдмреНрд▓реНрдпреВ http.esponseWriter, рдЖрд░ * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
рдкреА, _: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
t, _: = template.ParseFile ("view.html", nil)
t.Execute (рдкреА, рдбрдмреНрд▓реНрдпреВ)
}
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреЙрд▓рд┐рдВрдЧ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдХреЛрдб рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реИред рд╣рдо рдЗрд╕ рдХреЛрдб рдХреЛ рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд▓реЗ рдЬрд╛рдХрд░ рджреЛрд╣рд░рд╛рд╡ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдПрдБрдЧреЗ:
func viewHandler (рдбрдмреНрд▓реНрдпреВ http.esponseWriter, рдЖрд░ * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
рдкреА, _: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ (рдбрдмреНрд▓реНрдпреВ, "рд╡реНрдпреВ", рдкреА)
}
func editHandler (w http.ResponseWriter, r * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
p = & рдкреГрд╖реНрда {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ}
}
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ (рдбрдмреНрд▓реНрдпреВ, "рдПрдбрд┐рдЯ", рдкреА)
}
func renderTemplate (w http.ResponseWriter, tmpl string, p * рдкреЗрдЬ) {
t, _: = template.ParseFile (tmpl + "ред html", nil)
t.Execute (рдкреА, рдбрдмреНрд▓реНрдпреВ)
}
рд╣реИрдВрдбрд▓рд░ рдЕрдм рдЫреЛрдЯреЗ рдФрд░ рд╕рд░рд▓ рд╣реЛ рдЧрдП рд╣реИрдВред
рдЧреБрдо рдкреГрд╖реНрдареЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛
рдЬрдм рдЖрдк
/ view / APageThatDoesntExist рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ? рдХрд╛рд░реНрдпрдХреНрд░рдо рдЧрд┐рд░ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рд╕рднреА рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ
рд▓реЛрдбрдкреЗрдЬ рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдП рдЧрдП рджреВрд╕рд░реЗ рдореВрд▓реНрдп рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдпрджрд┐ рдкреГрд╖реНрда рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдо рдПрдХ рдирдпрд╛ рд▓реЗрдЦ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреГрд╖реНрда рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реЗрдВрдЧреЗ:
func viewHandler (рдбрдмреНрд▓реНрдпреВ http.ResponseWriter, рдЖрд░ * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ) {
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Redirect (w, r, "/ edit /" + рд╢реАрд░реНрд╖рдХ, http.StatusFound)
рд╡рд╛рдкрд╕реА
}
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ (рдбрдмреНрд▓реНрдпреВ, "рд╡реНрдпреВ", рдкреА)
}
HTTP.Redirect рдлрд╝рдВрдХреНрд╢рди HTTP рд╕реНрдерд┐рддрд┐
HTTP.StatusFound (302) рдФрд░
рд╕реНрдерд╛рди рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдХреЛ HTTP рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
рд╕реЗрд╡рд┐рдВрдЧ рдкреЗрдЬ
SaveHandler рдлрд╝рдВрдХреНрд╢рди рдбреЗрдЯрд╛ рдХреЛ рдкреНрд░рдкрддреНрд░ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред
func saveHandler (w http.ResponseWriter, r * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
рд╢рд░реАрд░: = r.FormValue ("рд╢рд░реАрд░")
p: = & рдкреЗрдЬ {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ, рдирд┐рдХрд╛рдп: [] рдмрд╛рдЗрдЯ (рд╢рд░реАрд░)}
рдкреАред рд╕реЗрд╡реЗ ()
http.Redirect (w, r, "/ рджреГрд╢реНрдп /" + рд╢реАрд░реНрд╖рдХ, http.StatusFound)
}
рдЪрдпрдирд┐рдд рд╕реБрд░рдХреНрд╖рд╛ рдФрд░ рдирд┐рдХрд╛рдп рдХреЗ рд╕рд╛рде рдПрдХ рдирдпрд╛ рдкреГрд╖реНрда рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╕рд╣реЗрдЬреЗрдВ () рд╡рд┐рдзрд┐ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рд╣реЗрдЬрддреА рд╣реИ, рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ
/ рджреГрд╢реНрдп / рдкреГрд╖реНрда рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
FormValue рджреНрд╡рд╛рд░рд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдорд╛рди рдЯрд╛рдЗрдк
рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд╛ рд╣реИ ред рдЗрд╕реЗ рдкреГрд╖реНрда рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ
[] рдмрд╛рдЗрдЯ рд▓рд┐рдЦрдХрд░
[] рдмрд╛рдЗрдЯ (рд╢рд░реАрд░) рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдореЗрдВ рддреНрд░реБрдЯрд┐
рд╣рдо рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рд╕рд░реНрд╡рд░ рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ред
рдкрд╣рд▓реЗ,
рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдЬреЛрдбрд╝реЗрдВ
func renderTemplate (w http.ResponseWriter, tmpl string, p * рдкреЗрдЬ) {
t, рдЗрд░реЗрдЯ: = template.ParseFile (tmpl + "ред html", nil)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Error (w, рдЗрд░реЗрдЯреАред рд╕реНрдЯреНрд░рд┐рдВрдЧ (), http.StatusInternalServerError)
рд╡рд╛рдкрд╕реА
}
рддрдХ = t.Execute (p, w)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Error (w, рдЗрд░реЗрдЯреАред рд╕реНрдЯреНрд░рд┐рдВрдЧ (), http.StatusInternalServerError)
}
}
Http.Error рдлрд╝рдВрдХреНрд╢рди рдЪрдпрдирд┐рдд HTTP рд╕реНрдерд┐рддрд┐ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, "рдЖрдВрддрд░рд┐рдХ рд╕рд░реНрд╡рд░ рддреНрд░реБрдЯрд┐") рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рджреЗрддрд╛ рд╣реИред
рдЖрдЗрдП
saveHandler рдореЗрдВ рдПрдХ рд╕рдорд╛рди рд╕рдВрдкрд╛рджрди рдХрд░реЗрдВ:
func saveHandler (рдбрдмреНрд▓реНрдпреВ http.ResponseWriter, рдЖрд░ * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ) {
рд╢рд░реАрд░: = r.FormValue ("рд╢рд░реАрд░")
p: = & рдкреЗрдЬ {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ, рдирд┐рдХрд╛рдп: [] рдмрд╛рдЗрдЯ (рд╢рд░реАрд░)}
рдЧрд╝рд▓рддреА рд╕реЗ: = p.save ()
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Error (w, рдЗрд░реЗрдЯреАред рд╕реНрдЯреНрд░рд┐рдВрдЧ (), http.StatusInternalServerError)
рд╡рд╛рдкрд╕реА
}
http.Redirect (w, r, "/ рджреГрд╢реНрдп /" + рд╢реАрд░реНрд╖рдХ, http.StatusFound)
}
P.save () рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдХреЛрдИ рднреА рддреНрд░реБрдЯрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рджреА рдЬрд╛рдПрдЧреАред
рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреИрд╢рд┐рдВрдЧ
рд╣рдорд╛рд░рд╛ рдХреЛрдб рдкрд░реНрдпрд╛рдкреНрдд рдХреБрд╢рд▓ рдирд╣реАрдВ рд╣реИ:
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣рд░ рдмрд╛рд░ рдХрд┐рд╕реА рдкреГрд╖реНрда рдХреЗ рд░реЗрдВрдбрд░
рд╣реЛрдиреЗ рдкрд░
ParseFile рдХреЙрд▓
рдХрд░рддрд╛ рд╣реИред рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░
ParseFile рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рднрд╡рд┐рд╖реНрдп рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ
* рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рд╛рдкреНрдд рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕рд╣реЗрдЬрдирд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ
рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдирдХреНрд╢рд╛ рдмрдирд╛рдПрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо
* рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ, рдореИрдк рдореЗрдВ рдХреБрдВрдЬреА
рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдирд╛рдо рд╣реЛрдЧрд╛:
var рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ = make (рдирдХреНрд╢рд╛ [рд╕реНрдЯреНрд░рд┐рдВрдЧ] * рдЯреЗрдореНрдкрд▓реЗрдЯ редemplate)
рдЕрдЧрд▓рд╛, рд╣рдо рдПрдХ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдлрдВрдХреНрд╢рди рдмрдирд╛рдПрдВрдЧреЗ, рдЬрд┐рд╕реЗ рд╣рдо
рдореЗрди () рд╕реЗ рдкрд╣рд▓реЗ рдХреЙрд▓ рдХрд░реЗрдВрдЧреЗред
рдЯреЗрдореНрдкрд▓реЗрдЯ ред
MustParseFile рдлрд╝рдВрдХреНрд╢рди
ParseFile рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг рд╣реИ рдЬреЛ рддреНрд░реБрдЯрд┐ рдХреЛрдб рдирд╣реАрдВ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдпрд╣ рдкреИрдирд┐рдХ рдХрд░рддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд▓рд┐рдП рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЧрд▓рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдХреИрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред
func init () {for _, tmpl: = range [] string {"edit", "view"} {рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ [tmpl] = template.MustParseFile (tmpl + "ред html", nil)}}ред
рд▓реВрдк рдХреЗ рд▓рд┐рдП
рд░реЗрдВрдЬ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рджрд┐рдП рдЧрдП рдкреИрдЯрд░реНрди рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдмрд╛рдж,
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмрджрд▓реЗрдВ рддрд╛рдХрд┐ рд╡рд╣ рд╕рдВрдмрдВрдзрд┐рдд рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреА
рдПрдХреНрд╕рдХреНрдпреВрдЯ рд╡рд┐рдзрд┐ рдХреЛ
рдХреЙрд▓ рдХрд░реЗ :
func renderTemplate (w http.ResponseWriter, tmpl string, p * рдкреЗрдЬ) {
рдЧрд▓рдд: = рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ [tmpl]ред рдирд┐рд╖реНрдкрд╛рджрд┐рдд (рдкреА, рдбрдмреНрд▓реНрдпреВ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Error (w, рдЗрд░реЗрдЯреАред рд╕реНрдЯреНрд░рд┐рдВрдЧ (), http.StatusInternalServerError)
}
}
рдорд╛рдиреНрдпрддрд╛
рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдЧрдВрднреАрд░ рд╕реБрд░рдХреНрд╖рд╛ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВред рдПрдХ рдирд╛рдо рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдПрдХ рдордирдорд╛рдирд╛ рдорд╛рд░реНрдЧ рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЬрд╛рдБрдЪ рдЬреЛрдбрд╝реЗрдВред
Regexp рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЖрдпрд╛рдд рдХрд░реЗрдВред рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рд╡реИрд░рд┐рдПрдмрд▓ рдмрдирд╛рдПрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЕрдкрдиреЗ рдЖрд░рд╡реА рдХреЛ рдмрдЪрд╛рддреЗ рд╣реИрдВ:
var titleValidator = regexp.MustCompile ("^ [a-zA-Z0-9] [$")
Regexp.MustCompile рдлрд╝рдВрдХреНрд╢рди рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐
рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░
regexp.Regexp рджреЗрддрд╛ рд╣реИред
MustCompile ,
рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреА рддрд░рд╣ред
MustParseFile ,
Compile рд╕реЗ рдЗрд╕ рдмрд╛рдд рдореЗрдВ рднрд┐рдиреНрди рд╣реИ рдХрд┐ рдпрд╣ рддреНрд░реБрдЯрд┐ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИ, рдЬрдмрдХрд┐
Compile рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛрдб рджреЗрддрд╛ рд╣реИред
рдЕрдм, URL рд╕реЗ рд╢реАрд░реНрд╖рдХ рдирд┐рдХрд╛рд▓рдиреЗ рд╡рд╛рд▓реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЙрд╕рдХреЗ PB рд╢реАрд░реНрд╖рдХ рдХреЛ
рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ :
func getTitle (рдбрдмреНрд▓реНрдпреВ http.ResponseWriter, рдЖрд░ * http.Request) (рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ, рдЗрд░ рдУрдПрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░) {
рд╢реАрд░реНрд╖рдХ = r.URL.Path [lenPath:]
if! titleValidator.MatchString (рд╢реАрд░реНрд╖рдХ) {
http.NotFound (w, r)
рдЧрд▓рдд = os.NewError ("рдЕрдорд╛рдиреНрдп рдкреГрд╖реНрда рд╢реАрд░реНрд╖рдХ")
}
рд╡рд╛рдкрд╕реА
}
рдпрджрд┐ рд╢реАрд░реНрд╖рдХ рд╕рд╣реА рд╣реИ, рддреЛ рдЙрд╕рдХреЗ рд╕рд╛рде
рд╢реВрдиреНрдп рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрдиреНрдпрдерд╛, "404 рдирд╣реАрдВ рдорд┐рд▓рд╛" рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджреА рдЬрд╛рдПрдЧреАред
рдкреНрд░рддреНтАНрдпреЗрдХ рд╣реИрдВрдбрд▓рд░ рдХреЛ
рдЧреЗрдЯрд▓рд┐рдЯрд▓ рдХреЙрд▓ рдЬреЛрдбрд╝реЗрдВ:
func viewHandler (рдбрдмреНрд▓реНрдпреВ http.esponseWriter, рдЖрд░ * http.Request) {
рд╢реАрд░реНрд╖рдХ, рдЧрд▓рдд: = getTitle (w, r)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
рд╡рд╛рдкрд╕реА
}
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Redirect (w, r, "/ edit /" + рд╢реАрд░реНрд╖рдХ, http.StatusFound)
рд╡рд╛рдкрд╕реА
}
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ (рдбрдмреНрд▓реНрдпреВ, "рд╡реНрдпреВ", рдкреА)
}
func editHandler (w http.ResponseWriter, r * http.Request) {
рд╢реАрд░реНрд╖рдХ, рдЧрд▓рдд: = getTitle (w, r)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
рд╡рд╛рдкрд╕реА
}
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
p = & рдкреГрд╖реНрда {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ}
}
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ (рдбрдмреНрд▓реНрдпреВ, "рдПрдбрд┐рдЯ", рдкреА)
}
func saveHandler (w http.ResponseWriter, r * http.Request) {
рд╢реАрд░реНрд╖рдХ, рдЧрд▓рдд: = getTitle (w, r)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
рд╡рд╛рдкрд╕реА
}
рд╢рд░реАрд░: = r.FormValue ("рд╢рд░реАрд░")
p: = & рдкреЗрдЬ {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ, рдирд┐рдХрд╛рдп: [] рдмрд╛рдЗрдЯ (рд╢рд░реАрд░)}
рддрдХ = p.save ()
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Error (w, рдЗрд░реЗрдЯреАред рд╕реНрдЯреНрд░рд┐рдВрдЧ (), http.StatusInternalServerError)
рд╡рд╛рдкрд╕реА
}
http.Redirect (w, r, "/ рджреГрд╢реНрдп /" + рд╢реАрд░реНрд╖рдХ, http.StatusFound)
}
рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░рдХрд╛рд░ рдФрд░ рдХреНрд▓реЛрдЬрд░
рддреНрд░реБрдЯрд┐рдпреЛрдВ рдФрд░ рд░рд┐рдЯрд░реНрди рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ рдПрдХ рд╕рдорд╛рди рдпреВрдирд┐рдлрд╝реЙрд░реНрдо рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рд▓рд┐рдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдпрджрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдХреЙрд▓ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░рдХрд╛рд░ рд╣рдореЗрдВ рдЗрд╕ рдХреЗ рд╕рд╛рде рдорджрдж рдХрд░реЗрдВрдЧреЗред
рд╣рдо
рд╢реАрд░реНрд╖рдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:
func viewHandler (w http.ResponseWriter, r * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ)
func editHandler (рдбрдмреНрд▓реНрдпреВ http.esponseWriter, рдЖрд░ * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ)
func saveHandler (w http.ResponseWriter, r * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ)
рдЕрдм рд╣рдо рдПрдХ рд░реИрдкрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдКрдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓реЗрддрд╛ рд╣реИ рдФрд░
http.HandlerFunc (рдЗрд╕реЗ
http.HandleFunc рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП)
рд▓реМрдЯрд╛рддрд╛ рд╣реИ :
func makeHandler (fn func (http.ResponseWriter, * http.Request, string)) http.HandlerFunc {
рд╡рд╛рдкрд╕реА func (w http.ResponseWriter, рдЖрд░ * http.Request) {
// рдпрд╣рд╛рдБ рд╣рдо рдЕрдиреБрд░реЛрдз рд╕реЗ рдкреГрд╖реНрда рдХрд╛ рд╢реАрд░реНрд╖рдХ рдирд┐рдХрд╛рд▓реЗрдВрдЧреЗ,
// рдФрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВрдбрд▓рд░ 'fn' рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ
}
}
рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдХреНрд▓реЛрдЬрд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рдмрд╛рд╣рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЪрд░
fn , рд╣реИрдВрдбрд▓рд░)ред
рдХреЛрдб рдХреЛ
рдЧреЗрдЯрд▓рд┐рдЯрд▓ рд╕реЗ рдпрд╣рд╛рдВ рд▓реЗ рдЬрд╛рдПрдВ :
func makeHandler (fn func (http.ResponseWriter, * http.Request, string)) http.HandlerFunc {
рд╡рд╛рдкрд╕реА func (w http.ResponseWriter, рдЖрд░ * http.Request) {
рд╢реАрд░реНрд╖рдХ: = r.URL.Path [lenPath:]
if! titleValidator.MatchString (рд╢реАрд░реНрд╖рдХ) {
http.NotFound (w, r)
рд╡рд╛рдкрд╕реА
}
fn (рдбрдмреНрд▓реНрдпреВ, рдЖрд░, рд╢реАрд░реНрд╖рдХ)
}
}
рдореЗрдХрд╣реИрдВрдбрд▓рд░ рджреНрд╡рд╛рд░рд╛ рджрд┐рдпрд╛ рдЧрдпрд╛
рдХреНрд▓реЛрдЬрд░ рдПрдХ рдРрд╕рд╛ рдлрдВрдХреНрд╢рди рд╣реИ, рдЬреЛ
http.ResponseWriter рдФрд░
http.Request (рдЬреИрд╕реЗ, http.HandlerFunc рдЬреИрд╕реЗ рдлрдВрдХреНрд╢рди) рдЬреИрд╕реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓реЗрддрд╛ рд╣реИред рдпрд╣ рдХреНрд▓реЛрдЬрд░ URL рд╕реЗ рд╢реАрд░реНрд╖рдХ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ PB
рдЯрд╛рдЗрдЯрд▓рд╡реАрдбрд┐рдПрдЯрд░ рдХреЛ рдЪреЗрдХ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдЧрд▓рдд рд╣реИ, рддреЛ рдПрдХ рддреНрд░реБрдЯрд┐
ResponseWriter (
http.NotFound рдХреЙрд▓ рдХрд░реЗрдВ) рдХреЛ рднреЗрдЬреА рдЬрд╛рдПрдЧреАред рдЕрдиреНрдпрдерд╛, рдЗрд╕реА
fn рд╣реИрдВрдбрд▓рд░ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдореБрдЦреНрдп () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг рдХреЙрд▓ рдЬреЛрдбрд╝реЗрдВ:
рджреБрд░реНрдЧрдВрдз рдореБрдЦреНрдп () {
http.HandleFunc ("/ view /", makeHandler (viewHandler))
http.HandleFunc ("/ edit /", makeHandler (editHandler))
http.andleFunc ("/ save /", makeHandler (saveHandler))
http.ListenAndServe (": 8080", рдиреАрд▓)
}
рдЕрдВрдд рдореЗрдВ рд╣рдо рд╣реИрдВрдбрд▓рд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдХреЙрд▓ рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рд╡реЗ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ:
func viewHandler (рдбрдмреНрд▓реНрдпреВ http.ResponseWriter, рдЖрд░ * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ) {
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Redirect (w, r, "/ edit /" + рд╢реАрд░реНрд╖рдХ, http.StatusFound)
рд╡рд╛рдкрд╕реА
}
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ (рдбрдмреНрд▓реНрдпреВ, "рд╡реНрдпреВ", рдкреА)
}
func editHandler (рдбрдмреНрд▓реНрдпреВ http.ResponseWriter, рдЖрд░ * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ) {
рдкреА, рдЗрд░реЗрдЯ: = рд▓реЛрдбрдкреЗрдЬ (рд╢реАрд░реНрд╖рдХ)
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
p = & рдкреГрд╖реНрда {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ}
}
рд░реЗрдВрдбрд░рдЯреЗрдореНрдкрд▓реЗрдЯ (рдбрдмреНрд▓реНрдпреВ, "рдПрдбрд┐рдЯ", рдкреА)
}
func saveHandler (рдбрдмреНрд▓реНрдпреВ http.ResponseWriter, рдЖрд░ * http.Request, рд╢реАрд░реНрд╖рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ) {
рд╢рд░реАрд░: = r.FormValue ("рд╢рд░реАрд░")
p: = & рдкреЗрдЬ {рд╢реАрд░реНрд╖рдХ: рд╢реАрд░реНрд╖рдХ, рдирд┐рдХрд╛рдп: [] рдмрд╛рдЗрдЯ (рд╢рд░реАрд░)}
рдЧрд╝рд▓рддреА рд╕реЗ: = p.save ()
рдЕрдЧрд░ рдЧрд▓рдд рд╣реИ! = nil {
http.Error (w, рдЗрд░реЗрдЯреАред рд╕реНрдЯреНрд░рд┐рдВрдЧ (), http.StatusInternalServerError)
рд╡рд╛рдкрд╕реА
}
http.Redirect (w, r, "/ рджреГрд╢реНрдп /" + рд╢реАрд░реНрд╖рдХ, http.StatusFound)
}
рдЗрд╕реА рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПрд╣рдо рдХреЛрдб рдХрд╛ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдирд╛ рдЖрд╡реЗрджрди рдЪрд▓рд╛рддреЗ рд╣реИрдВ:
$ 8g wiki.go
$ 8 рдПрд▓ рд╡рд┐рдХреА ред8
$ ./8.out
Http: // localhost: 8080 / view / ANewPage рдореЗрдВ рдлреЙрд░реНрдо рдХреЗ рд╕рд╛рде рдПрдХ рдкреЗрдЬ рд╣реЛрдЧрд╛ред рдЖрдк рдкреГрд╖реНрда рдХреЛ рд╕рд╣реЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕ рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдиреЛрдЯред рдХреЛрдбрд░ рдореЗрдВ textarea рдХреЛ рддреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдерд╛ рддрд╛рдХрд┐ habraparser рдХреЛ рд╕рдВрдХреНрд░рдорд┐рдд рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред