======================================================================
 PSGI::Handy Tutorial (tut/)
 නිබන්ධන අත්පොත                                            [SI] සිංහල
======================================================================

 tut/ යනු PSGI::Handy හි නිල ඉගැන්වීම් නිබන්ධනයයි: පරිච්ඡේද හයකින් සහ පියවර විසිහතරකින් යුත් පාඨමාලාවක් වන අතර, කිසිදු කළු පෙට්ටියක් නොමැතිව, හිස් HTTP ප්‍රතිචාරයකින් ආරම්භ වී සම්පූර්ණ CRUD යෙදුමක් දක්වා, ශුන්‍යයේ සිට වෙබ් යෙදුමක් ගොඩනඟයි. සෑම පියවරක්ම ස්වාධීන, ක්‍රියාත්මක කළ හැකි Perl වැඩසටහනකි. සම්පූර්ණ stack පිරිසිදු Perl සහ පරායත්තතා රහිතය: PSGI::Handy (රාමුව), HTTP::Handy (සේවාදායකය), HP::Handy (සැකිලි) සහ DB::Handy (දත්ත සමුදාය).

[ ක්‍රියාත්මක කරන ආකාරය ]

  tut/ නාමාවලිය ඇතුළතින් එක් වරකට එක් පියවරක් ක්‍රියාත්මක කරන්න, උදාහරණයක් ලෙස  perl 01_step01_text.pl  . සෑම වැඩසටහනක්ම සේවාදායකයක් ආරම්භ කර එහි URL මුද්‍රණය කරයි; browser එකේ http://127.0.0.1:8080/ විවෘත කර නැවැත්වීමට Ctrl-C ඔබන්න. templates/ නාමාවලිය සහ data.csv වත්මන් නාමාවලියෙන් ප්‍රවේශ විය හැකි විය යුතු බැවින්, වැඩසටහන් සැමවිටම tut/ ඇතුළතින් ආරම්භ කරන්න.

[ පොදු ශීර්ෂය ]

  සෑම .pl ගොනුවක්ම එකම ශීර්ෂයෙන් විවෘත වේ: use 5.00503; use strict; 5.6 ට වඩා පැරණි Perl හි ක්‍රියා විරහිත warnings stub එකක් සපයන කුඩා BEGIN කොටසක්; පසුව use warnings; local $^W = 1;  . වැඩසටහන් Perl 5.005_03 දක්වා වලංගුව පවතින පරිදි bareword filehandle සහ තර්ක දෙකක open භාවිතා කරයි. මෙම ශීර්ෂය සෑම පියවරකම සමාන වන අතර පහත නැවත නොකියනු ලැබේ.

----------------------------------------------------------------------
 root ගොනු
----------------------------------------------------------------------

  00_README.txt
      පාඨමාලා දළ විශ්ලේෂණය: සෑම පරිච්ඡේදයක් සහ පියවරක්ම එහි ඉගෙනුම් ඉලක්කය සමඟ. කිසියම් වැඩසටහනක් විවෘත කිරීමට පෙර සම්පූර්ණ ප්‍රවාහය බැලීමට මෙය මුලින් කියවන්න.

  data.csv
      පරිච්ඡේදය 4 සඳහා නියැදි දත්ත (CSV පියවර): id,name,age හි කොමාවෙන් වෙන් කළ පේළි තුනක්. පියවර 12, 14 සහ 15 මෙම ගොනුව නැවත ලියයි, එබැවින් එය යළි පිහිටුවීමට අවශ්‍ය නම් උපස්ථයක් තබා ගන්න. 1,Alice,20 / 2,Bob,22 / 3,Charlie,25

----------------------------------------------------------------------
 පරිච්ඡේදය 1 — HTTP ප්‍රතිචාර මූලික කරුණු (ස්ථිතිකයේ සිට ගතිකය දක්වා)
