Jump to content

Main Page: Difference between revisions

From the Vrienden Universe, a fictional wiki
No edit summary
Fix remaining broken arrow characters on main page
 
(7 intermediate revisions by 2 users not shown)
Line 1,012: Line 1,012:
<span class="vu-explore-description">Biographies recorded across the wiki.</span>
<span class="vu-explore-description">Biographies recorded across the wiki.</span>
</span>
</span>
<span class="vu-explore-arrow"></span>
<span class="vu-explore-arrow">&gt;</span>
</a>
</a>


Line 1,021: Line 1,021:
<span class="vu-explore-description">Places documented throughout the history.</span>
<span class="vu-explore-description">Places documented throughout the history.</span>
</span>
</span>
<span class="vu-explore-arrow"></span>
<span class="vu-explore-arrow">&gt;</span>
</a>
</a>


Line 1,030: Line 1,030:
<span class="vu-explore-description">Family lines and their members.</span>
<span class="vu-explore-description">Family lines and their members.</span>
</span>
</span>
<span class="vu-explore-arrow"></span>
<span class="vu-explore-arrow">&gt;</span>
</a>
</a>


Line 1,039: Line 1,039:
<span class="vu-explore-description">Institutions and organized groups.</span>
<span class="vu-explore-description">Institutions and organized groups.</span>
</span>
</span>
<span class="vu-explore-arrow"></span>
<span class="vu-explore-arrow">&gt;</span>
</a>
</a>


Line 1,048: Line 1,048:
<span class="vu-explore-description">Events recorded throughout the history.</span>
<span class="vu-explore-description">Events recorded throughout the history.</span>
</span>
</span>
<span class="vu-explore-arrow"></span>
<span class="vu-explore-arrow">&gt;</span>
</a>
</a>


Line 1,057: Line 1,057:
<span class="vu-explore-description">The historical periods used by the wiki.</span>
<span class="vu-explore-description">The historical periods used by the wiki.</span>
</span>
</span>
<span class="vu-explore-arrow"></span>
<span class="vu-explore-arrow">&gt;</span>
</a>
</a>
</nav>
</nav>
Line 1,074: Line 1,074:
<h2>
<h2>
<a data-wiki-title="Reichsministerium für Bergbau und Rohstoffe" href="/wiki/Reichsministerium_f%C3%BCr_Bergbau_und_Rohstoffe">
<a data-wiki-title="Reichsministerium für Bergbau und Rohstoffe" href="/wiki/Reichsministerium_f%C3%BCr_Bergbau_und_Rohstoffe">
Reichsministerium für Bergbau und Rohstoffe
Reichsministerium f&uuml;r Bergbau und Rohstoffe
</a>
</a>
</h2>
</h2>


<p>
<p>
The Reichsministerium für Bergbau und Rohstoffe was a central ministry of the
The Reichsministerium f&uuml;r Bergbau und Rohstoffe was a central ministry of the
<a data-wiki-title="Government of the Tanoa Einsatzgruppen" href="/wiki/Government_of_the_Tanoa_Einsatzgruppen">Government of the Tanoa Einsatzgruppen</a>.
<a data-wiki-title="Government of the Tanoa Einsatzgruppen" href="/wiki/Government_of_the_Tanoa_Einsatzgruppen">Government of the Tanoa Einsatzgruppen</a>.
It administered mining and the state supply of raw materials.
It administered mining and the state supply of raw materials.
Line 1,117: Line 1,117:


<section class="vu-people" id="vu-people-slider" aria-label="People slideshow">
<section class="vu-people" id="vu-people-slider" aria-label="People slideshow">
<div class="vu-people-status" id="vu-people-status">Loading biographies…</div>
<div class="vu-people-status" id="vu-people-status" hidden></div>


<div class="vu-people-stage">
<div class="vu-people-stage">
Line 1,139: Line 1,139:
id="vu-person-link"
id="vu-person-link"
href="/wiki/Toonio_Noord">
href="/wiki/Toonio_Noord">
Open biography
Open page
</a>
</a>
</div>
</div>
Line 1,145: Line 1,145:


