======================================================================
 PSGI::Handy Tutorial (tut/)
 ट्युटोरियल पुस्तिका                                      [NE] नेपाली
======================================================================

 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 ले append मोड (>>) मा 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
      चरण १२ को "Added" पुष्टि पृष्ठ: {{ name }} र फिर्ता लिङ्क देखाउँछ।

  templates/step13_list.html
      चरण १३ को अनुक्रमणिका: प्रत्येक प्रयोगकर्ता आफ्नो /user/:id विवरण पृष्ठमा लिङ्क हुन्छ।

  templates/step13_detail.html
      चरण 13 का लागि एक प्रयोगकर्ताको id/name/age देखाउँछ।

  templates/step14_list.html
      चरण १४ को पृष्ठ: हालका पङ्क्तिहरू र /update मा POST गर्ने अद्यावधिक फारम।

  templates/step15_list.html
      चरण १५ को पृष्ठ: हालका पङ्क्तिहरू र /delete मा POST गर्ने मेट्ने फारम।

  templates/step16_list.html
      चरण १६ को सादा DB प्रयोगकर्ता सूची (अहिले लिङ्क छैन)।

  templates/step17_form.html
      चरण 17 का लागि प्रयोगकर्ता थप्ने फारम।

  templates/step17_list.html
      /add मा "Add New User" लिङ्क भएको चरण १७ को सूची।

  templates/step18_list.html
      चरण १८ को सूची: प्रत्येक नाम आफ्नो /user/:id विवरणमा लिङ्क हुन्छ।

  templates/step18_detail.html
      चरण १८ को सादा प्रयोगकर्ता विवरण, फिर्ता लिङ्कसहित।

  templates/step19_list.html
      चरण १९ को सूची: प्रत्येक नाम आफ्नो विवरण पृष्ठमा लिङ्क हुन्छ।

  templates/step19_detail.html
      चरण १९ को प्रयोगकर्ता विवरण, सम्पादन लिङ्क र फिर्ता लिङ्कसहित।

  templates/step19_edit.html
      चरण 19 का लागि सम्पादन फारम (name, age); /user/:id/edit मा POST गर्छ।

  templates/step20_list.html
      प्रत्येक पङ्क्तिमा पुष्टिसहितको POST Delete बटन भएको चरण २० को सूची।

  templates/step21_join_list.html
      जोडिएको {{ user.dept_name }} स्तम्भसहित कर्मचारी सूची (चरण 21)।

  templates/step22_join_list.html
      चरण २२ को कर्मचारी अनुक्रमणिका: प्रत्येक नाम आफ्नो विवरण पृष्ठमा लिङ्क हुन्छ।

  templates/step22_join_detail.html
      विभागको नाम देखाउने कर्मचारी विवरण (चरण 22)।

  templates/step23_list.html
      /add मा "Add New Employee" लिङ्क भएको चरण २३ को कर्मचारी सूची।

  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

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