Changeset 6401681 in Klonkt
- Timestamp:
- 08/13/2026 01:08:32 PM (4 weeks ago)
- Branches:
- main
- Children:
- f59a46c
- Parents:
- 5300652
- git-author:
- Robin <roboburr@…> (08/13/2026 12:16:47 PM)
- git-committer:
- Robin <roboburr@…> (08/13/2026 01:08:32 PM)
- Location:
- src
- Files:
-
- 7 edited
-
assets/js/mod/admin-audio.js (modified) (1 diff)
-
assets/js/mod/admin-site-edit.js (modified) (1 diff)
-
routes/admin-audio.js (modified) (2 diffs)
-
routes/admin-sites.js (modified) (5 diffs)
-
services/i18n.js (modified) (3 diffs)
-
views/pages/admin-audio.ejs (modified) (1 diff)
-
views/pages/admin-site-edit.ejs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/mod/admin-audio.js
r5300652 r6401681 452 452 }); 453 453 })(); 454 455 // MusicBrainz-paneel (shaer-mbz). Binnen run(), niet op moduleniveau:456 // deze modules krijgen bij elke paginawissel opnieuw init(), en een blok dat457 // maar een keer per sessie draait is precies wat shaer-5s1 opleverde.458 wireMusicBrainz();459 454 } 460 461 // ── MusicBrainz: ben jij dit? (shaer-mbz, stap 2) ─────────────────462 //463 // De kandidaten komen van de server, want MusicBrainz eist een verzoek per464 // seconde per APPLICATIE en een User-Agent met contact -- allebei niet vanuit465 // een browser af te dwingen.466 //467 // WIJ KIEZEN NIET. Ook niet als er precies een treffer is: een verkeerd468 // geraden MBID zet jouw naam onder andermans werk. De knop staat er, de klik469 // is van de artiest.470 function wireMusicBrainz() {471 const knop = document.getElementById('mb-zoek-btn');472 const veld = document.getElementById('mb-q');473 const uit = document.getElementById('mb-uit');474 if (!knop || !veld || !uit || knop.__wired) return;475 knop.__wired = true;476 477 const el = (tag, cls, tekst) => {478 const e = document.createElement(tag);479 if (cls) e.className = cls;480 if (tekst != null) e.textContent = tekst; // textContent: nooit HTML uit een vreemd register481 return e;482 };483 484 async function zoek() {485 const q = (veld.value || '').trim();486 if (!q) return;487 uit.hidden = false;488 uit.replaceChildren(el('p', 'ax-hint', T.aaud_mb_busy || 'Zoeken…'));489 knop.disabled = true;490 try {491 const r = await fetch(`api/musicbrainz?q=${encodeURIComponent(q)}`, { credentials: 'same-origin' });492 const j = await r.json();493 toon((j && j.kandidaten) || []);494 } catch {495 uit.replaceChildren(el('p', 'ax-hint', T.aaud_mb_fail || 'MusicBrainz is even niet bereikbaar.'));496 } finally {497 knop.disabled = false;498 }499 }500 501 function toon(kandidaten) {502 if (!kandidaten.length) {503 uit.replaceChildren(el('p', 'ax-hint', T.aaud_mb_none || 'Niets gevonden.'));504 return;505 }506 const lijst = el('ul', 'mb-lijst');507 for (const k of kandidaten) {508 const li = el('li', 'mb-kandidaat');509 li.appendChild(el('strong', null, k.naam));510 // De toelichting is het hele punt: er zijn drie bands die Nirvana heten,511 // en zonder dit veld kiest iemand de verkeerde.512 const bij = [k.toelichting, k.soort, k.land, k.jaren].filter(Boolean).join(' · ');513 if (bij) li.appendChild(el('small', 'mb-bij', bij));514 const open = el('a', 'mb-open', T.aaud_mb_open || 'Bekijk op MusicBrainz');515 open.href = k.url; open.target = '_blank'; open.rel = 'noopener';516 li.appendChild(open);517 li.appendChild(kiesForm(k));518 lijst.appendChild(li);519 }520 uit.replaceChildren(lijst);521 }522 523 function kiesForm(k) {524 const f = document.createElement('form');525 f.method = 'POST';526 f.action = 'musicbrainz/link';527 for (const [naam, waarde] of [['_csrf', csrf()], ['mbid', k.mbid], ['naam', k.naam]]) {528 const i = document.createElement('input');529 i.type = 'hidden'; i.name = naam; i.value = waarde || '';530 f.appendChild(i);531 }532 const b = el('button', 'ax-btn', T.aaud_mb_pick || 'Dit ben ik');533 b.type = 'submit';534 f.appendChild(b);535 return f;536 }537 538 // Het token staat al in elk formulier op deze pagina; er is er geen apart voor.539 const csrf = () => (document.querySelector('input[name="_csrf"]') || {}).value || '';540 541 knop.addEventListener('click', zoek);542 veld.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); zoek(); } });543 } -
src/assets/js/mod/admin-site-edit.js
r5300652 r6401681 134 134 } 135 135 })(); 136 137 // MusicBrainz-paneel (shaer-mbz). Binnen run(), niet op moduleniveau: deze 138 // modules krijgen bij elke paginawissel opnieuw init(), en een blok dat maar 139 // een keer per sessie draait is precies wat shaer-5s1 opleverde. 140 wireMusicBrainz(); 136 141 } 142 143 // ── MusicBrainz: ben jij dit? (shaer-mbz) ───────────────────────── 144 // 145 // De kandidaten komen van de server, want MusicBrainz eist een verzoek per 146 // seconde per APPLICATIE en een User-Agent met contact -- allebei niet vanuit 147 // een browser af te dwingen. 148 // 149 // WIJ KIEZEN NIET. Ook niet als er precies een treffer is: een verkeerd geraden 150 // MBID zet jouw naam onder andermans werk. De knop staat er, de klik is van de 151 // artiest. En de keuze gaat mee met de Opslaan-knop van de pagina -- een eigen 152 // formulier kan hier niet, want deze pagina IS er een. 153 function wireMusicBrainz() { 154 const knop = document.getElementById('mb-zoek-btn'); 155 const veld = document.getElementById('mb-q'); 156 const uit = document.getElementById('mb-uit'); 157 const idVeld = document.getElementById('mb-id'); 158 const naamVeld = document.getElementById('mb-naam'); 159 const huidig = document.getElementById('mb-huidig'); 160 if (!knop || !veld || !uit || !idVeld || knop.__wired) return; 161 knop.__wired = true; 162 163 const el = (tag, cls, tekst) => { 164 const e = document.createElement(tag); 165 if (cls) e.className = cls; 166 // textContent en nooit innerHTML: dit is tekst uit een vreemd register. 167 if (tekst != null) e.textContent = tekst; 168 return e; 169 }; 170 171 function zet(mbid, naam) { 172 idVeld.value = mbid || ''; 173 naamVeld.value = naam || ''; 174 if (huidig) { 175 huidig.hidden = !mbid; 176 const n = document.getElementById('mb-huidig-naam'); 177 const a = document.getElementById('mb-huidig-link'); 178 if (n) n.textContent = naam || mbid || ''; 179 if (a) a.href = mbid ? `https://musicbrainz.org/artist/${mbid}` : '#'; 180 } 181 uit.hidden = true; 182 uit.replaceChildren(); 183 } 184 185 const wis = document.getElementById('mb-wis'); 186 if (wis) wis.addEventListener('click', () => zet('', '')); 187 188 async function zoek() { 189 const q = (veld.value || '').trim(); 190 if (!q) return; 191 uit.hidden = false; 192 uit.replaceChildren(el('p', 'form-hint', T.asite_mb_busy || 'Zoeken…')); 193 knop.disabled = true; 194 try { 195 const r = await fetch(`api/musicbrainz?q=${encodeURIComponent(q)}`, { credentials: 'same-origin' }); 196 const j = await r.json(); 197 toon((j && j.kandidaten) || []); 198 } catch { 199 uit.replaceChildren(el('p', 'form-hint', T.asite_mb_fail || 'MusicBrainz is even niet bereikbaar.')); 200 } finally { 201 knop.disabled = false; 202 } 203 } 204 205 function toon(kandidaten) { 206 if (!kandidaten.length) { 207 uit.replaceChildren(el('p', 'form-hint', T.asite_mb_none || 'Niets gevonden.')); 208 return; 209 } 210 const lijst = el('ul', 'mb-lijst'); 211 for (const k of kandidaten) { 212 const li = el('li', 'mb-kandidaat'); 213 li.appendChild(el('strong', null, k.naam)); 214 // De toelichting is het hele punt: er zijn drie bands die Nirvana heten, 215 // en zonder dit veld kiest iemand de verkeerde. 216 const bij = [k.toelichting, k.soort, k.land, k.jaren].filter(Boolean).join(' · '); 217 if (bij) li.appendChild(el('small', 'mb-bij', bij)); 218 const open = el('a', 'mb-open', T.asite_mb_open || 'Bekijk op MusicBrainz'); 219 open.href = k.url; open.target = '_blank'; open.rel = 'noopener'; 220 li.appendChild(open); 221 const b = el('button', 'btn', T.asite_mb_pick || 'Dit ben ik'); 222 b.type = 'button'; 223 b.addEventListener('click', () => zet(k.mbid, k.naam)); 224 li.appendChild(b); 225 lijst.appendChild(li); 226 } 227 uit.replaceChildren(lijst); 228 } 229 230 knop.addEventListener('click', zoek); 231 veld.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); zoek(); } }); 232 } -
src/routes/admin-audio.js
r5300652 r6401681 23 23 import { audioUrl } from '../services/AudioStreamService.js'; 24 24 import { mediaDir } from '../config/paths.js'; 25 import MusicBrainz from '../services/MusicBrainzService.js';26 25 27 26 const __dirname = path.dirname(fileURLToPath(import.meta.url)); … … 384 383 385 384 /** GET /admin/audio/api/albums — distinct list of album names (for datalist) */ 386 /**387 * "Ben jij dit?" -- kandidaten uit MusicBrainz (shaer-mbz, stap 1).388 *389 * De zoekopdracht draait HIER en niet in de browser: MusicBrainz staat een390 * verzoek per seconde toe per APPLICATIE, en dat is alleen af te dwingen als391 * alles langs een plek gaat. Bovendien eisen ze een User-Agent met contact, en392 * die kan een browser niet zetten.393 *394 * De keuze blijft van de artiest. Wij tonen kandidaten met hun toelichting; we395 * kiezen er niet zelf een, ook niet als er maar een treffer is -- een verkeerd396 * geraden MBID koppelt iemand aan het werk van een ander.397 */398 router.get('/api/musicbrainz', requireGod, async (req, res) => {399 const site = res.locals.site;400 if (!site) return res.status(404).json({ error: 'no_site' });401 // Standaard de artiestennaam die al in de site staat: negen van de tien keer402 // is dat precies waar iemand op zou zoeken.403 const q = String(req.query.q || site.author || site.title || '').trim();404 if (!q) return res.json({ ok: true, q: '', kandidaten: [] });405 const kandidaten = await MusicBrainz.zoekArtiesten(q);406 res.json({407 ok: true,408 q,409 gekoppeld: site.mb_artist_id410 ? { mbid: site.mb_artist_id, naam: site.mb_artist_name || '', url: MusicBrainz.artiestUrl(site.mb_artist_id) }411 : null,412 kandidaten,413 });414 });415 416 /**417 * De keuze vastleggen. Alleen een echte MBID komt de kolom in: de naam die we418 * ernaast bewaren is voor het scherm, de MBID is het enige dat naar buiten gaat.419 */420 router.post('/musicbrainz/link', requireGod, (req, res) => {421 const site = res.locals.site;422 if (!site) return res.status(404).end();423 const mbid = String(req.body.mbid || '').trim().toLowerCase();424 const naam = String(req.body.naam || '').trim().slice(0, 200);425 const terug = (res.locals.siteUrlBase || '') + '/admin/audio';426 if (!MusicBrainz.isMbid(mbid)) return res.redirect(`${terug}?error=` + encodeURIComponent('Geen geldige MusicBrainz-id.'));427 db.prepare('UPDATE sites SET mb_artist_id = ?, mb_artist_name = ? WHERE id = ?').run(mbid, naam || null, site.id);428 res.redirect(`${terug}?success=` + encodeURIComponent('Gekoppeld aan MusicBrainz.'));429 });430 431 /** Terugdraaien. Een verkeerde koppeling zet jouw naam onder andermans werk. */432 router.post('/musicbrainz/unlink', requireGod, (req, res) => {433 const site = res.locals.site;434 if (!site) return res.status(404).end();435 db.prepare('UPDATE sites SET mb_artist_id = NULL, mb_artist_name = NULL WHERE id = ?').run(site.id);436 res.redirect((res.locals.siteUrlBase || '') + '/admin/audio?success=' + encodeURIComponent('Ontkoppeld.'));437 });438 439 385 router.get('/api/albums', requireGod, (req, res) => { 440 386 const site = res.locals.site; -
src/routes/admin-sites.js
r5300652 r6401681 27 27 import { mediaDir } from '../config/paths.js'; 28 28 import AP from '../services/ActivityPubService.js'; 29 import MusicBrainz from '../services/MusicBrainzService.js'; 29 30 30 31 … … 322 323 323 324 // ==================== SAVE ==================== 325 /** 326 * "Ben jij dit?" -- kandidaten uit MusicBrainz (shaer-mbz). 327 * 328 * De zoekopdracht draait HIER en niet in de browser: MusicBrainz staat een 329 * verzoek per seconde toe per APPLICATIE, en dat is alleen af te dwingen als 330 * alles langs een plek gaat. Bovendien eisen ze een User-Agent met contact, en 331 * die kan een browser niet zetten. 332 * 333 * Wij kiezen NIET. Ook niet als er precies een treffer is: een verkeerd geraden 334 * MBID zet jouw naam onder andermans werk. 335 */ 336 router.get('/:slug/api/musicbrainz', requireSiteManagerBySlug, async (req, res) => { 337 const site = db.prepare('SELECT title, mb_artist_id, mb_artist_name FROM sites WHERE slug = ?').get(req.params.slug); 338 if (!site) return res.status(404).json({ error: 'no_site' }); 339 const q = String(req.query.q || site.title || '').trim(); 340 if (!q) return res.json({ ok: true, q: '', kandidaten: [] }); 341 res.json({ ok: true, q, kandidaten: await MusicBrainz.zoekArtiesten(q) }); 342 }); 343 324 344 router.post('/:slug/save', requireSiteManagerBySlug, async (req, res) => { 325 345 const site = db.prepare('SELECT id, ap_aliases FROM sites WHERE slug = ?').get(req.params.slug); … … 346 366 // accent: only accept colors from the curated ACCENTS list. Falls back to 347 367 // the orange default if the submitted value isn't recognised. 368 // De MusicBrainz-koppeling (shaer-mbz). Alleen een echte MBID komt de kolom 369 // in: zonder deze zeef sluipt er een hele URL of een handle in het veld dat 370 // straks naar buiten gaat. Leeg is een geldige keuze -- dat is ontkoppelen. 371 const mbRuw = String(f.mb_artist_id || '').trim().toLowerCase(); 372 const mbArtistId = MusicBrainz.isMbid(mbRuw) ? mbRuw : null; 373 348 374 const accent = ThemeService.validateAccent(f.accent) || '#e8b04b'; 349 375 … … 355 381 profile_links = ?, 356 382 ap_aliases = ?, 383 mb_artist_id = ?, mb_artist_name = ?, 357 384 is_public = ?, robots_index = ?, require_login_to_comment = ?, 358 385 enable_audio_player = ?, … … 374 401 profileLinksJson, 375 402 apAliasesJson, 403 mbArtistId, 404 mbArtistId ? (String(f.mb_artist_name || '').trim().slice(0, 200) || null) : null, 376 405 f.is_public ? 1 : 0, 377 406 f.robots_index ? 1 : 0, -
src/services/i18n.js
r5300652 r6401681 360 360 'aaud.fedi_off': 'Niet op de fediverse gedeeld (alleen webspeler, bestand verborgen) — klik om te delen', 361 361 'aaud.embed_player': 'Embedbare speler', 362 'aaud.mb_title': 'Ben jij dit in MusicBrainz?', 363 'aaud.mb_hint': 'MusicBrainz is het open register waar muziekdiensten je aan herkennen. Zoek jezelf op en kies je eigen pagina — dan weten anderen dat jouw muziek van jou is.', 364 'aaud.mb_search': 'Zoeken', 365 'aaud.mb_none': 'Niets gevonden. Sta je er nog niet in? Dan kun je jezelf aanmelden op musicbrainz.org — dat kan alleen daar, niet vanuit Klonkt.', 366 'aaud.mb_pick': 'Dit ben ik', 367 'aaud.mb_linked': 'Gekoppeld aan', 368 'aaud.mb_unlink': 'Ontkoppelen', 369 'aaud.mb_open': 'Bekijk op MusicBrainz', 370 'aaud.mb_busy': 'Zoeken…', 371 'aaud.mb_fail': 'MusicBrainz is even niet bereikbaar.', 362 'asite.mb_title': 'Ben jij dit in MusicBrainz?', 363 'asite.mb_hint': 'MusicBrainz is het open register waar muziekdiensten je aan herkennen. Zoek jezelf op en kies je eigen pagina — dan weten anderen dat jouw muziek van jou is.', 364 'asite.mb_search': 'Zoeken', 365 'asite.mb_placeholder': 'Je artiestennaam', 366 'asite.mb_none': 'Niets gevonden. Sta je er nog niet in? Dan kun je jezelf aanmelden op musicbrainz.org — dat kan alleen daar, niet vanuit Klonkt.', 367 'asite.mb_pick': 'Dit ben ik', 368 'asite.mb_linked': 'Gekoppeld aan', 369 'asite.mb_unlink': 'Ontkoppelen', 370 'asite.mb_open': 'Bekijk op MusicBrainz', 371 'asite.mb_busy': 'Zoeken…', 372 'asite.mb_fail': 'MusicBrainz is even niet bereikbaar.', 372 373 'aaud.embed_hint': 'Plak deze code op je eigen website/blog om je muziek met deze speler in te sluiten:', 373 374 'aaud.preview_player': 'Speler-voorbeeld openen', … … 1317 1318 'aaud.fedi_off': 'Not shared on the fediverse (web player only, file hidden) — click to share', 1318 1319 'aaud.embed_player': 'Embeddable player', 1319 'aaud.mb_title': 'Is this you on MusicBrainz?', 1320 'aaud.mb_hint': 'MusicBrainz is the open register music services recognise you by. Look yourself up and pick your own page — then others know your music is yours.', 1321 'aaud.mb_search': 'Search', 1322 'aaud.mb_none': 'Nothing found. Not in there yet? You can add yourself on musicbrainz.org — that can only be done there, not from Klonkt.', 1323 'aaud.mb_pick': 'This is me', 1324 'aaud.mb_linked': 'Linked to', 1325 'aaud.mb_unlink': 'Unlink', 1326 'aaud.mb_open': 'View on MusicBrainz', 1327 'aaud.mb_busy': 'Searching…', 1328 'aaud.mb_fail': 'MusicBrainz is unreachable right now.', 1320 'asite.mb_title': 'Is this you on MusicBrainz?', 1321 'asite.mb_hint': 'MusicBrainz is the open register music services recognise you by. Look yourself up and pick your own page — then others know your music is yours.', 1322 'asite.mb_search': 'Search', 1323 'asite.mb_placeholder': 'Your artist name', 1324 'asite.mb_none': 'Nothing found. Not in there yet? You can add yourself on musicbrainz.org — that can only be done there, not from Klonkt.', 1325 'asite.mb_pick': 'This is me', 1326 'asite.mb_linked': 'Linked to', 1327 'asite.mb_unlink': 'Unlink', 1328 'asite.mb_open': 'View on MusicBrainz', 1329 'asite.mb_busy': 'Searching…', 1330 'asite.mb_fail': 'MusicBrainz is unreachable right now.', 1329 1331 'aaud.embed_hint': 'Paste this code on your own website/blog to embed your music with this player:', 1330 1332 'aaud.preview_player': 'Open player preview', … … 2273 2275 'aaud.fedi_off': 'Nicht im Fediverse geteilt (nur Web-Player, Datei verborgen) — zum Teilen klicken', 2274 2276 'aaud.embed_player': 'Einbettbarer Player', 2275 'aaud.mb_title': 'Bist das du bei MusicBrainz?', 2276 'aaud.mb_hint': 'MusicBrainz ist das offene Register, an dem Musikdienste dich erkennen. Suche dich und wähle deine eigene Seite — dann wissen andere, dass deine Musik von dir ist.', 2277 'aaud.mb_search': 'Suchen', 2278 'aaud.mb_none': 'Nichts gefunden. Noch nicht dabei? Du kannst dich auf musicbrainz.org eintragen — das geht nur dort, nicht aus Klonkt heraus.', 2279 'aaud.mb_pick': 'Das bin ich', 2280 'aaud.mb_linked': 'Verknüpft mit', 2281 'aaud.mb_unlink': 'Trennen', 2282 'aaud.mb_open': 'Bei MusicBrainz ansehen', 2283 'aaud.mb_busy': 'Suche läuft…', 2284 'aaud.mb_fail': 'MusicBrainz ist gerade nicht erreichbar.', 2277 'asite.mb_title': 'Bist das du bei MusicBrainz?', 2278 'asite.mb_hint': 'MusicBrainz ist das offene Register, an dem Musikdienste dich erkennen. Suche dich und wähle deine eigene Seite — dann wissen andere, dass deine Musik von dir ist.', 2279 'asite.mb_search': 'Suchen', 2280 'asite.mb_placeholder': 'Dein Künstlername', 2281 'asite.mb_none': 'Nichts gefunden. Noch nicht dabei? Du kannst dich auf musicbrainz.org eintragen — das geht nur dort, nicht aus Klonkt heraus.', 2282 'asite.mb_pick': 'Das bin ich', 2283 'asite.mb_linked': 'Verknüpft mit', 2284 'asite.mb_unlink': 'Trennen', 2285 'asite.mb_open': 'Bei MusicBrainz ansehen', 2286 'asite.mb_busy': 'Suche läuft…', 2287 'asite.mb_fail': 'MusicBrainz ist gerade nicht erreichbar.', 2285 2288 'aaud.embed_hint': 'Füge diesen Code auf deiner eigenen Website/deinem Blog ein, um deine Musik mit diesem Player einzubetten:', 2286 2289 'aaud.preview_player': 'Player-Vorschau öffnen', -
src/views/pages/admin-audio.ejs
r5300652 r6401681 12 12 <% if (success) { %><div class="ax-flash ax-flash-ok"><%= success %></div><% } %> 13 13 <% if (error) { %><div class="ax-flash ax-flash-err"><%= error %></div><% } %> 14 15 <%# ── MUSICBRAINZ ─────────────────────────────────────────────16 Wie ben jij, buiten Klonkt? Een MBID is geen vocabulaire maar een17 register: eraan koppelen is als je ISBN noemen. Andere muziekdiensten18 -- Funkwhale voorop -- herkennen je eraan zonder dat wij hun model19 hoeven over te nemen (shaer-mbz). %>20 <section class="ax-card" id="mb-card">21 <div class="ax-card-title"><%= t('aaud.mb_title') %></div>22 <p class="ax-hint"><%= t('aaud.mb_hint') %></p>23 24 <% if (site.mb_artist_id) { %>25 <p class="mb-linked">26 <%= t('aaud.mb_linked') %>27 <strong><%= site.mb_artist_name || site.mb_artist_id %></strong>28 <a href="https://musicbrainz.org/artist/<%= site.mb_artist_id %>"29 target="_blank" rel="noopener"><%= t('aaud.mb_open') %></a>30 </p>31 <%# Ontkoppelen moet kunnen: een verkeerde koppeling zet jouw naam onder32 andermans werk, en dat hoort met een klik terug te draaien zijn. %>33 <form method="POST" action="<%= (typeof siteUrlBase !== 'undefined' ? siteUrlBase : '') %>/admin/audio/musicbrainz/unlink">34 <input type="hidden" name="_csrf" value="<%= csrfToken %>">35 <button type="submit" class="ax-btn ax-btn-quiet"><%= t('aaud.mb_unlink') %></button>36 </form>37 <% } %>38 39 <div class="mb-zoek">40 <input type="text" id="mb-q" value="<%= site.author || site.title || '' %>"41 placeholder="<%= t('aaud.artist') %>" autocomplete="off">42 <button type="button" class="ax-btn" id="mb-zoek-btn"><%= t('aaud.mb_search') %></button>43 </div>44 <div id="mb-uit" class="mb-uit" hidden></div>45 </section>46 14 47 15 <%# ── UPLOAD ──────────────────────────────────────────────── %> -
src/views/pages/admin-site-edit.ejs
r5300652 r6401681 190 190 </fieldset> 191 191 192 <%# ── MUSICBRAINZ ───────────────────────────────────────────── 193 Naast de aliassen, want het is dezelfde vraag: wie ben jij elders? 194 Een MBID is geen vocabulaire maar een register -- eraan koppelen is als 195 je ISBN noemen, en muziekdiensten herkennen je eraan zonder dat wij hun 196 model hoeven over te nemen (shaer-mbz). 197 198 GEEN EIGEN FORMULIER: deze pagina IS er een, en een formulier in een 199 formulier bestaat niet in HTML. De keuze zet een verborgen veld en gaat 200 mee met de Opslaan-knop van de pagina, net als de profielfoto. %> 201 <fieldset id="mb-veld"> 202 <legend><%= t('asite.mb_title') %></legend> 203 <p class="form-hint"><%= t('asite.mb_hint') %></p> 204 205 <input type="hidden" name="mb_artist_id" id="mb-id" value="<%= site.mb_artist_id || '' %>"> 206 <input type="hidden" name="mb_artist_name" id="mb-naam" value="<%= site.mb_artist_name || '' %>"> 207 208 <p class="mb-huidig" id="mb-huidig" <%= site.mb_artist_id ? '' : 'hidden' %>> 209 <%= t('asite.mb_linked') %> 210 <strong id="mb-huidig-naam"><%= site.mb_artist_name || site.mb_artist_id || '' %></strong> 211 <a id="mb-huidig-link" target="_blank" rel="noopener" 212 href="https://musicbrainz.org/artist/<%= site.mb_artist_id || '' %>"><%= t('asite.mb_open') %></a> 213 <button type="button" class="btn" id="mb-wis"><%= t('asite.mb_unlink') %></button> 214 </p> 215 216 <div class="mb-zoek"> 217 <input type="text" id="mb-q" value="<%= site.title || '' %>" autocomplete="off" 218 placeholder="<%= t('asite.mb_placeholder') %>"> 219 <button type="button" class="btn" id="mb-zoek-btn"><%= t('asite.mb_search') %></button> 220 </div> 221 <div id="mb-uit" class="mb-uit" hidden></div> 222 </fieldset> 223 192 224 <fieldset> 193 225 <legend><%= t('asite.feed_view') %></legend>
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)