----------------------------------------------------------------------

  HTTP ප්‍රතිචාරයක හැඩය තේරුම් ගැනීමට, සැකිලි එන්ජිමක් නොමැතිව, browser සහ සේවාදායකය අතර හැකි සරලම හුවමාරුව.

  01_step01_text.pl
      GET / සඳහා $c->text() හරහා සරල පෙළ '.' ආපසු දෙයි. හැකි කුඩාම යෙදුම: browser අමු අක්ෂර ලබා ගනී (text/plain).

  01_step02_html.pl
      $c->html() හරහා '<a>.' text/html ලෙස ආපසු දෙයි. පියවර 1 හා සමාන බයිට, නමුත් Content-Type browser ට ඒවා markup ලෙස සැලකීමට කියයි. පෙළ එදිරිව HTML වෙනස පෙන්වයි.

  01_step03_dyn_text.pl
      වත්මන් වේලාව සරල පෙළ ලෙස ආපසු දෙයි, සෑම ඉල්ලීමකදීම scalar localtime() සමඟ අලුතින් කියවයි. ගතික ප්‍රතිදානයේ පළමු රසය: ප්‍රතිචාරය සෑම විටම වෙනස් වේ.

  01_step04_dyn_html.pl
      ගතික වේලාව <h1>/<p> markup තුළ ඔතා HTML ලෙස ආපසු දෙයි. විචල්‍යවලින් string එකක් එකලස් කිරීමෙන් තිරයක් ගොඩනැගීම.

----------------------------------------------------------------------
 පරිච්ඡේදය 2 — පරිශීලක ආදානය සහ තත්ත්වය (පෝරම සහ අතු බෙදීම)
----------------------------------------------------------------------

  browser එකෙන් සේවාදායකයට දත්ත යැවීම, සහ පැමිණෙන දේ මත අතු බෙදීම.

  02_step05_form.pl
      GET / මඟින් /echo වෙත POST කරන HTML පෝරමයක් (පෙළ කොටුවක් සහ submit බොත්තමක්) පෙන්වයි. ඉදිරිපත් කිරීම සඳහා තවම handler එකක් නැත; මෙම පියවර පෝරම markup පමණක් ගැනයි.

  02_step06_echo.pl
      POST /echo handler එක එක් කරයි. එය $c->param('message') සමඟ 'message' field එක කියවා HTML ප්‍රතිචාරය තුළ එය ආපසු දෝංකාර කරයි: ඉල්ලීමේ සිට ප්‍රතිචාරය දක්වා මූලික ගමන.

  02_step07_auth.pl
      අවම පිවිසුමක්. POST /login මඟින් 'username' සහ 'password' කියවා අතු බෙදීමට if එකක් භාවිතා කරයි: admin/secret සාර්ථක පිටුවට ළඟා වේ, අනෙක් සියල්ල අසාර්ථක පිටුවට. සත්‍යාපනය සහ කොන්දේසි සහිත ප්‍රවාහයේ බීජය.

----------------------------------------------------------------------
 පරිච්ඡේදය 3 — View වෙන් කිරීම (HP::Handy හඳුන්වාදීම)
----------------------------------------------------------------------

  වැඩසටහන තුළ HTML ලිවීම නවත්වන්න; එය සැකිලි ගොනුවලට ගෙන යන්න. HP::Handy මඟින් render_file()/render_string() නිරාවරණය කරයි, එබැවින් එය සැකිලි නමක් render_file() වෙත සිතියම්ගත කරන කුඩා CODE renderer එකක් හරහා PSGI::Handy වෙත සම්බන්ධ වේ. එම renderer කොටස සැකිලි සහිත සෑම පියවරකම සමාන වේ.

  03_step08_template.pl
      විචල්‍ය නොමැතිව ස්ථිතික templates/step08.html render කරයි. HTML දැන් තර්කයෙන් වෙන්ව, තමන්ගේම ගොනුවේ පවතී.

  03_step09_template_var.pl
      templates/step09.html වෙත { current_time => ... } යවයි, එය {{ current_time }} placeholder සමඟ එය මුද්‍රණය කරයි. දත්ත වැඩසටහනෙන් සැකිල්ලට ගලා යයි.

  03_step10_template_form.pl
      සැකිලි දෙකක් භාවිතා කරමින් පියවර 6 හි දෝංකාරය නැවත ලියයි: ආදානය සඳහා step10_form.html සහ ප්‍රතිඵලය සඳහා step10_result.html. handler තර්කය ඉතා කුඩා වේ.

