« get me outta code hell

content, external-links: pass url entry through, handle annotation - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content/dependencies
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2026-05-01 08:53:23 -0300
committer(quasar) nebula <qznebula@protonmail.com>2026-05-01 08:53:57 -0300
commitf6aad9a81fbb1b4e619355cbec316988837fb61a (patch)
tree6281b063b7741bd4fb46b087bfabedc8a0b97c8d /src/content/dependencies
parent92d82211fdf3d653b1a5a4d2cfdad5c684e2367d (diff)
content, external-links: pass url entry through, handle annotation
Diffstat (limited to 'src/content/dependencies')
-rw-r--r--src/content/dependencies/generateAlbumCommentaryPage.js4
-rw-r--r--src/content/dependencies/generateAlbumSidebarGroupBox.js2
-rw-r--r--src/content/dependencies/generateArtTagGalleryPage.js2
-rw-r--r--src/content/dependencies/generateArtTagInfoPage.js2
-rw-r--r--src/content/dependencies/generateArtistInfoPage.js2
-rw-r--r--src/content/dependencies/generateArtistInfoPageMusicVideosChunkItem.js2
-rw-r--r--src/content/dependencies/generateContributionTooltipExternalLinkSection.js6
-rw-r--r--src/content/dependencies/generateExternalHandle.js4
-rw-r--r--src/content/dependencies/generateExternalIcon.js4
-rw-r--r--src/content/dependencies/generateExternalPlatform.js4
-rw-r--r--src/content/dependencies/generateFlashInfoPage.js2
-rw-r--r--src/content/dependencies/generateGroupInfoPage.js2
-rw-r--r--src/content/dependencies/generateLyricsEntry.js2
-rw-r--r--src/content/dependencies/generateMusicVideo.js2
-rw-r--r--src/content/dependencies/generateReleaseInfoListenLine.js2
-rw-r--r--src/content/dependencies/linkExternal.js72
-rw-r--r--src/content/dependencies/transformContent.js4
17 files changed, 69 insertions, 49 deletions
diff --git a/src/content/dependencies/generateAlbumCommentaryPage.js b/src/content/dependencies/generateAlbumCommentaryPage.js
index a380f468..d2706918 100644
--- a/src/content/dependencies/generateAlbumCommentaryPage.js
+++ b/src/content/dependencies/generateAlbumCommentaryPage.js
@@ -52,7 +52,7 @@ export default {
 
       relations.albumCommentaryListeningLinks =
         album.urls
-          .map(entry => relation('linkExternal', entry.url));
+          .map(entry => relation('linkExternal', entry));
 
       if (album.hasCoverArt) {
         relations.albumCommentaryCover =
@@ -75,7 +75,7 @@ export default {
     relations.trackCommentaryListeningLinks =
       query.tracksWithCommentary
         .map(track =>
-          track.urls.map(entry => relation('linkExternal', entry.url)));
+          track.urls.map(entry => relation('linkExternal', entry)));
 
     relations.trackCommentaryCovers =
       query.tracksWithCommentary
diff --git a/src/content/dependencies/generateAlbumSidebarGroupBox.js b/src/content/dependencies/generateAlbumSidebarGroupBox.js
index 15fedf75..9aa29cf6 100644
--- a/src/content/dependencies/generateAlbumSidebarGroupBox.js
+++ b/src/content/dependencies/generateAlbumSidebarGroupBox.js
@@ -39,7 +39,7 @@ export default {
 
     relations.externalLinks =
       group.urls
-        .map(entry => relation('linkExternal', entry.url));
+        .map(entry => relation('linkExternal', entry));
 
     if (group.descriptionShort) {
       relations.description =
diff --git a/src/content/dependencies/generateArtTagGalleryPage.js b/src/content/dependencies/generateArtTagGalleryPage.js
index ec0624d1..49f58a9d 100644
--- a/src/content/dependencies/generateArtTagGalleryPage.js
+++ b/src/content/dependencies/generateArtTagGalleryPage.js
@@ -42,7 +42,7 @@ export default {
     if (!empty(artTag.extraReadingURLs)) {
       relations.extraReadingLinks =
         artTag.extraReadingURLs
-          .map(entry => relation('linkExternal', entry.url));
+          .map(entry => relation('linkExternal', entry));
     }
 
     if (!empty(artTag.directAncestorArtTags)) {
diff --git a/src/content/dependencies/generateArtTagInfoPage.js b/src/content/dependencies/generateArtTagInfoPage.js
index db26260b..dc7ee364 100644
--- a/src/content/dependencies/generateArtTagInfoPage.js
+++ b/src/content/dependencies/generateArtTagInfoPage.js
@@ -50,7 +50,7 @@ export default {
 
     extraReadingLinks:
       artTag.extraReadingURLs
-        .map(entry => relation('linkExternal', entry.url)),
+        .map(entry => relation('linkExternal', entry)),
 
     relatedArtTagLinks:
       artTag.relatedArtTags
diff --git a/src/content/dependencies/generateArtistInfoPage.js b/src/content/dependencies/generateArtistInfoPage.js
index 3961dc49..45b111ed 100644
--- a/src/content/dependencies/generateArtistInfoPage.js
+++ b/src/content/dependencies/generateArtistInfoPage.js
@@ -62,7 +62,7 @@ export default {
 
     visitLinks:
       artist.urls
-        .map(entry => relation('linkExternal', entry.url)),
+        .map(entry => relation('linkExternal', entry)),
 
     tracksChunkedList:
       relation('generateArtistInfoPageTracksChunkedList', artist),
diff --git a/src/content/dependencies/generateArtistInfoPageMusicVideosChunkItem.js b/src/content/dependencies/generateArtistInfoPageMusicVideosChunkItem.js
index 570a984a..4351d590 100644
--- a/src/content/dependencies/generateArtistInfoPageMusicVideosChunkItem.js
+++ b/src/content/dependencies/generateArtistInfoPageMusicVideosChunkItem.js
@@ -38,7 +38,7 @@ export default {
 
     externalLinks:
       query.musicVideo.urls
-        .map(entry => relation('linkExternal', entry.url)),
+        .map(entry => relation('linkExternal', entry)),
   }),
 
   data: (query, _artist, contribs) => ({
diff --git a/src/content/dependencies/generateContributionTooltipExternalLinkSection.js b/src/content/dependencies/generateContributionTooltipExternalLinkSection.js
index cc61fab4..f6af70d2 100644
--- a/src/content/dependencies/generateContributionTooltipExternalLinkSection.js
+++ b/src/content/dependencies/generateContributionTooltipExternalLinkSection.js
@@ -4,15 +4,15 @@ export default {
   relations: (relation, contribution) => ({
     icons:
       contribution.artist.urls
-        .map(entry => relation('generateExternalIcon', entry.url)),
+        .map(entry => relation('generateExternalIcon', entry)),
 
     handles:
       contribution.artist.urls
-        .map(entry => relation('generateExternalHandle', entry.url)),
+        .map(entry => relation('generateExternalHandle', entry)),
 
     platforms:
       contribution.artist.urls
-        .map(entry => relation('generateExternalPlatform', entry.url)),
+        .map(entry => relation('generateExternalPlatform', entry)),
   }),
 
   data: (contribution) => ({
diff --git a/src/content/dependencies/generateExternalHandle.js b/src/content/dependencies/generateExternalHandle.js
index 8653b177..358b4305 100644
--- a/src/content/dependencies/generateExternalHandle.js
+++ b/src/content/dependencies/generateExternalHandle.js
@@ -1,7 +1,7 @@
 import {isExternalLinkContext} from '#external-links';
 
 export default {
-  data: (url) => ({url}),
+  data: (urlEntry) => ({urlEntry}),
 
   slots: {
     context: {
@@ -11,7 +11,7 @@ export default {
   },
 
   generate: (data, slots, {language}) =>
-    language.formatExternalLink(data.url, {
+    language.formatExternalLink(data.urlEntry, {
       style: 'handle',
       context: slots.context,
     }),
diff --git a/src/content/dependencies/generateExternalIcon.js b/src/content/dependencies/generateExternalIcon.js
index 03af643e..0f3ee1b7 100644
--- a/src/content/dependencies/generateExternalIcon.js
+++ b/src/content/dependencies/generateExternalIcon.js
@@ -1,7 +1,7 @@
 import {isExternalLinkContext} from '#external-links';
 
 export default {
-  data: (url) => ({url}),
+  data: (urlEntry) => ({urlEntry}),
 
   slots: {
     context: {
@@ -16,7 +16,7 @@ export default {
         html.tag('use', {
           href:
             to('staticMisc.icon',
-              language.formatExternalLink(data.url, {
+              language.formatExternalLink(data.urlEntry, {
                 style: 'icon-id',
                 context: slots.context,
               })),
diff --git a/src/content/dependencies/generateExternalPlatform.js b/src/content/dependencies/generateExternalPlatform.js
index b2822d64..98c09815 100644
--- a/src/content/dependencies/generateExternalPlatform.js
+++ b/src/content/dependencies/generateExternalPlatform.js
@@ -1,7 +1,7 @@
 import {isExternalLinkContext} from '#external-links';
 
 export default {
-  data: (url) => ({url}),
+  data: (urlEntry) => ({urlEntry}),
 
   slots: {
     context: {
@@ -11,7 +11,7 @@ export default {
   },
 
   generate: (data, slots, {language}) =>
-    language.formatExternalLink(data.url, {
+    language.formatExternalLink(data.urlEntry, {
       style: 'platform',
       context: slots.context,
     }),
diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js
index b334412b..39590832 100644
--- a/src/content/dependencies/generateFlashInfoPage.js
+++ b/src/content/dependencies/generateFlashInfoPage.js
@@ -42,7 +42,7 @@ export default {
 
     externalLinks:
       query.urls
-        .map(entry => relation('linkExternal', entry.url)),
+        .map(entry => relation('linkExternal', entry)),
 
     artworkColumn:
       relation('generateFlashArtworkColumn', flash),
diff --git a/src/content/dependencies/generateGroupInfoPage.js b/src/content/dependencies/generateGroupInfoPage.js
index 261d2212..87d5d2f8 100644
--- a/src/content/dependencies/generateGroupInfoPage.js
+++ b/src/content/dependencies/generateGroupInfoPage.js
@@ -51,7 +51,7 @@ export default {
 
     visitLinks:
       group.urls
-        .map(entry => relation('linkExternal', entry.url)),
+        .map(entry => relation('linkExternal', entry)),
 
     description:
       relation('transformContent', group.description),
diff --git a/src/content/dependencies/generateLyricsEntry.js b/src/content/dependencies/generateLyricsEntry.js
index 0ecf319f..b1113e57 100644
--- a/src/content/dependencies/generateLyricsEntry.js
+++ b/src/content/dependencies/generateLyricsEntry.js
@@ -13,7 +13,7 @@ export default {
 
     sourceLinks:
       entry.sourceURLs
-        .map(url => relation('linkExternal', url)),
+        .map(url => relation('linkExternal', {url})),
 
     originDetails:
       relation('transformContent', entry.originDetails),
diff --git a/src/content/dependencies/generateMusicVideo.js b/src/content/dependencies/generateMusicVideo.js
index 15eb233b..8508fdb6 100644
--- a/src/content/dependencies/generateMusicVideo.js
+++ b/src/content/dependencies/generateMusicVideo.js
@@ -21,7 +21,7 @@ export default {
 
     watchLinks:
       musicVideo.urls
-        .map(entry => relation('linkExternal', entry.url)),
+        .map(entry => relation('linkExternal', entry)),
   }),
 
   data: (musicVideo, _thing) => ({
diff --git a/src/content/dependencies/generateReleaseInfoListenLine.js b/src/content/dependencies/generateReleaseInfoListenLine.js
index cd3baaf2..54e7985f 100644
--- a/src/content/dependencies/generateReleaseInfoListenLine.js
+++ b/src/content/dependencies/generateReleaseInfoListenLine.js
@@ -65,7 +65,7 @@ export default {
   relations: (relation, query, _thing) => ({
     links:
       query.urls
-        .map(entry => relation('linkExternal', entry.url)),
+        .map(entry => relation('linkExternal', entry)),
   }),
 
   data(query, thing) {
diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js
index e1393455..b47b1a90 100644
--- a/src/content/dependencies/linkExternal.js
+++ b/src/content/dependencies/linkExternal.js
@@ -9,8 +9,12 @@ export default {
       wikiInfo.canonicalMediaBase,
   }),
 
-  data: (sprawl, url) => ({
-    url,
+  data: (sprawl, urlEntry) => ({
+    url:
+      urlEntry.url,
+
+    annotation:
+      urlEntry.annotation,
 
     canonicalBase:
       sprawl.canonicalBase,
@@ -70,11 +74,9 @@ export default {
   },
 
   generate(data, slots, {html, language, to}) {
-    const {url} = data;
-
     let urlIsValid;
     try {
-      new URL(url);
+      new URL(data.url);
       urlIsValid = true;
     } catch {
       urlIsValid = false;
@@ -83,31 +85,39 @@ export default {
     let href;
     if (urlIsValid) {
       const {canonicalBase, canonicalMediaBase} = data;
-      const past = front => decodeURIComponent(url.slice(front.length));
-      if (canonicalMediaBase && url.startsWith(canonicalMediaBase)) {
+      const past = front => decodeURIComponent(data.url.slice(front.length));
+      if (canonicalMediaBase && data.url.startsWith(canonicalMediaBase)) {
         href = to('media.path', past(canonicalMediaBase));
-      } else if (canonicalBase && url.startsWith(canonicalBase)) {
+      } else if (canonicalBase && data.url.startsWith(canonicalBase)) {
         href = to('shared.path', past(canonicalBase));
       } else {
-        href = url;
+        href = data.url;
       }
     }
 
+    const urlEntry = {
+      url: href,
+      annotation: data.annotation,
+    };
+
     let formattedLink;
+    let formattedPlatform;
     if (urlIsValid) {
       formattedLink =
-        language.formatExternalLink(url, {
+        language.formatExternalLink(urlEntry, {
           style: slots.style,
           context: slots.context,
         });
 
+      formattedPlatform =
+        language.formatExternalLink(urlEntry, {
+          style: 'platform',
+          context: slots.context,
+        });
+
       // Fall back to platform if nothing matched the desired style.
-      if (html.isBlank(formattedLink) && slots.style !== 'platform') {
-        formattedLink =
-          language.formatExternalLink(url, {
-            style: 'platform',
-            context: slots.context,
-          });
+      if (html.isBlank(formattedLink)) {
+        formattedLink = formattedPlatform;
       }
     } else {
       formattedLink = null;
@@ -119,6 +129,10 @@ export default {
 
     let linkContent;
     if (urlIsValid) {
+      // For valid URLs, the annotation (if any) is already handled
+      // by formatExternalLink. It is not shown at all, in up-front
+      // presentation, if there is custom content.
+
       linkAttributes.set('href', href);
 
       if (html.isBlank(slots.content)) {
@@ -127,17 +141,25 @@ export default {
         linkContent = slots.content;
       }
     } else {
+      // For invalid URLs, there is no automatically formatted link,
+      // and the annotation (if any) is rolled into presentation below.
+      // However, it's still not shown if there is custom content.
+
       if (html.isBlank(slots.content)) {
-        linkContent =
-          html.tag('i',
-            language.$('misc.external.invalidURL.annotation'));
+        if (data.annotation) {
+          linkContent =
+            language.$('misc.external.withAnnotation', {
+              link: html.tag('i', language.$('misc.external.invalidURL.annotation')),
+              annotation: language.sanitize(data.annotation),
+            });
+        } else {
+          linkContent = html.tag('i', language.$('misc.external.invalidURL'));
+        }
       } else {
         linkContent =
-          language.$('misc.external.invalidURL', {
+          language.$('misc.external.withAnnotation', {
             link: slots.content,
-            annotation:
-              html.tag('i',
-                language.$('misc.external.invalidURL.annotation')),
+            annotation: html.tag('i', language.$('misc.external.invalidURL.annotation')),
           });
       }
     }
@@ -159,9 +181,7 @@ export default {
         } else {
           titleText =
             language.$('misc.external.opensInNewTab', {
-              link: formattedLink,
-              annotation:
-                language.$('misc.external.opensInNewTab.annotation'),
+              platform: formattedPlatform,
             });
         }
       } else if (!html.isBlank(slots.content)) {
diff --git a/src/content/dependencies/transformContent.js b/src/content/dependencies/transformContent.js
index 775ccfdc..62a547e4 100644
--- a/src/content/dependencies/transformContent.js
+++ b/src/content/dependencies/transformContent.js
@@ -282,14 +282,14 @@ export default {
         nodes
           .filter(({type}) => type === 'external-link')
           .map(({data: {href}}) =>
-            relation('linkExternal', href)),
+            relation('linkExternal', {url: href})),
 
       externalLinksForTooltipNodes:
         nodes
           .filter(({type}) => type === 'tooltip')
           .filter(({data}) => data.link)
           .map(({data: {link: href}}) =>
-            relation('linkExternal', href)),
+            relation('linkExternal', {url: href})),
 
       images:
         nodes