======================================================================
 PSGI::Handy Tutorial (tut/)
 ٹیوٹوریل دستی کتاب                                         [UR] اردو
======================================================================

 tut/ PSGI::Handy کا سرکاری تدریسی ٹیوٹوریل ہے: چھ ابواب اور چوبیس مراحل کا ایک نصاب جو کسی بلیک باکس کے بغیر، ایک سادہ HTTP جواب سے شروع ہو کر ایک مکمل CRUD ایپلیکیشن تک، صفر سے ایک ویب ایپلیکیشن بناتا ہے۔ ہر مرحلہ ایک خود مختار، قابلِ اجرا Perl پروگرام ہے۔ پورا اسٹیک خالص Perl اور انحصار سے پاک ہے: PSGI::Handy (فریم ورک)، HTTP::Handy (سرور)، HP::Handy (ٹیمپلیٹس) اور DB::Handy (ڈیٹابیس)۔

[ کیسے چلائیں ]

  tut/ ڈائریکٹری کے اندر سے ایک وقت میں ایک مرحلہ چلائیں، مثلاً  perl 01_step01_text.pl  ۔ ہر پروگرام ایک سرور شروع کرتا ہے اور اپنا URL پرنٹ کرتا ہے؛ براؤزر میں http://127.0.0.1:8080/ کھولیں اور روکنے کے لیے Ctrl-C دبائیں۔ templates/ ڈائریکٹری اور data.csv موجودہ ڈائریکٹری سے قابلِ رسائی ہونے چاہئیں، اس لیے پروگرام ہمیشہ tut/ کے اندر سے شروع کریں۔

[ مشترکہ ہیڈر ]

  ہر .pl فائل ایک ہی ہیڈر سے کھلتی ہے: use 5.00503; use strict; ایک چھوٹا BEGIN بلاک جو 5.6 سے پرانے Perl پر ایک غیر فعال warnings stub فراہم کرتا ہے؛ پھر use warnings; local $^W = 1;  ۔ پروگرام Perl 5.005_03 تک درست رہنے کے لیے bareword filehandle اور دو دلیلوں والا open استعمال کرتے ہیں۔ یہ ہیڈر ہر مرحلے میں یکساں ہے اور نیچے دہرایا نہیں گیا۔

----------------------------------------------------------------------
 روٹ فائلیں
----------------------------------------------------------------------

  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 جواب کی شکل کو سمجھنے کے لیے براؤزر اور سرور کے درمیان، بغیر کسی ٹیمپلیٹ انجن کے، ممکنہ سادہ ترین تبادلہ۔

  01_step01_text.pl
      GET / کے لیے $c->text() کے ذریعے سادہ متن '.' واپس کرتا ہے۔ ممکنہ سب سے چھوٹی ایپ: براؤزر خام حروف وصول کرتا ہے (text/plain)۔

  01_step02_html.pl
      $c->html() کے ذریعے '<a>.' کو text/html کے طور پر واپس کرتا ہے۔ مرحلہ 1 جیسے ہی بائٹس، لیکن Content-Type براؤزر کو انہیں مارک اپ سمجھنے کو کہتا ہے۔ متن بمقابلہ HTML کا فرق دکھاتا ہے۔

  01_step03_dyn_text.pl
      موجودہ وقت کو سادہ متن کے طور پر واپس کرتا ہے، ہر درخواست پر scalar localtime() سے تازہ پڑھا جاتا ہے۔ متحرک آؤٹ پٹ کا پہلا ذائقہ: جواب ہر بار بدلتا ہے۔

  01_step04_dyn_html.pl
      متحرک وقت کو <h1>/<p> مارک اپ میں لپیٹتا ہے اور HTML کے طور پر واپس کرتا ہے۔ متغیرات سے ایک سٹرنگ جوڑ کر ایک سکرین بنانا۔

----------------------------------------------------------------------
 باب 2 — صارف ان پٹ اور حالت (فارم اور شاخیں)
