рдирдорд╕реНрддреЗ!
рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рдореИрдВ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рддрд╛ рд╣реВрдВ рдЬреЛ рдХрд╛рдЙрдмреЙрдп рд╡реЗрдм рд╕рд░реНрд╡рд░ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдЕрдиреБрднрд╡ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреЗрд╡рд▓ рдЪрд░рд╡рд╛рд╣рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реБрди-рд╕реБрдирдХрд░ рд╕реНрд╡рд╛рдЧрдд рдХрд░рддреЗ рд╣реИрдВ!
рд╣рдо рдХреНрдпрд╛ рдХрд░реЗрдВрдЧреЗ:
- рд╕рд░реНрд╡рд░ рдХреА рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╕реНрдерд╛рдкрдирд╛ рдФрд░ рд╢реБрд░реБрдЖрдд
- рд░реВрдЯрд┐рдВрдЧ, рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рд░рдЦрд░рдЦрд╛рд╡ рдХрд╛ рдЕрд╡рд▓реЛрдХрди
- ErlyDTL рдХреЗ рд╕рд╛рде рдкреИрдЯрд░реНрдирд┐рдВрдЧ (Erlang рдХреЗ рд▓рд┐рдП Django рдЯреЗрдореНрдкрд▓реЗрдЯ рднрд╛рд╖рд╛)
рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ rebar рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╕реНрдерд╛рдкрдирд╛:
> git clone git://github.com/basho/rebar.git && cd rebar && ./bootstrap
рдЕрдм rebar рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рд╣рдорд╛рд░реА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреА рд╣реИ - $ PATH рдореЗрдВ рдХрд╣реАрдВ рдЗрд╕реЗ рдХреЙрдкреА (рдпрд╛ рдмреЗрд╣рддрд░ рд▓рд┐рдВрдХ)ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
> sudo ln -s `pwd`/rebar /usr/bin/rebar
рдФрд░ рдпрд╣рд╛рдБ рд╣рдо рдЪрд▓реЗ!
рд╕рд░реНрд╡рд░ рдХреА рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╕реНрдерд╛рдкрдирд╛ рдФрд░ рд╢реБрд░реБрдЖрдд
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдорд╛рд░реЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдФрд░ рдХрдВрдХрд╛рд▓ рдмрдирд╛рдПрдВ, rebar рдЗрд╕рд╕реЗ рд╣рдореЗрдВ рдорджрдж рдорд┐рд▓реЗрдЧреАред рд╣рдо рдХрд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВрдЧреЗ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВрдЧреЗ:
> mkdir webserver && cd webserver && rebar create-app appid=webserver
rebar create-app appid=webserver
рдПрдХ рд╕рд╛рдзрд╛рд░рдг
rebar create-app appid=webserver
рдХрд╛ рдХрдВрдХрд╛рд▓ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдм рд╣рдорд╛рд░реА рд╡реЗрдмрд╕рд░реНрд╡рд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЗрд╕ рддрд░рд╣
rebar create-app appid=webserver
рдЪрд╛рд╣рд┐рдП:

