Florian Schuttkowski Florian Schuttkowski

[ ✏️ blog ]  [ 📒 cv  [ 🧑🏻 referenzen ]  [ ❤️ widmung 


Anleitung: Eine Scryfall-Integration für Eleventy selbst bauen

Disclaimer: Dieser Blogpost wurde im Rahmen eines Test von einer KI geschrieben. Author ist Gemini Code Assist 2.5 Pro.

Schritt 1: Das Ziel und die Werkzeuge

Unser Ziel ist es, einen einfachen Shortcode zu erstellen, der ein ansprechendes Bild und Metadaten für die entsprechende Karte rendert.

Dafür benötigen wir einige Dinge:

Schritt 2: Die Shortcode-Datei erstellen

Zuerst erstellen wir eine dedizierte JavaScript-Datei für unsere Shortcode-Logik. Ich habe eine Datei namens scryfall.js im Stammverzeichnis meines Projekts erstellt. Diese wird die gesamte Logik für das Abrufen von Daten, das Caching und die Erzeugung des finalen HTML-Codes enthalten.

Schritt 3: Kartendaten von Scryfall abrufen

In scryfall.js benötigen wir eine Funktion, um Kartendaten von der Scryfall-API zu beziehen. Wir verwenden eine fetch-Anfrage an deren API-Endpunkt. Entscheidend ist, dass wir die Ergebnisse zwischenspeichern (cachen). Die API bei jedem einzelnen Build aufzurufen wäre sehr langsam und könnte dazu führen, dass wir von der API blockiert werden (Rate-Limiting).

Hier ist eine vereinfachte Version der Datenabruffunktion:

// In scryfall.js
const fs = require("node:fs/promises");
const path = require("node:path");

const SCRYFALL_CACHE_DIR = path.join(".cache", "scryfall");

async function getScryfallCard(query) {
  const cacheKey = query.toLowerCase().replace(/[^a-z0-9]/g, "");
  const cachePath = path.join(SCRYFALL_CACHE_DIR, `${cacheKey}.json`);

  // Zuerst versuchen, aus dem Cache zu lesen
  try {
    const cachedData = JSON.parse(await fs.readFile(cachePath, "utf8"));
    // Hier könntest du eine Gültigkeitsprüfung (Time-To-Live, TTL) einbauen
    return cachedData;
  } catch (error) {
    // Wenn nicht im Cache, von der API abrufen
  }

  await fs.mkdir(SCRYFALL_CACHE_DIR, { recursive: true });
  const url = `https://api.scryfall.com/cards/named?fuzzy=${encodeURIComponent(query)}`;
  const response = await fetch(url);
  const data = await response.json();

  // Für das nächste Mal im Cache speichern
  await fs.writeFile(cachePath, JSON.stringify(data, null, 2), "utf8");
  return data;
}

Code-Erklärung im Detail:

Schritt 4: Bildverarbeitung mit eleventy-img

Die Kartendaten von Scryfall enthalten eine URL zum Bild der Karte. Wir könnten einfach diese URL in einem <img>-Tag verwenden, aber das ist ineffizient. Stattdessen verwenden wir @11ty/eleventy-img, um das Bild herunterzuladen, seine Größe anzupassen und es in moderne Formate wie WebP und AVIF zu konvertieren.

Dies geschieht innerhalb unserer Haupt-Shortcode-Funktion.

Schritt 5: Die asynchrone Shortcode-Funktion

Nun führen wir alles in einer async-Shortcode-Funktion in scryfall.js zusammen.

// In scryfall.js
const Image = require("@11ty/eleventy-img");

async function scryfallShortcode(query) {
  // 1. Kartendaten abrufen (aus dem Cache oder von der API)
  const card = await getScryfallCard(query);

  // 2. Bild-URL aus den Daten extrahieren
  const imageUrl = card.image_uris?.normal;
  if (!imageUrl) {
    return `<p>Kein Bild für ${query} gefunden</p>`;
  }

  // 3. Bild mit eleventy-img verarbeiten
  const metadata = await Image(imageUrl, {
    widths: [672], // maximale Breite des Bildes
    formats: ["avif", "webp", "jpeg"],
    outputDir: path.join("_site", "img", "scryfall"),
    urlPath: "/img/scryfall",
  });

  // 4. HTML für das responsive Bild generieren
  const pictureMarkup = Image.generateHTML(metadata, {
    alt: card.name,
    loading: "lazy",
    decoding: "async",
  });

  // 5. Finales HTML für die Kartenanzeige zurückgeben
  return `<figure class="scryfall-card">
    <a href="${card.scryfall_uri}" target="_blank" rel="noopener noreferrer">
      ${pictureMarkup}
    </a>
    <figcaption>${card.name}</figcaption>
  </figure>`;
}

// Nicht vergessen, die Funktion zu exportieren
module.exports.scryfallShortcode = scryfallShortcode;

Code-Erklärung im Detail:

Schritt 6: Den Shortcode in Eleventy registrieren

Der letzte Schritt ist, Eleventy über unseren neuen Shortcode zu informieren. Das tun wir in der Konfigurationsdatei eleventy.config.js.

// In eleventy.config.js
const { scryfallShortcode } = require("./scryfall.js");

module.exports = function (eleventyConfig) {
  // ... andere Konfigurationen
  eleventyConfig.addNunjucksAsyncShortcode("scryfall", scryfallShortcode);
};

Code-Erklärung im Detail:

Da unser Shortcode await für API-Anfragen und Bildverarbeitung verwenden muss, müssen wir ihn als asynchronen Shortcode registrieren. addNunjucksAsyncShortcode macht genau das. Der Name "scryfall" ist der Name, den wir in unseren Markdown- oder Nunjucks-Dateien verwenden werden.

Schritt 7: Den Shortcode verwenden

Das war's! Jetzt kannst du den Shortcode in jeder deiner Markdown- oder Nunjucks-Dateien verwenden.

Probieren wir es mit einer klassischen Karte aus:

Black Lotus
Black LotusEdition: EgalAnzahl: 1

Dieser Aufruf wird nun automatisch die Daten für Black Lotus abrufen, das Bild verarbeiten und das von uns definierte HTML rendern. Beim nächsten Build wird es blitzschnell gehen, da die Daten und Bilder direkt aus dem Cache gelesen werden.

Ich hoffe, diese Anleitung hilft dir dabei, deine eigenen coolen Integrationen mit Eleventy zu bauen!