Zum Inhalt springen

Behaviors & Code-Erzeugung

Definitionen beschreiben, wie Blöcke aussehen; Behaviors definieren, was sie tun. Die Behaviors-Map paart jeden Block-Identifier mit der Funktion, die seinen ausführbaren Code erzeugt:

import type { MorphicBehaviorMap } from "morphic-blocks";
export const behaviors: MorphicBehaviorMap = {
text_print(proxy) {
return `console.log(${proxy.inputs.TEXT ?? "undefined"});\n`;
},
};

Die Code-Erzeugung ist einseitig und entwicklergesteuert: Was auch immer dein Behavior als String zurückgibt, ist der Code. Es gibt keine feste Zielsprache — Behaviors geben typischerweise JavaScript aus, weil der Browser das ausführen kann, aber die Strings gehören dir.

Deine Generate-Funktion erhält einen Proxy des lebenden Blocks:

Eigenschaft Was sie enthält
blockId Die Blockly-Block-ID
blockType Der saubere Block-Identifier (z. B. text_print)
mode Der aktive Workspace-Mode
inputs Erzeugter Code angehängter Blöcke, geschlüsselt nach Input-Namen
fields Feldwerte, geschlüsselt nach Feldnamen
context Render-Kontext

proxy.inputs.TEXT ist der bereits erzeugte Code des Blocks, der im TEXT-Slot steckt — die Erzeugung rekursiert für dich durch das Programm.

Ein Behavior kann mehr als eine Generate-Funktion sein. Die Langform:

export const behaviors: MorphicBehaviorMap = {
text_print: {
init(block, context) {
// einmaliges Setup bei Erstellung des Blocks
},
onViewApplied(block, context) {
// aufgerufen, nachdem ein Mode/View angewendet wurde — hier *eigene*
// Blockly-Felder anhängen (Dropdown/Text/Number/Checkbox via `fields`)
},
generate(proxy) {
return `console.log(${proxy.inputs.TEXT ?? "undefined"});\n`;
},
},
};
Hook Wann er läuft
init Einmal, bei Instanziierung des Blocks
onViewApplied Nach jeder Mode-Anwendung — eigene Felder anhängen (Standard-Dropdown/Text/Number/Checkbox gehören in fields)
generate Während der Code-Erzeugung

Eine reine Funktion ist die Kurzform für { generate }.

const js = engine.generateJavaScript();
// mit Block-zu-Codeposition-Metadaten (von der Selection-Sync genutzt):
const { code, metadata } = engine.generateJavaScriptWithMetadata();
// in der Seite ausführen:
engine.runJavaScript();

Blöcke kodieren Gruppierung durch Verschachtelung: Ein Multiplikations-Block, der einen Additions-Block enthält, ist 2 * (3 + 4). Reiner Text verliert das, sofern die Klammern nicht ausgeschrieben werden — deshalb setzt das Framework sie: im ausführbaren Code ebenso wie im gerenderten Text.

Ein Operand wird geklammert, wenn zwei Bedingungen zutreffen: Der Operand-Block setzt selbst Werte zusammen (er hat Value-Inputs), und das Template des Eltern-Blocks setzt mehrere Werte zusammen. Die zweite Bedingung hält Templates mit nur einem Slot sauber:

Template Value-Slots Ergebnis
%1 %OP %2 2 2 * (3 + 4) — Gruppierung bleibt erhalten
print(%1) 1 print(2 * 3)
if %1: 1 if 10 == 20: — idiomatisches Python

Ein unärer Operator ist die Ausnahme: -%1 hat nur einen Slot, -(3 + 4) braucht aber Klammern. Schreibe sie dort selbst ins Template — -(%1) —, wo das Framework die Absicht nicht ableiten kann.

Zwei verschiedene Dinge machen aus Blöcken Text — verwechsle sie nicht:

  • Behaviors erzeugen den ausführbaren Code (generateJavaScript()).
  • Templates (code-Elements mit %N-Einsetzung) erzeugen, was Codespace und Preview anzeigen.

Sie sind absichtlich unabhängig: Was Lernende sehen, kann Python sein, während das, was läuft, JavaScript ist. Siehe Presets & Views zum Verdrahten der Views und die Codespace-Anleitung für die editierbare Text-Ansicht.