рдЖрддреНрдорд╛: Node.js MVC рдлреНрд░реЗрдорд╡рд░реНрдХ



рд╣рд╛рдп рджреЛрд╕реНрддреЛрдВ! рдЕрдм рд╕реЗ, рдореИрдВ node.js



рд▓рд┐рдП рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдПрдорд╡реАрд╕реА рдврд╛рдВрдЪрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ node.js



, рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рдЖрддреНрдорд╛ рд╣реЛрдЧрд╛ред



рдкрд╣рд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдЪрд╛рд░ рднрд╛рдЧ рд╣реЛрдВрдЧреЗ:

1. рд░реВрдкрд░реЗрдЦрд╛ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдФрд░ рдорд┐рд╢рди

2. рд╕рд░реНрд╡рд░ рд╕реЗрдЯрдЕрдк

3. рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ рдврд╛рдВрдЪрд╛ рдмрдирд╛рдирд╛

4. рдПрдХ рдЙрдиреНрдирдд рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд░рд╛рдЙрдЯрд░ рдмрдирд╛рдирд╛



рдореИрдВ рдЖрдкрдХреЛ рддреБрд░рдВрдд рдЪреЗрддрд╛рд╡рдиреА рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рд▓реЗрдЦ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкрд╛рда рдФрд░ рдХреЛрдб рдХреЗ рдмрдбрд╝реЗ рдмреНрд▓реЙрдХ рд╣реИрдВред







рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдФрд░ рдорд┐рд╢рди



рдкреНрд░реЗрд░рдгрд╛, рдордиреЛрджрд╢рд╛ рдФрд░ рд╕рдордп (рдЬреЛ рдЕрднреА рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ) рдХреЗ рд░реВрдк рдореЗрдВ рдЖрддреНрдорд╛ рдзреАрд░реЗ-рдзреАрд░реЗ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрдЧреАред рдпрджреНрдпрдкрд┐ рдЖрд▓реЛрдЪрдирд╛ рдФрд░ рд╕реБрдЭрд╛рд╡реЛрдВ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ - рдореИрдВ рдЗрд╕реЗ рдЕрдкрдиреА рджреГрд╖реНрдЯрд┐ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд░реВрдВрдЧрд╛, рдФрд░ рдпрджрд┐ рдкрд╣рд▓реЗ рд▓реЗрдЦ рдХреЛ рд╕рдореБрджрд╛рдп рджреНрд╡рд╛рд░рд╛ рдЧрд░реНрдордЬреЛрд╢реА рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рддреЛ рд▓реЗрдЦ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рддрд╛рд░реНрдХрд┐рдХ рдЕрдиреБрднрд╛рдЧ рдХрд╛ рд╡рд┐рд╡рд░рдг рджреЗрдирд╛ред



рдореБрдЦреНрдп рд▓рдХреНрд╖реНрдп рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдФрд░ рдордВрдЪ рдореЗрдВ рд░реБрдЪрд┐ рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдирд╛ рд╣реИред рдореБрдЭреЗ рдмрд╣реБрдд рдЦреБрд╢реА рд╣реЛрдЧреА рдЕрдЧрд░ рдХрд┐рд╕реА рдиреЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ рдмрдирд╛рдИ, рддреЛ рдЖрдк рдореБрдЭреЗ рдиреИрддрд┐рдХ рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рднреА рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдлрд┐рд░ рднреА, рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдЖрддреНрдорд╛ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рднрд╛рдЧ рд▓реЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдХреИрд╕реЗ рдХрдорд╛рдПрдВ (рд╡рд╛рд╕реНрддрд╡рд┐рдХ) рдХрд░реНрдо - shocksilien@gmail.com рдкрд░ рд▓рд┐рдЦреЗрдВ, рд╣рдо рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗ)ред



Github рдкрд░ рд╕рднреА рд╕реНрд░реЛрдд рдХреЛрдб github.com/theshock/spirit рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реЛрдВрдЧреЗ



рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореИрдВ рд╡рд┐рд╡рд░рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛, рдкреНрд░рд╕реНрддреБрддрд┐ рд╢реИрд▓реА рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдкрд╛рдардХ рдХрдо рд╕реЗ рдХрдо рдкреНрд░рд╢рд╛рд╕рди рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рдЬрд╛рдирддрд╛ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдиреЛрдб рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧред рдФрд░ рд╕реАрдПрдордПрдл рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╡рд┐рдЪрд╛рд░ рд╣реИред рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдкрд░, рд▓реЗрдЦ рдХреЛ рдЕрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХрд╛рдЯ рджрд┐рдП, рдХреЗрд╡рд▓ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдЫреЛрдбрд╝рдХрд░, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рд╕реНрд╡рдпрдВ рдЙрдирдХреЗ рд╕рд╛рде рдЖрдПрдВрдЧреЗред рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдПрдХ рдкреВрд░реНрдг рдФрд░ рдХрд╛рдордХрд╛рдЬреА рдЙрджрд╛рд╣рд░рдг GitHub рдкрд░ рд╣реИред



рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдо рдбреЗрдмрд┐рдпрди рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рд╣реЛрдо рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ "/ рд╣реЛрдо / рд╕реНрдкрд┐рд░рд┐рдЯ" рд╣реИред рдЬрдм рддрдХ рдЕрдиреНрдпрдерд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрдм рддрдХ рд╕рд╛рдЗрдЯ рдХреЛ soul.example.com рдкрд░ рд╣реЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛



рд╕рд░реНрд╡рд░ рд╕реЗрдЯрдЕрдк



рдиреЗрдЧрдиреЗрдХреНрд╕ рдФрд░ рдЕрдкрд╛рдЪреЗ рдиреЛрдб рдХреЗ рд╡рд┐рдкрд░реАрддред рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдиреЛрдбреНрд╕ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕рд░реНрд╡рд░ рдкрд░ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЖрд╡рд╢реНрдпрдХ рд╣реИред



рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, init



рдХреА рдорджрдж рд╕реЗ рд╣рдо рдПрдХ рдбреЗрдореЙрди рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ monit



рдХреА рдорджрдж рд╕реЗ monit



рдХрд┐ рдХреНрдпрд╛ рд╕рд░реНрд╡рд░ рдХреНрд░реИрд╢ рд╣реЛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЪрд┐рддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд╛рдирдХрд╛рд░реА Google рдореЗрдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рд╛рдЗрдЯ рдиреЛрдбрдЬреЗрд╕рд░реВ рдкрд░ ред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдиреЛрдб.рдЬреЗрдПрд╕ рдкрд░ рд▓рд┐рдВрдХ рд░рд┐рдбреНрдпреВрд╕рд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдкрд░реАрдХреНрд╖рдг рдФрд░ рдЕрдиреБрдореЛрджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдХреБрдЫ рдШрдВрдЯреЛрдВ рдореЗрдВ 15,000 рд╕реЗ рдЕрдзрд┐рдХ рд▓рд┐рдВрдХ рдХрдо рдХрд░ рджреЗрддрд╛ рд╣реИ рдФрд░ рдлрд╝реНрд▓рд┐рдк рднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдЕрднреА рднреА (рд▓рдЧрднрдЧ 20 рджрд┐рди) рдЦрдбрд╝рд╛ рд╣реИред



рджреВрд╕рд░рд╛ рдХрджрдо рдПрдХ рджреГрд╢реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдиреЗрдЧреНрдиреЗрдХреНрд╕ рд╣реИред

 server { listen 80; server_name spirit.example.com; access_log /home/spirit/example-app/logs/nginx.access.log; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8124/; } location ~* \.(html|js|ico|gif|jpg|png|css|doc|xml|rar|zip|swf|avi|mpg|flv|mpeg|wmv|ogv|oga|ogg)$ { root /home/spirit/example-app/public; } }
      
      





рд╣рдо рдмрд╣реБрдд рд╕рд░рд▓ рдХреЛрдб рджреЗрдЦрддреЗ рд╣реИрдВ - рдирдЧреАрдирдХреНрд╕ рд╣рдорд╛рд░реЗ рдиреЛрдб рдХреЗ рд▓рд┐рдП рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рдм рдХреБрдЫ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИред рдЬреЗрдПрд╕, рдЬреЛ рдкреЛрд░реНрдЯ 8124 (рдпрд╛ рдЬреЛ рднреА рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ) рдкрд░ рд╕реНрдерд┐рдд рд╣реЛрдЧрд╛ред рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдХреЛ рдиреЛрдб рдХреЗ рдХрд┐рд╕реА рднреА рднрд╛рдЧреАрджрд╛рд░реА рдХреЗ рдмрд┐рдирд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╕реАрдзреЗ рдирдЧреАрдиреЗрдХреНрд╕ рдХреЗ рд╕рд╛рдеред



рдПрдХ рдврд╛рдВрдЪрд╛ рдХрдВрдХрд╛рд▓ рдмрдирд╛рдПрдБ



рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗ:

/home/spirit/

тФЬ lib/

тФВ тФЬ mysql-libmysqlclient/

тФВ тФЬ spirit/

тФВ тФФ MooTools.js

тФЬ example-app/

тФВ тФЬ engine/

тФВ тФВ тФЬ classes/

тФВ тФВ тФФ init.js

тФВ тФЬ logs/

тФВ тФФ public/

тФФ another-example-app/

тФЬ engine/

тФВ тФЬ classes/

тФВ тФФ init.js

тФЬ logs/

тФФ public/







рдЗрд╕ рдЖрд░реЗрдЦ рдореЗрдВ рджреЛ рдкреНрд░рдореБрдЦ рд╡рд┐рдЪрд╛рд░ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

