पिछले कुछ वर्षों में, मेरा काम
CMS Drupal का उपयोग करने के आसपास रहा है, लेकिन अपने खाली समय में मैंने अध्ययन किया और सिर्फ पायथन फ्रेमवर्क
Django ,
फ्लास्क और
ट्विस्टेड पर लॉन्च किए गए मजेदार प्रोजेक्ट्स के लिए। अब मैंने दो या तीन लोकप्रिय PHP फ्रेमवर्क की मूल बातें सीखने का फैसला किया और पहले मैंने
Zend फ्रेमवर्क 2 और
Yii का अध्ययन करने का फैसला किया।
Zend फ्रेमवर्क 2 से परिचित होने की प्रक्रिया में, मैंने आधिकारिक साइट (
http://framework.zend.com/manual/2.2/en/user-guide/overview.html ) से ट्यूटोरियल का अध्ययन किया, फ्रेमवर्क के प्रलेखन को देखा (
http: //framework.zend .com / मैन्युअल / 2.2 / en / index.html ), माइकल रोमर की पुस्तक "Zend फ्रेमवर्क 2 के साथ वेब विकास," पढ़ें और अपने स्वयं के परीक्षण एप्लिकेशन को एक साथ रखें।
यह सब जानकारी हजम करने के बाद, मैं इस निष्कर्ष पर पहुंचा कि रूपरेखा के लिए आधिकारिक ट्यूटोरियल बल्कि सूखा है:
- यह उपयोगकर्ताओं, सत्रों और अभिगम अधिकारों के साथ काम करने के बारे में बात नहीं करता है,
- केवल गुजरने का ढांचा ही ऐसा मूलभूत हिस्सा है जैसा कि सेवा प्रबंधक ने माना है
- तालिका गेटवे पैटर्न (और फ्रेमवर्क में इसके अनुरूप कार्यान्वयन) का उपयोग डेटाबेस के साथ इंटरफेस के रूप में किया जाता है,
- फ़्रेमवर्क में निर्मित टेम्पलेट इंजन का उपयोग करना, जो कि पायथन जिनजा 2 के बाद पूरी तरह से असहज और आदिम लगता है,
- आदि
नतीजतन, मैं किताब पढ़ने के बाद कार्यक्षमता अनुप्रयोग में कम या ज्यादा संतोषजनक बनाने में सक्षम था।
इस लेख में मैं एक साधारण ब्लॉग को विकसित करने का एक उदाहरण देना चाहता हूं, इसमें आधिकारिक ट्यूटोरियल से कई अंतर होंगे। सबसे पहले, मैं उन मुद्दों पर ध्यान केंद्रित करने की कोशिश करूंगा जो अध्ययन के दौरान मुझे आधिकारिक ट्यूटोरियल में अपर्याप्त रूप से प्रकट हुए थे। इसके अलावा, मैं कुछ तकनीकों का उपयोग करूंगा जो कि Zend फ्रेमवर्क में डिफ़ॉल्ट रूप से उपयोग किए जाने वाले विकल्प हैं:
- टहनी का उपयोग टेम्पलेट इंजन के रूप में किया जाएगा,
- डेटाबेस के साथ काम करने के लिए - सिद्धांत ORM ,
- उपयोग अधिकार के प्रमाणीकरण / प्रमाणीकरण और वितरण के लिए मैं मौजूदा ZfcUser और BjyAuthorize मॉड्यूल का उपयोग करूंगा ,
- मैं अपने स्वयं के फ़ॉर्म सत्यापनकर्ताओं, व्यू प्लगइन्स और अन्य के विकास पर भी विचार करूंगा।
लेख शुरुआती लोगों के लिए एक शुरुआती (ज़ेंड फ्रेमवर्क में) द्वारा लिखा गया था, इसलिए मामले की किसी भी आलोचना और आवेदन में सुधार के लिए सुझावों का स्वागत है।
आप Github:
github.com/romka/zend-blog-example पर प्रोजेक्ट कोड पा सकते हैं।
लेख को 3 भागों में विभाजित किया जाएगा:
- पहले (वर्तमान) भाग में मैं ZendSkeletonApplication की संरचना पर विचार करूंगा,
- दूसरे भाग में मैं अपने स्वयं के मॉड्यूल (रूपों, डॉक्ट्रिन ओआरएम का उपयोग कर डेटाबेस के साथ काम करना, व्यू प्लगइन का विकास) का विश्लेषण करूँगा ,
- तीसरा भाग उपयोगकर्ताओं और ट्विग टेम्पलेट इंजन के साथ काम करने के लिए समर्पित होगा।
तो चलिए शुरू करते हैं।
पर्यावरण
मुझे लगता है कि आपके पास पहले से ही एक कॉन्फ़िगर वेब सर्वर है (मेरा
zblog.kece.ru पर उपलब्ध है) और MySQL ने इस परियोजना के लिए एक खाली डेटाबेस बनाया है। इस तथ्य के कारण कि मैं डेटाबेस के साथ काम करने के लिए डॉक्ट्रिन का उपयोग करने की योजना बना रहा हूं, डेटाबेस इस ओआरएम द्वारा समर्थित हो सकता है।
मुझे लगता है कि आपके पास अपनी उंगलियों पर ZendSkeletonApllication या मेरे ट्यूटोरियल का स्रोत कोड है। आप उन्हें यहाँ ले जा सकते हैं:
github.com/zendframework/ZendSkeletonApplication और यहाँ:
github.com/romka/zend-blog-example । इसके अलावा, मेरा मानना है कि आप एमवीसी पैटर्न को समझते हैं, कुछ प्रकार के टेम्पलेट इंजन के साथ काम करने का अनुभव रखते हैं और सत्यापनकर्ता हैं।
ज़ेंड फ्रेमवर्क अद्भुत
संगीतकार निर्भरता प्रबंधक का उपयोग करता है, जिसे आपके सिस्टम पर भी स्थापित किया जाना चाहिए। आप इस लेख में संगीतकार के बारे में अधिक पढ़ सकते हैं:
habrahabr.ru/post/145946 । संक्षेप में, कम्पोज़र एक कमांड-लाइन उपयोगिता है जो आपको बाहरी पुस्तकालयों को जल्दी और आसानी से डाउनलोड करने और स्थापित करने की अनुमति देता है जो आपके पीएचपी प्रोजेक्ट पर निर्भर करता है। इनपुट में, उपयोगिता एक JSON फ़ाइल को एक सहज ज्ञान युक्त प्रारूप में स्वीकार करती है, जिसमें आउटपुट पर नाम और निर्भरता के संस्करणों की एक सूची होती है, यह आवश्यक पुस्तकालयों को डाउनलोड और इंस्टॉल करता है और आपको नियमित काम से मुक्त करता है।
लेख का पाठ कभी-कभी बाहरी अनुप्रयोगों या फ़ाइलों के स्रोत कोड को स्वचालित रूप से संगीतकार द्वारा उत्पन्न करेगा। ये फाइलें रिपॉजिटरी में नहीं हैं, इसलिए इस ट्यूटोरियल में विकसित एप्लिकेशन के गहन अध्ययन के लिए, आपको स्वयं आवश्यक सॉफ़्टवेयर इंस्टॉल करना होगा।
ZendSkeletonApplication
Zend फ्रेमवर्क का उपयोग करके, आप अपने एप्लिकेशन की संरचना को खरोंच से डिज़ाइन और बना सकते हैं, लेकिन सिस्टम का अध्ययन करने के लिए
ZendSkeletonApplication prefab का उपयोग करना बेहतर है। यदि आपने कंपोज़र कॉन्फ़िगर किया है, तो केवल कमांड चलाएँ:
php composer.phar create-project --repository-url="http://packages.zendframework.com" -s dev zendframework/skeleton-application path/to/install
(यदि ठीक से कॉन्फ़िगर किया गया है, तो
php कंपोज़र। थापर कमांड को बस
कंपोज़र से बदला जा सकता है, लेकिन बाद में लेख में मैं पहले विकल्प को एक अधिक सार्वभौमिक के रूप में दूंगा)
इसके निष्पादन के बाद, आपको निम्नलिखित संरचना के साथ एक आवेदन प्राप्त होगा (मैंने केवल सबसे दिलचस्प निर्देशिका और फाइलें छोड़ दी हैं):
config/ autoload/ global.php application.config.php module/ Application/ < Application > public/ css/ img/ js/ index.php vendor/ < , Zend Framework> composer.json init_autoloader.php
अब आप बनाए गए प्रोजेक्ट को खोल सकते हैं। मेरा संस्करण
zblog.kece.ru पर उपलब्ध है।
आइए बनाई गई निर्देशिकाओं और फ़ाइलों पर एक करीब से नज़र डालें।
परियोजना की संरचना
composer.json
चलिए प्रोजेक्ट की जड़ में
कंपोज़र.जॉन फ़ाइल से शुरू करते हैं। इसका निम्न रूप है:
{ "name": "zendframework/skeleton-application", "description": "Skeleton Application for ZF2", "license": "BSD-3-Clause", "keywords": [ "framework", "zf2" ], "homepage": "http:// framework.zend.com/", "require": { "php": ">=5.3.3", "zendframework/zendframework": ">2.2.0rc1" } }
यह फ़ाइल अनुप्रयोग पैरामीटर सेट करती है जो कि संगीतकार द्वारा उपयोग की जाएगी। इस कॉन्फ़िगरेशन का सबसे दिलचस्प हिस्सा आवश्यकता अनुभाग है, जिसमें बाहरी पुस्तकालयों की एक सूची होती है जो कि आवेदन पर निर्भर करती है। अब निर्भरता की सूची में केवल Zend फ्रेमवर्क 2 है, लेकिन भविष्य में, हम यहां कुछ और निर्भरताएं जोड़ेंगे: Doctrine, Twig और अन्य। एक नई निर्भरता जोड़ने के बाद, यह कंसोल में कमांड को निष्पादित करने के लिए पर्याप्त होगा:
php composer.phar update
और संगीतकार आवश्यक पुस्तकालयों को डाउनलोड करता है। सभी बाहरी निर्भरताएं
विक्रेता निर्देशिका में जोड़ दी जाती हैं, अब हम इसमें zendframework और संगीतकार निर्देशिका देख सकते हैं।
दस्तावेज़ जड़
हमारे आवेदन का document_root प्रोजेक्ट की जड़ में नहीं है, लेकिन
सार्वजनिक निर्देशिका में, यह यहाँ है कि
index.php फ़ाइल स्थित है - हमारे प्रोजेक्ट के लिए प्रवेश बिंदु और वेब सर्वर को इस निर्देशिका के साथ काम करने के लिए कॉन्फ़िगर किया जाना चाहिए।
Index.php कई महत्वपूर्ण कार्य करता है, जिनमें से दो सबसे दिलचस्प बाहरी पुस्तकालय कनेक्ट कर रहे हैं, एप्लिकेशन कॉन्फ़िगरेशन लोड कर रहे हैं और इसे लॉन्च कर रहे हैं।
बाहरी पुस्तकालयों को जोड़ने के लिए,
init_autoloader.php फ़ाइल को प्रोजेक्ट रूट से
निष्पादित किया जाता है, जो बदले में
विक्रेता / ऑटोलैड.php और
विक्रेता / कंपोज़र / autoaload_real.php फ़ाइल को स्वचालित रूप से
कंपोज़र द्वारा उत्पन्न करता है। यह फ़ाइल संगीतकार द्वारा लोड किए गए बाहरी पुस्तकालयों के लिए ऑटोलॉड विधियों को परिभाषित करती है। इस प्रकार, जब हम अपने मॉड्यूल के कोड में फॉर्म
Zend \ View \ Model \ ViewModel के नामस्थान को जोड़ते हैं, तो PHP को पता होगा कि निर्दिष्ट नामस्थानों की खोज करने के लिए कौन सी फाइलें हैं।
कोड की लाइन:
Zend\Mvc\Application::init(require 'config/application.config.php')->run();
एप्लिकेशन कॉन्फ़िगरेशन फ़ाइलों को डाउनलोड करता है और इसे लॉन्च करता है। एप्लिकेशन को आरंभीकृत करने की प्रक्रिया में (
Zend \ Mvc \ Application :: init () विधि को कॉल करके), एक
ServiceManager बनाया जाता है - एक प्रमुख ऑब्जेक्ट जो अनुप्रयोग के कई हिस्सों में उपयोग किया जाता है। डिफ़ॉल्ट रूप से, ServiceManager एक अन्य मुख्य ऑब्जेक्ट बनाता है - EventManager। भविष्य में, जब हम उनकी सेटिंग में हमारे मॉड्यूल बनाते हैं, तो हम सेवा प्रबंधक को सूचित करेंगे कि हमारे मॉड्यूल को काम करने के लिए आपको किन अन्य वस्तुओं की आवश्यकता है।
हम बाद में ServiceManager के बारे में बात करेंगे, लेकिन अब हम
विन्यास निर्देशिका पर करीब से नज़र डालते हैं। इसमें फ़ाइल
application.config.php शामिल है , जो
एप्लिकेशन के कॉन्फ़िगरेशन के साथ एक सरणी देता है, जो बहुत सारी दिलचस्प बातें बता सकता है।
मॉड्यूल सरणी में शामिल मॉड्यूल की एक सूची शामिल है। अब हमारे पास केवल एक एप्लिकेशन मॉड्यूल सक्षम है, लेकिन भविष्य में अधिक होगा।
माड्यूल_लिस्टर_ओप्शन्स एरे में दो दिलचस्प तत्व होते हैं - माड्यूल_पैथ और config_glob_paths अरेस्ट:
- मॉड्यूल_पैथ बताता है कि प्लग-इन के लिए कहां देखना है, डिफ़ॉल्ट रूप से विक्रेता निर्देशिकाओं में बाहरी निर्भरताएं हैं, और मॉड्यूल - यहां हमारी परियोजना के लिए हमारे द्वारा विकसित मॉड्यूल होंगे।
- Config_glob_paths में मॉड्यूल कॉन्फ़िगरेशन फ़ाइलों के लिए पथ मास्क होते हैं। रेग्युलर एक्सप्रेशन 'config / autoload / {, *।} {Global, local} .php' का अर्थ है कि फॉर्म की सभी फाइलें mod_name। {Global या स्थानीय} .php, global.php, config. autoload निर्देशिका से local.php डाउनलोड की जाएंगी। ।
इस प्रकार, सबसे पहले, सेटिंग्स को config / application.config.php फ़ाइल से लोड किया जाता है, फिर सेटिंग्स को config / autoload / {, *।} {} ग्लोबल, स्थानीय} .php फ़ाइलों से डाउनलोड किया जाता है, और मॉड्यूल स्तर पर निर्दिष्ट सेटिंग्स (। हम इस बारे में बाद में बात करेंगे)।
यदि config / autoload में एक ही मॉड्यूल के लिए दो सेटिंग्स फ़ाइलें हैं: वैश्विक और स्थानीय (मॉड्यूल_name.global.php और मॉड्यूल_name.local.php), तो वैश्विक फ़ाइल पहले लोड की जाएगी, उसके बाद स्थानीय फ़ाइल, अर्थात् स्थानीय सेटिंग्स वैश्विक लोगों पर पूर्वता लें।
स्थानीय .php और * .local.php फाइलें डिफ़ॉल्ट रूप से .gitignore फाइल में शामिल हैं (यदि आप एक अलग संस्करण नियंत्रण प्रणाली का उपयोग करते हैं, तो आपको उन्हें मैन्युअल रूप से अपवादों में जोड़ना होगा) और उनका उपयोग केवल उन सेटिंग्स के लिए किया जाना चाहिए जो केवल वर्तमान परिवेश के अनुरूप हों। यही है, यदि आपके पास कई अलग-अलग साइटों पर एक फॉर्म या किसी अन्य में लॉन्च की गई परियोजना है: उत्पादन, परीक्षण और विकास साइटें, तो एप्लिकेशन की वैश्विक सेटिंग्स में आपको डेटा संग्रहीत करने की आवश्यकता होती है जो सभी सूचीबद्ध साइटों के लिए प्रासंगिक है, और स्थानीय सेटिंग्स में जो प्रत्येक साइट के लिए अद्वितीय है, उदाहरण के लिए। , डेटाबेस तक पहुँचने के लिए डेटा।
संपूर्ण एप्लिकेशन के लिए वैश्विक कॉन्फ़िगरेशन फ़ाइलों के अलावा, प्रत्येक मॉड्यूल की अपनी सेटिंग फ़ाइल हो सकती है। इस तरह के मॉड्यूल विन्यास फाइल को उस क्रम में लोड किया जाता है जिसमें
अनुप्रयोग .config.php फ़ाइल में सक्रिय मॉड्यूल की सूची परिभाषित होती है। इस प्रकार, यदि आप अपने मॉड्यूल में किसी अन्य मॉड्यूल की सेटिंग को ओवरराइड करना चाहते हैं, तो इस सूची में आपका मॉड्यूल कम होना चाहिए।
अंतिम महत्वपूर्ण और अभी तक नहीं माना गया निर्देशिका मॉड्यूल निर्देशिका है। इस निर्देशिका में हमारे आवेदन के लिए हमारे द्वारा विकसित मॉड्यूल शामिल होंगे। ZendSkeletonApplication के साथ, एक अनुप्रयोग मॉड्यूल की आपूर्ति की जाती है, लेकिन इसकी संरचना की खोज करने से पहले, आइए देखें कि एक ServiceManager क्या है और इसकी आवश्यकता क्यों है।
ServiceManager
आधिकारिक दस्तावेज (
http://framework.zend.com/manual/2.2/en/modules/zend.service-manager.intro.html ) का कहना है कि ServiceManager एक घटक है जो सेवा लोकेटर पैटर्न को लागू करता है, जिसे अन्य वस्तुओं को पुनः प्राप्त करने के लिए डिज़ाइन किया गया है। । दूसरे शब्दों में, यह कुछ प्रविष्टि बिंदु है जो आपको सेवा प्रबंधक में पंजीकृत किसी भी ऑब्जेक्ट को एप्लिकेशन में कहीं से भी एक्सेस करने की अनुमति देता है।
ऑब्जेक्ट्स ServiceManager में या तो मॉड्यूल में दर्ज किए जाते हैं। service_manager सेक्शन में mod.config.php कॉन्फ़िगरेशन फ़ाइल या getServiceConfig () विधि में
Module.php में, यह कुछ इस तरह दिखता है (उदाहरण प्रलेखन से कॉपी किया गया है):
<?php // a module configuration, "module/SomeModule/config/module.config.php" return array( 'service_manager' => array( 'aliases' => array( // 'SomeModule\Model\User' => 'User', ), 'factories' => array( // — , // — , FactoryInterface, // , FactoryInterface, // PHP 'User' => 'SomeModule\Service\UserFactory', 'UserForm' => function ($serviceManager) { $form = new SomeModule\Form\User(); // Retrieve a dependency from the service manager and inject it! $form->setInputFilter($serviceManager->get('UserInputFilter')); return $form; }, ), 'invokables' => array( // — , // — , . 'UserInputFiler' => 'SomeModule\InputFilter\User', ), 'services' => array( // — , // — . 'Auth' => new SomeModule\Authentication\AuthenticationService(), ), ), );
हमारे किसी भी नियंत्रक में ServiceManager के उपरोक्त विन्यास के बाद, हम अब फॉर्म का एक कोड कह सकते हैं:
$user_form = $this->getServiceLocator()->get('UserForm');
और $ user_form ऑब्जेक्ट में संबंधित फॉर्म होगा।
अब यह अनुप्रयोग मॉड्यूल पर लौटने का समय है, ZendSkeletonApplication का हिस्सा है।
आवेदन मॉड्यूल
इस मॉड्यूल का डायरेक्टरी ट्री इस तरह दिखता है:
config/ module.config.php language/ < *.po > src/ Application/ Controller/ IndexController.php view/ application/ index/ index.phtml error/ 404.phtml index.phtml layout/ layout.phtml Module.php
आइए Module.php से शुरू करते हैं। यह फ़ाइल 3 विधियों के साथ एक मॉड्यूल वर्ग घोषित करती है:
- onBootstrap ();
- getConfig ();
- getAutoloaderConfig ()।
इस मॉड्यूल में onBootstrap () विधि का कोड सेगमेंट प्रकार के मार्गों की सर्विसिंग के लिए ज़िम्मेदार है (लगभग रूट थोड़ा नीचे)।
GetAutoloaderConfig () विधि उस ढांचे के मूल को बताती है जहां मॉड्यूल के स्रोत कोड को देखना है:
public function getAutoloaderConfig() { return array( 'Zend\Loader\StandardAutoloader' => array( 'namespaces' => array( __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, ), ), ); }
वर्तमान मामले में, यह
मॉड्यूल / अनुप्रयोग / src / अनुप्रयोग निर्देशिका है।
GetConfig () विधि मॉड्यूल सेटिंग फ़ाइल का पथ लौटाती है:
return include __DIR__ . '/config/module.config.php';
यह फ़ाइल निम्न डेटा वाली सेटिंग्स के साथ एक सरणी देता है:
- राउटर सरणी का तत्व एक सरणी है जिसमें मॉड्यूल द्वारा सेवा किए गए मार्गों की सूची और प्रत्येक मार्गों के लिए नियंत्रकों की एक सूची है,
- view_manager में टेम्प्लेट के लिए पथ होते हैं जिनका उपयोग एप्लिकेशन द्वारा किया जाएगा और टेम्पलेट इंजन के लिए कई अतिरिक्त सेटिंग्स,
- service_manager - उन वस्तुओं की सूची जो सेवा प्रबंधक द्वारा आरम्भ की जानी चाहिए,
- कई अन्य सेटिंग्स।
अन्य MVC फ्रेमवर्क की तरह, Zend फ्रेमवर्क अवधारणाओं का उपयोग करता है जैसे कि एक मार्ग, एक नियंत्रक और एक क्रिया। मार्ग पृष्ठ का पता, नियंत्रक और क्रिया - कार्यों को निर्धारित करता है जो पृष्ठ प्रदर्शित करने के लिए किए जाएंगे। प्रत्येक नियंत्रक एक वर्ग है, और क्रियाएँ नाम nameAction () प्रकार के नाम के साथ विधियां हैं। नतीजतन, प्रत्येक नियंत्रक में कई क्रियाएं शामिल हो सकती हैं, उदाहरण के लिए, BlogPostController () नियंत्रक, जिसे हम आगे बनाएंगे, इसमें क्रियाएं addAction (), editAction (), deleteAction (), viewAction () और indexAction () शामिल होंगे।
एप्लिकेशन मॉड्यूल सेटिंग्स दो मार्गों को परिभाषित करती हैं:
return array( 'router' => array( 'routes' => array( 'home' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'index', ), ), ), 'application' => array( 'type' => 'Literal', 'options' => array( 'route' => '/application', 'defaults' => array( '__NAMESPACE__' => 'Application\Controller', 'controller' => 'Index', 'action' => 'index', ), ), 'may_terminate' => true, 'child_routes' => array( 'default' => array( 'type' => 'Segment', 'options' => array( 'route' => '/[:controller[/:action]]', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ), 'defaults' => array( ), ), ), ), ), ), ), );
- मार्ग / (साइट रूट, टाइप लिटरल) के लिए, एप्लिकेशन \ नियंत्रक \ सूचकांक नियंत्रक जिम्मेदार है।
- फॉर्म / एप्लिकेशन / [: कंट्रोलर [/: एक्शन]] (टाइप सेगमेंट) के प्रकारों के लिए - कंट्रोलर और एक्शन तर्क के रूप में पारित हो जाता है, यानी मॉड्यूल के अंदर यह नए कंट्रोलर और एक्शन को परिभाषित करने के लिए पर्याप्त है और वे तुरंत वर्णित पते पर उपलब्ध होंगे। इसके कारण, मार्ग / यहाँ मार्ग / अनुप्रयोग / सूचकांक / सूचकांक के समान है।
कई प्रकार के मार्ग हैं, उनका विवरण प्रलेखन में पाया जा सकता है:
Framework.zend.com/manual/2.2/en/modules/zend.mvc.rout.html ।
एप्लिकेशन मॉड्यूल में एक सिंगल इंडेक्सकंट्रोलर () कंट्रोलर के साथ एक सिंगल इंडेक्सएशन () एक्शन होता है, जो स्वागत संदेश के साथ एक पेज देता है। इस पृष्ठ को प्रदर्शित करने के लिए, टेम्पलेट्स का उपयोग किया जाता है जो मॉड्यूल की दृश्य निर्देशिका में हैं।
इसके साथ, मैं लेख के पहले भाग को पूरा करना चाहूंगा, अगर यह मांग में निकला, तो मैं शेष दो हिस्सों को पूरा करूंगा और प्रकाशित करूंगा, जिसमें मेरे खुद के मॉड्यूल को विकसित करने और उपयोगकर्ताओं के साथ काम करने के लिए तंत्र का वर्णन करने का उदाहरण होगा।
युपीडी:लेख का दूसरा और
तीसरा भाग।