Software Berater Logo Software Berater #neuland seit 1993

Gitea Embeds für Jekyll

Github Gists haben die Funktion schon lang: Man kann den Inhalt mit einem Stückchen Javascript “live” in eine Webseite einbetten. Das ist sehr praktisch, wenn man über Code schreiben möchte, der sich unter Git-Versionierung befindet. Der Besucher sieht dann stets den aktuellen Inhalt des Gists, auch wenn dieser nach Veröffentlichen der Seite weiter bearbeitet wird. Das von mir eingesetzt Gitea bringt diese Funktion von Haus aus nicht mit. Ich hab mir ein Plugin für Jekyll dafür gebaut.

Die Idee ist: Im Quelltext der Seite findet sich ein statisches, leeres Element, das beim Betrachten per Javascript mit Inhalt gefüllt und möglich mit passendem Syntax-Highlighting versehen wird.

Ich benötige ein wenig standardisierte HTML-Struktur, damit ich das Javascript daran “anhängen” kann. Die könnte man von Hand bauen (und genau so hab ich das ganz am Anfang auch gemacht), später empfiehlt sich ein Liquid Tag dafür, den ich per Jekyll-Plugin registriere.

_plugins/gitea.rb auf git.software-berater.net

Im Jekyll-Dokument verwende ich dann eine Zeile wie diese:

{% gitea https://git.software-berater.net/christian/software-berater.net/src/branch/master/_plugins/gitea.rb %}

Dabei kann ich sowohl die src- als auch die raw-URL angeben.

A touch of Javascript

Auf diese Weise wird ein code-Element erzeugt, das noch leer ist. Es fehlt die Funktion, die angegebene URL in die Seite zu laden.

class RemoteCode {
  constructor (elem) { this.elem = elem }

  update() {
    fetch(this.elem.dataset.src)
      .then(response => response.text())
      .then(text => {
        this.elem.textContent = text;
        Prism.highlightElement(this.elem);
      })
      .catch(error => {
        this.elem.textContent = error;
        console.error(error)
      });
  }
}

document.addEventListener("DOMContentLoaded", function(event) {
  document
    .querySelectorAll('code.highlighter-prism')
    .forEach((elem) => { new RemoteCode(elem).update() });
});

JS-Code analog zu diesem Beispiel bettet man in die Seite ein, sodass er beim Ereignis DOMContentLoaded ausgeführt wird. Das Javascript und CSS für den Syntax-Highlighter prism.js muss zuvor geladen worden sein.

Auf CORS Header achten

Ich versuche hier, per Javascript Content von einer anderen Domain zu laden. Auf diese Weise kann viel Blödsinn passieren, daher wird solcher Zugriff streng limitiert: Normalerweise dürfen Skripte nur Daten von der selben Domain laden, von der sie selbst auch geladen wurden - Same Origin Policy. CORS, das Cross-Origin Resource Sharing ist der Gegenmechanismus dazu: Wenn die abzurufende URL per Antwortheader mitteilt, dass die Ressource geladen werden darf, dann akzeptiert der Browser dies. CORS ist im Browser standardmäßig eingeschaltet, Webserver liefern im Standard keine CORS-Header aus.

Für meinen Gitea-Server, der ja via Traefik im Netz erreichbar ist, schaut die Konfiguration damit so aus:

gitea/docker-compose.yml auf git.software-berater.net

Hier ist die Middleware cors-header wichtig.