<div class="vu-people-controls">
<div class="vu-people-controls">
<button class="vu-slide-button" id="vu-person-prev" type="button" aria-label="Previous person"></button>
<button class="vu-slide-button" id="vu-person-prev" type="button" aria-label="Previous person">&lt;</button>
<button class="vu-slide-button" id="vu-person-toggle" type="button" aria-label="Pause slideshow">Pause</button>
<button class="vu-slide-button" id="vu-person-toggle" type="button" aria-label="Pause slideshow">Pause</button>


Line 1,154: Line 1,154:
<div class="vu-slide-count" id="vu-person-count">1 / 1</div>
<div class="vu-slide-count" id="vu-person-count">1 / 1</div>


<button class="vu-slide-button" id="vu-person-next" type="button" aria-label="Next person"></button>
<button class="vu-slide-button" id="vu-person-next" type="button" aria-label="Next person">&gt;</button>
</div>
</div>
</section>
</section>
<div class="vu-heading">
<div class="vu-heading">
<div class="vu-heading-title">How to use this wiki</div>
<div class="vu-heading-title">How to use this wiki</div>
Line 1,233: Line 1,232:
"use strict";
"use strict";


function ready(callback) {
function onReady(callback) {
if (document.readyState === "loading") {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", callback);
document.addEventListener("DOMContentLoaded", callback, { once: true });
} else {
} else {
callback();
callback();
Line 1,241: Line 1,240:
}
}


ready(function () {
onReady(function () {
var root = document.querySelector(".vu-main");
var root = document.querySelector(".vu-main");
if (!root || !window.fetch || !window.DOMParser) return;
var fallbackImage = "/wiki/Special:Redirect/file/Vu-logo.png";
var slider = document.getElementById("vu-people-slider");
var slider = document.getElementById("vu-people-slider");
var status = document.getElementById("vu-people-status");
var status = document.getElementById("vu-people-status");
Line 1,251: Line 1,247:
var title = document.getElementById("vu-person-title");
var title = document.getElementById("vu-person-title");
var extract = document.getElementById("vu-person-extract");
var extract = document.getElementById("vu-person-extract");
var link = document.getElementById("vu-person-link");
var pageLink = document.getElementById("vu-person-link");
var count = document.getElementById("vu-person-count");
var count = document.getElementById("vu-person-count");
var previous = document.getElementById("vu-person-prev");
var previous = document.getElementById("vu-person-prev");
var next = document.getElementById("vu-person-next");
var next = document.getElementById("vu-person-next");
var toggle = document.getElementById("vu-person-toggle");
var toggle = document.getElementById("vu-person-toggle");
if (!slider || !status || !image || !title || !extract || !link || !count || !previous || !next || !toggle) return;


function wikiUrl(name) {
if (
if (window.mw && mw.util) return mw.util.getUrl(name);
!root ||
return "/wiki/" + encodeURIComponent(name.replace(/ /g, "_")).replace(/%2F/g, "/");
!slider ||
!status ||
!image ||
!title ||
!extract ||
!pageLink ||
!count ||
!previous ||
!next ||
!toggle
) {
return;
}
}


function fetchText(url) {
var fallbackImage = "/wiki/Special:Redirect/file/Vu-logo.png";
return fetch(url, { credentials: "same-origin", cache: "no-store" }).then(function (response) {
var cacheKey = "vu-main-people-slides-v9";
if (!response.ok) throw new Error("Request failed");
var cacheLifetime = 6 * 60 * 60 * 1000;
return response.text();
var slideInterval = 9000;
});
var apiPath = "/wiki/api.php";
var people = [];
var currentIndex = 0;
var timer = null;
var playing = false;
 
previous.disabled = true;
next.disabled = true;
toggle.disabled = true;
count.textContent = "1 / 1";
toggle.textContent = "Play";
previous.textContent = "<";
next.textContent = ">";
 
function showStatus(message) {
if (!message) {
status.hidden = true;
status.textContent = "";
return;
}
 
status.textContent = message;
status.hidden = false;
}
}


function shuffle(items) {
function shuffle(items) {
for (var i = items.length - 1; i > 0; i--) {
var result = items.slice();
var j = Math.floor(Math.random() * (i + 1));
 
var temporary = items[i];
for (var index = result.length - 1; index > 0; index--) {
items[i] = items[j];
var randomIndex = Math.floor(Math.random() * (index + 1));
items[j] = temporary;
var temporary = result[index];
result[index] = result[randomIndex];
result[randomIndex] = temporary;
}
}
return items;
 
return result;
}
}


function unique(items) {
function cleanText(value) {
var seen = {};
return String(value || "")
return items.filter(function (item) {
.replace(/\[\s*\d+(?:\.\d+)?\s*\]/g, "")
if (!item || !item.title || seen[item.title]) return false;
.replace(/\s+/g, " ")
seen[item.title] = true;
.trim();
return true;
});
}
}


function markMissingLinks() {
function shorten(value, limit) {
if (!window.mw || !mw.loader) return;
var cleaned = cleanText(value);
mw.loader.using(["mediawiki.api", "mediawiki.util"]).then(function () {
var api = new mw.Api();
var links = Array.prototype.slice.call(root.querySelectorAll("a[data-wiki-title]"));
var titles = links.map(function (item) { return item.getAttribute("data-wiki-title"); })
.filter(function (item, index, all) { return item && all.indexOf(item) === index; });
for (var i = 0; i < titles.length; i += 50) {
(function (batch) {
api.get({ action: "query", formatversion: 2, titles: batch.join("|") }).then(function (data) {
var missing = {};
if (data.query && data.query.pages) {
data.query.pages.forEach(function (page) { if (page.missing) missing[page.title] = true; });
}
links.forEach(function (item) {
var pageTitle = item.getAttribute("data-wiki-title");
if (!missing[pageTitle]) return;
item.classList.add("new");
item.href = mw.util.getUrl(pageTitle, { action: "edit", redlink: 1 });
item.title = pageTitle + " (page does not exist)";
});
}).catch(function () {});
})(titles.slice(i, i + 50));
}
}).catch(function () {});
}


markMissingLinks();
if (!cleaned || cleaned.length <= limit) {
return cleaned;
}


var fallbackTitles = [
var cut = cleaned.slice(0, limit);
"Abdelkrim El Berkani", "Alessandro Nostrini", "Alexandru Ionuț", "Ana-Maria Nistor",
var sentenceEnd = Math.max(
"Andrei Ionuț", "Angela Noord", "Angelo Angedrik Noord", "Angelo Martin Zuid",
cut.lastIndexOf(". "),
"Antonie Ronald Paap", "Ben Paap", "Benny Paap", "Bob Noord", "Cees Paap",
cut.lastIndexOf("! "),
"Charlie Churchill", "Derek Paap", "Domenico Nostrini", "Eef Hoos", "Eef Paap",
cut.lastIndexOf("? ")
"Emiel Noord", "Eva Noord", "Evert Angedrik Noord", "Francesco Nostrini",
);
"Girolamo Nostrini", "Grozav Ionuț", "Humphrey van Hetten", "Jan Paap",
"Kateryna Moroz", "Kenzi Schladenberg", "Lorenzo Nostrini", "Lourens Schroeter",
"Martin Noord", "Matteo Nostrini", "Nicolae Ionuț", "Otto Hoos", "Rasmus Rogganoid",
"Richard Hoos", "Rikard Rogganoid", "Toonio Noord", "Viorica Rogganoid", "Walter Noord"
];


function fallbackMembers() {
if (sentenceEnd > 180) {
return fallbackTitles.map(function (name) { return { title: name, url: wikiUrl(name) }; });
return cut.slice(0, sentenceEnd + 1);
}
}


function parseCategory(html) {
var finalSpace = cut.lastIndexOf(" ");
var doc = new DOMParser().parseFromString(html, "text/html");
return cut.slice(0, finalSpace > 0 ? finalSpace : limit) + "...";
var area = doc.querySelector("#mw-pages") || doc.querySelector(".mw-category");
if (!area) return [];
var anchors = Array.prototype.slice.call(area.querySelectorAll(".mw-category-group a, .mw-category a"));
return unique(anchors.map(function (anchor) {
var name = (anchor.textContent || "").trim();
var href = anchor.getAttribute("href") || "";
if (!name || !href || /^(Category|Special|File|Template|Help|Talk|User|MediaWiki):/i.test(name)) return null;
return { title: name, url: new URL(href, window.location.href).href };
}));
}
}


function getMembers() {
function getImage(page) {
return fetchText(wikiUrl("Category:People")).then(function (html) {
if (page.thumbnail && page.thumbnail.source) {
var members = parseCategory(html);
return page.thumbnail.source;
if (members.length < 2) throw new Error("No category members");
}
return members;
}).catch(function () { return fallbackMembers(); });
}


function clean(text) {
if (page.original && page.original.source) {
return (text || "").replace(/\[\s*\d+(?:\.\d+)?\s*\]/g, "").replace(/\s+/g, " ").trim();
return page.original.source;
}
}


function shorten(text, limit) {
return "";
var value = clean(text);
if (value.length <= limit) return value;
var cut = value.slice(0, limit);
var stop = Math.max(cut.lastIndexOf(". "), cut.lastIndexOf("! "), cut.lastIndexOf("? "));
if (stop > 180) return cut.slice(0, stop + 1);
var space = cut.lastIndexOf(" ");
return cut.slice(0, space > 0 ? space : limit) + "";
}
}


function findLead(content) {
function pageUrl(pageTitle) {
if (!content) return "";
if (window.mw && mw.util) {
var paragraphs = Array.prototype.slice.call(content.children).filter(function (element) { return element.tagName === "P"; });
return mw.util.getUrl(pageTitle);
paragraphs = paragraphs.concat(Array.prototype.slice.call(content.querySelectorAll("p")));
for (var i = 0; i < paragraphs.length; i++) {
var paragraph = paragraphs[i];
if (paragraph.closest("table") || paragraph.closest(".navbox") || paragraph.closest(".mw-references-wrap")) continue;
var value = clean(paragraph.textContent);
if (value.length >= 70) return value;
}
}
return "";
 
return "/wiki/" + encodeURIComponent(pageTitle.replace(/ /g, "_"));
}
}


function scoreImage(element, pageTitle) {
function normalizePages(pages) {
var source = element.getAttribute("src") || element.getAttribute("data-src") || "";
return shuffle(
var alt = ((element.getAttribute("alt") || "") + " " + (element.getAttribute("title") || "")).toLowerCase();
pages
var combined = (source + " " + alt).toLowerCase();
.filter(function (page) {
if (!source || /(logo|icon|button|spinner|poweredby|powered_by|wikimedia-button|ambox|question_book|edit-clear|magnify-clip)/i.test(combined)) return -1000;
return page && !page.missing && page.title;
var score = 0;
})
if (/(signature|coat of arms|flag of|map of|location map)/i.test(alt)) score -= 8;
.map(function (page) {
if (alt.indexOf(pageTitle.toLowerCase()) !== -1) score += 12;
var pageExtract = shorten(page.extract, 650);
if (element.closest(".infobox")) score += 10;
 
if (element.closest("table")) score += 4;
if (!pageExtract) {
var width = parseInt(element.getAttribute("width"), 10) || 0;
pageExtract =
var height = parseInt(element.getAttribute("height"), 10) || 0;
"This page is listed in Category:People. Open the page for the full article.";
if (width >= 150 || height >= 180) score += 3;
}
return score;
 
return {
title: page.title,
extract: pageExtract,
image: getImage(page) || fallbackImage,
url: page.fullurl || pageUrl(page.title)
};
})
);
}
}


function findImage(content, pageTitle, pageUrl) {
function readCache() {
if (!content) return "";
try {
var images = Array.prototype.slice.call(content.querySelectorAll(".infobox img, table img, figure img, .thumb img, img"));
var cached = JSON.parse(
var best = null;
window.sessionStorage.getItem(cacheKey) || "null"
var bestScore = -1000;
);
images.forEach(function (candidate) {
 
var score = scoreImage(candidate, pageTitle);
if (
if (score > bestScore) { bestScore = score; best = candidate; }
cached &&
});
cached.savedAt &&
if (!best || bestScore < 0) return "";
Date.now() - cached.savedAt < cacheLifetime &&
var source = best.getAttribute("src") || best.getAttribute("data-src") || "";
Array.isArray(cached.people) &&
try { return new URL(source, pageUrl).href; } catch (error) { return ""; }
cached.people.length > 1
}
) {
return cached.people;
}
} catch (error) {
return null;
}


function parsePerson(member, html) {
return null;
var doc = new DOMParser().parseFromString(html, "text/html");
var content = doc.querySelector("#mw-content-text .mw-parser-output") || doc.querySelector(".mw-parser-output");
var heading = doc.querySelector("#firstHeading");
var pageTitle = heading ? heading.textContent.trim() : member.title;
var lead = findLead(content);
var pageImage = findImage(content, pageTitle, member.url);
if (!lead || !pageImage) return null;
return { title: pageTitle, extract: shorten(lead, 660), image: pageImage, url: member.url };
}
}


function loadPerson(member) {
function saveCache(items) {
return fetchText(member.url).then(function (html) { return parsePerson(member, html); }).catch(function () { return null; });
try {
window.sessionStorage.setItem(
cacheKey,
JSON.stringify({
savedAt: Date.now(),
people: items
})
);
} catch (error) {
return;
}
}
}


function loadPeople(members, desired) {
function preloadNext() {
var candidates = shuffle(unique(members).slice()).slice(0, 60);
if (people.length < 2) {
var results = [];
return;
var cursor = 0;
function worker() {
if (cursor >= candidates.length || results.length >= desired) return Promise.resolve();
var member = candidates[cursor++];
return loadPerson(member).then(function (person) {
if (person && !results.some(function (existing) { return existing.title === person.title; })) results.push(person);
}).then(worker);
}
}
var workers = [];
 
for (var i = 0; i < 6; i++) workers.push(worker());
var nextIndex = (currentIndex + 1) % people.length;
return Promise.all(workers).then(function () { return results.slice(0, desired); });
var preload = new Image();
preload.src = people[nextIndex].image;
}
}
var people = [];
var current = 0;
var timer = null;
var playing = true;
var interval = 9000;


function restartProgress() {
function restartProgress() {
slider.classList.remove("is-playing");
slider.classList.remove("is-playing");
void slider.offsetWidth;
void slider.offsetWidth;
if (playing && people.length > 1) slider.classList.add("is-playing");
 
if (playing && people.length > 1) {
slider.classList.add("is-playing");
}
}
}


function schedule() {
function scheduleNext() {
if (timer) window.clearTimeout(timer);
if (timer) {
window.clearTimeout(timer);
}
 
restartProgress();
restartProgress();
if (!playing || people.length < 2) return;
 
timer = window.setTimeout(function () { show(current + 1); }, interval);
if (!playing || people.length < 2) {
return;
}
 
timer = window.setTimeout(function () {
showSlide(currentIndex + 1);
}, slideInterval);
}
}


function show(index) {
function showSlide(index) {
if (!people.length) return;
if (!people.length) {
current = (index + people.length) % people.length;
return;
var person = people[current];
}
 
currentIndex = (index + people.length) % people.length;
var person = people[currentIndex];
 
slider.classList.add("is-changing");
slider.classList.add("is-changing");
window.setTimeout(function () {
window.setTimeout(function () {
image.src = person.image || fallbackImage;
image.src = person.image || fallbackImage;
Line 1,472: Line 1,470:
title.textContent = person.title;
title.textContent = person.title;
extract.textContent = person.extract;
extract.textContent = person.extract;
link.href = person.url;
pageLink.href = person.url;
count.textContent = (current + 1) + " / " + people.length;
pageLink.textContent = "Open page";
window.setTimeout(function () { slider.classList.remove("is-changing"); }, 40);
count.textContent =
}, 150);
String(currentIndex + 1) + " / " + String(people.length);
schedule();
 
window.setTimeout(function () {
slider.classList.remove("is-changing");
}, 40);
 
preloadNext();
}, 140);
 
scheduleNext();
}
}


function setPlaying(value) {
function setPlaying(value) {
playing = value && people.length > 1;
playing = Boolean(value && people.length > 1);
toggle.textContent = playing ? "Pause" : "Play";
toggle.textContent = playing ? "Pause" : "Play";
toggle.setAttribute("aria-label", playing ? "Pause slideshow" : "Play slideshow");
toggle.setAttribute(
if (playing) schedule();
"aria-label",
else {
playing ? "Pause slideshow" : "Play slideshow"
if (timer) window.clearTimeout(timer);
);
 
if (playing) {
scheduleNext();
} else {
if (timer) {
window.clearTimeout(timer);
}
 
slider.classList.remove("is-playing");
slider.classList.remove("is-playing");
}
}
}
}


previous.addEventListener("click", function () { show(current - 1); });
function activateSlides(items) {
next.addEventListener("click", function () { show(current + 1); });
if (!Array.isArray(items) || !items.length) {
toggle.addEventListener("click", function () { setPlaying(!playing); });
showStatus("No people pages were loaded.");
return;
}
 
people = shuffle(items);
currentIndex = 0;
previous.disabled = people.length < 2;
next.disabled = people.length < 2;
toggle.disabled = people.length < 2;
showStatus("");
showSlide(0);
setPlaying(people.length > 1);
}
 
previous.addEventListener("click", function () {
showSlide(currentIndex - 1);
});
 
next.addEventListener("click", function () {
showSlide(currentIndex + 1);
});
 
toggle.addEventListener("click", function () {
setPlaying(!playing);
});
 
slider.addEventListener("mouseenter", function () {
slider.addEventListener("mouseenter", function () {
if (playing && timer) { window.clearTimeout(timer); slider.classList.remove("is-playing"); }
if (playing && timer) {
window.clearTimeout(timer);
slider.classList.remove("is-playing");
}
});
 
slider.addEventListener("mouseleave", function () {
if (playing) {
scheduleNext();
}
});
 
image.addEventListener("error", function () {
if (image.src.indexOf("Vu-logo.png") === -1) {
image.src = fallbackImage;
}
});
});
slider.addEventListener("mouseleave", function () { if (playing) schedule(); });
image.addEventListener("error", function () { if (image.src.indexOf("Vu-logo.png") === -1) image.src = fallbackImage; });


status.hidden = false;
function buildQuery(params) {
getMembers()
var parts = [];
.then(function (members) { return loadPeople(members, 12); })
 
.then(function (loaded) {
Object.keys(params).forEach(function (key) {
if (loaded.length >= 2) return loaded;
parts.push(
return loadPeople(fallbackMembers(), 12).then(function (fallbackLoaded) { return unique(loaded.concat(fallbackLoaded)); });
encodeURIComponent(key) +
})
"=" +
.then(function (loaded) {
encodeURIComponent(params[key])
status.hidden = true;
);
if (!loaded.length) {
});
count.textContent = "1 / 1";
 
setPlaying(false);
return parts.join("&");
}
 
function requestJson(params) {
return window
.fetch(apiPath + "?" + buildQuery(params), {
credentials: "same-origin"
})
.then(function (response) {
if (!response.ok) {
throw new Error("API HTTP " + response.status);
}
 
return response.json();
});
}
 
function copyParams(params) {
var copied = {};
 
Object.keys(params).forEach(function (key) {
copied[key] = params[key];
});
 
return copied;
}
 
function loadCategoryMembers(params, collectedPages) {
return requestJson(params).then(function (data) {
var nextPages =
data &&
data.query &&
Array.isArray(data.query.categorymembers)
? data.query.categorymembers
: [];
var allPages = collectedPages.concat(nextPages);
 
if (data && data.continue) {
var nextParams = copyParams(params);
 
Object.keys(data.continue).forEach(function (key) {
nextParams[key] = data.continue[key];
});
 
showStatus("Loading people... " + String(allPages.length));
return loadCategoryMembers(nextParams, allPages);
}
 
return allPages;
});
}
 
function uniqueTitles(items) {
var seen = {};
var titles = [];
 
items.forEach(function (item) {
if (!item || !item.title || seen[item.title]) {
return;
return;
}
}
people = shuffle(loaded);
 
previous.disabled = people.length < 2;
seen[item.title] = true;
next.disabled = people.length < 2;
titles.push(item.title);
toggle.disabled = people.length < 2;
});
show(0);
 
setPlaying(people.length > 1);
return titles;
}
 
function loadPageDetails(titles) {
var groups = [];
 
for (var index = 0; index < titles.length; index += 1) {
groups.push(titles.slice(index, index + 1));
}
 
return groups
.reduce(function (chain, group) {
return chain.then(function (pages) {
return requestJson({
action: "query",
titles: group.join("|"),
prop: "extracts|pageimages|info",
exintro: 1,
explaintext: 1,
exchars: 700,
piprop: "thumbnail|original",
pithumbsize: 1000,
inprop: "url",
redirects: 1,
formatversion: 2,
format: "json"
}).then(function (data) {
var nextPages =
data &&
data.query &&
Array.isArray(data.query.pages)
? data.query.pages
: [];
 
if (
(pages.length + nextPages.length) % 10 === 0 ||
pages.length + nextPages.length === titles.length
) {
showStatus(
"Loading details... " +
String(pages.length + nextPages.length) +
" / " +
String(titles.length)
);
}
return pages.concat(nextPages);
});
});
}, Promise.resolve([]));
}
 
var cachedPeople = readCache();
 
if (cachedPeople) {
activateSlides(cachedPeople);
}
 
if (!window.fetch) {
showStatus("This browser cannot load the people list.");
return;
}
 
showStatus("Loading people...");
loadCategoryMembers(
{
action: "query",
list: "categorymembers",
cmtitle: "Category:People",
cmnamespace: 0,
cmtype: "page",
cmlimit: "max",
formatversion: 2,
format: "json"
},
[]
)
.then(function (members) {
var titles = uniqueTitles(members);
showStatus("Loading details... 0 / " + String(titles.length));
return loadPageDetails(titles);
})
.then(function (pages) {
var loadedPeople = normalizePages(pages);
 
saveCache(loadedPeople);
activateSlides(loadedPeople);
})
})
.catch(function () {
.catch(function () {
status.hidden = true;
showStatus("Could not load people list.");
count.textContent = "1 / 1";
previous.disabled = true;
next.disabled = true;
toggle.disabled = true;
setPlaying(false);
});
});
/*
* Raw HTML links need a separate existence check so missing pages
* keep MediaWiki's red-link appearance.
*/
if (window.mw && mw.loader) {
mw.loader
.using(["mediawiki.api", "mediawiki.util"])
.then(function () {
var api = new mw.Api();
var links = Array.prototype.slice.call(
root.querySelectorAll("a[data-wiki-title]")
);
var titles = links
.map(function (item) {
return item.getAttribute("data-wiki-title");
})
.filter(function (item, index, allItems) {
return item && allItems.indexOf(item) === index;
});
if (!titles.length) {
return;
}
return api
.get({
action: "query",
titles: titles.join("|"),
formatversion: 2
})
.then(function (data) {
var missing = {};
if (data.query && Array.isArray(data.query.pages)) {
data.query.pages.forEach(function (page) {
if (page.missing) {
missing[page.title] = true;
}
});
}
links.forEach(function (item) {
var pageTitle =
item.getAttribute("data-wiki-title");
if (!missing[pageTitle]) {
return;
}
item.classList.add("new");
item.href = mw.util.getUrl(pageTitle, {
action: "edit",
redlink: 1
});
item.title =
pageTitle + " (page does not exist)";
});
});
});
}
});
});
})();
})();

