Zero-dependency static site. config.json-driven. Deploy: docker compose up -d Publish: GitHub Pages / Cloudflare Pages / Tailscale Serve Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
86 lines
2.9 KiB
JavaScript
86 lines
2.9 KiB
JavaScript
// AI HUB Tilburg — community site runtime
|
|
// Reads config.json and populates the page.
|
|
|
|
(function () {
|
|
function get(obj, path) {
|
|
return path.split('.').reduce(function (o, k) {
|
|
return o && o[k] !== undefined ? o[k] : null;
|
|
}, obj);
|
|
}
|
|
|
|
function applyConfig(cfg) {
|
|
// Text nodes
|
|
document.querySelectorAll('[data-config]').forEach(function (el) {
|
|
var val = get(cfg, el.dataset.config);
|
|
if (val !== null) el.textContent = val;
|
|
});
|
|
|
|
// href → direct config path
|
|
document.querySelectorAll('[data-config-href]').forEach(function (el) {
|
|
var val = get(cfg, el.dataset.configHref);
|
|
if (val) el.href = val;
|
|
});
|
|
|
|
// href → Google Maps query
|
|
document.querySelectorAll('[data-config-href-maps]').forEach(function (el) {
|
|
var val = get(cfg, el.dataset.configHrefMaps);
|
|
if (val) el.href = 'https://www.google.com/maps/search/' + encodeURIComponent(val);
|
|
});
|
|
|
|
// Rules list
|
|
var rulesEl = document.getElementById('rules-list');
|
|
if (rulesEl && cfg.rules && cfg.rules.length) {
|
|
rulesEl.innerHTML = cfg.rules.map(function (r) {
|
|
return '<li>' + r + '</li>';
|
|
}).join('');
|
|
}
|
|
|
|
// Projects grid
|
|
var grid = document.getElementById('projects-grid');
|
|
if (grid && cfg.projects && cfg.projects.length) {
|
|
grid.innerHTML = cfg.projects.map(function (p) {
|
|
return [
|
|
'<div class="project-card">',
|
|
' <div class="project-icon">' + (p.icon || '🔧') + '</div>',
|
|
' <h3>' + p.name + '</h3>',
|
|
' <p>' + p.description + '</p>',
|
|
p.url ? ' <a class="link" href="' + p.url + '" target="_blank" rel="noopener">Bekijk project →</a>' : '',
|
|
' <div class="project-meta" style="margin-top:12px;font-size:12px;color:var(--text-4);font-family:var(--font-mono)">' + (p.author || '') + '</div>',
|
|
'</div>'
|
|
].join('');
|
|
}).join('');
|
|
}
|
|
|
|
// Founding members in footer
|
|
var fLink = document.getElementById('founding-link');
|
|
if (fLink && cfg.founding_members && cfg.founding_members.length) {
|
|
var fm = cfg.founding_members[0];
|
|
fLink.textContent = fm.name;
|
|
if (fm.url) fLink.href = fm.url;
|
|
}
|
|
|
|
// Language
|
|
if (cfg.community && cfg.community.language) {
|
|
document.documentElement.lang = cfg.community.language;
|
|
}
|
|
|
|
// Page title
|
|
if (cfg.community && cfg.community.name) {
|
|
document.title = cfg.community.name;
|
|
}
|
|
}
|
|
|
|
// Try to load from config.json (works when served via HTTP)
|
|
fetch('../config.json')
|
|
.then(function (r) { return r.json(); })
|
|
.then(applyConfig)
|
|
.catch(function () {
|
|
// Fallback: try same directory
|
|
fetch('config.json')
|
|
.then(function (r) { return r.json(); })
|
|
.then(applyConfig)
|
|
.catch(function () {
|
|
console.info('[tilburg-hub] config.json not found — using HTML defaults');
|
|
});
|
|
});
|
|
})();
|