फ़ैक्ट्री ब्लॉक करने के लिए प्लगिन फ़ील्ड जोड़ें

Blockly Developer Tools की मदद से ब्लॉक का इस्तेमाल करके कस्टम ब्लॉक बनाए जा सकते हैं! यह कोर Blockly के साथ आने वाले फ़ील्ड के साथ-साथ प्लगिन के तौर पर पब्लिश होने वाले फ़ील्ड के साथ भी काम करता है. अगर आपने कस्टम फ़ील्ड बनाया है, तो इस गाइड की मदद से ब्लॉक फ़ैक्ट्री में उसके लिए सहायता जोड़ी जा सकती है. कस्टम फ़ील्ड को npm पर प्रकाशित करने के बाद ही उसके लिए सहायता जोड़ी जा सकती है. आपको Blockly में हुए बदलावों के हिसाब से, अपने फ़ील्ड को भी अपडेट करना होगा. ऐसा न करने पर, हो सकता है कि हम आने वाले समय में इसे Block फ़ैक्ट्री से हटा दें.

डेवलपमेंट ऑन द ब्लॉक फ़ैक्ट्री

ब्लॉक फ़ैक्ट्री का सोर्स कोड, examples/developer-tools डायरेक्ट्री की ब्लॉकली सैंपल रिपॉज़िटरी में मौजूद है.

ब्लॉकली सैंपल वाले डेवलपर टूल में बदलाव सबमिट करने के लिए, आपको ब्लॉक वाले सैंपल में डेवलप करने के सामान्य चरणों का पालन करना होगा. हालांकि, प्लगिन के साथ काम करने के उलट, आपको npm install को सीधे examples/developer-tools डायरेक्ट्री से चलाना होगा, न कि ब्लॉकली सैंपल के रूट लेवल पर.

प्लग इन इंस्टॉल करें

ब्लॉक फ़ैक्ट्री आपके कस्टम फ़ील्ड को झलक में दिखा सके, इसके लिए कस्टम फ़ील्ड इंस्टॉल करना होगा. अपने फ़ील्ड को डेवलपर टूल की एनपीएम डिपेंडेंसी के तौर पर जोड़ें. इसके बाद, उसे रजिस्टर करें या developer-tools/src/blocks/index.ts में जाकर सेटअप का कोई अन्य ज़रूरी काम करें.

फ़ील्ड के लिए ब्लॉक बनाना

ब्लॉक फ़ैक्ट्री, कस्टम ब्लॉक बनाने के लिए ब्लॉक का इस्तेमाल करती है. इसलिए, आपको अपने कस्टम फ़ील्ड को दिखाने वाले ब्लॉक की ज़रूरत होगी.

ब्लॉक की परिभाषा तय करना

आपको अपने फ़ील्ड के लिए ब्लॉक डिज़ाइन करना होगा; अगर आपको मेटा पाना है, तो ब्लॉक फ़ैक्ट्री का इस्तेमाल करके भी उसे डिज़ाइन किया जा सकता है! ब्लॉक से, उपयोगकर्ता आपके फ़ील्ड के लिए ज़रूरी सेटअप कॉन्फ़िगर कर सकेगा, जैसे कि डिफ़ॉल्ट वैल्यू और नाम. ब्लॉक करने के इस तरीके को developer-tools/src/blocks/fields.ts में जोड़कर, उसे developer-tools/src/blocks/index.ts में इंपोर्ट करें.

टूलबॉक्स में ब्लॉक जोड़ें

इसके बाद, आपको इस ब्लॉक को टूलबॉक्स की परिभाषा में जोड़ना होगा, ताकि उपयोगकर्ता इसे ऐक्सेस कर सकें. टूलबॉक्स की परिभाषा developer-tools/src/toolbox.ts में मौजूद है. आपका ब्लॉक "फ़ील्ड" कैटगरी में जोड़ना चाहिए.

कोड जनरेटर

ब्लॉक फ़ैक्ट्री उस कोड जनरेटर सिस्टम की मदद से काम करती है, जिसके बारे में आप पहले से ही छिपा हुआ हैं. ब्लॉक फ़ैक्ट्री से जनरेट किए गए हर तरह के आउटपुट के लिए, हर ब्लॉक में एक ब्लॉक-कोड जनरेटर होता है. पैरंट ब्लॉक, चाइल्ड ब्लॉक के कोड को सही आउटपुट में इकट्ठा करते हैं. किसी कस्टम फ़ील्ड के लिए सहायता जोड़ने के लिए, आपको हर कोड जनरेटर क्लास के लिए ब्लॉक-कोड जनरेटर फ़ंक्शन जोड़ना होगा.