Latest revision as of 14:46, 19 June 2026


Vrienden Universe logo
Vrienden Universe
The history of De Vrienden and the wider world recorded around them.

About the wiki

The Vrienden Universe began in 2019 as De Lijers De Vrienden, a project about De Vrienden. The project expanded as related pages were added and became a single encyclopedia covering the wider history around its original subject.

The wiki now contains hundreds of connected pages developed over several years. Information established on one page is carried into related articles, allowing readers to follow the same history throughout the site.

Explore
Featured and browse
Featured page

Reichsministerium für Bergbau und Rohstoffe

The Reichsministerium für Bergbau und Rohstoffe was a central ministry of the Government of the Tanoa Einsatzgruppen. It administered mining and the state supply of raw materials.

The ministry supported the command economy of Tanoa and supplied the regime's industrial system.

Open page
People
Toonio Noord

Toonio Noord

Toonio Noord, born 4 April 1969, is a Dutch registration official and former security guard from Vriendendam. He works for the Stichting Noord Registratiebureau and is a member of the Noord family.

Open page
1 / 1
How to use this wiki

Choose a starting point

Most articles link directly to the subjects needed to continue through the history. Readers can begin with De Vrienden or select a broader section above.

The principal family pages provide the main route from De Vrienden into family history. Index pages provide access to the rest of the site.

Community

Information about contributing is available on the community page.

Details

Information about the scope of the site is available in the disclaimer.

Content notice
This wiki contains material intended for mature audiences. Some pages contain disturbing subject matter. Reader discretion is advised.