Changeset 013e16c in Klonkt


Ignore:
Timestamp:
08/13/2026 01:09:24 PM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
f50a84b
Parents:
f59a46c
git-author:
Robin <roboburr@…> (08/13/2026 01:01:18 PM)
git-committer:
Robin <roboburr@…> (08/13/2026 01:09:24 PM)
Message:

Naar SEO & social, want sameAs is schema.org (Robins vraag)

Hij vroeg of het niet onder SEO en social hoort, "omdat het ook een soort
koppeling is". Dat is het, en sterker dan dat: op die pagina staat een blok
"Uitgever (JSON-LD / rich results)", en sameAs IS een schema.org-eigenschap.
Zelfde vocabulaire, zelfde plek. Het paneel staat nu direct onder Uitgever.

DAARDOOR VOEDT EEN KOPPELING NU TWEE UITGANGEN. Naast schema:sameAs op de
fediverse-actor komt hij in de JSON-LD van de pagina zelf, in _publisher. Dat
is hetzelfde feit, verteld aan de andere lezer -- en het was gratis, want het
blok stond er al.

BETERE LABELS, want de oude waren geschreven voor het audioscherm. "Ben jij dit
in MusicBrainz?" werd "MusicBrainz (dezelfde artiest elders)" als legenda, met
een hint die zegt wat het OPLEVERT in plaats van alleen wat het is: je komt als
sameAs in de JSON-LD en in je fediverse-profiel, en er verandert niets bij
MusicBrainz zelf. Dat laatste is de geruststelling die er hoort te staan. Plus
een veldlabel ("Zoek jezelf op") met de toelichting "de naam waaronder je muziek
uitbrengt" -- want dat is de vraag, niet je sitenaam. Drie talen.

Het zoekveld begint nu op publisher_name en valt terug op de sitetitel: op deze
pagina heb je die naam net ingevuld.

Meeverhuisd: het endpoint (/admin/seo/api/musicbrainz) en het clientblok, in een
nieuwe mod/admin-seo.js. Die pagina had nog geen JavaScript; opzoeken vraagt er
wel om. Het profielscherm is weer helemaal schoon.

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

