diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2026-08-12 18:05:41 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2026-08-12 18:05:41 +0200 |
| commit | 52a4aa583ea522afb1aba9a529f434666f3be776 (patch) | |
| tree | 970a8b3bd56657f6f1daac5e016d4ecc3fb3ebb5 /Info | |
| parent | 37779aebcb9f859866e6458afef5ab406b5607fd (diff) | |
| download | unterricht-52a4aa583ea522afb1aba9a529f434666f3be776.tar.gz unterricht-52a4aa583ea522afb1aba9a529f434666f3be776.zip | |
planet: add collectable glossary entries
Diffstat (limited to 'Info')
| -rw-r--r-- | Info/9/3/Planet/Readme.md | 4 | ||||
| -rw-r--r-- | Info/9/3/Planet/glossar.yml | 16 | ||||
| -rw-r--r-- | Info/9/3/Planet/modellierung/landung/modellierung.md | 2 | ||||
| -rw-r--r-- | Info/9/3/Planet/modellierung/zwischenlager/methoden-testen.md | 10 | ||||
| -rw-r--r-- | Info/9/3/Planet/templates/add-glossary-item.js | 117 | ||||
| -rw-r--r-- | Info/9/3/Planet/templates/planet-mebis-page-template.css | 24 | ||||
| -rw-r--r-- | Info/9/3/Planet/templates/planet-mebis-page-template.html | 3 |
7 files changed, 169 insertions, 7 deletions
diff --git a/Info/9/3/Planet/Readme.md b/Info/9/3/Planet/Readme.md index f3c7b693..28900ac8 100644 --- a/Info/9/3/Planet/Readme.md +++ b/Info/9/3/Planet/Readme.md @@ -43,6 +43,10 @@ Einige werden automatisch mit dem Abschließen mancher TODO-Aktivitäten vergebe * Wiederholung vor den Kontroll-Strukturen * Erklärung warum graphische Repräsentation (Struktogramme) nützlich sind * Sich weiter aufbauendes Cheatsheet +* Glossar + * Ergänze mehr Begriffe + * Vergebe einen Badge wenn alle Begriffe gefunden wurden. + * Mache den Style von GLoassr-Einträgen weniger aufdringlich * Tipps für bedingte Wiederholung (SuS) sollten Code mal gesehen haben oder Hilfe beim Erarbeiten bekommen. ## Lizenz diff --git a/Info/9/3/Planet/glossar.yml b/Info/9/3/Planet/glossar.yml index cca2bd36..f8c9a972 100644 --- a/Info/9/3/Planet/glossar.yml +++ b/Info/9/3/Planet/glossar.yml @@ -1,6 +1,20 @@ title: Glossar entries: + - name: Klasse + def: ein Bauplan für Objekte + - name: Objekt + def: Konkretes Exemplar, das nach dem Bauplan (seiner Klasse) erstellt wurde + - name: Attribut + def: Merkmal eines Objekts + - name: Attributwert + def: Merkmal eines Objekts - name: Methode def: Fähigkeit eines Objekts - name: Methodenaufruf - def: Botschaft an ein Objekt, seine Methode auszuführen + def: Botschaft an ein Objekt, eine Methode auszuführen + - name: Datentyp + def: Angabe welche Werte möglich sind (Text, Ganzahlen, ...) + - name: Parameter + def: Platzhalter für Eingaben + - name: Rückgabewert + def: Wert, der bei einem Methodenaufruf als Antwort zurückgegeben wird diff --git a/Info/9/3/Planet/modellierung/landung/modellierung.md b/Info/9/3/Planet/modellierung/landung/modellierung.md index fa20b3f1..11a15973 100644 --- a/Info/9/3/Planet/modellierung/landung/modellierung.md +++ b/Info/9/3/Planet/modellierung/landung/modellierung.md @@ -21,7 +21,7 @@ Notiere dir deinen Online-IDE Zugang aus der Seite: Überblick Online-IDE. #### Schritt 0.1 :::{.merke data-class="Merke: Modellierung"} -**Modellierung** bezeichnet die Übertragung von Dingen aus der "echten" Welt in Konzepte einer Programmiersprache, wie beispielsweise **Klassen** und **Objekte**. +**Modellierung** bezeichnet die Übertragung von Dingen aus der "echten" Welt in Konzepte einer Programmiersprache, wie beispielsweise [**Klassen**]{.glossary-item-toadd data-term="Klasse" data-def="ein Bauplan für Objekte"} und [**Objekte**]{.glossary-item-toadd data-term="Objekt" data-def="Konkretes Exemplar, das nach dem Bauplan (seiner Klasse) erstellt wurde"}. ::: :::{.tipp style="margin-top:1em;"} diff --git a/Info/9/3/Planet/modellierung/zwischenlager/methoden-testen.md b/Info/9/3/Planet/modellierung/zwischenlager/methoden-testen.md index a291355d..8143c04f 100644 --- a/Info/9/3/Planet/modellierung/zwischenlager/methoden-testen.md +++ b/Info/9/3/Planet/modellierung/zwischenlager/methoden-testen.md @@ -11,7 +11,7 @@ Vergiss nicht das Arbeitsblatt: Methoden Testen herunterzuladen. #### Schritt 3.1.1 Klassen legen fest, was Objekte tut können. -Die Logik was ein Objekt tun kann nennt man **Methode**. +Die Logik was ein Objekt tun kann nennt man [**Methode**]{.glossary-item-toadd data-def="Fähigkeit eines Objekts"}. * Jede Methode hat einen Namen gefolgt von einem Klammernpaar `()`{.java}, z. B. besitzt ein Rover die Methode `fahre()`{.java}. * Methoden verändern den Zustand von Objekten, z. B. wird durch Aufruf der Methode `fahre()`{.java} die Position des Rovers verändert: @@ -32,7 +32,7 @@ object rover { :::: :::: {.column width=20%} -Methodenaufruf +[Methodenaufruf]{.glossary-item-toadd data-def="Botschaft an ein Objekt, eine Methode auszuführen"} ``` fahre() @@ -55,8 +55,8 @@ object rover { :::: ::: -* Manche Methoden verlangen eine Eingabe, einen sogenannten Parameter, z. B. `drehe(String richtung)`{.java}. -→ `richtung` ist ein Parameter vom Datentyp `String`. Ein `String` ist eine Zeichenkette, als Wert muss man also einen Text eingeben und diesen in Anführungszeichen setzen, z. B. `drehe("rechts")`{.java}. +* Manche Methoden verlangen eine Eingabe, einen sogenannten [Parameter]{.glossary-item-toadd data-def="Platzhalter für Eingaben"}, z. B. `drehe(String richtung)`{.java}. +→ `richtung` ist ein Parameter vom [Datentyp]{.glossary-item-toadd data-def="Angabe welche Werte möglich sind (Text, Ganzahlen, ...)"} `String`. Ein `String` ist eine Zeichenkette, als Wert muss man also einen Text eingeben und diesen in Anführungszeichen setzen, z. B. `drehe("rechts")`{.java}. :::{.merke data-class="Merke: Methoden"} Eine Methode beschreibt die Fähigkeit eines Objekts. @@ -155,7 +155,7 @@ Planet: Methoden Sortieren **Verändernde Methoden** verändern den Objektzustand, sie beginnen mit dem Schlüsselwort `void`{.java}. Beispiel: `void fahre()`{.java} -**Zurückgebende Methoden** geben Attributwerte aus, sie beginnen mit dem Datentyp des zurückzugebenden Wertes. +**Zurückgebende Methoden** geben [Attributwerte]{.glossary-item-toadd data-term="Attributwert" data-def="Konkreter Wert eines Attributs"} aus, sie beginnen mit dem Datentyp des zurückzugebenden Wertes. Beispiel: `boolean huegelVorhanden()`{.java} ::: diff --git a/Info/9/3/Planet/templates/add-glossary-item.js b/Info/9/3/Planet/templates/add-glossary-item.js new file mode 100644 index 00000000..8d9eb33b --- /dev/null +++ b/Info/9/3/Planet/templates/add-glossary-item.js @@ -0,0 +1,117 @@ +// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later +// Copyright (C) 2026 Florian Fischer + +// Get the id to this course's glossary activity +const activityAutoLinkDiv = document.getElementById("glossary-autolink"); +const activityLinkNode = activityAutoLinkDiv.querySelector("a.autolink"); +const glossaryUrl = activityLinkNode.href; +const glossaryId = (/id=(\d+)/).exec(glossaryUrl)[1]; +// Remove the dummy autolink +activityLinkNode.remove(); + +class GlossaryPost { + constructor(eid, showurl, concept) { + this.eid = eid; + this.showurl = showurl; + this.concept = concept; + } +} + +function autoLinkHTML(post) { + const a = document.createElement("a"); + a.classList.add("glossary", "autolink", "concept", `glossaryid${post.eid}`); + a.dataset.entryid=post.eid; + a.href = post.showurl; + a.innerHTML = post.concept; + return a.outerHTML; +} + +function replaceAllText(node, pattern, newHTML) { + var walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT); + + const found = []; + + while (walker.nextNode()) { + const node = walker.currentNode; + if (node.nodeValue.trim() && !(["SCRIPT", "STYLE"]).includes(node.parentNode.nodeName) ) { + + if (node.nodeValue.includes(pattern)) + found.push(node.parentNode); + } + } + + for (const node of found) { + node.innerHTML = node.innerHTML.replace(pattern, newHTML); + } +} + +const termsAlreadyAdded = new Map(); + +async function autoLink() { + const glRes = await fetch(glossaryUrl + "&hook=ALL"); + const glDoc = new DOMParser().parseFromString(await glRes.text(), "text/html"); + + glDoc.querySelectorAll(".glossarypost.dictionary").forEach((post) => { + const concept = post.querySelector(".entry > .concept").innerText; + const showurl = post.querySelector('.commands > a.icon[title*="Eingabelink"]').href; + const eid = (/eid=(\d+)/).exec(showurl)[1]; + + termsAlreadyAdded.set(concept, new GlossaryPost(eid, showurl, concept)); + }); + + const page = document.querySelector('div[role="main"]'); + for (const post of termsAlreadyAdded.values()) { + replaceAllText(page, post.concept, autoLinkHTML(post)); + } +} + +async function addGlossaryItems() { + const itemsToAdd = document.querySelectorAll(".glossary-item-toadd"); + for (const item of itemsToAdd) { + if (termsAlreadyAdded.has(item.dataset.term)) { + item.classList.remove("glossary-item-toadd"); + continue; + } + + item.addEventListener("click", async function() { + const editFormData = new FormData(); + + editFormData.set("cmid", glossaryId); + editFormData.set("sesskey", M.cfg.sesskey); + + const editRes = await fetch("/mod/glossary/edit.php", { + method: "POST", + body: editFormData, + }); + + const editDoc = new DOMParser().parseFromString(await editRes.text(), "text/html"); + const form = editDoc.querySelector('div[role="main"] > form'); + const formData = new FormData(form); + + formData.set("concept", item.dataset.term ? item.dataset.term: item.textContent); + formData.set("definition_editor[text]", item.dataset.definition); + formData.set("usedynalink", "1"); + formData.set("submitbutton", "Änderung speichern"); + + const addRes = await fetch("/mod/glossary/edit.php", { + method: "POST", + body: formData, + }); + const showAddedPostUrl = addRes.url; + + item.classList.remove("glossary-item-toadd"); + + const eid = (/hook=(\d+)/).exec(showAddedPostUrl)[1]; + const showurl = `/mod/glossary/showentry.php?eid=${eid}&displayformat=dictionary`; + const post = new GlossaryPost(eid, showurl, item.dataset.term) + item.innerHTML = autoLinkHTML(post); + + // Link to all occurrences of the added term + const page = document.querySelector('div[role="main"]'); + replaceAllText(page, post.concept, autoLinkHTML(post)); + }, { once: true }); + } +} + +autoLink().then( addGlossaryItems ); +// @license-end diff --git a/Info/9/3/Planet/templates/planet-mebis-page-template.css b/Info/9/3/Planet/templates/planet-mebis-page-template.css index 0a10283d..f9ac9791 100644 --- a/Info/9/3/Planet/templates/planet-mebis-page-template.css +++ b/Info/9/3/Planet/templates/planet-mebis-page-template.css @@ -310,3 +310,27 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } opacity:0; } } + +.glossary-item-toadd { + cursor: pointer; + display: inline-block; + border-radius: 5; + animation: glossary-item-glow 1s infinite alternate; +} + +@keyframes glossary-item-glow { + from { + box-shadow: 0 0 10px -10px #aef4af; + } + to { + box-shadow: 0 0 10px 10px #aef4af; + } +} + +@media print { + .glossary-item-toadd { + background-color: none; + animation: none; + } +} + diff --git a/Info/9/3/Planet/templates/planet-mebis-page-template.html b/Info/9/3/Planet/templates/planet-mebis-page-template.html index 70c1e3b7..7c78d921 100644 --- a/Info/9/3/Planet/templates/planet-mebis-page-template.html +++ b/Info/9/3/Planet/templates/planet-mebis-page-template.html @@ -13,6 +13,8 @@ $for(include-before)$ $include-before$ $endfor$ +<div id="glossary-autolink">Glossar</div> + $body$ $for(include-after)$ @@ -21,6 +23,7 @@ $endfor$ <script> $js/h5p-autoembed.js()$ +$js/add-glossary-item.js()$ </script> </body> </html> |
