рд╡реЗрдм рд╡рд┐рдХрд╛рд╕ рдЬрд╛рдУ

рд▓реЗрдЦ рдЧреЛ рд╕реЗ рдХреЛрдбрд▓реИрдм рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВ, рдЖрдк рдХреНрд░рдорд╢рдГ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди, рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдЗрдирдкреБрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП 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 рдХреЛ рд╕рдВрдХреНрд░рдорд┐рдд рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред

Source: https://habr.com/ru/post/In122095/


All Articles