// i18n — eenvoudige interface-vertaling (UI-strings), bezoeker-instelbaar. // // Taalkeuze: req.session.lang (gezet via /lang/:code) → anders browser-taal // (Accept-Language) → anders 'nl'. De helper t(lang, key, vars) zoekt de string op // in DICT[lang], valt terug op 'nl', dan op de key zelf. Alleen INTERFACE-teksten; // door gebruikers geschreven content (posts, sitenaam, bio) wordt niet vertaald. export const SUPPORTED = ['nl', 'en', 'de']; export const LANG_NAMES = { nl: 'Nederlands', en: 'English', de: 'Deutsch' }; const DICT = { nl: { 'nav.back_to_site': '← Terug naar site', 'nav.home': 'Home', 'nav.archive': 'Archief', 'nav.search': 'Zoeken', 'nav.theme': 'Thema wisselen', 'nav.install': 'App installeren', 'nav.login': 'Inloggen', 'nav.logout': 'Uitloggen', 'nav.admin': 'Beheer', 'nav.account': 'Account', 'nav.profile': 'Profiel', 'nav.favorites': 'Favorieten', 'nav.new_post': 'Nieuwe post', 'nav.language': 'Taal', 'switch.agenda': 'Agenda', 'switch.solo': 'Solo', 'switch.circle': 'Cirkel', 'switch.timeline': 'Tijdlijn', 'switch.grid': 'Grid', 'postnav.newer': 'Nieuwer', 'postnav.older': 'Ouder', 'postnav.newest': 'Nieuwste post', 'postnav.oldest': 'Oudste post', 'footer.subscribe_cta': 'Blijf op de hoogte', 'footer.subscribe': 'Inschrijven', 'footer.install': 'Installeer app', 'common.email_placeholder': 'jouw@email.nl', 'common.back_to_admin': '← Beheer', // Agenda (publiek) 'agenda.title': 'Agenda', 'agenda.empty': 'Geen aangekondigde evenementen op dit moment.', 'agenda.tickets': 'Tickets', 'agenda.notify_h': 'Mis geen evenement', 'agenda.notify_sub': 'Laat je e-mail achter en je krijgt een seintje bij een nieuw evenement. Uitschrijven kan altijd.', 'agenda.notify_btn': 'Houd me op de hoogte', 'agenda.msg_done': '✓ Je staat op de lijst — je hoort het zodra er een evenement wordt aangekondigd.', 'agenda.msg_check': '✉ Check je mail om je aanmelding te bevestigen.', // Downloads (publiek) 'downloads.title': 'Downloads', 'downloads.sub': 'Gratis te downloaden — laat je e-mailadres achter en je krijgt het bestand.', 'downloads.empty': 'Er staan momenteel geen downloads klaar.', 'downloads.btn': '⬇ Download', // Beheer-dashboard 'admin.title': 'Beheer', 'admin.tagline_solo': 'Solo-modus — jouw site.', 'admin.tagline_hub': 'Hub-modus — bedrijfssite met gebruikers, elk hun eigen Klonkt Hub.', 'admin.b_sites': '🌐 Sites', 'admin.b_users': '👥 Gebruikers', 'admin.b_audio': '🎵 Audio', 'admin.b_playlists': '📃 Playlists', 'admin.b_comments': '💬 Reacties', 'admin.b_seo': '🔎 SEO', 'admin.b_settings': '⚙️ Instellingen', 'admin.b_newpost': '✍️ Nieuwe post', 'admin.b_look': '🎨 Uiterlijk', 'admin.b_makesite': '🎨 Maak je site aan', 'admin.b_circle': '🔗 Cirkel', 'admin.b_stats': '📊 Statistieken', 'admin.b_newsletter': '✉️ Nieuwsbrief', 'admin.b_perskit': '📰 Perskit', 'admin.b_downloads': '⬇ Downloads', 'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 'admin.b_google': '🔑 Google', 'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Handleiding', 'admin.st_users': 'Gebruikers', 'admin.st_sites': 'Sites', 'admin.st_posts': 'Posts', 'admin.st_published': 'Gepubliceerd', 'admin.sec_posts': 'Posts', 'admin.sec_sites': 'Sites', 'admin.sec_users': 'Users', 'admin.draft': 'Concept', 'admin.edit': 'Bewerken', 'admin.view': 'Bekijk', 'admin.th_slug': 'Slug', 'admin.th_title': 'Titel', 'admin.th_owner': 'Eigenaar', 'admin.th_created': 'Aangemaakt', 'admin.th_username': 'Gebruikersnaam', 'admin.th_email': 'E-mail', 'admin.th_role': 'Rol', 'admin.th_joined': 'Lid sinds', }, en: { 'nav.back_to_site': '← Back to site', 'nav.home': 'Home', 'nav.archive': 'Archive', 'nav.search': 'Search', 'nav.theme': 'Toggle theme', 'nav.install': 'Install app', 'nav.login': 'Log in', 'nav.logout': 'Log out', 'nav.admin': 'Admin', 'nav.account': 'Account', 'nav.profile': 'Profile', 'nav.favorites': 'Favorites', 'nav.new_post': 'New post', 'nav.language': 'Language', 'switch.agenda': 'Agenda', 'switch.solo': 'Solo', 'switch.circle': 'Circle', 'switch.timeline': 'Timeline', 'switch.grid': 'Grid', 'postnav.newer': 'Newer', 'postnav.older': 'Older', 'postnav.newest': 'Newest post', 'postnav.oldest': 'Oldest post', 'footer.subscribe_cta': 'Stay in the loop', 'footer.subscribe': 'Subscribe', 'footer.install': 'Install app', 'common.email_placeholder': 'you@email.com', 'common.back_to_admin': '← Admin', 'agenda.title': 'Agenda', 'agenda.empty': 'No announced events at the moment.', 'agenda.tickets': 'Tickets', 'agenda.notify_h': 'Never miss an event', 'agenda.notify_sub': 'Leave your email and we’ll let you know about new events. Unsubscribe any time.', 'agenda.notify_btn': 'Keep me posted', 'agenda.msg_done': '✓ You’re on the list — we’ll let you know when an event is announced.', 'agenda.msg_check': '✉ Check your email to confirm your sign-up.', 'downloads.title': 'Downloads', 'downloads.sub': 'Free to download — leave your email and you’ll get the file.', 'downloads.empty': 'No downloads available right now.', 'downloads.btn': '⬇ Download', 'admin.title': 'Admin', 'admin.tagline_solo': 'Solo mode — your site.', 'admin.tagline_hub': 'Hub mode — a company site with users, each their own Klonkt Hub.', 'admin.b_sites': '🌐 Sites', 'admin.b_users': '👥 Users', 'admin.b_audio': '🎵 Audio', 'admin.b_playlists': '📃 Playlists', 'admin.b_comments': '💬 Comments', 'admin.b_seo': '🔎 SEO', 'admin.b_settings': '⚙️ Settings', 'admin.b_newpost': '✍️ New post', 'admin.b_look': '🎨 Appearance', 'admin.b_makesite': '🎨 Create your site', 'admin.b_circle': '🔗 Circle', 'admin.b_stats': '📊 Statistics', 'admin.b_newsletter': '✉️ Newsletter', 'admin.b_perskit': '📰 Press kit', 'admin.b_downloads': '⬇ Downloads', 'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 'admin.b_google': '🔑 Google', 'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Manual', 'admin.st_users': 'Users', 'admin.st_sites': 'Sites', 'admin.st_posts': 'Posts', 'admin.st_published': 'Published', 'admin.sec_posts': 'Posts', 'admin.sec_sites': 'Sites', 'admin.sec_users': 'Users', 'admin.draft': 'Draft', 'admin.edit': 'Edit', 'admin.view': 'View', 'admin.th_slug': 'Slug', 'admin.th_title': 'Title', 'admin.th_owner': 'Owner', 'admin.th_created': 'Created', 'admin.th_username': 'Username', 'admin.th_email': 'Email', 'admin.th_role': 'Role', 'admin.th_joined': 'Joined', }, de: { 'nav.back_to_site': '← Zurück zur Seite', 'nav.home': 'Start', 'nav.archive': 'Archiv', 'nav.search': 'Suche', 'nav.theme': 'Thema wechseln', 'nav.install': 'App installieren', 'nav.login': 'Anmelden', 'nav.logout': 'Abmelden', 'nav.admin': 'Verwaltung', 'nav.account': 'Konto', 'nav.profile': 'Profil', 'nav.favorites': 'Favoriten', 'nav.new_post': 'Neuer Beitrag', 'nav.language': 'Sprache', 'switch.agenda': 'Termine', 'switch.solo': 'Solo', 'switch.circle': 'Kreis', 'switch.timeline': 'Zeitleiste', 'switch.grid': 'Raster', 'postnav.newer': 'Neuer', 'postnav.older': 'Älter', 'postnav.newest': 'Neuester Beitrag', 'postnav.oldest': 'Ältester Beitrag', 'footer.subscribe_cta': 'Bleib auf dem Laufenden', 'footer.subscribe': 'Abonnieren', 'footer.install': 'App installieren', 'common.email_placeholder': 'du@email.de', 'common.back_to_admin': '← Verwaltung', 'agenda.title': 'Termine', 'agenda.empty': 'Zurzeit keine angekündigten Termine.', 'agenda.tickets': 'Tickets', 'agenda.notify_h': 'Keinen Termin verpassen', 'agenda.notify_sub': 'Hinterlasse deine E-Mail und wir melden uns bei neuen Terminen. Abmelden jederzeit möglich.', 'agenda.notify_btn': 'Halt mich auf dem Laufenden', 'agenda.msg_done': '✓ Du stehst auf der Liste — wir melden uns, sobald ein Termin angekündigt wird.', 'agenda.msg_check': '✉ Prüfe deine E-Mail, um die Anmeldung zu bestätigen.', 'downloads.title': 'Downloads', 'downloads.sub': 'Kostenlos herunterladen — hinterlasse deine E-Mail und du bekommst die Datei.', 'downloads.empty': 'Momentan keine Downloads verfügbar.', 'downloads.btn': '⬇ Herunterladen', 'admin.title': 'Verwaltung', 'admin.tagline_solo': 'Solo-Modus — deine Seite.', 'admin.tagline_hub': 'Hub-Modus — eine Firmenseite mit Nutzern, je ein eigener Klonkt Hub.', 'admin.b_sites': '🌐 Seiten', 'admin.b_users': '👥 Nutzer', 'admin.b_audio': '🎵 Audio', 'admin.b_playlists': '📃 Playlists', 'admin.b_comments': '💬 Kommentare', 'admin.b_seo': '🔎 SEO', 'admin.b_settings': '⚙️ Einstellungen', 'admin.b_newpost': '✍️ Neuer Beitrag', 'admin.b_look': '🎨 Aussehen', 'admin.b_makesite': '🎨 Seite erstellen', 'admin.b_circle': '🔗 Kreis', 'admin.b_stats': '📊 Statistik', 'admin.b_newsletter': '✉️ Newsletter', 'admin.b_perskit': '📰 Pressekit', 'admin.b_downloads': '⬇ Downloads', 'admin.b_linkbio': '🔗 Link-in-Bio', 'admin.b_agenda': '📅 Termine', 'admin.b_google': '🔑 Google', 'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Anleitung', 'admin.st_users': 'Nutzer', 'admin.st_sites': 'Seiten', 'admin.st_posts': 'Beiträge', 'admin.st_published': 'Veröffentlicht', 'admin.sec_posts': 'Beiträge', 'admin.sec_sites': 'Seiten', 'admin.sec_users': 'Nutzer', 'admin.draft': 'Entwurf', 'admin.edit': 'Bearbeiten', 'admin.view': 'Ansehen', 'admin.th_slug': 'Slug', 'admin.th_title': 'Titel', 'admin.th_owner': 'Eigentümer', 'admin.th_created': 'Erstellt', 'admin.th_username': 'Benutzername', 'admin.th_email': 'E-Mail', 'admin.th_role': 'Rolle', 'admin.th_joined': 'Mitglied seit', }, }; export function t(lang, key, vars) { const l = SUPPORTED.includes(lang) ? lang : 'nl'; let s = (DICT[l] && DICT[l][key]); if (s === undefined) s = (DICT.nl[key] !== undefined ? DICT.nl[key] : key); if (vars) for (const k in vars) s = s.replace(new RegExp('\\{' + k + '\\}', 'g'), vars[k]); return s; } // Bepaal de taal voor dit request: sessie-keuze → browser-taal → nl. export function resolveLang(req) { const s = req && req.session && req.session.lang; if (s && SUPPORTED.includes(s)) return s; const al = ((req && req.headers && req.headers['accept-language']) || '').toLowerCase(); const first = al.split(',')[0].trim().slice(0, 2); if (SUPPORTED.includes(first)) return first; return 'nl'; }