----------------------------------------------------------------------
 පරිච්ඡේදය 4 — ගොනු I/O සහ CSV ස්ථීරතාව (CRUD මූලික කරුණු)
----------------------------------------------------------------------

  දත්ත සමුදායක් නොමැතිව, සරල CSV ගොනුවකට එරෙහිව Create/Read/Update/Delete ක්‍රියාත්මක කරන්න. අතින් දත්ත හැසිරවීමේ පිරිවැය දැනීම පරිච්ඡේදය 5 හි දත්ත සමුදායකට මාරු වීමට පොළඹවයි.

  04_step11_csv_readall.pl
      Read All. data.csv විවෘත කර, සෑම පේළියක්ම කොමාවලින් { id, name, age } hash වලට බෙදා, ලැයිස්තුව HTML වගුවක් ලෙස render කරයි (step11_list.html).

  04_step12_csv_create.pl
      Create. POST /add මඟින් append මාදිලියේ (>>) data.csv වෙත 'id,name,age' පේළියක් එක් කරයි, පසුව සම්පූර්ණ පිටුවක් පෙන්වයි.

  04_step13_csv_readone.pl
      Read One. route /user/:id මඟින් id එකක් අල්ලයි; වැඩසටහන ගැළපෙන පේළිය සඳහා data.csv scan කර එහි විස්තර පෙන්වයි (step13_detail.html), හෝ සොයාගත නොහැකි නම් 404 ආපසු දෙයි.

  04_step14_csv_update.pl
      Update. එක් පේළියක් වෙනස් කිරීමට එය සෑම පේළියක්ම කියවා, ගැළපෙන පේළිය ප්‍රතිස්ථාපනය කර සම්පූර්ණ ගොනුව නැවත ලියයි: දත්ත සමුදාය ඉවත් කරන 'සියල්ල කියවන්න, මාරු කරන්න, සියල්ල ලියන්න' වැඩය.

  04_step15_csv_delete.pl
      Delete. එම සම්පූර්ණ ගොනු නැවත ලිවීම, නමුත් ගැළපෙන පේළිය ප්‍රතිස්ථාපනය කරනවා වෙනුවට මඟ හැරේ.

----------------------------------------------------------------------
 පරිච්ඡේදය 5 — Model හඳුන්වාදීම (DB::Handy වෙත මාරු වීම)
----------------------------------------------------------------------

  CSV DB::Handy සමඟ ප්‍රතිස්ථාපනය කරන්න. handle එක DB::Handy->connect('data','app',{...}) සමඟ සාදා db => $dbh හරහා එන්නත් කරනු ලැබේ, පසුව handler වල $c->db ලෙස ළඟා වේ. _bootstrap() දින චර්යාවක් 'users' වගුව වරක් සාදා බීජ වපුරයි, එබැවින් සෑම උදාහරණයක්ම ස්වාධීනව ක්‍රියාත්මක වේ.

  05_step16_db_readall.pl
      Read All. selectall_arrayref(..., { Slice => {} }) ලැයිස්තු සැකිල්ල (step16_list.html) සඳහා සෑම users පේළියක්ම hash ලෙස ගෙන එයි. තවදුරටත් අතින් ගොනු parse කිරීමක් නැත.

  05_step17_db_create.pl
      Create. POST /add මඟින් placeholder INSERT එකක් සමඟ පේළියක් ඇතුළු කර, පසුව / (ලැයිස්තුව) වෙත redirect කරයි: සම්මත post-then-redirect රටාව.

  05_step18_db_readone.pl
      Read One. /user/:id මඟින් selectrow_hashref() සමඟ ප්‍රාථමික යතුර අනුව තනි පේළියක් ගෙන එයි, හෝ 404 ආපසු දෙයි. සෑම පේළියක්ම scan කරනවා වෙනුවට සෘජු යතුරු සෙවීමක්.

  05_step19_db_update.pl
      Update. GET /user/:id/edit මඟින් සංස්කරණ පෝරමය පෙන්වයි; POST මඟින් UPDATE ... WHERE id=? ධාවනය කර විස්තර පිටුවට redirect කරයි. මතකයේ සම්පූර්ණ ගොනු නැවත ලිවීමක් නැත.

  05_step20_db_delete.pl
      Delete. DELETE ... WHERE id=? ධාවනය කර, පසුව / වෙත redirect. තත්ත්වය වෙනස් කරන route එක POST පමණි, GET එකකින් අහම්බෙන් මැකීම වැළැක්වීමට.

