source: Klonkt/src/assets/js/mod/admin-seo.js@ f50a84b

main
Last change on this file since f50a84b was f50a84b, checked in by Robin <roboburr@…>, 4 weeks ago

Jouw teksten, en de twee dingen die ze beloofden (shaer-mbz)

De titel is nu "MusicBrainz Koppeling" met jouw omschrijving eronder, in drie
talen. Maar die omschrijving belooft twee dingen die de code nog niet deed, en
een label dat liegt is erger dan een lelijk label. Dus allebei gebouwd.

"OF JE MUSICBRAINZ ID ALS JE DIE KENT". Plak je een UUID, dan wordt hij
rechtstreeks opgezocht in plaats van gezocht. Dat is geen luxe: een
zoekopdracht OP een UUID levert bij MusicBrainz niets op, dus zonder deze tak
gaf plakken juist het slechtste resultaat.

"MET TERUG-WEG VALIDATIE". Een koppeling van onze kant is een bewering --
iedereen kan een id in een veld typen. Pas als de MusicBrainz-pagina TERUGWIJST
naar dit domein is het een paar, en dan weet een lezer dat dezelfde persoon aan
allebei de kanten stond. Dezelfde gedachte als rel="me". Het paneel zegt
"wederzijds" of "nog eenzijdig", en bij dat laatste staat erbij WAT je moet doen:
het domein op je MusicBrainz-pagina zetten onder "social networking".

Wij zetten die terugwijzing niet zelf. Kan niet via hun API, en hoort ook niet.

ECHT GEMETEN, en dat gaf de test zijn vorm: robo-burr staat in MusicBrainz met
score 100 (24abe2be-c0bc-4c63-9642-d6f89ec6a00a, "AKA roboburr") en heeft
precies EEN url-relatie -- type "social network", naar sound-fabrics.com. Voor
dev.klonkt.com is de terug-weg dus false, en dat is precies de waarde van de
controle. Die vorm staat nu in een test.

Bij een storing komt er false EN een lege lijst uit: niet kunnen kijken is niet
hetzelfde als niet gevonden, en nooit stilletjes "wederzijds".

Een controle erbij die eist dat alle drie de talen dezelfde mb_-sleutels
hebben. Bij het herschrijven waren er zeven weggevallen die het scherm nog
gebruikt -- een gat in een vertaling geeft een leeg label en dat valt nooit
vanzelf op.

Co-Authored-By: Claude Opus 5 <noreply@…>

  • Property mode set to 100644