----------------------------------------------------------------------

  براؤزر سے سرور کو ڈیٹا بھیجنا، اور جو آتا ہے اس پر شاخیں بنانا۔

  02_step05_form.pl
      GET / ایک HTML فارم (ایک ٹیکسٹ باکس اور ایک submit بٹن) دکھاتا ہے جو /echo پر POST کرتا ہے۔ جمع کرانے کے لیے ابھی کوئی ہینڈلر نہیں ہے؛ یہ مرحلہ صرف فارم مارک اپ کے بارے میں ہے۔

  02_step06_echo.pl
      POST /echo ہینڈلر شامل کرتا ہے۔ یہ $c->param('message') سے 'message' فیلڈ پڑھتا ہے اور اسے HTML جواب کے اندر واپس گونجاتا ہے: درخواست سے جواب کا بنیادی چکر۔

  02_step07_auth.pl
      ایک کم از کم لاگ ان۔ POST /login 'username' اور 'password' پڑھتا ہے اور شاخ بنانے کے لیے ایک if استعمال کرتا ہے: admin/secret کامیابی کے صفحے تک پہنچتا ہے، باقی سب ناکامی کے صفحے تک۔ تصدیق اور مشروط بہاؤ کا بیج۔

----------------------------------------------------------------------
 باب 3 — View کو الگ کرنا (HP::Handy کا تعارف)
----------------------------------------------------------------------

  پروگرام کے اندر HTML لکھنا بند کریں؛ اسے ٹیمپلیٹ فائلوں میں منتقل کریں۔ HP::Handy render_file()/render_string() ظاہر کرتا ہے، اس لیے یہ ایک چھوٹے CODE renderer کے ذریعے PSGI::Handy سے جڑا ہے جو ایک ٹیمپلیٹ نام کو render_file() پر میپ کرتا ہے۔ وہ renderer بلاک ہر ٹیمپلیٹ والے مرحلے میں یکساں ہے۔

  03_step08_template.pl
      متغیرات کے بغیر جامد templates/step08.html رینڈر کرتا ہے۔ HTML اب منطق سے الگ، اپنی فائل میں رہتا ہے۔

  03_step09_template_var.pl
      templates/step09.html کو { current_time => ... } پاس کرتا ہے، جو اسے {{ current_time }} پلیس ہولڈر کے ساتھ پرنٹ کرتا ہے۔ ڈیٹا پروگرام سے ٹیمپلیٹ میں بہتا ہے۔

  03_step10_template_form.pl
      دو ٹیمپلیٹس استعمال کرتے ہوئے مرحلہ 6 کی گونج دوبارہ لکھتا ہے: ان پٹ کے لیے step10_form.html اور نتیجے کے لیے step10_result.html۔ ہینڈلر منطق بہت چھوٹی ہو جاتی ہے۔

----------------------------------------------------------------------
 باب 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 ٹیبل کے طور پر رینڈر کرتا ہے (step11_list.html)۔

  04_step12_csv_create.pl
      Create. POST /add ضمیمہ موڈ (>>) میں data.csv میں ایک 'id,name,age' لائن شامل کرتا ہے، پھر ایک تکمیل کا صفحہ دکھاتا ہے۔

  04_step13_csv_readone.pl
      Read One. روٹ /user/:id ایک id پکڑتا ہے؛ پروگرام مماثل قطار کے لیے data.csv اسکین کرتا ہے اور اس کی تفصیل دکھاتا ہے (step13_detail.html)، یا نہ ملنے پر 404 واپس کرتا ہے۔

  04_step14_csv_update.pl
      Update. ایک قطار بدلنے کے لیے یہ ہر لائن پڑھتا ہے، مماثل کو بدلتا ہے اور پوری فائل دوبارہ لکھتا ہے: 'سب پڑھو، بدلو، سب لکھو' کا کام جسے ڈیٹابیس ختم کر دے گا۔

  04_step15_csv_delete.pl
      Delete. وہی پوری فائل دوبارہ لکھنا، لیکن مماثل قطار کو بدلنے کے بجائے چھوڑ دیا جاتا ہے۔

----------------------------------------------------------------------
 باب 5 — Model کا تعارف (DB::Handy کی طرف بڑھنا)