----------------------------------------------------------------------
 පරිච්ඡේදය 6 — සම්බන්ධිත දත්ත සහ සැබෑ යෙදුමක්
----------------------------------------------------------------------

  දෙවන දත්ත සමුදායක 'app2' හි සම්බන්ධිත වගු දෙකක් (users සහ depts). JOIN එක කළු පෙට්ටියක් නොවන පරිදි Perl හි අතින් කරනු ලැබේ, පසුව සියල්ල එක් සම්පූර්ණ යෙදුමකට එකලස් කරනු ලැබේ.

  06_step21_db_join_list.pl
      JOIN List. වගු දෙකම කියවා, dept_id => name සෙවුමක් ගොඩනඟා, සෑම පරිශීලකයෙකුටම dept_name අමුණා (අතින් ලියන ලද JOIN), ඒවා ලැයිස්තුගත කරයි (step21_join_list.html).

  06_step22_db_join_detail.pl
      JOIN Read One. එක් පරිශීලකයෙකු ගෙන, පසුව එම පරිශීලකයාගේ තනි දෙපාර්තමේන්තුව සොයා විස්තර පිටුව සඳහා එහි නම අමුණයි (step22_join_detail.html).

  06_step23_db_form_select.pl
      Select පෝරමය. දෙපාර්තමේන්තු master එක load කර එය <select> dropdown එකක් ලෙස render කරයි (step23_form_select.html), එවිට පරිශීලකයා id එකක් ටයිප් කරනවා වෙනුවට දෙපාර්තමේන්තුවක් තෝරයි.

  06_step24_fullstack_app.pl
      එක් ගොනුවක සම්පූර්ණ යෙදුම: users+depts දත්ත මත list, detail, add, edit සහ delete; අමුණන ලද දෙපාර්තමේන්තු නම්, select dropdown එකක්, සෑම තැනකම post-then-redirect, සහ _next_id() උපකාරකයක් (DB::Handy හි auto-increment නැත). app_list.html සහ app_form.html භාවිතා කරයි.

----------------------------------------------------------------------
 සැකිලි (templates/)