output-generators/fields डायरेक्ट्री में, अपने फ़ील्ड ब्लॉक के लिए फ़ाइल बनाएं. इस फ़ाइल में, इनमें से हर एक जनरेटर के लिए आपको ब्लॉक-कोड जनरेटर जोड़ना होगा. इस फ़ाइल को blocks/index.ts फ़ाइल में इंपोर्ट करें, ताकि ब्लॉक-कोड जनरेटर फ़ंक्शन ऐप्लिकेशन में लोड हो सकें.

JavaScript की परिभाषा

javascriptDefinitionGenerator, कोड को बनाता है, जिसे उस ब्लॉक की JavaScript परिभाषा में शामिल किया जाएगा जिसमें आपका कस्टम फ़ील्ड शामिल है. आम तौर पर, इसका मतलब है कि ब्लॉक-कोड जनरेटर, .appendField(new YourFieldConstructor(arg1, arg2), 'userSpecifiedName') की तरह दिखने वाले कोड की लाइन दिखाएगा. ध्यान दें कि कोड की इस लाइन में सेमीकोलन शामिल नहीं है, क्योंकि जिस इनपुट में कई फ़ील्ड हैं उसमें appendField को कई कॉल एक साथ जोड़े जाएंगे. कंस्ट्रक्टर के आर्ग्युमेंट, उन वैल्यू से लिए जाते हैं जिन्हें उपयोगकर्ता ने फ़ील्ड ब्लॉक पर सेट किया है. यहां FieldAngle के लिए ब्लॉक-कोड जनरेटर का एक उदाहरण दिया गया है:

javascriptDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JavascriptDefinitionGenerator,
): string {
  const name = generator.quote_(block.getFieldValue('FIELDNAME'));
  const angle = block.getFieldValue('ANGLE');
  return `.appendField(new FieldAngle(${angle}), ${name})`;
};

उपयोगकर्ता ने ब्लॉक फ़ैक्ट्री टूलबॉक्स की "फ़ील्ड" कैटगरी से जो ऐंगल ब्लॉक लिया है उसमें दो फ़ील्ड होते हैं:

  • FIELDNAME: उपयोगकर्ता अपने कस्टम ब्लॉक पर फ़ील्ड का नाम सेट कर सकता है
  • ANGLE: उपयोगकर्ता, ऐंगल की डिफ़ॉल्ट वैल्यू सेट कर सकता है

इस ब्लॉक-कोड जनरेटर में, हमें ऐंगल की डिफ़ॉल्ट वैल्यू मिलती है और उसे FieldAngle कंस्ट्रक्टर के लिए, एकमात्र आर्ग्युमेंट के तौर पर पास किया जाता है. फ़ील्ड का नाम हमेशा appendField के दूसरे आर्ग्युमेंट के तौर पर पास किया जाता है.

JSON की परिभाषा

jsonDefinitionGenerator भी मिलता-जुलता है, लेकिन यह आपके फ़ील्ड से मेल खाने वाले JSON ब्लॉक की परिभाषा का हिस्सा दिखाता है. आम तौर पर, यह कोड एक JSON ऑब्जेक्ट होता है. इसमें ये चीज़ें शामिल होती हैं:

  • type: यह ब्लॉकली फ़ील्ड रजिस्ट्री में मौजूद आपके फ़ील्ड के नाम से मेल खाता है
  • name: उपयोगकर्ता अपने कस्टम ब्लॉक पर फ़ील्ड का नाम सेट कर सकता है
  • आपके फ़ील्ड के JSON शुरू करने के तरीके के लिए ज़रूरी कोई भी दूसरी कस्टम प्रॉपर्टी.

यहां FieldAngle का एक उदाहरण दोबारा दिया गया है:

jsonDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JsonDefinitionGenerator,
): string {
  const code = {
    type: 'field_angle',
    name: block.getFieldValue('FIELDNAME'),
    angle: block.getFieldValue('ANGLE'),
  };
  return JSON.stringify(code);
};

कोड हेडर

कोड हेडर जनरेटर, ब्लॉक फ़ैक्ट्री में दिखाया गया कोड हेडर आउटपुट बनाता है. इस आउटपुट को esmodule इंपोर्ट और स्क्रिप्ट टैग के बीच टॉगल किया जा सकता है. यह इस बात पर निर्भर करता है कि उपयोगकर्ता कोड को कैसे लोड करना चाहता है. इसलिए, यहां दो अलग-अलग जनरेटर इंस्टेंस होते हैं: हर मामले के लिए एक. आपको हर एक के लिए ब्लॉक-कोड जनरेटर जोड़ना होगा. यहां FieldAngle का एक उदाहरण दिया गया है:

importHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `import {registerFieldAngle, FieldAngle} from '@blockly/field-angle';`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

scriptHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `<script src="https://unpkg.com/@blockly/field-angle"></script>`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

इन जनरेटर में addHeaderLine नाम का एक तरीका होता है. इससे, कोड की एक लाइन तय की जा सकती है. इस लाइन को, कोड में आपके फ़ील्ड का इस्तेमाल करने से पहले कॉल किया जाना चाहिए. आम तौर पर, इसमें फ़ील्ड को इंपोर्ट करने या स्क्रिप्ट टैग के ज़रिए लोड करने जैसे काम शामिल होते हैं. साथ ही, इनमें ऐसे फ़ंक्शन को कॉल करना भी शामिल हो सकता है जो Blockly की फ़ील्ड रजिस्ट्री के साथ फ़ील्ड को रजिस्टर करेगा.

इन दो ब्लॉक-कोड जनरेटर के लिए, सभी कोड addHeaderLine पर कॉल के ज़रिए जोड़े जाने चाहिए. यह फ़ंक्शन पक्का करेगा कि हेडर लाइन सिर्फ़ एक बार दिखे, भले ही आपके कस्टम फ़ील्ड ब्लॉक का इस्तेमाल एक कस्टम ब्लॉक में कई बार किया गया हो. ब्लॉक-कोड जनरेटर को खाली स्ट्रिंग देनी चाहिए.

जनरेटर स्टब

आखिर में, हमारे पास जनरेटर है जो फ़ील्ड के लिए जनरेटर स्टब बनाता है. इस ब्लॉक-कोड जनरेटर में, आपको ऐसा कोड लिखा जाएगा जो कोड जनरेट करने वाला कोड जनरेट करता है. इससे उपयोगकर्ता को कोड जनरेट करने वाला कोड लिखने में मदद मिलती है. अभी तक उलझन में हैं? यह सुनने से भी ज़्यादा आसान है!

कस्टम ब्लॉक के लिए जनरेटर स्टब में पहले से बनाया हुआ वैरिएबल होता है, जो ब्लॉक पर हर फ़ील्ड को दिखाता है. इसके बाद, उपयोगकर्ता को इन सभी वैरिएबल को फ़ाइनल कोड स्ट्रिंग में जोड़ने के लिए एक TODO पूरा करना होगा, ताकि उनका कस्टम ब्लॉक वापस आ जाएगा. इसका मतलब है कि आम तौर पर आपके सभी ब्लॉक-कोड जनरेटर को वह लाइन वापस करनी होती है जो इस कस्टम वैरिएबल को बनाती है. मान लें कि उपयोगकर्ता एक कस्टम ब्लॉक बना रहा है, जिससे उसके कैनवस पर सूरज की किरणें आएंगी. वे ब्लॉक में एक ऐंगल फ़ील्ड जोड़ते हैं और उसे "SUN_DIRECTION" नाम देते हैं. इस ब्लॉक के लिए जनरेटर स्टब में const angle_sun_direction = block.getFieldValue("SUN_DIRECTION"); लाइन शामिल होगी. यह वह कोड लाइन है जो ऐंगल फ़ील्ड के लिए हमारे ब्लॉक-कोड जनरेटर को लौटाना होता है:

generatorStubGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: GeneratorStubGenerator,
): string {
  const name = block.getFieldValue('FIELDNAME');
  const fieldVar = generator.createVariableName('angle', name);
  return `const ${fieldVar} = block.getFieldValue(${generator.quote_(
    name,
  )});\n`;
};

वैरिएबल के लिए स्टैंडर्ड नाम पाने के लिए, generator.createVariableName को कॉल करें और फ़ील्ड का टाइप (जैसे कि angle, number वगैरह) पास करें. साथ ही, यह भी बताएं कि उपयोगकर्ता ने फ़ील्ड को क्या नाम दिया है.

इसका परीक्षण करें

ये सभी हिस्से लिख लेने के बाद, blockly-samples/examples/developer-tools डायरेक्ट्री में npm start चलाकर ब्लॉक फ़ैक्ट्री का इस्तेमाल किया जा सकता है. फ़ील्ड कैटगरी से अपना ब्लॉक खींचकर, उसे ब्लॉक के इनपुट में जोड़ा जा सकता है. साथ ही, आउटपुट में हुए बदलाव को देखा जा सकता है. जांचें कि ब्लॉक की झलक सही दिख रही है और हर आउटपुट सेक्शन का कोड सही है.