MediaWiki

MediaWiki:BibBackbone.js

From Illustrations in German Translations of Mark Twain's Works

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
(function () {

const DATA_URL = "/index.php?title=BibliographyData&action=raw&ctype=application/json";

document.addEventListener("DOMContentLoaded", init);

async function init() {
    document.getElementById("generateBtn").onclick = generateHTML;
}

async function loadData() {
    const res = await fetch(DATA_URL);
    return await res.json();
}

// ---------------- MAIN ----------------

async function generateHTML() {

    const data = await loadData();

    let tagsSet = new Set();

    data.forEach(item => {
        (item.tags || []).forEach(t => tagsSet.add(t));
    });

    let html = "";

// ---------------- TAG BAR ----------------

    html += `<div class="bib-tags">\n`;

    [...tagsSet].sort().forEach(tag => {
        html += `  <span class="tag" data-tag="${escapeHtml(tag)}">${escapeHtml(tag)}</span>\n`;
    });

    html += `</div>\n\n`;

// ---------------- LIST VIEW ----------------

    html += `<div id="listView" class="bibliography">\n\n`;

    data.sort((a,b) =>
        (a.title || "").localeCompare(b.title || "")
    );

    data.forEach((item, index) => {

        const authors = formatAuthors(item.authors);
        const tags = item.tags || [];

        html += `<!-- ${index + 1} -->\n`;

        html += `<div class="bib-entry" data-tags="${tags.join(" ")}">\n`;

        html += `  <h3>${authors}. <i>${item.title || "Untitled"}</i>. ${item.year || ""}.</h3>\n\n`;

        html += `  <div class="bib-tags">\n`;

        tags.forEach(t => {
            html += `    <span class="tag" data-tag="${escapeHtml(t)}">${escapeHtml(t)}</span>\n`;
        });

        html += `  </div>\n\n`;

        if (item.abstract) {
            html += `  <p class="short-abstract">${escapeHtml(item.abstract)}</p>\n\n`;
        } else {
            html += `  <p class="short-abstract"></p>\n\n`;
        }

        html += `  <button class="expand-btn">Show Abstract</button>\n`;

        html += `  <div class="abstract hidden">\n`;

        html += `    <p>${escapeHtml(item.abstract || "")}</p>\n`;

        html += `  </div>\n`;

        html += `</div>\n\n`;
    });

    html += `</div>`;

// ---------------- OUTPUT ----------------

    document.getElementById("output").value = html;
}

// ---------------- HELPERS ----------------

function formatAuthors(authors) {
    if (!authors || authors.length === 0) return "Unknown";

    return authors.map(a => {
        if (typeof a === "string") return a;
        return (a.family || "Unknown") + (a.given ? ", " + a.given : "");
    }).join(", ");
}

function escapeHtml(str) {
    if (!str) return "";
    return str
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}

})();