1. рд╕рднреА рдкреБрд╕реНрддрдХрд╛рд▓рдп, inclред рдФрд░ рдЖрддреНрдорд╛ рд╕реНрд╡рдпрдВ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рд╕реЗ рдЕрд▓рдЧ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛрдЧреА - рдпрд╣ рдЖрдкрдХреЛ рд╕рднреА рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рджреЛрд╣рд░рд╛рдП рдмрд┐рдирд╛ рдПрдХ рд╣реА рд╕рд░реНрд╡рд░ рдкрд░ рдХрдИ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд░рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред

2. рдкреНрд░рддреНрдпреЗрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рджреЛ рдкреНрд░рдореБрдЦ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ - рдЗрдВрдЬрди, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╕рд░реНрд╡рд░ рд▓реЙрдЬрд┐рдХ рдФрд░ рдкрдмреНрд▓рд┐рдХ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕рдХреА рд╕рднреА рд╕рд╛рдордЧреНрд░реА рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рджреЗрдВрдЧреЗред рдпрд╣ рд╕рд░реНрд╡рд░ рдХреЛрдб рдХреЛ рдмрд╛рд╣рд░ рд╕реЗ рдХрд┐рд╕реА рднреА рдЕрддрд┐рдХреНрд░рдордг рд╕реЗ рдмрдЪрд╛рдПрдЧрд╛ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рддрд░реНрдХ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░реЗрдЧрд╛ред



lib



рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╣рдо рдЙрди рд╕рднреА рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдбрдВрдк рдХрд░реЗрдВрдЧреЗ рдЬрд┐рдирдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред



рдЖрддреНрдорд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдореВрдУрдЯреЙрд▓реНрд╕ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдореИрдВрдиреЗ рдЗрд╕реЗ рд▓рд┐рдВрдХ рд╢реЙрд░реНрдЯрдирд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╖рдп рдореЗрдВ рдХреИрд╕реЗ рдЬреЛрдбрд╝рд╛ред рдХрдиреЗрдХреНрд╢рди рдореЗрдВ рдЖрд╕рд╛рдиреА рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ MooTools.More Class рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд┐рдпрд╛ред рдпрд╣ рд╕реАрдзреЗ lib/MooTools.js



рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдЬреБрдбрд╝рддрд╛ рд╣реИ , рдЬреЛ рдмрд┐рдирд╛ рд╕рдВрджрд░реНрдн рдЦреЛрдП рддрд░реНрдХ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдФрд░ htmlEscape



, ucfirst



рдФрд░ lcfirst



рдХреЛ рдЬреЛрдбрд╝рдХрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХрд╛ рдереЛрдбрд╝рд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдЧрд╛ред



рдЖрд╡реЗрджрди рдЖрд░рдВрднреАрдХрд░рдг



рдХреЛрдб рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ (рдЖрд╡рд╢реНрдпрдХ) рдирд┐рдореНрди рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдЖрддрд╛ рд╣реИ:

1. рдирд╛рдо рд╕реЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, require( 'fs' )



ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдХрд░реНрдиреЗрд▓ рдХреЛ рд╡рд╛рдпрд░реНрдб рдХрд┐рдП рдЧрдП рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВ ред

2. рд╡рд░реНрддрдорд╛рди рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдкрде рдХреЗ рдЕрдиреБрд╕рд╛рд░ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, require( './classes/foo' )



рдпрд╛ require( '../lib/mootools.js' )





3. рдкрд░рдо рдкрдеред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, require( '/home/spirit/lib/mootools' )







рджреВрд╕рд░рд╛ рдФрд░ рддреАрд╕рд░рд╛ рддрд░реАрдХрд╛, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд▓рд┐рдВрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрдд рдореЗрдВ .js рдХреЗ рдмрд┐рдирд╛ (рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЕрдиреНрдпрдерд╛ рдПрдХ рддреНрд░реБрдЯрд┐ рдкрдХрдбрд╝рдиреЗ рдХрд╛ рдореМрдХрд╛ рд╣реИ)ред рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдЖрдк рд╕рд╛рдкреЗрдХреНрд╖ рд░рд╛рд╕реНрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░рдЦреЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЕрд╕рдВрдЧрдд рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдкрд░реНрдпрд╛рд╡рд░рдг рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рд░реВрдЯ рд╣реЛрддрд╛ рд╣реИред

 // __dirname -  ,   //  ,      var libPath = __dirname + '/../../lib'; //  : /home/spirit/lib //            // fs.realpathSync(libPath),     //    MooTools   , //      require(libPath + '/MooTools').apply(GLOBAL); //       var spirit = require(libPath + '/spirit/spirit') .createSpirit(__dirname, libPath); //     -   //    ,   require('http').listen spirit.listen("127.0.0.1:8124");
      
      







рд╣рдо рдореБрдЦреНрдп рд╡рд░реНрдЧ рд▓рд┐рдЦрддреЗ рд╣реИрдВ



