Blockly Developer Tools מאפשר ליצור בלוקים בהתאמה אישית באמצעות בלוקים! הוא תומך בשדות שמתפרסמים כתוספים, בנוסף לשדות שמגיעים עם ליבת Blockly. אם יצרתם שדה בהתאמה אישית, אתם יכולים להוסיף לו תמיכה ב-Block Factory באמצעות המדריך הזה. כדי להוסיף תמיכה בשדה מותאם אישית, צריך לפרסם אותו ב-npm. בנוסף, עליך להתחייב לעדכן את השדה כדי להתעדכן בשינויים ב-Blockly, אחרת יכול להיות שנצטרך להסיר אותו מ-Block Factory בעתיד.
פיתוח ב-Block Factory
קוד המקור של Block Factory נמצא במאגר blockly-samples בספרייה examples/developer-tools
.
כדי לשלוח שינוי בכלי הפיתוח ב-blockly-samples, צריך לפעול לפי השלבים הרגילים לפיתוח ב-blockly-samples. בניגוד לעבודה עם תוספים, תצטרכו להריץ את npm
install
ישירות מהספרייה examples/developer-tools
, ולא מרמת הבסיס של blockly-samples.
התקנת הפלאגין
כדי שהשדה המותאם אישית יופיע בתצוגה המקדימה ב-Block Factory, צריך להתקין אותו. מוסיפים את השדה כ-npm dependency של developer-tools. לאחר מכן, רושמים אותו או מבצעים פעולות הגדרה אחרות שנדרשות ב-developer-tools/src/blocks/index.ts
.
יצירת בלוק לשדה
מפעל הבלוקים משתמש בבלוקים כדי ליצור בלוקים בהתאמה אישית, ולכן תצטרכו בלוק שמייצג את השדה המותאם אישית.
יצירת הגדרת הבלוק
צריך לעצב את הבלוק לשדה. אם רוצים, אפשר אפילו לעצב אותו באמצעות Block Factory. הבלוק צריך לאפשר למשתמש להגדיר את ההגדרה הנדרשת בשדה, כמו ערכי ברירת מחדל ושם. מוסיפים את הגדרת הבלוק אל developer-tools/src/blocks/fields.ts
ומייבאים אותה אל developer-tools/src/blocks/index.ts
.
הוספת בלוק לארגז הכלים
לאחר מכן, צריך להוסיף את הבלוק הזה להגדרה של ארגז הכלים כדי שהמשתמשים יוכלו לגשת אליו. ההגדרה של ארגז הכלים נמצאת ב-developer-tools/src/toolbox.ts
. הבלוק אמור להתווסף לקטגוריה Fields (שדות).
מחוללי קוד
התכונה Block Factory פועלת באמצעות מערכת Code Generator שאתם כבר מכירים מ-Blockly. לכל בלוק יש מחולל קוד בלוקים לכל סוג של פלט שנוצר על ידי Block Factory, ובלוקי האב מרכיבים את הקוד של בלוקי הבן לפלט הנכון. כדי להוסיף תמיכה בשדה מותאם אישית, צריך להוסיף פונקציות ליצירת קוד בלוק לכל אחת מהמחלקות של CodeGenerator.
יוצרים קובץ בשביל בלוק השדות בספרייה 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})`;
};
בלוק הזווית שהמשתמש גרר מהקטגוריה Fields (שדות) בארגז הכלים Block Factory יש שני שדות:
-
FIELDNAME
: המשתמש יכול להגדיר את שם השדה באבן הבניין המותאמת אישית -
ANGLE
: המשתמש יכול להגדיר את ערך ברירת המחדל של הזווית
במחולל קוד הבלוקים הזה, מקבלים את ערך הזווית שמוגדר כברירת מחדל ומעבירים אותו כארגומנט היחיד לבונה FieldAngle
. שם השדה תמיד מועבר כארגומנט השני ל-appendField
.
הגדרת JSON
הפלט של jsonDefinitionGenerator
דומה, אבל הוא מציג את החלק בהגדרת בלוק ה-JSON שמתאים לשדה. בדרך כלל, הקוד הזה הוא אובייקט JSON שכולל:
-
type
: תואם לשם השדה שלכם במרשם השדות של Blockly -
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);
};
כותרות קוד
מחולל כותרות הקוד יוצר את פלט כותרות הקוד שמוצג ב-Block
Factory. אפשר להחליף בין ייבוא של esmodule לבין תגי script, בהתאם לאופן שבו המשתמש רוצה לטעון את הקוד. לכן יש למעשה שני מופעים שונים של הגנרטור: אחד לכל מקרה. צריך להוסיף גנרטור של קודים לחסימה לכל אחד מהם. דוגמה ל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
שמאפשרת לציין שורת קוד שצריך להפעיל לפני שמשתמשים בשדה בקוד. בדרך כלל, הפעולה הזו כוללת ייבוא של השדה או טעינה שלו באמצעות תג script, ואולי גם קריאה לפונקציה שתבצע רישום של השדה במרשם השדות של Blockly.
במקרה של שני מחוללי הקודים האלה, צריך להוסיף את כל הקוד באמצעות קריאות ל-addHeaderLine
. הפונקציה הזו תבטיח שכל שורת כותרת תוצג רק פעם אחת, גם אם בלוק השדות המותאמים אישית שלכם ישמש כמה פעמים בבלוק מותאם אישית אחד. מחולל קוד החסימה אמור להחזיר מחרוזת ריקה.
קובץ stub של גנרטור
לבסוף, יש לנו את הגנרטור שיוצר את ה-stub של הגנרטור בשדה. במחולל קוד הבלוקים הזה, תכתבו קוד שמייצר קוד שעוזר למשתמש לכתוב קוד שמייצר קוד. מבולבלים? זה יותר פשוט ממה שזה נשמע!
ה-stub של הגנרטור עבור בלוק מותאם אישית כולל משתנה מוכן מראש שמייצג כל שדה בבלוק. לאחר מכן יש TODO
שהמשתמש צריך לסיים כדי להרכיב את כל המשתנים האלה למחרוזת הקוד הסופית שהבלוק המותאם אישית יחזיר. כלומר, בדרך כלל כל מה שצריך לעשות גנרטור קוד הבלוקים הוא להחזיר את השורה שיוצרת את המשתנה המותאם אישית הזה. נניח שהמשתמש יוצר בלוק בהתאמה אישית שיוסיף קרני שמש לקנבס. הם
מוסיפים שדה זווית לבלוק ונותנים לו את השם "SUN_DIRECTION"
. ה-stub של הגנרטור עבור הבלוק הזה יכלול את השורה 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
וכו') יחד עם השם שהמשתמש נתן לשדה.
בדיקה
אחרי שכותבים את כל החלקים האלה, אפשר להפעיל את BlockFactory על ידי הרצת npm start
בספרייה blockly-samples/examples/developer-tools
. אפשר לגרור את הבלוק מקטגוריית השדה, להוסיף אותו לקלט בבלוק ולראות את השינוי בפלט. בודקים שהתצוגה המקדימה של הבלוק נראית נכון, ושהקוד של כל אחד מקטעי הפלט נכון.