Sync LibreBible public catalog snapshot
This commit is contained in:
+80
-16
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LibreBible Catalog | Christ IT</title>
|
||||
<meta name="description" content="Public catalog of free Bible translation resources prepared for Libre Study and other Christ IT tools.">
|
||||
<meta name="description" content="Public catalog of free Bible translations, commentaries, dictionaries, and study resources prepared for Libre Study and other Christ IT tools.">
|
||||
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%23111827'/%3E%3Crect x='29' y='10' width='8' height='44' rx='3' fill='%23f8fafc'/%3E%3Crect x='16' y='25' width='34' height='8' rx='3' fill='%23f97316'/%3E%3C/svg%3E" type="image/svg+xml">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
@@ -297,7 +297,7 @@
|
||||
<div class="container">
|
||||
<span class="eyebrow"><i class="fa-solid fa-book-bible"></i> Public Bible resource catalog</span>
|
||||
<h1>LibreBible</h1>
|
||||
<p class="hero-copy">A growing catalog of free-to-use Bible translations and attached study resources prepared for Libre Study, GracePress, and future Christ IT tools.</p>
|
||||
<p class="hero-copy">A growing catalog of free-to-use Bible translations, commentaries, dictionaries, and attached study resources prepared for Libre Study, GracePress, and future Christ IT tools.</p>
|
||||
<div class="button-row">
|
||||
<a class="button" href="https://git.christit.com/libre-study/libre-bible-data"><i class="fa-solid fa-code-branch"></i> Source Repository</a>
|
||||
<a class="button secondary" href="catalog/catalog.json"><i class="fa-solid fa-database"></i> Catalog JSON</a>
|
||||
@@ -309,9 +309,9 @@
|
||||
<div class="container">
|
||||
<div class="summary-grid" id="summary" aria-live="polite">
|
||||
<div class="stat"><span>Resources</span><strong id="resource-count">-</strong></div>
|
||||
<div class="stat"><span>Translations</span><strong id="translation-count">-</strong></div>
|
||||
<div class="stat"><span>Study Helps</span><strong id="study-help-count">-</strong></div>
|
||||
<div class="stat"><span>Verses</span><strong id="verse-count">-</strong></div>
|
||||
<div class="stat"><span>Strong's Links</span><strong id="strongs-count">-</strong></div>
|
||||
<div class="stat"><span>Study Entries</span><strong id="entry-count">-</strong></div>
|
||||
</div>
|
||||
|
||||
<div class="toolbar">
|
||||
@@ -397,11 +397,15 @@
|
||||
const badges = document.createElement("div");
|
||||
badges.className = "badge-row";
|
||||
badges.append(
|
||||
makeBadge(iconForType(resource.resource_type), labelForType(resource.resource_type)),
|
||||
makeBadge("fa-solid fa-language", `${text(resource.language && resource.language.name)}${resource.language && resource.language.dialect ? " / " + resource.language.dialect : ""}`),
|
||||
makeBadge("fa-solid fa-scale-balanced", text(resource.license && resource.license.name)),
|
||||
makeBadge("fa-solid fa-book-open", text(resource.canon && resource.canon.scope))
|
||||
makeBadge("fa-solid fa-scale-balanced", text(resource.license && resource.license.name))
|
||||
);
|
||||
|
||||
if (resource.canon && resource.canon.scope && resource.resource_type === "translation") {
|
||||
badges.append(makeBadge("fa-solid fa-book-open", text(resource.canon.scope)));
|
||||
}
|
||||
|
||||
const features = document.createElement("div");
|
||||
features.className = "feature-row";
|
||||
const featureLabels = (resource.catalog_display && resource.catalog_display.primary_features) || (resource.features || []).map((feature) => feature.label);
|
||||
@@ -409,12 +413,7 @@
|
||||
|
||||
const details = document.createElement("div");
|
||||
details.className = "detail-grid";
|
||||
details.append(
|
||||
makeDetail("Translation", `${text(resource.translation && resource.translation.base_title)} (${text(resource.translation && resource.translation.translation_year)})`),
|
||||
makeDetail("Edition", `${text(resource.translation && resource.translation.edition)}${resource.translation && resource.translation.edition_year ? " / " + resource.translation.edition_year : ""}`),
|
||||
makeDetail("Source", `${text(resource.source && resource.source.provider)} / ${text(resource.source && resource.source.upstream_id)}`),
|
||||
makeDetail("Counts", `${number(resource.counts && resource.counts.verses)} verses, ${number(resource.counts && resource.counts.strongs_links)} Strong's links`)
|
||||
);
|
||||
details.append(...detailsForResource(resource));
|
||||
|
||||
card.append(head, summary, badges, features, details);
|
||||
return card;
|
||||
@@ -422,14 +421,17 @@
|
||||
|
||||
function renderCatalog(catalog) {
|
||||
const resources = Array.isArray(catalog.resources) ? catalog.resources : [];
|
||||
const translations = resources.filter((resource) => resource.resource_type === "translation");
|
||||
const studyHelps = resources.filter((resource) => resource.resource_type !== "translation");
|
||||
const verseTotal = resources.reduce((sum, resource) => sum + (resource.counts && Number(resource.counts.verses) || 0), 0);
|
||||
const strongsTotal = resources.reduce((sum, resource) => sum + (resource.counts && Number(resource.counts.strongs_links) || 0), 0);
|
||||
const entryTotal = resources.reduce((sum, resource) => {
|
||||
const counts = resource.counts || {};
|
||||
return sum + (Number(counts.entries) || 0) + (Number(counts.strongs_links) || 0);
|
||||
}, 0);
|
||||
|
||||
document.getElementById("resource-count").textContent = number(resources.length);
|
||||
document.getElementById("translation-count").textContent = number(translations.length);
|
||||
document.getElementById("study-help-count").textContent = number(studyHelps.length);
|
||||
document.getElementById("verse-count").textContent = number(verseTotal);
|
||||
document.getElementById("strongs-count").textContent = number(strongsTotal);
|
||||
document.getElementById("entry-count").textContent = number(entryTotal);
|
||||
document.getElementById("catalog-status").textContent = `Generated ${text(catalog.generated_at)}`;
|
||||
|
||||
const list = document.getElementById("resource-list");
|
||||
@@ -443,6 +445,68 @@
|
||||
}
|
||||
}
|
||||
|
||||
function labelForType(type) {
|
||||
const labels = {
|
||||
translation: "Translation",
|
||||
commentary: "Commentary",
|
||||
dictionary: "Dictionary",
|
||||
lexicon: "Lexicon",
|
||||
map: "Map",
|
||||
cross_reference: "Cross references",
|
||||
study_notes: "Study notes"
|
||||
};
|
||||
return labels[type] || text(type, "Resource");
|
||||
}
|
||||
|
||||
function iconForType(type) {
|
||||
const icons = {
|
||||
translation: "fa-solid fa-book-bible",
|
||||
commentary: "fa-solid fa-book-open-reader",
|
||||
dictionary: "fa-solid fa-spell-check",
|
||||
lexicon: "fa-solid fa-language",
|
||||
map: "fa-solid fa-map-location-dot",
|
||||
cross_reference: "fa-solid fa-arrows-turn-to-dots",
|
||||
study_notes: "fa-solid fa-note-sticky"
|
||||
};
|
||||
return icons[type] || "fa-solid fa-cube";
|
||||
}
|
||||
|
||||
function detailsForResource(resource) {
|
||||
if (resource.resource_type === "translation") {
|
||||
return [
|
||||
makeDetail("Translation", `${text(resource.translation && resource.translation.base_title)} (${text(resource.translation && resource.translation.translation_year)})`),
|
||||
makeDetail("Edition", `${text(resource.translation && resource.translation.edition)}${resource.translation && resource.translation.edition_year ? " / " + resource.translation.edition_year : ""}`),
|
||||
makeDetail("Source", `${text(resource.source && resource.source.provider)} / ${text(resource.source && resource.source.upstream_id)}`),
|
||||
makeDetail("Counts", `${number(resource.counts && resource.counts.verses)} verses, ${number(resource.counts && resource.counts.strongs_links)} Strong's links`)
|
||||
];
|
||||
}
|
||||
|
||||
if (resource.resource_type === "commentary") {
|
||||
return [
|
||||
makeDetail("Resource Type", "Commentary"),
|
||||
makeDetail("Entries", `${number(resource.counts && (resource.counts.commentary_entries || resource.counts.entries))} commentary entries`),
|
||||
makeDetail("Source", `${text(resource.source && resource.source.provider)} / ${text(resource.source && resource.source.upstream_id)}`),
|
||||
makeDetail("Anchors", "Book, chapter, verse, and verse range")
|
||||
];
|
||||
}
|
||||
|
||||
if (resource.resource_type === "dictionary" || resource.resource_type === "lexicon") {
|
||||
return [
|
||||
makeDetail("Resource Type", labelForType(resource.resource_type)),
|
||||
makeDetail("Entries", `${number(resource.counts && (resource.counts.dictionary_entries || resource.counts.entries))} entries`),
|
||||
makeDetail("Source", `${text(resource.source && resource.source.provider)} / ${text(resource.source && resource.source.upstream_id)}`),
|
||||
makeDetail("Anchors", "Dictionary key, Strong's number, topic, or lemma")
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
makeDetail("Resource Type", labelForType(resource.resource_type)),
|
||||
makeDetail("Entries", `${number(resource.counts && resource.counts.entries)} entries`),
|
||||
makeDetail("Source", `${text(resource.source && resource.source.provider)} / ${text(resource.source && resource.source.upstream_id)}`),
|
||||
makeDetail("License", text(resource.license && resource.license.name))
|
||||
];
|
||||
}
|
||||
|
||||
fetch(catalogUrl, { cache: "no-cache" })
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
|
||||
Reference in New Issue
Block a user