File size: 5.4 KB
Line 
1// De SEO-pagina: op dit moment alleen het MusicBrainz-paneel (shaer-mbz).
2//
3// De rest van dit scherm is gewone formuliervelden en heeft geen JavaScript
4// nodig; deze module bestaat omdat opzoeken dat wel doet.
5
6import { pageData, makeSweeper } from './lib.js';
7
8const doc = makeSweeper();
9let T = {};
10
11export function init() {
12 doc.sweep();
13 T = pageData();
14 run();
15}
16
17function run() {
18 // Binnen run() en niet op moduleniveau: deze modules krijgen bij elke
19 // paginawissel opnieuw init(), en een blok dat maar een keer per sessie
20 // draait is precies wat shaer-5s1 opleverde.
21 wireMusicBrainz();
22}
23
24/**
25 * "Zoek jezelf op" in MusicBrainz.
26 *
27 * De kandidaten komen van de server, want MusicBrainz eist een verzoek per
28 * seconde per APPLICATIE en een User-Agent met contact -- allebei niet vanuit
29 * een browser af te dwingen.
30 *
31 * WIJ KIEZEN NIET. Ook niet als er precies een treffer is: een verkeerd geraden
32 * MBID zet jouw naam onder andermans werk. De knop staat er, de klik is van de
33 * artiest. En de keuze gaat mee met de Opslaan van de pagina -- een eigen
34 * formulier kan hier niet, want deze pagina IS er een.
35 */
36function wireMusicBrainz() {
37 const knop = document.getElementById('mb-zoek-btn');
38 const veld = document.getElementById('mb-q');
39 const uit = document.getElementById('mb-uit');
40 const idVeld = document.getElementById('mb-id');
41 const naamVeld = document.getElementById('mb-naam');
42 const huidig = document.getElementById('mb-huidig');
43 if (!knop || !veld || !uit || !idVeld || knop.__wired) return;
44 knop.__wired = true;
45
46 const el = (tag, cls, tekst) => {
47 const e = document.createElement(tag);
48 if (cls) e.className = cls;
49 // textContent en nooit innerHTML: dit is tekst uit een vreemd register.
50 if (tekst != null) e.textContent = tekst;
51 return e;
52 };
53
54 function zet(mbid, naam) {
55 idVeld.value = mbid || '';
56 if (naamVeld) naamVeld.value = naam || '';
57 if (huidig) {
58 huidig.hidden = !mbid;
59 const n = document.getElementById('mb-huidig-naam');
60 const a = document.getElementById('mb-huidig-link');
61 if (n) n.textContent = naam || mbid || '';
62 if (a) a.href = mbid ? `https://musicbrainz.org/artist/${mbid}` : '#';
63 }
64 uit.hidden = true;
65 uit.replaceChildren();
66 checkTerugweg(mbid);
67 }
68
69 const wis = document.getElementById('mb-wis');
70 if (wis) wis.addEventListener('click', () => zet('', ''));
71
72 // DE TERUG-WEG. Wij zetten hem niet -- dat kan niet via hun API en hoort ook
73 // niet -- we kijken alleen of de artiestenpagina ons domein noemt. Zolang dat
74 // niet zo is staat er "nog eenzijdig", want een halve koppeling die als
75 // bevestigd leest is het soort stilte waar we vandaag al genoeg van zagen.
76 const terugweg = document.getElementById('mb-terugweg');
77 async function checkTerugweg(mbid) {
78 if (!terugweg) return;
79 if (!mbid) { terugweg.hidden = true; terugweg.textContent = ''; return; }
80 terugweg.hidden = false;
81 terugweg.className = 'mb-terugweg';
82 terugweg.textContent = T.aseo_mb_checking || 'Terug-weg controleren…';
83 try {
84 const r = await fetch(`/admin/seo/api/musicbrainz/terugweg?mbid=${encodeURIComponent(mbid)}`, { credentials: 'same-origin' });
85 const j = await r.json();
86 terugweg.className = 'mb-terugweg ' + (j.verified ? 'is-ok' : 'is-eenzijdig');
87 terugweg.textContent = j.verified
88 ? (T.aseo_mb_verified || 'Wederzijds.')
89 : (T.aseo_mb_unverified || 'Nog eenzijdig.');
90 } catch {
91 terugweg.hidden = true;
92 }
93 }
94 // Meteen bij het openen, want de artiest kan hem intussen op MusicBrainz
95 // hebben gezet en hoort dat hier te zien zonder opnieuw te koppelen.
96 if (idVeld.value) checkTerugweg(idVeld.value);
97
98 async function zoek() {
99 const q = (veld.value || '').trim();
100 if (!q) return;
101 uit.hidden = false;
102 uit.replaceChildren(el('p', 'form-hint', T.aseo_mb_busy || 'Zoeken…'));
103 knop.disabled = true;
104 try {
105 const r = await fetch(`/admin/seo/api/musicbrainz?q=${encodeURIComponent(q)}`, { credentials: 'same-origin' });
106 const j = await r.json();
107 toon((j && j.kandidaten) || []);
108 } catch {
109 uit.replaceChildren(el('p', 'form-hint', T.aseo_mb_fail || 'MusicBrainz is even niet bereikbaar.'));
110 } finally {
111 knop.disabled = false;
112 }
113 }
114
115 function toon(kandidaten) {
116 if (!kandidaten.length) {
117 uit.replaceChildren(el('p', 'form-hint', T.aseo_mb_none || 'Niets gevonden.'));
118 return;
119 }
120 const lijst = el('ul', 'mb-lijst');
121 for (const k of kandidaten) {
122 const li = el('li', 'mb-kandidaat');
123 li.appendChild(el('strong', null, k.naam));
124 // De toelichting is het hele punt: er zijn drie bands die Nirvana heten,
125 // en zonder dit veld kiest iemand de verkeerde.
126 const bij = [k.toelichting, k.soort, k.land, k.jaren].filter(Boolean).join(' · ');
127 if (bij) li.appendChild(el('small', 'mb-bij', bij));
128 const open = el('a', 'mb-open', T.aseo_mb_open || 'Bekijk op MusicBrainz');
129 open.href = k.url; open.target = '_blank'; open.rel = 'noopener';
130 li.appendChild(open);
131 const b = el('button', 'btn', T.aseo_mb_pick || 'Dit ben ik');
132 b.type = 'button';
133 b.addEventListener('click', () => zet(k.mbid, k.naam));
134 li.appendChild(b);
135 lijst.appendChild(li);
136 }
137 uit.replaceChildren(lijst);
138 }
139
140 knop.addEventListener('click', zoek);
141 veld.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); zoek(); } });
142}
Note: See TracBrowser for help on using the repository browser.