Location:
src
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • src/assets/js/mod/admin-site-edit.js

    rf59a46c r013e16c  
    135135})();
    136136
    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();
    141137}
    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-seo.js

    rf59a46c r013e16c  
    1919import { requireGod } from '../middleware/auth.js';
    2020import { getPrimarySite } from '../middleware/site.js';
     21import { isMbid } from '../services/ap-core.js';
     22import MusicBrainz from '../services/MusicBrainzService.js';
    2123
    2224const router = express.Router();
     
    3739  renderPage(req, res, 'pages/admin-seo', {
    3840    pageTitleKey: 'admin.t_seo',
     41    pageJs: 'admin-seo',
    3942    bodyClass: 'on-admin',
    4043    site,
     
    4245    error: req.query.error || null,
    4346  });
     47});
     48
     49/**
     50 * "Zoek jezelf op" -- kandidaten uit MusicBrainz (shaer-mbz).
     51 *
     52 * De zoekopdracht draait HIER en niet in de browser: MusicBrainz staat een
     53 * verzoek per seconde toe per APPLICATIE, en dat is alleen af te dwingen als
     54 * alles langs een plek gaat. Bovendien eisen ze een User-Agent met contact, en
     55 * die kan een browser niet zetten.
     56 *
     57 * Wij kiezen NIET. Ook niet als er precies een treffer is: een verkeerd geraden
     58 * MBID zet jouw naam onder andermans werk.
     59 */
     60router.get('/api/musicbrainz', requireGod, async (req, res) => {
     61  const site = getPrimarySite(req);
     62  const q = String(req.query.q || (site && (site.publisher_name || site.title)) || '').trim();
     63  if (!q) return res.json({ ok: true, q: '', kandidaten: [] });
     64  res.json({ ok: true, q, kandidaten: await MusicBrainz.zoekArtiesten(q) });
    4465});
    4566
     
    7293      publisher_url = ?,
    7394      publisher_logo = ?,
     95      mb_artist_id = ?, mb_artist_name = ?,
    7496      updated_at = CURRENT_TIMESTAMP
    7597    WHERE id = ?
     98  // De MusicBrainz-koppeling (shaer-mbz). Alleen een echte MBID komt de kolom
     99  // in: zonder deze zeef sluipt er een URL of een handle in het veld dat naar
     100  // buiten gaat, en het gaat naar TWEE uitgangen -- de JSON-LD en de actor.
     101  // Leeg is een geldige keuze; dat is ontkoppelen.
     102  const mbRuw = String(f.mb_artist_id || '').trim().toLowerCase();
     103  const mbArtistId = isMbid(mbRuw) ? mbRuw : null;
     104
    76105  `).run(
    77106    f.robots_index ? 1 : 0,
     
    93122    trimOrNull(f.publisher_url, 200),
    94123    trimOrNull(f.publisher_logo, 500),
     124    mbArtistId,
     125    mbArtistId ? (String(f.mb_artist_name || '').trim().slice(0, 200) || null) : null,
    95126    primary.id,
    96127  );
  • src/routes/admin-sites.js

    rf59a46c r013e16c  
    2727import { mediaDir } from '../config/paths.js';
    2828import AP from '../services/ActivityPubService.js';
    29 import MusicBrainz from '../services/MusicBrainzService.js';
    3029
    3130
     
    323322
    324323// ==================== 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 
    344324router.post('/:slug/save', requireSiteManagerBySlug, async (req, res) => {
    345325  const site = db.prepare('SELECT id, ap_aliases FROM sites WHERE slug = ?').get(req.params.slug);
     
    366346  // accent: only accept colors from the curated ACCENTS list. Falls back to
    367347  // 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 
    374348  const accent = ThemeService.validateAccent(f.accent) || '#e8b04b';
    375349
     
    381355      profile_links = ?,
    382356      ap_aliases = ?,
    383       mb_artist_id = ?, mb_artist_name = ?,
    384357      is_public = ?, robots_index = ?, require_login_to_comment = ?,
    385358      enable_audio_player = ?,
     
    401374    profileLinksJson,
    402375    apAliasesJson,
    403     mbArtistId,
    404     mbArtistId ? (String(f.mb_artist_name || '').trim().slice(0, 200) || null) : null,
    405376    f.is_public ? 1 : 0,
    406377    f.robots_index ? 1 : 0,
  • src/services/i18n.js

    rf59a46c r013e16c  
    360360    'aaud.fedi_off': 'Niet op de fediverse gedeeld (alleen webspeler, bestand verborgen) — klik om te delen',
    361361    'aaud.embed_player': 'Embedbare speler',
    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.',
     362    'aseo.mb_legend': 'MusicBrainz (dezelfde artiest elders)',
     363    'aseo.mb_search_label': 'Zoek jezelf op',
     364    'aseo.mb_search_hint': 'de naam waaronder je muziek uitbrengt',
     365    'aseo.mb_hint': 'MusicBrainz is het open register van de muziekwereld. Koppel je eigen pagina en je komt als sameAs in de JSON-LD van deze site én in je fediverse-profiel te staan — zo weten zoekmachines en muziekdiensten dat jouw muziek van jou is. Je verandert er niets mee bij MusicBrainz zelf; we verwijzen er alleen naar.',
     366    'aseo.mb_search': 'Zoeken',
     367    'aseo.mb_placeholder': 'Je artiestennaam',
     368    'aseo.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.',
     369    'aseo.mb_pick': 'Dit ben ik',
     370    'aseo.mb_linked': 'Gekoppeld aan',
     371    'aseo.mb_unlink': 'Ontkoppelen',
     372    'aseo.mb_open': 'Bekijk op MusicBrainz',
     373    'aseo.mb_busy': 'Zoeken…',
     374    'aseo.mb_fail': 'MusicBrainz is even niet bereikbaar.',
    373375    'aaud.embed_hint': 'Plak deze code op je eigen website/blog om je muziek met deze speler in te sluiten:',
    374376    'aaud.preview_player': 'Speler-voorbeeld openen',
     
    13181320    'aaud.fedi_off': 'Not shared on the fediverse (web player only, file hidden) — click to share',
    13191321    'aaud.embed_player': 'Embeddable player',
    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.',
     1322    'aseo.mb_legend': 'MusicBrainz (the same artist elsewhere)',
     1323    'aseo.mb_search_label': 'Look yourself up',
     1324    'aseo.mb_search_hint': 'the name you release music under',
     1325    'aseo.mb_hint': 'MusicBrainz is the music world\u2019s open register. Link your own page and it appears as sameAs in this site\u2019s JSON-LD and in your fediverse profile — so search engines and music services know your music is yours. It changes nothing at MusicBrainz itself; we only point at it.',
     1326    'aseo.mb_search': 'Search',
     1327    'aseo.mb_placeholder': 'Your artist name',
     1328    'aseo.mb_none': 'Nothing found. Not in there yet? You can add yourself on musicbrainz.org — that can only be done there, not from Klonkt.',
     1329    'aseo.mb_pick': 'This is me',
     1330    'aseo.mb_linked': 'Linked to',
     1331    'aseo.mb_unlink': 'Unlink',
     1332    'aseo.mb_open': 'View on MusicBrainz',
     1333    'aseo.mb_busy': 'Searching…',
     1334    'aseo.mb_fail': 'MusicBrainz is unreachable right now.',
    13311335    'aaud.embed_hint': 'Paste this code on your own website/blog to embed your music with this player:',
    13321336    'aaud.preview_player': 'Open player preview',
     
    22752279    'aaud.fedi_off': 'Nicht im Fediverse geteilt (nur Web-Player, Datei verborgen) — zum Teilen klicken',
    22762280    'aaud.embed_player': 'Einbettbarer Player',
    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.',
     2281    'aseo.mb_legend': 'MusicBrainz (dieselbe Künstlerin anderswo)',
     2282    'aseo.mb_search_label': 'Dich selbst suchen',
     2283    'aseo.mb_search_hint': 'der Name, unter dem du Musik veröffentlichst',
     2284    'aseo.mb_hint': 'MusicBrainz ist das offene Register der Musikwelt. Verknüpfe deine Seite, und sie erscheint als sameAs im JSON-LD dieser Website und in deinem Fediverse-Profil — so wissen Suchmaschinen und Musikdienste, dass deine Musik von dir ist. Bei MusicBrainz selbst ändert sich nichts; wir verweisen nur darauf.',
     2285    'aseo.mb_search': 'Suchen',
     2286    'aseo.mb_placeholder': 'Dein Künstlername',
     2287    'aseo.mb_none': 'Nichts gefunden. Noch nicht dabei? Du kannst dich auf musicbrainz.org eintragen — das geht nur dort, nicht aus Klonkt heraus.',
     2288    'aseo.mb_pick': 'Das bin ich',
     2289    'aseo.mb_linked': 'Verknüpft mit',
     2290    'aseo.mb_unlink': 'Trennen',
     2291    'aseo.mb_open': 'Bei MusicBrainz ansehen',
     2292    'aseo.mb_busy': 'Suche läuft…',
     2293    'aseo.mb_fail': 'MusicBrainz ist gerade nicht erreichbar.',
    22882294    'aaud.embed_hint': 'Füge diesen Code auf deiner eigenen Website/deinem Blog ein, um deine Musik mit diesem Player einzubetten:',
    22892295    'aaud.preview_player': 'Player-Vorschau öffnen',
  • src/views/pages/admin-seo.ejs

    rf59a46c r013e16c  
    8888    </fieldset>
    8989
     90    <%# ── MUSICBRAINZ ─────────────────────────────────────────────
     91        Direct onder Uitgever, en dat is geen willekeur: sameAs IS een
     92        schema.org-eigenschap, en dat blok hierboven is waar ons schema.org
     93        vandaan komt. Een koppeling hier voedt twee uitgangen tegelijk -- de
     94        JSON-LD van de pagina en het fediverse-profiel (shaer-mbz). %>
     95    <fieldset id="mb-veld">
     96      <legend><%= t('aseo.mb_legend') %></legend>
     97      <p class="form-hint"><%= t('aseo.mb_hint') %></p>
     98
     99      <input type="hidden" name="mb_artist_id" id="mb-id" value="<%= site.mb_artist_id || '' %>">
     100      <input type="hidden" name="mb_artist_name" id="mb-naam" value="<%= site.mb_artist_name || '' %>">
     101
     102      <p class="mb-huidig" id="mb-huidig" <%= site.mb_artist_id ? '' : 'hidden' %>>
     103        <%= t('aseo.mb_linked') %>
     104        <strong id="mb-huidig-naam"><%= site.mb_artist_name || site.mb_artist_id || '' %></strong>
     105        <a id="mb-huidig-link" target="_blank" rel="noopener"
     106           href="https://musicbrainz.org/artist/<%= site.mb_artist_id || '' %>"><%= t('aseo.mb_open') %></a>
     107        <button type="button" class="btn" id="mb-wis"><%= t('aseo.mb_unlink') %></button>
     108      </p>
     109
     110      <label>
     111        <span><%= t('aseo.mb_search_label') %> <small class="form-hint-inline">— <%= t('aseo.mb_search_hint') %></small></span>
     112        <div class="mb-zoek">
     113          <input type="text" id="mb-q" value="<%= site.publisher_name || site.title || '' %>"
     114                 autocomplete="off" placeholder="<%= t('aseo.mb_placeholder') %>">
     115          <button type="button" class="btn" id="mb-zoek-btn"><%= t('aseo.mb_search') %></button>
     116        </div>
     117      </label>
     118      <div id="mb-uit" class="mb-uit" hidden></div>
     119    </fieldset>
     120
    90121    <fieldset>
    91122      <legend><%= t('aseo.verify_legend') %></legend>
  • src/views/pages/admin-site-edit.ejs

    rf59a46c r013e16c  
    190190    </fieldset>
    191191
    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 
    224192    <fieldset>
    225193      <legend><%= t('asite.feed_view') %></legend>
  • src/views/shell.ejs

    rf59a46c r013e16c  
    9090if (safeSite.publisher_logo) {
    9191  _publisher.logo = { '@type': 'ImageObject', url: safeSite.publisher_logo };
     92}
     93// Dezelfde koppeling die de fediverse-actor draagt, hier in de JSON-LD
     94// (shaer-mbz). sameAs is schema.org-eigen, dus dit is geen extra vocabulaire --
     95// het is hetzelfde feit, verteld aan de andere lezer.
     96if (safeSite.mb_artist_id) {
     97  _publisher.sameAs = 'https://musicbrainz.org/artist/' + safeSite.mb_artist_id;
    9298}
    9399let _jsonLd = null;
Note: See TracChangeset for help on using the changeset viewer.