----------------------------------------------------------------------

  CSV کو DB::Handy سے بدلیں۔ ہینڈل DB::Handy->connect('data','app',{...}) سے بنایا جاتا ہے اور db => $dbh کے ذریعے داخل کیا جاتا ہے، پھر ہینڈلرز میں $c->db کے طور پر پہنچا جاتا ہے۔ ایک _bootstrap() روٹین 'users' ٹیبل کو ایک بار بناتا اور بیج ڈالتا ہے، اس لیے ہر مثال خود مختار طور پر چلتی ہے۔

  05_step16_db_readall.pl
      Read All. selectall_arrayref(..., { Slice => {} }) فہرست ٹیمپلیٹ (step16_list.html) کے لیے ہر users قطار کو hash کے طور پر لاتا ہے۔ اب کوئی دستی فائل پارسنگ نہیں۔

  05_step17_db_create.pl
      Create. POST /add ایک پلیس ہولڈر INSERT کے ساتھ ایک قطار داخل کرتا ہے، پھر / (فہرست) پر ری ڈائریکٹ کرتا ہے: معیاری post-then-redirect پیٹرن۔

  05_step18_db_readone.pl
      Read One. /user/:id selectrow_hashref() کے ساتھ بنیادی کلید کے ذریعے ایک واحد قطار لاتا ہے، یا 404 واپس کرتا ہے۔ ہر قطار اسکین کرنے کے بجائے براہِ راست کلید تلاش۔

  05_step19_db_update.pl
      Update. GET /user/:id/edit ترمیم فارم دکھاتا ہے؛ POST UPDATE ... WHERE id=? چلاتا ہے اور تفصیل کے صفحے پر ری ڈائریکٹ کرتا ہے۔ میموری میں کوئی پوری فائل دوبارہ لکھنا نہیں۔

  05_step20_db_delete.pl
      Delete. DELETE ... WHERE id=? چلایا جاتا ہے، پھر / پر ری ڈائریکٹ۔ حالت بدلنے والا روٹ صرف 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 فارم. شعبہ ماسٹر لوڈ کرتا ہے اور اسے ایک <select> ڈراپ ڈاؤن کے طور پر رینڈر کرتا ہے (step23_form_select.html)، تاکہ صارف ایک id ٹائپ کرنے کے بجائے ایک شعبہ منتخب کرے۔

  06_step24_fullstack_app.pl
      ایک فائل میں مکمل ایپلیکیشن: users+depts ڈیٹا پر list، detail، add، edit اور delete؛ جوڑے گئے شعبے کے نام، ایک select ڈراپ ڈاؤن، ہر جگہ post-then-redirect، اور ایک _next_id() مددگار (DB::Handy میں کوئی آٹو-انکریمنٹ نہیں)۔ app_list.html اور app_form.html استعمال کرتا ہے۔

----------------------------------------------------------------------
 ٹیمپلیٹس (templates/)
----------------------------------------------------------------------

  HP::Handy ٹیمپلیٹس Jinja2 جیسا نحو استعمال کرتے ہیں: {{ var }} ایک قدر پرنٹ کرتا ہے ({{ user.name }} جیسے نقطے دار راستے hash کے اندر پہنچتے ہیں)، {% for x in list %} ... {% endfor %} لوپ کرتا ہے، اور {% if ... %} شاخ بناتا ہے۔ renderer کو auto_escape => 1 کے ساتھ بنایا جاتا ہے، اس لیے پرنٹ شدہ اقدار HTML-escape ہوتی ہیں۔

  templates/step08.html
      مرحلہ 8 کے ذریعے استعمال ہونے والا مکمل طور پر جامد صفحہ؛ کوئی پلیس ہولڈر نہیں۔

  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 }} پر لوپ کرتا ہے (مرحلہ 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 }} ہدف create اور update کے درمیان سوئچ کرتا ہے، اور شعبہ <select> {% if %} کے ذریعے {{ user.dept_id }} کو پہلے سے منتخب کرتا ہے۔

----------------------------------------------------------------------
 حوالہ جات
----------------------------------------------------------------------

  MetaCPAN پر PSGI::Handy اور باقی Handy اسٹیک، اور 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

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