----------------------------------------------------------------------

  HP::Handy සැකිලි Jinja2 වැනි syntax භාවිතා කරයි: {{ var }} මඟින් අගයක් මුද්‍රණය කරයි ({{ user.name }} වැනි තිත් සහිත මාර්ග hash වලට ළඟා වේ), {% for x in list %} ... {% endfor %} loop කරයි, සහ {% if ... %} අතු බෙදයි. renderer එක auto_escape => 1 සමඟ සාදා ඇත, එබැවින් මුද්‍රණය කරන ලද අගයන් HTML-escape වේ.

  templates/step08.html
      පියවර 8 මඟින් භාවිතා කරන සම්පූර්ණයෙන්ම ස්ථිතික පිටුවක්; placeholder නැත.

  templates/step09.html
      {{ current_time }} හරහා සේවාදායක වේලාව මුද්‍රණය කරයි (පියවර 9).

  templates/step10_form.html
      පියවර 10 හි දෝංකාරය සඳහා ආදාන පෝරමය; 'message' /echo වෙත POST කරයි.

  templates/step10_result.html
      පියවර 10 සඳහා දෝංකාර වූ {{ message }} පෙන්වයි.

  templates/step11_list.html
      CSV වගුව ඇඳීමට {{ users }} මත loop කරයි (පියවර 11).

  templates/step12_form.html
      පියවර 12 සඳහා එක් කිරීමේ පෝරමය (id, name, age).

  templates/step12_result.html
      පියවර 12 හි "Added" තහවුරු පිටුව: {{ name }} සහ ආපසු යාමේ සබැඳියක් පෙන්වයි.

  templates/step13_list.html
      පියවර 13 හි සූචිය: සෑම පරිශීලකයෙක්ම තම /user/:id විස්තර පිටුවට සබැඳෙයි.

  templates/step13_detail.html
      පියවර 13 සඳහා එක් පරිශීලකයෙකුගේ id/name/age පෙන්වයි.

  templates/step14_list.html
      පියවර 14 හි පිටුව: වත්මන් පේළි සහ /update වෙත POST කරන යාවත්කාලීන පෝරමයක්.

  templates/step15_list.html
      පියවර 15 හි පිටුව: වත්මන් පේළි සහ /delete වෙත POST කරන මැකීමේ පෝරමයක්.

  templates/step16_list.html
      පියවර 16 සඳහා සරල DB පරිශීලක ලැයිස්තුව (තවම සබැඳි නැත).

  templates/step17_form.html
      පියවර 17 සඳහා පරිශීලක එක් කිරීමේ පෝරමය.

  templates/step17_list.html
      /add වෙත "Add New User" සබැඳිය සහිත පියවර 17 ලැයිස්තුව.

  templates/step18_list.html
      පියවර 18 ලැයිස්තුව: සෑම නමක්ම තම /user/:id විස්තරයට සබැඳෙයි.

  templates/step18_detail.html
      පියවර 18 සඳහා සරල පරිශීලක විස්තරය, ආපසු යාමේ සබැඳියක් සහිතව.

  templates/step19_list.html
      පියවර 19 ලැයිස්තුව: සෑම නමක්ම තම විස්තර පිටුවට සබැඳෙයි.

  templates/step19_detail.html
      පියවර 19 පරිශීලක විස්තරය, Edit සබැඳියක් සහ ආපසු යාමේ සබැඳියක් සහිතව.

  templates/step19_edit.html
      පියවර 19 සඳහා සංස්කරණ පෝරමය (name, age); /user/:id/edit වෙත POST කරයි.

  templates/step20_list.html
      සෑම පේළියකම තහවුරු කිරීම සහිත POST Delete බොත්තමක් සහිත පියවර 20 ලැයිස්තුව.

  templates/step21_join_list.html
      සම්බන්ධිත {{ user.dept_name }} තීරුව සමඟ සේවක ලැයිස්තුව (පියවර 21).

  templates/step22_join_list.html
      පියවර 22 සේවක සූචිය: සෑම නමක්ම තම විස්තර පිටුවට සබැඳෙයි.

  templates/step22_join_detail.html
      දෙපාර්තමේන්තු නම පෙන්වන සේවක විස්තර (පියවර 22).

  templates/step23_list.html
      /add වෙත "Add New Employee" සබැඳිය සහිත පියවර 23 සේවක ලැයිස්තුව.

  templates/step23_form_select.html
      {{ depts }} වෙතින් ගොඩනඟන ලද දෙපාර්තමේන්තු <select> සමඟ එක් කිරීමේ පෝරමය (පියවර 23).

  templates/app_list.html
      සම්පූර්ණ යෙදුමේ සේවක ලැයිස්තුව (පියවර 24): ID, සම්බන්ධිත නම, දෙපාර්තමේන්තුව, මෙන්ම සෑම පේළියකටම Edit සහ තහවුරු කිරීමෙන් ආරක්ෂිත POST Delete, සහ Add සබැඳියක්.

  templates/app_form.html
      සම්පූර්ණ යෙදුමේ බෙදාගත් එක්කිරීම්/සංස්කරණ පෝරමය (පියවර 24): {{ action }} ඉලක්කය නිර්මාණය සහ යාවත්කාලීන කිරීම අතර මාරු වන අතර, දෙපාර්තමේන්තු <select> එක {% if %} හරහා {{ user.dept_id }} පෙර තෝරයි.

----------------------------------------------------------------------
 යොමු
----------------------------------------------------------------------

  MetaCPAN හි PSGI::Handy සහ Handy stack හි ඉතිරි කොටස, සහ PSGI පිරිවිතර:

    https://metacpan.org/dist/PSGI-Handy
    https://metacpan.org/dist/HTTP-Handy
    https://metacpan.org/dist/HP-Handy
    https://metacpan.org/dist/DB-Handy
    https://github.com/plack/psgi-specs/blob/master/PSGI.pod

======================================================================