рдирд┐рд░реНрдпрд╛рдд рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рд╕рдВрднрд╡ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдЬреЛ рдХреБрдЫ рднреА рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ - рд╣рдореЗрдВ рдирд┐рд░реНрдпрд╛рдд рд╡рд╕реНрддреБ рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣реА рд╣реИ, рдЕрдЧрд░ рд╣рдо var foo = new (require( './bar' ). bar );



, bar.js



рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣рдореЗрдВ рдпрд╣ рдХрд░рдирд╛ рд╣реЛрдЧрд╛: exports . bar = new Class({ /* ... */ });



exports . bar = new Class({ /* ... */ });



ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЪрд░ рдХреЛ рдбреЙрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рд╡рд░реНрдЧ рдХреЛрд╖реНрдардХ рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рдлрд┐рд░ рд╕рдВрдкрд╛рджрдХреЛрдВ рдореЗрдВ рдЗрд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ (рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рд╕рдмрд╕реЗ рдХрдо рд╣реЛрддрд╛ рд╣реИ) рдХреЗ рд░реВрдк рдореЗрдВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕рдХреЗ рд╕рд╛рде рд╣реА рдЙрд╕ рд╡рд░реНрдЧ рдХреЗ рдирд╛рдо рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рджреВрд╕рд░реЗ, рдкрд╣рд▓реЗ рддреЛ рдореБрдЭреЗ рдпрд╣ рддрд░реАрдХрд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рдЖрдпрд╛ рдФрд░ рдореИрдВрдиреЗ рдЗрд╕реЗ рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рднреА рдкрд╛рдпрд╛ (рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЖрдкрдХреЛ рджреЛ bar



рдмрд╛рд░ рджреЛрд╣рд░рд╛рдиреЗ рдХреА require



), рд▓реЗрдХрд┐рди рдЕрдВрдд рдореЗрдВ рд╣рдо рдЗрд╕реЗ рдмрджрд▓ рджреЗрдВрдЧреЗ рддрд╛рдХрд┐ рдпрд╣ рд╣рдорд╛рд░реЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рдЦреЗрд▓реЗ - рдпрд╣ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рд╕реБрдВрджрд░ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдореБрдЦреНрдп рд╡рд░реНрдЧ рдХреЛ рдмрдирд╛рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп:

 exports['createSpirit'] = function (projectPath, libPath) { return new Spirit(projectPath, libPath); };
      
      







рдХрдХреНрд╖рд╛ рдореЗрдВ рд╣реА, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:

1. рд╕рднреА рдХрдХреНрд╖рд╛рдПрдВ app/classes



рдФрд░ lib/spirit/classes





2. рдЬрдм рдирд╛рдо рд╕реЗ рдПрдХ рд╡рд░реНрдЧ рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╣рдо рдкрд╣рд▓реЗ рдЖрд╡реЗрджрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рдлреНрд░реЗрдорд╡рд░реНрдХ (рдЬрдм рддрдХ рдХрд┐ рдЕрдиреНрдпрдерд╛ рдирд╣реАрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ)ред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЖрдк рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдпрд╣ рд╣рд┐рд╕реНрд╕рд╛ рдмрд╛рдж рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)

3. рднрд░реА рд╣реБрдИ рдХрдХреНрд╖рд╛рдПрдВ - рдХреИрд╢реНрдб рд╣реЛрддреА рд╣реИрдВ, рдЬреЛ рдПрдлрдПрд╕ рдХреЗ рд▓рд┐рдП рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкрд╣реБрдВрдЪ рд╕реЗ рдмрдЪреЗрдВрдЧреА (рдпрд╛ рдЗрд╕реЗ рдиреЛрдб.рдЬреЗрдПрд╕ рдореЗрдВ рдХреИрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ?)

4. рдХрдХреНрд╖рд╛ рдЕрдиреНрдп рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╢реБрд░реБрдЖрддреА рдмрд┐рдВрджреБ рд╣реЛрдЧреАред



рдореИрдВ рдкреЗрд╕реНрдЯрд┐рди рдкрд░ рдХреНрд▓рд╛рд╕ рдХреЛрдб рдкреЛрд╕реНрдЯ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдореИрдВ рдХреЗрд╡рд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛



pastebin.com/0b14MEbe

 var Spirit = new Class({ Binds: ['hit', 'load'], initialize : function (String projectPath, String libPath) { }, load : function (String className, Boolean fromSpirit) { //   load    , : // spirit.load('Controllers.User'); //     ,  ,    -   //  fromSpirit    //  ,    }, loadLib : function (libName) { //     , : // spirit.loadLib('mysql-libmysqlclient') //     libPath //           }, //       hit : function (req, res) { }, listen : function (port, url) { //     //  .listen(8124, '127.0.0.1')  //  .listen('127.0.0.1:8124') } }); var load = function (path, className) { // some code is here //         //    Spirit.      ? //  ! return data[className](this); };
      
      







рдЗрд╕рд▓рд┐рдП рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рдиреЗ рдХреА рдЕрдЧрд▓реА рд╢реИрд▓реА рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИред

 exports['Name.Space.ClassName'] = function (spirit) { return new Class({ method : function (msg) { this.response.writeHead(200, {'Content-Type': 'text/plain'}); this.response.end(msg); } }); };
      
      







рдпрд╣ рдЕрднреА рддрдХ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

 exports['Helper.AnotherClass'] = function (spirit) { var mysql = spirit.loadLib('mysql-libmysqlclient'); return new Class({ Extends : spirit.load('Name.Space.ClassName'), start : function (msg) { this.method('Started'); }, query : function () { // using mysql } }); };
      
      







рдФрд░ рдЖрдк Name.Space.ClassName



рдХреЛ рдХреИрд╕реЗ рд╢рд╛рдорд┐рд▓ Name.Space.ClassName



? require( '../Name/Space/ClassName' );



? рдФрд░ рдпрджрд┐ рдЖрдк рдХрдХреНрд╖рд╛ рдХреЛ рджреВрд╕рд░реА рдЬрдЧрд╣ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХреНрдпрд╛ рдЖрдк рд╕рднреА рддрд░реАрдХреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВрдЧреЗ? рдХреНрдпрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреВрд░реНрдг рдкрде рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рдХреЗ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛?

рдЖрдЗрдП рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рдПрдХ рд░рд╛рдЙрдЯрд░ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рд╣рд░ рд╣рд┐рдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ:

 exports['Router'] = function (spirit) { return new Class({ // .. hit : function (request, response) { // some code }, // .. }); };
      
      







рд╣рдо рд╣рд┐рдЯ рд▓реЙрдЧрд┐рдВрдЧ рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╣рдо рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд░рд╛рдЙрдЯрд░ рд╡рд░реНрдЧ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ:



 exports['Router'] = function (spirit) { var Logger = spirit.load('Logger'); var logger = new Logger; return new Class({ Extends : spirit.load('Router', true), hit : function (request, response) { logger.log('hit!'); this.parent(request, response); }, // .. }); };
      
      







рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд░реВрдкрд░реЗрдЦрд╛ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред



рдПрдХ рд░рд╛рдЙрдЯрд░ рдмрдирд╛рдПрдВ



рд░рд╛рдЙрдЯрд░ рдЗрд╕реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░реЗрдЧрд╛ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рд╡рд╛рдВрдЫрд┐рдд рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рджреЗрдЧрд╛ред

рд░реВрдЯрд┐рдВрдЧ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧреА:

1. рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, regexp рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдПрдХ рдореИрдЪ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝реЗ рдЧрдП рдорд╛рд░реНрдЧреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рдкрддреЗ рдХреЗ рд╕рд╛рде рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рд╡рд┐рд╢реЗрд╖ URL рджрд░реНрдЬ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░рд╛рдЙрдЯрд░ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрдВрддрд░реНрдЧрдд рдирд╣реАрдВ рдЖрддреЗ рд╣реИрдВ

2. рдпрджрд┐ рдорд╛рд░реНрдЧ рдкреИрд░рд╛ 2 рдореЗрдВ рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдкрддрд╛ рд╕реНрд▓реИрд╢ рд╕реЗ рдЯреВрдЯ рдЧрдпрд╛ рд╣реИ рдФрд░ рдирд┐рдХрдЯрддрдо рдХреЛ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рдмреАрдЪ рдЦреЛрдЬрд╛ рдЧрдпрд╛ рд╣реИред рдкрддреЗ рдкрд░ url / AA / BB / CC / DD / EE, рдирд┐рдпрдВрддреНрд░рдХ AA.BB.CC.DD.EE рдХреЛ рдкрд╣рд▓реЗ рдЦреЛрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ AA.BB.CC.DD, рдФрд░ рдЗрд╕реА рддрд░рд╣, рдЬрдм рддрдХ рдХрд┐ рд╡рд╛рдВрдЫрд┐рдд рдирд╣реАрдВ рдорд┐рд▓ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдРрд╕рд╛ рдХреЛрдИ рдирд┐рдпрдВрддреНрд░рдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕реВрдЪрдХрд╛рдВрдХ рдирд┐рдпрдВрддреНрд░рдХ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ AA.BB.CC.DD рдирд┐рдпрдВрддреНрд░рдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди AA.BB.CC.DD.Index рд╣реИ, рддреЛ рдЙрд╕рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдлрд┐рд░ рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред



рд╕рднреА рдЖрд░рдВрднрд┐рдХ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдЖрд╡реЗрджрди рдЖрд░рдВрднреАрдХрд░рдг рдХреЗ рджреМрд░рд╛рди рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЧрд▓рддрдлрд╣рдореА рд╕реЗ рдмрдЪреЗрдВрдЧреЗред



рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:

/home/spirit/example-app/

тФЬ engine/

тФВ тФЬ classes/

тФВ тФВ тФЬ controllers/

тФВ тФВ тФВ тФЬ Admin/

тФВ тФВ тФВ тФВ тФЬ Articles.js

тФВ тФВ тФВ тФВ тФФ Index.js

тФВ тФВ тФВ тФЬ Man/

тФВ тФВ тФВ тФВ тФЬ Index.js

тФВ тФВ тФВ тФВ тФФ Route.js

тФВ тФВ тФВ тФЬ Index.js

тФВ тФВ тФВ тФФ Users.js

тФВ тФВ тФФ Controller.js

тФВ тФФ init.js

тФЬ logs/

тФФ public/









рд╣рдорд╛рд░реА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрдирд┐рдЯ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ, рдЬреЛ рдореИрдиреБрдЕрд▓ рдорд╛рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред : A, D:, H,: W рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреИрдЯрд░реНрди рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВ: [az], [0-9], [0-9a-f], [0-9a-z], рдХреНрд░рдорд╢рдГред рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП <рдФрд░> рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВ рдХрд┐ рдпрд╣ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреНрд░рдорд╢рдГ рд╢реБрд░реБрдЖрдд рдФрд░ рдкрддреЗ рдХреЗ рдЕрдВрдд рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЬреИрд╕реЗ рдХрд┐ </test-:A>



url рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддреА " /test-abc123



", рдЬрдмрдХрд┐ рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ /test-:A



рдЗрд╕ url рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИред рд╕рднреА рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ argsMap рд╣реИ, рддреЛ рд╣реИрд╢ рдкреНрд░рд╕рд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, " /articles-15/page-3



" рдХреЗ рдкрддреЗ рдХреЗ рд╕рд╛рде, рдкрд╣рд▓рд╛ рддрд░реНрдХ рдПрдХ рд╕рд░рдгреА [15, 3]



, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк argsMap : ['id', 'page']



рдкрд╛рд╕ argsMap : ['id', 'page']



, рд╣реИрд╢ {id:15, page:3}



рд╡рд┐рдзрд┐ рд╕реЗ рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред {id:15, page:3}



ред

 spirit.createRouter() .addRoutes( { route : "</article-:D/page-:D" , contr : 'Man.Route:articleWithPage' , argsMap : ['id', 'page'] }, { route : "</article-:D" , contr : 'Man.Route:article' , argsMap : ['id'] }, { route : "</~:W>" , contr : 'Man.Route:user' }, { route : "</hash-:H>" , contr : 'Man.Route:hash' } );
      
      







рдФрд░ рдпрд╣рд╛рдВ рдирд┐рдпрдВрддреНрд░рдХ рд╣реИ рдЬреЛ рдЗрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рдКрдкрд░ рдЪрд┐рддреНрд░ рдореЗрдВ рдЗрд╕реЗ рдмреЛрд▓реНрдб рдореЗрдВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ):

 exports['Controllers.Man.Route'] = function (spirit) { return new Class({ Extends : spirit.load('Controller'), indexAction : function () { this.exit('(Man.Route) index action'); }, testAction : function () { this.exit('(Man.Route) test action'); }, articleWithPageAction : function (args) { this.exit('(Man.Route) article #' + args.id + ', page #' + args.page); }, articleAction : function (args) { this.exit('(Man.Route) article #' + args.id); }, hashAction : function (args) { this.exit('(Man.Route) hash: ' + args[0]); }, userAction : function (args) { this.exit('(Man.Route) user: ' + args[0]); } }); };
      
      





рдФрд░ рдЕрднрд┐рднрд╛рд╡рдХ рдирд┐рдпрдВрддреНрд░рдХ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рд╕рднреА рдмрдЪреНрдЪреЛрдВ рдХреЛ exit



рд╡рд┐рдзрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗ:

 exports['Controller'] = function (spirit) { return new Class({ exit : function (msg) { this.response.writeHead(200, {'Content-Type': 'text/plain'}); this.response.end(msg); } }); };
      
      







рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЖрддреНрдорд╛ рд╡рд░реНрдЧ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╣рдо рд░рд╛рдЙрдЯрд░ рдХреЗ рдХрдВрдзреЛрдВ рдкрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

  createRouter : function () { var Router = this.load('Router'); var router = new Router(); router.spirit = this; this.router = router; router.init(); return router; }, hit : function (req, res) { this.router.hit(req, res); },
      
      







рд░рд╛рдЙрдЯрд░ рдЦреБрдж рднреА рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдвреЗрд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЕрдкрдиреЗ рдбрд┐рдкреНрдЯреА рдХреЛ рдореБрдЦреНрдп рдХрд╛рдо рджреЗрдЧрд╛:

 exports['Router'] = function (spirit) { var RouterHelper = spirit.load('Router.Helper'); return new Class({ init : function () { var path = this.spirit.requirePath + 'Controllers'; this.routerHelper = new RouterHelper(this); this.routerHelper.requireAll(path); }, hit : function (request, response) { var contrData = this.routerHelper.route(request); var contr = contrData.contr; contr.spirit = this.spirit; contr.request = request; contr.response = response; if (typeof contr.before == 'function') contr.before(); contr[contrData.method](contrData.args); if (typeof contr.after == 'function') contr.after(); }, addRoutes : function () { var rh = this.routerHelper; rh.addRoutes.apply(rh, arguments); } }); };
      
      







рдбрд┐рдкреНрдЯреА рдХреЗ рдкрд╛рд╕ рджреЛ рдЕрдзреАрдирд╕реНрде рднреА рд╣реИрдВ - рд╡рд╣ рдЬреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝реЗ рдЧрдП рдорд╛рд░реНрдЧреЛрдВ (RouterRegexp) рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ рдФрд░ рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддрд░реАрдХреЗ рд╕реЗ рдорд╛рд░реНрдЧ (RouterPlain) рдХрд░рддрд╛ рд╣реИред рдЖрд╡рд╢реНрдпрдХрддрд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ рд╕рднреА рд╡рд┐рдзрд┐ - рдЗрд╕рдореЗрдВ рдПрдХ рд╕рдордХрд╛рд▓рд┐рдХ рд╢реИрд▓реА рдореЗрдВ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╣реЛрддреА рд╣реИ рдФрд░ рд╕рднреА рд╡рд░реНрдЧ рдЬреБрдбрд╝реЗ рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдХреЗрд╡рд▓ рддрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рдореЗрдВ рдРрд╕реА рдЪреАрдЬреЛрдВ рдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╢реИрд▓реА рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЙрдЪрд┐рдд рд╣реИ - рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдореЗрдВ рд▓рдЧрдиреЗ рд╡рд╛рд▓рд╛ рд╕рдордп рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдзреАрдорд╛ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдореБрдЭреЗ Node.js рдкрд╕рдВрдж рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреБрдЫ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╕рднреА рд╡рд┐рдзрд┐ рдирд╛рдо рд╕реНрдкрд╖реНрдЯ, рд╕реБрдВрджрд░, рд▓рдШреБ рдФрд░ рдПрдХ рд╣реА рд╢реИрд▓реА рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реИрдВред



 var fs = require('fs'); exports['Router.Helper'] = function (spirit) { var RouterPlain = spirit.load('Router.Plain'); var RouterRegexp = spirit.load('Router.Regexp'); return new Class({ initialize : function (router) { this.router = router; this.plain = new RouterPlain(this); this.regexp = new RouterRegexp(this); }, route : function (request) { var url = request.url; return this.regexp.route(url) || this.plain.route(url); }, requireAll : function (path) { var files = fs.readdirSync(path); for (var i = 0; i < files.length; i++) { var file = path + '/' + files[i]; var stat = fs.statSync(file); if (stat.isFile()) { this.addController(file); } else if (stat.isDirectory()) { this.requireAll(file); } } this.checkAllIndexActions(); }, //       regexp  addRoutes : function (routes) {}, //  ".js"       removeExt : function (file) {}, //      indexAction checkAllIndexActions : function () {}, //       addController : function (file) {}, //     false,   createController : function (name) {} }); };
      
      







рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ addRoutes



рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдирд┐рдпрдорд┐рдд рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

 exports['Router.Regexp'] = function (spirit) { return new Class({ initialize : function (routerHelper) { this.routerHelper = routerHelper; }, route : function (url) { //            for (var i = 0; i < this.routes.length; i++) { var route = this.routes[i]; //           //      lastIndex,  //        , //   route.regexp.lastIndex = 0; var result = route.regexp.exec(url); if (result) { return { contr : this.routerHelper .createController(route.contr.name), method : route.contr.method, args : this.regexpRouteArgs(result, route.argsMap) }; } } return false; }, routes : [], addRoute : function (route, controller, argsMap) { }, addRoutes : function (hash) { }, //     ,   addRoutes //         , //  ( )) -    regexpContr : function (string) { var parts = string.split(':'); var method = parts.length > 0 ? parts[1] + 'Action' : 'indexAction'; var contr = 'Controllers.' + parts[0]; // ... }, //         //      // ,        regexpRoute : function (route) { var re = new RegExp(); re.compile(this.prepareRegexp(route), 'ig'); return re; }, replaces : { A : '([az]+)', D : '([0-9]+)', H : '([0-9a-f]+)', W : '([0-9a-z]+)', }, prepareRegexp : function (route) { return route .escapeRegExp() .replace(/>$/, '$') .replace(/^</, '^') .replace(/:([ADHW])/g, function ($0, $1) { return this.replaces[$1]; }.bind(this)); }, //  ,   regexp.exec  //    input  lastIndex  //  ,   argsMap regexpRouteArgs : function (result, argsMap) { }, }); };
      
      







рдЬрдм рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд░рд╛рдЙрдЯрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рдерд╛, рд╣рдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд░рд╛рдЙрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

 var url = require('url'); exports['Router.Plain'] = function (spirit) { return new Class({ initialize : function (routerHelper) { this.routerHelper = routerHelper; }, route : function (url) { var parts = this.getControllerName(url); var controller = this.routerHelper.createController(parts.name); var method = 'indexAction'; if (parts.args.length) { var action = parts.args[0].lcfirst(); //    -      //     -  ,  -  indexAction if (typeof controller[action + 'Action'] == 'function') { method = action + 'Action'; parts.args.shift(); } } return { contr : controller, method : method, args : parts.args }; }, getControllerName : function (url) { var controllers = this.routerHelper.controllers; //  pathname       var path = this.splitUrl(url); var name, args = []; do { if (!path.length) { //     - name = 'Controllers.Index'; break; } //         name = 'Controllers.' + path.join('.') + '.Index'; if (controllers[name]) break; //  -      name = 'Controllers.' + path.join('.'); if (controllers[name]) break; //    -    args.unshift(path.pop()); } while (true); return { name : name, args : args }; }, splitUrl : function (urlForSplit) { return url .parse(urlForSplit, true) .pathname.split('/') .filter(function (item) { return !!item; }) .map(function (item) { return item.ucfirst(); }); }, }); };
      
      







рдХрдХреНрд╖рд╛ рд╡рд┐рд╕реНрддрд╛рд░



UPD: рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдореБрдЭреЗ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рд░рд╛рдЙрдЯрд░ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛, рдЬрдм рдпреВрдЖрд░рдПрд▓ рдореЗрдВ рдЖрдкрдХреЛ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдВрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕рдВрд╢реЛрдзрди рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд▓рд┐рдВрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рд░рд╛рд╕реНрддреЗ рд╕реЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, " shock/spirit/init.js/f81e45



"ред рдореИрдВ рдЗрд╕ рд▓рд┐рдВрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ:

http://example.com/compare/( shock/spirit/init.js/f81e45 )/( tenshi/spirit/src/init.js/d5d218 )



, рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рд╛рдЗрд▓ рдХреЛрд╖реНрдардХ рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдлреНрд░реЗрдорд╡рд░реНрдХ рдЯреВрд▓реНрд╕ рдЗрд╕рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ (рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рдЫреБрдП рдмрд┐рдирд╛) рд╣рдо рд░рд╛рдЙрдЯрд░ рдмрдирд╛рддреЗ рд╣реИрдВред Regexp рд╡рд░реНрдЧ:



 exports['Router.Regexp'] = function (spirit) { return new Class({ Extends : spirit.load('Router.Regexp', true), prepareRegexp : function (route) { return this.parent(route) .replace(/:P/g, '([0-9a-z._\\/-]+)'); } }); };
      
      





рд╣рдордиреЗ рдПрдХ рдирдпрд╛ рд╕рдВрд╢реЛрдзрдХ рдкреЗрд╢ рдХрд┐рдпрд╛ - ": рдкреА"ред рдпрд╣ рд╢рд╛рдпрдж рдХреЗрд╡рд▓ Router.Regexp.replaces рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕рд╣реА рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рд╡рд┐рдзрд┐ рдЕрдзрд┐рднрд╛рд░ рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдареАрдХ рд╣реИ, рдЕрдм init.js рдореЗрдВ рдПрдХ рдирдпрд╛ рдорд╛рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ:



 spirit.createRouter() .addRoutes( // ... { route : "</compare/(:P)/(:P)>" , contr : 'Man.Route:compare' } );
      
      





рдФрд░ Man.Route рдореЗрдВ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:

  compareAction : function (args) { this.exit('Compare "' + args[0] + '" and "' + args[1] + '"'); }
      
      





рд╣рдо рд▓рд┐рдВрдХ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рддреЗ рд╣реИрдВ http://example.com/compare/( shock/spirit/init.js/f81e45 )/( tenshi/spirit/src/init.js/d5d218 )



рдФрд░ рдЙрддреНрддрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:

Compare " shock/spirit/init.js/f81e45 " and " tenshi/spirit/src/init.js/d5d218 "







рдирд┐рд╖реНрдХрд░реНрд╖



рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ, рд╕рд░реНрд╡рд░ рдХреЛ рд╡реЗрдм рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛, рдпрд╣ рд╕реАрдЦрд╛ рдХрд┐ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдП рдФрд░, рдкрддреЗ рдХреЛ рдЫрд╛рдВрдЯрд╛ рдЬрд╛рдП, рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдЖрд╡рд╢реНрдпрдХ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рднреЗрдЬреЗрдВред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓реЗрдЦреЛрдВ рдореЗрдВ, рд╣рдо рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди, рдФрд░ рдореЙрдбрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рджреГрд╢реНрдп рдХреЛ рдЬреЛрдбрд╝реЗрдВрдЧреЗ, рдЬреЛ рд╣рдорд╛рд░реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ред рдХреБрдЫ рд▓реЗрдЦреЛрдВ рдореЗрдВ рд╣рдо рдЕрдкрдиреЗ рдврд╛рдВрдЪреЗ рдкрд░ рдПрдХ рдмреНрд▓реЙрдЧ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗред рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ?



All Articles