рдЕрдЧрд▓реА рдЪреАрдЬ рдЬреЛ рд╣рдо рдХрд░реЗрдВрдЧреЗ, рд╡рд╣ рдХрд╛рдЙрдмреЙрдп, рд╕рд┐рдВрдХ, рдорд╛рдЗрдореЗрдЯрд┐рдкреНрд╕ рдФрд░ рдПрд░реНрд▓реАрдбрд▓ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рд╣реИред рдХрд╛рдЙрдмреЙрдп рд╣рдорд╛рд░рд╛ рд╡реЗрдм рд╕рд░реНрд╡рд░ рд╣реИ, рд╕рд┐рдВрдХ рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдФрд░ рдЕрдкрдбреЗрдЯ рдХреЗ рджреМрд░рд╛рди рдЦреБрдж рдХреЛ рдмрджрд▓реЗ рд╣реБрдП рдореЙрдбреНрдпреВрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЬреЛрдбрд╝ рджреЗрдЧрд╛, Mimetypes рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди mimetype рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ (рдЙрдкрдпреЛрдЧреА рдЬрдм рд╣рдо рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ), рдФрд░ Erlydtl - рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрдиред Rebar.config рдирд╛рдордХ rebar рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ:
Rebar.config рд╕рд╛рдордЧреНрд░реА {deps, [ {cowboy, ".*", {git, "https://github.com/extend/cowboy.git", {branch, "master"}}}, {sync, ".*", {git, "git://github.com/rustyio/sync.git", {branch, "master"}}}, {mimetypes, ".*", {git, "git://github.com/spawngrid/mimetypes.git", {branch, "master"}}}, {erlydtl, ".*", {git, "git://github.com/evanmiller/erlydtl.git", {branch, "master"}}} ]}.
рдЪрд▓рд┐рдП src / webserver.erl рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдЕрднреА рдЕрдкрдирд╛ рд╕рд░реНрд╡рд░ рд╢реБрд░реВ рдФрд░ рдмрдВрдж рдХрд░реЗрдВрдЧреЗ:
Src / webserver.erl рд╕рд╛рдордЧреНрд░реА рдЕрдм, рд╡реЗрдмрд╕рд░реНрд╡рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛: рд╕реНрдЯрд╛рд░реНрдЯ () рдХреНрд░рд┐рдкреНрдЯреЛ, рд░реИрдВрдЪ, рдХрд╛рдЙрдмреЙрдп, рд╡реЗрдмрд╕рд░реНрд╡рд░ рдФрд░ рдСрдЯреЛ-рдЕрдкрдбреЗрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдмрджрд▓реЗ рдореЗрдВ рд╕рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░реЗрдЧрд╛, рдФрд░ рд╡реЗрдмрд╕рд░реНрд╡рд░: рд╕реНрдЯреЙрдк рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВ рдЪрд▓рдиреЗ рд╡рд╛рд▓реА рд╣рд░ рдЪреАрдЬ рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛ред
рдЭрд░рдирд╛ рддреИрдпрд╛рд░ рд╣реИ, рдпрд╣ рдХрд╛рдЙрдмреЙрдп рдкрд░ рдЬрд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред Webserver_app.erl рдЦреЛрд▓реЗрдВ рдФрд░ рдкреНрд░рд╛рд░рдВрдн / 2 рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
рдХрд╛рдордХрд╛рдЬ webserver_app: рдкреНрд░рд╛рд░рдВрдн / 2 start(_StartType, _StartArgs) -> Dispatch = cowboy_router:compile([ {'_', [ {"/", index_handler, []}, {'_', notfound_handler, []} ]} ]), Port = 8008, {ok, _} = cowboy:start_http(http_listener, 100, [{port, Port}], [{env, [{dispatch, Dispatch}]}] ), webserver_sup:start_link().
рдкреНрд░реЗрд╖рдг рдирд┐рдпрдореЛрдВ рдореЗрдВ, рд╣рдордиреЗ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдХрд┐ рд╣рдо "/" рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдХрд┐ notfound_handler (рд╣рдо 404 рддреНрд░реБрдЯрд┐рдпрд╛рдВ рджреЗрдВрдЧреЗ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд░реНрд╡рд░ рдкрд░ рдЖрдПрдВрдЧреЗ, рдФрд░ рд╣рдо index_handler рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "/" рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВрдЧреЗред рддреЛ рдпрд╣ рдЙрдиреНрд╣реЗрдВ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ:
Src / index_handler.erl рд╕рд╛рдордЧреНрд░реА -module(index_handler). -behaviour(cowboy_http_handler).
Src / notfound_handler.erl рд╕рд╛рдордЧреНрд░реА -module(notfound_handler). -behaviour(cowboy_http_handler).
рдпрд╣ рд╕рдм рд╣реИ - рд╣рдордиреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╡реЗрдм рд╕рд░реНрд╡рд░ рдмрдирд╛рдпрд╛ рд╣реИ рдЬреЛ
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ: 8008 рдФрд░
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ : 8008 / рд╡реНрд╣рд╛рдЯрдПрд╡рд░ред рдЕрдм рдпрд╣ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдФрд░ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ:
> rebar get-deps > rebar compile > erl -pa ebin deps/*/ebin -s webserver
rebar get-deps
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реЗ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдЦреАрдВрдЪрддрд╛ рд╣реИ,
rebar compile
рдХреЛрдб рдХреЛ
rebar compile
erl -pa ebin deps/*/ebin -s webserver
, рдФрд░
erl -pa ebin deps/*/ebin -s webserver
рд╕реНрд╡рдпрдВ рд╕рд░реНрд╡рд░ рдХреЛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред рд╡реИрд╕реЗ, рдЙрдкрд░реЛрдХреНрдд рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдореЗрдХрдлрд╛рдЗрд▓ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ:
рдореЗрдХрдлрд╛рдЗрд▓ рд╕рд╛рдордЧреНрд░реА REBAR = `рдЬреЛ rebar` рд╣реИ
рд╕рднреА: deps рд╕рдВрдХрд▓рди
deps:
@ ($ (REBAR) get-deps)
рд╕рдВрдХрд▓рди: рд╕реНрд╡рдЪреНрдЫ
@ ($ (REBAR) рд╕рдВрдХрд▓рди)
рд╕рд╛рдл:
@ ($ (REBAR) рд╕реНрд╡рдЪреНрдЫ)
рдЪрд▓рд╛рдПрдБ:
@ (erl -pa ebin deps / * / ebin -s webserver)
.PHONY: рд╕рднреА рдбрд┐рдкреНрд╕ рд╕реНрд╡рдЪреНрдЫ рд░рди рд╕рдВрдХрд▓рди рдХрд░рддреЗ рд╣реИрдВ
рдЕрдм рдЖрдк рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ
make run
рдХреЙрд▓ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░
make run
рд╕рд░реНрд╡рд░ рд╢реБрд░реВ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдкрд╣рд▓реЗ
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ : 8008, рдФрд░ рдлрд┐рд░
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ: 8008 / рдЬреЛ рднреА рд╣реЛ рдФрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╕рд░реНрд╡рд░ рдЕрдкреЗрдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдкрд╣рд▓рд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдкрд░ "рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ" рдФрд░ рджреВрд╕рд░рд╛ "404 рдкреГрд╖реНрда рдирд╣реАрдВ рдорд┐рд▓рд╛"ред
рд░реВрдЯрд┐рдВрдЧ, рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рд░рдЦрд░рдЦрд╛рд╡ рдХрд╛ рдЕрд╡рд▓реЛрдХрди
рдХрд╛рдЙрдмреЙрдп рдореЗрдВ рд░реВрдЯрд┐рдВрдЧ рдпрд╣ рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдмрд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд╛рдлреА рд╕рд╣рди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ - рдореБрдЦреНрдп рдорд╛рдкрджрдВрдбреЛрдВ рдЬреИрд╕реЗ URL рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рдФрд░ рдЗрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдирд╛ рдЙрдкрд▓рдмреНрдз рд╣реИрдВред рдЕрдм рддрдХ, рдкреНрд░реЗрд╖рдг рдирд┐рдпрдореЛрдВ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЗрд╡рд▓ рджреЛ рдорд╛рд░реНрдЧ рд╣реИрдВ:
{"/", index_handler, []}, {'_', notfound_handler, []}
рдЬреЛ рджреВрд╕рд░реЗ рдХреЗ рдЕрдВрджрд░ рд╕реНрдерд┐рдд рд╣реИ, рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХрд┐ рд╣рдо рдХрд┐рд╕ рдореЗрдЬрдмрд╛рди рдХреЗ рд▓рд┐рдП рдиреЗрд╕реНрдЯреЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдпрд╣рд╛рдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ:
github.com/extend/cowboy/blob/master/guide/rout.md рдФрд░ рдпрд╣рд╛рдВ рдореИрдВ рдХреЗрд╡рд▓ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдкрд░рдорд╛рдгреБ '_' рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдорд╛рд░реНрдЧ рдмрд┐рд▓реНрдХреБрд▓ рд╕рднреА рдкрддреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдзреЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рдПрдЧрд╛ , notfound_handler рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо рд╣реИ рдЬреЛ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдЧрд╛, рдФрд░ [] ext рдХреА рд╕реВрдЪреА рд╣реИред рдкреИрд░рд╛рдореАрдЯрд░ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░ рджрд┐рдпрд╛
рд╣рдо рдирд┐рдЬреА / css рдирд┐рдЬреА / js, рдирд┐рдЬреА / img рдЙрдкрдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдореЗрдВ рдирд┐рдЬреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╕реНрдЯреЗрдЯрд┐рдХреНрд╕ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рд╣рдо рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдорд┐рд▓рд╛рди рдХрд░реЗрдВрдЧреЗ:
/css/WHATEVER -> /priv/css/WHATEVER /js/WHATEVER -> /priv/js/WHATEVER /img/WHATEVER -> priv/img/WHATEVER
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреНрд░рдорд╢рдГ 3 рдорд╛рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ:
Dispatch = cowboy_router:compile([ {'_', [ {"/css/[...]", cowboy_static, [ {directory, {priv_dir, webserver, [<<"css">>]}}, {mimetypes, {fun mimetypes:path_to_mimes/2, default}} ]}, {"/js/[...]", cowboy_static, [ {directory, {priv_dir, webserver, [<<"js">>]}}, {mimetypes, {fun mimetypes:path_to_mimes/2, default}} ]}, {"/img/[...]", cowboy_static, [ {directory, {priv_dir, webserver, [<<"img">>]}}, {mimetypes, {fun mimetypes:path_to_mimes/2, default}} ]}, {"/", index_handler, []}, {'_', notfound_handler, []} ]} ]).
mimetypes: path_to_mimes / 2 рдлрд╝рдВрдХреНрд╢рди рдлрд╝рд╛рдЗрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рджреНрд╡рд╛рд░рд╛ рд╕рд╣реА mimetype рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред
рдпрд╣ рджреЗрдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рдкрд┐рдЫрд▓реЗ 3 рд░реВрдЯ рд▓рдЧрднрдЧ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдорд╛рдореВрд▓реА рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рджреВрд╕рд░реЗ рдХреА рдирдХрд▓ рдХрд░рддреЗ рд╣реИрдВ, рдЪрд▓реЛ рд╕реНрдереИрддрд┐рдХ рдорд╛рд░реНрдЧ рдХреА рдкреАрдврд╝реА рдХреЛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдбрд╛рд▓рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдорд╛рд░реНрдЧреЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
Static = fun(Filetype) -> {lists:append(["/", Filetype, "/[...]"]), cowboy_static, [ {directory, {priv_dir, webserver, [list_to_binary(Filetype)]}}, {mimetypes, {fun mimetypes:path_to_mimes/2, default}} ]} end, Dispatch = cowboy_router:compile([ {'_', [ Static("css"), Static("js"), Static("img"), {"/", index_handler, []}, {'_', notfound_handler, []} ]} ]).
рдЕрдм, рдирдП рдкреНрд░реЗрд╖рдг рдирд┐рдпрдореЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╕рд░реНрд╡рд░ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдпрд╛ рдЪрд░рд╡рд╛рд╣реЗ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: set_v / 3
рдкрд╣рд▓рд╛ рдПрдХ рдЕрдкреНрд░рдорд╛рдгрд┐рдХ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рд░реВрдЯрд┐рдВрдЧ рдирд┐рдпрдореЛрдВ рдореЗрдВ рд╕рднреА рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рд╕рддрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЕрдкрдиреА рд╡реЗрдмрд╕рд░реНрд╡рд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд░реВрдЯрд┐рдВрдЧ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝реЗрдВрдЧреЗ рддрд╛рдХрд┐ рд╡реЗрдмрд╕рд░реНрд╡рд░: update_rout () рдХрдВрд╕реЛрд▓ рдореЗрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдФрд░ рдЗрд╕рд▓рд┐рдП рдХрд┐ рд╡реЗрдмрд╕рд░реНрд╡рд░: update_rout / 0 рдлрд╝рдВрдХреНрд╢рди рдирдП рдорд╛рд░реНрдЧреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддрд╛ рд╣реИ, рд╣рдо рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЙрдирдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, webserver_app.erl рдлрд╝рд╛рдЗрд▓ рдирд┐рдореНрди рд░реВрдк рд▓реЗрдЧреА:
Src / webserver_app.erl рд╕рд╛рдордЧреНрд░реА -module(webserver_app). -behaviour(application).
рдЕрдм web_verver.erl рдореЙрдбреНрдпреВрд▓ рдореЗрдВ update_rout рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝реЗрдВ:
рд╡реЗрдмрд╕рд░реНрд╡рд░ рдлрд╝рдВрдХреНрд╢рди: update_routes / 0 update_routes() -> Routes = webserver_app:dispatch_rules(), cowboy:set_env(http_listener, dispatch, Routes).
рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ -export () рд╡рд┐рд╢реЗрд╖рддрд╛ рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рди рднреВрд▓реЗрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
рдХрдВрд╕реЛрд▓ рдореЗрдВ
webserver:update_routes().
рдЪрд▓рд╛рдПрдВ
webserver:update_routes().
рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрдирд╛рдПрдВ
> mkdir priv && cd priv && mkdir css js img
рдФрд░ рд╡рд╣рд╛рдВ рдХреБрдЫ рдЙрдкрдпреБрдХреНрдд рдлрд╛рдЗрд▓реЗрдВ рдбрд╛рд▓реЗрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдЖрдк рдЬрд╛рдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ,
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ рдХреЛ рджрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ: 8008 / рдкрде / рдлрд╛рдЗрд▓
ErlyDTL рдХреЗ рд╕рд╛рде рдкреИрдЯрд░реНрдирд┐рдВрдЧ (Erlang рдХреЗ рд▓рд┐рдП Django рдЯреЗрдореНрдкрд▓реЗрдЯ рднрд╛рд╖рд╛)
рдЗрд▓рдВрдЧ рдХреЗ рд▓рд┐рдП рдХреБрдЦреНрдпрд╛рдд рд╢рд┐рдХрд╛рдЧреЛ рдмреЙрд╕ рд╡реЗрдм рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд▓реЗрдЦрдХ рдЗрд╡рд╛рди рдорд┐рд▓рд░ рдиреЗ рдПрд░реНрд▓рд╛рдВрдЧ рдХреЗ рд▓рд┐рдП Django рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд▓реИрдВрдЧреНрд╡реЗрдЬ (https://docs.djangoproject.com/en/dev/topics/templates/) рдХреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ, рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рд╣реИ рдХрд┐ рдореИрдВ рдЖрдкрдХреЗ рднрд╡рд┐рд╖реНрдп рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХрд░реВрдВрдЧрд╛ - рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдХреЛрдИ рдмреЗрд╣рддрд░ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рджреЗрдЦрд╛ рд╣реИред
рдПрдХ рдирдИ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╡реЗрдмрд╕рд░реНрд╡рд░ / tpl рдмрдирд╛рдПрдБ рдФрд░ рд╡рд╣рд╛рдБ рддреАрди рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕рд╣реЗрдЬреЗрдВ:
Tpl / layout.dtl рд╕рд╛рдордЧреНрд░реА <!DOCTYPE html> <html> <head> <title>Webserver</title> </head> <body> {% block content %}{% endblock %} </body> </html>
Tpl / index.dtl рд╕рд╛рдордЧреНрд░реА {% extends "layout.dtl" %} {% block content %} <h1>Hello, {{ username | default : "stranger" }}!</h1> {% endblock %}
Tpl / 404.dtl рд╕рд╛рдордЧреНрд░реА {% extends "layout.dtl" %} {% block content %} <h1>URL <span style="color:red;">{{ url }}</span> does not exists.</h1> {% endblock %}
рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ erlydtl рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рд╕рдВрдХрд▓рди / 3 рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
ok = erlydtl:compile("tpl/layout.dtl", "layout_tpl", []), ok = erlydtl:compile("tpl/index.dtl", "index_tpl", []), ok = erlydtl:compile("tpl/404.dtl", "404_tpl", []).
рдЕрдВрддрд┐рдо рддрд░реНрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИ, рдЬрд┐рд╕реЗ рдЖрдк рдпрд╣рд╛рдВ рдФрд░ рдЕрдзрд┐рдХ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ:
github.com/evanmiller/erlydtlрдкреНрд░рддреНрдпреЗрдХ рдмрд╛рд░ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдЯреЗрдореНрдкреНрд▓реЗрдЯреЛрдВ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡реЗрдмрд╕рд░реНрд╡рд░ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдмрдирд╛рдПрдВрдЧреЗ рдЬреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛрдВрдЧреЗ:
рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп c_tpl() -> c_tpl([]). c_tpl(Opts) -> c_tpl(filelib:wildcard("tpl/*.dtl"), Opts). c_tpl([], _Opts) -> ok; c_tpl([File | Files], Opts) -> ok = erlydtl:compile(File, re:replace(filename:basename(File), ".dtl", "_tpl", [global, {return, list}]), Opts), c_tpl(Files, Opts).
рдФрд░ рдЙрдиреНрд╣реЗрдВ рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ:
c_tpl / 0 рдмрд┐рдирд╛ рд╡рд┐рдХрд▓реНрдк рдХреЗ tpl рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕реЗ рд╕рднреА рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЬреЛрдбрд╝ рджреЗрдЧрд╛, c_tpl / 1 рджрд┐рдП рдЧрдП рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рд╣реА рдХрд░реЗрдЧрд╛, рдФрд░ c_tpl / 2 рджрд┐рдП рдЧрдП рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рджрд┐рдП рдЧрдП рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЬреЛрдбрд╝ рджреЗрдЧрд╛ред рдЖрдЗрдП
webserver:c_tpl().
рдХреЛ рдЪрд▓рд╛рдХрд░ рд╕рднреА рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ
webserver:c_tpl().
Erlang рдХреЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ
webserver:c_tpl().
рд╣рдо рдЕрдкрдиреЗ rebar.config рдХреЛ рднреА рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗ рддрд╛рдХрд┐ рдЬрдм рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП рддреЛ рдпрд╣ рднреА рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ (
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж):
рдирд╡реАрдиреАрдХреГрдд rebar.config {plugins,[rebar_erlydtl_compiler]}. {deps, [ {cowboy, ".*", {git, "https://github.com/extend/cowboy.git", {branch, "master"}}}, {sync, ".*", {git, "git://github.com/rustyio/sync.git", {branch, "master"}}}, {mimetypes, ".*", {git, "git://github.com/spawngrid/mimetypes.git", {branch, "master"}}}, {erlydtl, ".*", {git, "git://github.com/evanmiller/erlydtl.git", {branch, "master"}}} ]}. {erlydtl_opts,[ {compiler_options, [debug_info]}, [ {doc_root, "tpl"}, {out_dir, "ebin"}, {source_ext, ".dtl"}, {module_ext, "_tpl"} ] ]}.
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рдЖрд╕рд╛рди рдХрд╛рдо рдирд╣реАрдВ рдерд╛ рдХрд┐ рд╡реЗ рд╕рд░рд▓ рддрд░реАрдХреЛрдВ рд╕реЗ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдкрдХрдбрд╝ рд╕рдХреЗрдВ, рдореИрдВ рдЗрд╕рдХреЗ рдХреЛрдб рдХреЛ рдереЛрдбрд╝рд╛ рдмрд╛рдж рдореЗрдВ рджреЗрдЦреВрдВрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЕрднреА рднреА рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдкреБрдирд░реНрдореВрд▓реНрдпрд╛рдВрдХрди рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИред
рдЕрдм рд╣рдо рдЕрдкрдиреЗ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╡реЗ рд╕рдВрдХрд▓рд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рд╡рд╛рдкрд╕ рджреЗрдВ, рдФрд░ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЪрд░ рднреА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ:
Src / index_handler.erl рд╕рд╛рдордЧреНрд░реА -module(index_handler). -behaviour(cowboy_http_handler).
Src / notfound_handler.erl рд╕рд╛рдордЧреНрд░реА -module(notfound_handler). -behaviour(cowboy_http_handler).
рд╡рд╣, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдм рд╣реИред рдУрдкрди
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ : 8008 /? рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо = рджреБрдирд┐рдпрд╛ рдпрд╛
рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ : 8008 / qweqweasdasd рдФрд░ рдЦреБрд╢реА рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╡реИрд╕рд╛ рд╣реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕рд╛ рд╣рдо рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВред
рдкреВрд░реНрдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛрдб рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
github.com/chvanikoff/webserverрдпрд╣ рдореЗрд░реА рдХрд╣рд╛рдиреА рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЖрдЬ рд╣рдорд╛рд░реЗ рд▓рд┐рдЦрд┐рдд рдЖрд╡реЗрджрди рдореЗрдВ рдмрд╣реБрднрд╛рд╖реА рд╕рдорд░реНрдерди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред рдкреНрд░рд╢реНрди, рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ, рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ;)