 # Wie unsere Website tickt. *Die Chaotikum Website ist weit mehr als nur ein mit Jekyll betriebener Blog. So hat sie mal angefangen, aber inzwischen ist sie ein Bindeglied in verschiedenen Bereichen der Infrastruktur des Vereins. Man könnte sagen, ist das nicht zu viel? Ist eine Website wirklich immer das richtige Tool? Insbesondere eine statische? Vermutlich ist die Frage berechtigt.* *Aber wie so häugfig nimmt man die Software die man gerade hat um Probleme zu lösen, und wir hatten diese Software.* ## Statischer Content - Semi-Dynamisch Der Takt der Chaotikum Website ist ein Build alle 30 Minuten. Die Chaotikum Website wird regelmäßig alle 30 Minuten gebaut. Egal ob sich was ändert oder nicht. Dafür gibt es einen [Pipeline-Schedule](https://git.chaotikum.org/chaotikum/website/-/pipeline_schedules) ``` * /30 * * * * ``` Der Grund ist denkbar einfach: Release Zeiten für Blog-Posts oder Videos können für die Zukunft eingetragen werden. Sobald der Zeitpunkt überschritten ist, werden die Posts auftomatisiert öffentlich. Danach grreifen entsprechende Automatismen, z.B. durch das RSS Tröts im Fediverse usw... ## Eine Sammlung von Sammlungen Um unsere Website zu verstehen, hilft es sich grundsätzlich damit beschäftigt zu haben, wie [Static Site Generators](https://en.wikipedia.org/wiki/Static_site_generator) üblicherweise arbeiten. Da gibt es natürlich viel varianz, aber sehr, sehr häufig entsteht ein Blog indem man haufenweise Markdown dateien in einen Ordner wirft und ein paar Templates, wie diese dargestellt werden sollten. So auch bei uns. Die Posts des Blogs finden sich im Ordner `_posts`. Bei vielen Websites ist da mehr oder weniger Schluss. Nicht bei der Chaotikum Website. Wer sich die Datei-Struktur dieses Jekyll-Projekts ansieht bemerkt allerdingsn, die große Menge an weiteren Ordnern, welche alle mit einem Unterstrich beginnen. ``` _briefing _categories _conferencefrab _conferences _events _imagemeta _includes _inventory _layouts _loan _loancal _media _people _plugins _posts _press _projects _sass _sets _site _sponsors ``` Bis auf wenige ausnahmen finden sich darin viele Markdown-Dateien. Es handelt sich um Sammlungen ([Jekyll Collections](https://jekyllrb.com/docs/collections/)). Die Ausnahmen sind `_includes` und `_layouts` (darin befinden sich die html Templates zur Darstellung der Website), `_plugins` (Jekyll Plugins), `_sass` (CSS für die Seite), `_site` (In dem ordner befindet sich die gebaute Seite). Alle anderen Ordner repräsentieren Inhalte (*Content*) der Website in Form von Collections, welche miteinander interagieren. Und große Menge an solchen miteinander interagierenden Sammlungen ist, was das Projekt komplex macht. Wer einfach nur einen neuen Blogpost schreiben möchte, oder die Beschreibung eines Geräts oder Projektes verbessern will, der wird damit auch meist nicht in Berüfung kommen. Wer aber Templates verbessern will oder neue Logik einbauen möchte, muss sich damit beschäftigen. Im Folgenden wird ein Überblick über einige Grundgedanken und Wiederkehrenden Elemente gegeben, danach auf andere Kapitel der Doku verwiesen. ## UID für (so ziemlich) alles Fast jedes Element in fast jeder Samlung erhält eine UID im Frontmatter Teil der Markdown-Datei. Dieses wird üblicherweise genutzt, um das Element zu referenzieren. Weil es deswegen wichtig ist, dass jede UID tatsächlich Unique ist, haben wir ein [Skript in der Build-Pipeline, die das prüft](/docs/uids.md). Für alle Elementen in `_events`, `_inventory`, `_loan`, und `_media` gilt, dass sie über eine (innerhalb der Seite) eindeutige UID verfügen müssen. Sie wird verwendet, um die Inhalte miteinander zu verknüfen. Wenn z.B. folgende Datei im ordner loan angelegt wird: ``` --- layout: loan title: "Verleih" eventdate: 2024-02-13 00:00:00 +0200 eventend: 2024-02-14 23:59:59 +0200 #https://www.uuidgenerator.net/ uid: 466cbac6-1706-4f7d-add3-501037b1bed8 contact: verleih@chaotikum.org devices: - ed7a8302-34af-429f-9736-86740a03962a short: "Ausgeliehen" --- ``` So referenziert sie eindeutig das Objekt `ed7a8302-34af-429f-9736-86740a03962a` im Invantar: ``` --- layout: device name: "ROEDE Mikrofone (Koffer Blau)" #https://www.uuidgenerator.net/ uid: ed7a8302-34af-429f-9736-86740a03962a wikilink: https://wiki.chaotikum.org/hackspace:equipment:rode_wireless_go_1 calcolor: "#322ce8" sets: - video - leihbar - kofferblau --- ROEDE Mikrofone (Koffer Blau) ``` als entliehen. Manchmal verknüft die Website Dinge allerdings auch mit lesbaren IDs oder Tags. Das ist zwar inkonsitent, aber eben lesbar. Diese Ausnahmen sind: ### Relevante Ausnahmen * Personen (`_people`) haben keine UID sondern eine `person_id` welche einem selbst gewählten Nickname entspricht. * Aktivitäten (`_projects`) werden über ihr tag referenziert * Konferenzen (`_conferences`) haben eine `acronym` * Sets (`_sets`) existieren primär, um Gruppen von Geräten mit einem merkbaren Namen zu referenzieren, und haben daher ein `tag` anstelle eienr uid ### Wie stellt sich das im Code dar Angenommen, wir haben ein Decive im Inventar, welches durch feolgende Markdown Datei im ordner `_inventory` repräsentiert wird: ``` --- layout: device name: "Bohr- und Fräsmaschine: KF 16 L Vario Bernardo" #https://www.uuidgenerator.net/ uid: 10992f1f-fb14-491f-9e68-6b1b84154674 safetybriefing: true wikilink: "" calcolor: "#96aa3d" imagetag: freaesebernardo contact: - p1 - p2 sets: - werkstatt - holzundmetal hints: - "Nutzung nur nach Einweisung bzw. Überprüfung deiner Kenntnisse" - "Gefahr durch rotierende Teile sowie Quetschungen." - "Niemals unbeaufsichtigt laufen lassen." commandsigns: - M002 - M003 - M004 - M016 --- ``` So sind hier also Zwei Kontaktpersonen (`_people`) mit ihrer `person_id` angegeben. Wenn wir diese aber im Template anzeigen wollen, ist das nicht hilfreich. Daher finden sich im [Liquid](https://jekyllrb.com/docs/liquid/) häufig kleine Schleifen, um die korrekten personen zu finden: ``` {% if page.contact -%} Ansprechpersonen: <div class="toolcontact" id="toolcontact"> <ul> {% for con in page.contact -%} <li>{% include entity.html -%}</li> {% endfor -%} </ul> </div> {% endif -%} ``` *(Aus `_layouts/device.html`)* sowie ``` {% assign found = '' -%} {% for person in site.people -%} {% if person.person_id == con -%} {% assign found = person.name -%} {{person.name}} {% if person.email and person.email != '' -%} <a class="personlink" href="mailto:{{person.email}}"><span class="fa fa-envelope"></span></a> {% endif -%} {% if person.web and person.web != '' -%} <a class="personlink" href="{{ person.web }}"><span class="fa fa-globe"></span></a> {% endif %} {% if person.mastodon and person.mastodon != '' -%} <a class="personlink" href="{{ person.mastodon }}"><span class="fa fa-brands fa-mastodon"></span></a> {% endif -%} {% if person.matrix and person.matrix != '' -%} <a class="navlink" href="{{ person.matrix }}"><span class="fa fa-matrix-org"></span></a> {% endif -%} {% if person.gitlab and person.gitlab != '' -%} <a class="navlink" href="{{ person.gitlab }}"><span class="fa fa-brands fa-gitlab"></span></a> {% endif %} {% endif -%} {% endfor -%} {% if found == nil or found == '' -%} {{con}} {% endif -%} ``` *(Aus `_includes/entity.html`)* In `entity.html` gehen wir also für jede `person_id` in der Variable `con` durch alle personen (`_people`) und schreiben Namen und Kontakdetails raus, sobald die korrekte Person gefunden wurde. Das ist teuer. Bei größeren Collections lohnt sich daher häufig eine Where-Syntax (eigentlich lohnt die sich immer, aber genutzt wird sie nicht immer.) #### Where Syntax Eine Where-Syntax ist in liquid etwas anstrengend, hier sind ein paar beispiele: ``` {% assign relevant_tools = site.inventory | where_exp: "rtools", "rtools.sets contains 'werkstatt'" -%} ``` *(Aus `_includes/tool_list.html`)* Zieht sich alle geräte aus der Inventory-Liste, wenn im set das set werkstatt ist. ``` {% assign events = site.events | where: "uid", video.event -%} ``` *(Aus `_includes/media_in_list.html`)* Zieht alle Events, deren UID die eines events ist (dies sollte lediglich eins sein).