diff options
Diffstat (limited to 'src/content/dependencies')
41 files changed, 1876 insertions, 1753 deletions
diff --git a/src/content/dependencies/generateAlbumCommentaryPage.js b/src/content/dependencies/generateAlbumCommentaryPage.js index 05dbdcf3..c14640af 100644 --- a/src/content/dependencies/generateAlbumCommentaryPage.js +++ b/src/content/dependencies/generateAlbumCommentaryPage.js @@ -130,11 +130,11 @@ export default { return data; }, - generate(data, relations, {html, language}) { - return relations.layout - .slots({ + generate: (data, relations, {html, language}) => + language.encapsulate('albumCommentaryPage', pageCapsule => + relations.layout.slots({ title: - language.$('albumCommentaryPage.title', { + language.$(pageCapsule, 'title', { album: data.name, }), @@ -146,7 +146,7 @@ export default { mainClasses: ['long-content'], mainContent: [ html.tag('p', - language.$('albumCommentaryPage.infoLine', { + language.$(pageCapsule, 'infoLine', { words: html.tag('b', language.formatWordCount(data.wordCount, {unit: true})), @@ -156,39 +156,41 @@ export default { language.countCommentaryEntries(data.entryCount, {unit: true})), })), - relations.albumCommentaryEntries && [ - relations.albumCommentaryHeading.slots({ - tag: 'h3', - color: data.color, - - title: - language.$('albumCommentaryPage.entry.title.albumCommentary', { - album: relations.albumCommentaryLink, - }), - - stickyTitle: - language.$('albumCommentaryPage.entry.title.albumCommentary.sticky', { - album: data.name, - }), - - accent: - language.$('albumCommentaryPage.entry.title.albumCommentary.accent', { - [language.onlyIfOptions]: ['listeningLinks'], - listeningLinks: - language.formatUnitList( - relations.albumCommentaryListeningLinks - .map(link => link.slots({ - context: 'album', - tab: 'separate', - }))), - }), - }), - - relations.albumCommentaryCover - ?.slots({mode: 'commentary'}), - - relations.albumCommentaryEntries, - ], + relations.albumCommentaryEntries && + language.encapsulate(pageCapsule, 'entry', entryCapsule => [ + language.encapsulate(entryCapsule, 'title.albumCommentary', titleCapsule => + relations.albumCommentaryHeading.slots({ + tag: 'h3', + color: data.color, + + title: + language.$(titleCapsule, { + album: relations.albumCommentaryLink, + }), + + stickyTitle: + language.$(titleCapsule, 'sticky', { + album: data.name, + }), + + accent: + language.$(titleCapsule, 'accent', { + [language.onlyIfOptions]: ['listeningLinks'], + listeningLinks: + language.formatUnitList( + relations.albumCommentaryListeningLinks + .map(link => link.slots({ + context: 'album', + tab: 'separate', + }))), + }), + })), + + relations.albumCommentaryCover + ?.slots({mode: 'commentary'}), + + relations.albumCommentaryEntries, + ]), stitchArrays({ heading: relations.trackCommentaryHeadings, @@ -206,31 +208,33 @@ export default { cover, entries, color, - }) => [ - heading.slots({ - tag: 'h3', - attributes: {id: directory}, - color, - - title: - language.$('albumCommentaryPage.entry.title.trackCommentary', { - track: link, - }), - - accent: - language.$('albumCommentaryPage.entry.title.trackCommentary.accent', { - [language.onlyIfOptions]: ['listeningLinks'], - listeningLinks: - language.formatUnitList( - listeningLinks.map(link => - link.slot('tab', 'separate'))), - }), - }), + }) => + language.encapsulate(pageCapsule, 'entry', entryCapsule => [ + language.encapsulate(entryCapsule, 'title.trackCommentary', titleCapsule => + heading.slots({ + tag: 'h3', + attributes: {id: directory}, + color, + + title: + language.$(titleCapsule, { + track: link, + }), + + accent: + language.$(titleCapsule, 'accent', { + [language.onlyIfOptions]: ['listeningLinks'], + listeningLinks: + language.formatUnitList( + listeningLinks.map(link => + link.slot('tab', 'separate'))), + }), + })), cover?.slots({mode: 'commentary'}), entries.map(entry => entry.slot('color', color)), - ]), + ])), ], navLinkStyle: 'hierarchical', @@ -251,6 +255,5 @@ export default { ], leftSidebar: relations.sidebar, - }); - }, + })), }; diff --git a/src/content/dependencies/generateAlbumGalleryPage.js b/src/content/dependencies/generateAlbumGalleryPage.js index aa025688..44d49c54 100644 --- a/src/content/dependencies/generateAlbumGalleryPage.js +++ b/src/content/dependencies/generateAlbumGalleryPage.js @@ -160,11 +160,11 @@ export default { return data; }, - generate(data, relations, {language}) { - return relations.layout - .slots({ + generate: (data, relations, {language}) => + language.encapsulate('albumGalleryPage', pageCapsule => + relations.layout.slots({ title: - language.$('albumGalleryPage.title', { + language.$(pageCapsule, 'title', { album: data.name, }), @@ -223,6 +223,5 @@ export default { ], secondaryNav: relations.secondaryNav, - }); - }, + })), }; diff --git a/src/content/dependencies/generateAlbumInfoPage.js b/src/content/dependencies/generateAlbumInfoPage.js index 9e4b8816..3af312bb 100644 --- a/src/content/dependencies/generateAlbumInfoPage.js +++ b/src/content/dependencies/generateAlbumInfoPage.js @@ -92,109 +92,120 @@ export default { }), generate: (data, relations, {html, language}) => - relations.layout.slots({ - title: language.$('albumPage.title', {album: data.name}), - headingMode: 'sticky', - - color: data.color, - styleRules: [relations.albumStyleRules], - - cover: - relations.cover - ?.slots({ - alt: language.$('misc.alt.albumCover'), - }) - ?? null, - - mainContent: [ - relations.releaseInfo, - - html.tag('p', - {[html.onlyIfContent]: true}, - {[html.joinChildren]: html.tag('br')}, - - [ - !html.isBlank(relations.additionalFilesList) && - language.$('releaseInfo.additionalFiles.shortcut', { - link: html.tag('a', - {href: '#additional-files'}, - language.$('releaseInfo.additionalFiles.shortcut.link')), + language.encapsulate('albumPage', pageCapsule => + relations.layout.slots({ + title: + language.$(pageCapsule, 'title', { + album: data.name, + }), + + color: data.color, + headingMode: 'sticky', + styleRules: [relations.albumStyleRules], + + cover: + relations.cover + ?.slots({ + alt: language.$('misc.alt.albumCover'), + }) + ?? null, + + mainContent: [ + relations.releaseInfo, + + html.tag('p', + {[html.onlyIfContent]: true}, + {[html.joinChildren]: html.tag('br')}, + + language.encapsulate('releaseInfo', capsule => [ + !html.isBlank(relations.additionalFilesList) && + language.$(capsule, 'additionalFiles.shortcut', { + link: html.tag('a', + {href: '#additional-files'}, + language.$(capsule, 'additionalFiles.shortcut.link')), + }), + + (relations.galleryLink && relations.commentaryLink + ? language.encapsulate(capsule, 'viewGalleryOrCommentary', capsule => + language.$(capsule, { + gallery: + relations.galleryLink + .slot('content', language.$(capsule, 'gallery')), + + commentary: + relations.commentaryLink + .slot('content', language.$(capsule, 'commentary')), + })) + + : relations.galleryLink + ? language.encapsulate(capsule, 'viewGallery', capsule => + language.$(capsule, { + link: + relations.galleryLink + .slot('content', language.$(capsule, 'link')), + })) + + : relations.commentaryLink + ? language.encapsulate(capsule, 'viewCommentary', capsule => + language.$(capsule, { + link: + relations.commentaryLink + .slot('content', language.$(capsule, 'link')), + })) + + : html.blank()), + ])), + + relations.trackList, + + html.tag('p', + {[html.onlyIfContent]: true}, + {[html.joinChildren]: html.tag('br')}, + + language.encapsulate('releaseInfo', capsule => [ + language.$(capsule, 'addedToWiki', { + [language.onlyIfOptions]: ['date'], + date: language.formatDate(data.dateAddedToWiki), }), - - relations.galleryLink && relations.commentaryLink && - language.$('releaseInfo.viewGalleryOrCommentary', { - gallery: - relations.galleryLink - .slot('content', language.$('releaseInfo.viewGalleryOrCommentary.gallery')), - commentary: - relations.commentaryLink - .slot('content', language.$('releaseInfo.viewGalleryOrCommentary.commentary')), + ])), + + language.encapsulate('releaseInfo.additionalFiles', capsule => + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'additional-files'}, + title: language.$(capsule, 'heading'), + }), + + relations.additionalFilesList, + ])), + + relations.artistCommentarySection, + ], + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + { + auto: 'current', + accent: + relations.albumNavAccent.slots({ + showTrackNavigation: true, + showExtraLinks: true, }), + }, + ], - relations.galleryLink && !relations.commentaryLink && - language.$('releaseInfo.viewGallery', { - link: - relations.galleryLink - .slot('content', language.$('releaseInfo.viewGallery.link')), - }), + navContent: + relations.chronologyLinks, - !relations.galleryLink && relations.commentaryLink && - language.$('releaseInfo.viewCommentary', { - link: - relations.commentaryLink - .slot('content', language.$('releaseInfo.viewCommentary.link')), - }), - ]), - - relations.trackList, - - html.tag('p', - {[html.onlyIfContent]: true}, - {[html.joinChildren]: html.tag('br')}, - - [ - language.$('releaseInfo.addedToWiki', { - [language.onlyIfOptions]: ['date'], - date: language.formatDate(data.dateAddedToWiki), - }), - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'additional-files'}, - title: language.$('releaseInfo.additionalFiles.heading'), - }), - - relations.additionalFilesList, - ]), - - relations.artistCommentarySection, - ], - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - { - auto: 'current', - accent: - relations.albumNavAccent.slots({ - showTrackNavigation: true, - showExtraLinks: true, - }), - }, - ], - - navContent: - relations.chronologyLinks, - - banner: relations.banner ?? null, - bannerPosition: 'top', - - secondaryNav: relations.secondaryNav, - - leftSidebar: relations.sidebar, - - socialEmbed: relations.socialEmbed, - }), + banner: relations.banner ?? null, + bannerPosition: 'top', + + secondaryNav: relations.secondaryNav, + + leftSidebar: relations.sidebar, + + socialEmbed: relations.socialEmbed, + })), }; diff --git a/src/content/dependencies/generateAlbumNavAccent.js b/src/content/dependencies/generateAlbumNavAccent.js index 121af439..4b6fb062 100644 --- a/src/content/dependencies/generateAlbumNavAccent.js +++ b/src/content/dependencies/generateAlbumNavAccent.js @@ -62,18 +62,21 @@ export default { }, generate(data, relations, slots, {html, language}) { + const albumNavCapsule = language.encapsulate('albumPage.nav'); + const trackNavCapsule = language.encapsulate('trackPage.nav'); + const {content: extraLinks = []} = slots.showExtraLinks && {content: [ (!data.galleryIsStub || slots.currentExtra === 'gallery') && relations.albumGalleryLink?.slots({ attributes: {class: slots.currentExtra === 'gallery' && 'current'}, - content: language.$('albumPage.nav.gallery'), + content: language.$(albumNavCapsule, 'gallery'), }), relations.albumCommentaryLink?.slots({ attributes: {class: slots.currentExtra === 'commentary' && 'current'}, - content: language.$('albumPage.nav.commentary'), + content: language.$(albumNavCapsule, 'commentary'), }), ]}; @@ -94,8 +97,8 @@ export default { {href: '#', 'data-random': 'track-in-sidebar'}, (data.isTrackPage - ? language.$('trackPage.nav.random') - : language.$('albumPage.nav.randomTrack'))); + ? language.$(trackNavCapsule, 'random') + : language.$(albumNavCapsule, 'randomTrack'))); const allLinks = [ ...previousNextLinks, diff --git a/src/content/dependencies/generateAlbumReleaseInfo.js b/src/content/dependencies/generateAlbumReleaseInfo.js index 26e2e160..e4c184c0 100644 --- a/src/content/dependencies/generateAlbumReleaseInfo.js +++ b/src/content/dependencies/generateAlbumReleaseInfo.js @@ -59,61 +59,63 @@ export default { return data; }, - generate(data, relations, {html, language}) { - return html.tags([ - html.tag('p', - {[html.onlyIfContent]: true}, - {[html.joinChildren]: html.tag('br')}, - - [ - relations.artistContributionsLine - .slots({stringKey: 'releaseInfo.by'}), - - relations.coverArtistContributionsLine - .slots({stringKey: 'releaseInfo.coverArtBy'}), - - relations.wallpaperArtistContributionsLine - .slots({stringKey: 'releaseInfo.wallpaperArtBy'}), - - relations.bannerArtistContributionsLine - .slots({stringKey: 'releaseInfo.bannerArtBy'}), - - language.$('releaseInfo.released', { - [language.onlyIfOptions]: ['date'], - date: language.formatDate(data.date), - }), - - language.$('releaseInfo.artReleased', { - [language.onlyIfOptions]: ['date'], - date: language.formatDate(data.coverArtDate), - }), - - language.$('releaseInfo.duration', { - [language.onlyIfOptions]: ['duration'], - duration: - language.formatDuration(data.duration, { - approximate: data.durationApproximate, - }), - }), - ]), - - html.tag('p', - {[html.onlyIfContent]: true}, - language.$('releaseInfo.listenOn', { - [language.onlyIfOptions]: ['links'], - links: - language.formatDisjunctionList( - relations.externalLinks - .map(link => - link.slot('context', [ - 'album', - (data.numTracks === 0 - ? 'albumNoTracks' - : data.numTracks === 1 - ? 'albumOneTrack' - : 'albumMultipleTracks'), - ]))), - })), - ]); - }, + generate: (data, relations, {html, language}) => + language.encapsulate('releaseInfo', capsule => + html.tags([ + html.tag('p', + {[html.onlyIfContent]: true}, + {[html.joinChildren]: html.tag('br')}, + + [ + relations.artistContributionsLine + .slots({stringKey: capsule + '.by'}), + + relations.coverArtistContributionsLine + .slots({stringKey: capsule + '.coverArtBy'}), + + relations.wallpaperArtistContributionsLine + .slots({stringKey: capsule + '.wallpaperArtBy'}), + + relations.bannerArtistContributionsLine + .slots({stringKey: capsule + '.bannerArtBy'}), + + language.$(capsule, 'released', { + [language.onlyIfOptions]: ['date'], + date: language.formatDate(data.date), + }), + + language.$(capsule, 'artReleased', { + [language.onlyIfOptions]: ['date'], + date: language.formatDate(data.coverArtDate), + }), + + language.$(capsule, 'duration', { + [language.onlyIfOptions]: ['duration'], + duration: + language.formatDuration(data.duration, { + approximate: data.durationApproximate, + }), + }), + ]), + + html.tag('p', + {[html.onlyIfContent]: true}, + + language.$(capsule, 'listenOn', { + [language.onlyIfOptions]: ['links'], + + links: + language.formatDisjunctionList( + relations.externalLinks + .map(link => + link.slot('context', [ + 'album', + (data.numTracks === 0 + ? 'albumNoTracks' + : data.numTracks === 1 + ? 'albumOneTrack' + : 'albumMultipleTracks'), + ]))), + })), + ])), }; diff --git a/src/content/dependencies/generateAlbumSidebarGroupBox.js b/src/content/dependencies/generateAlbumSidebarGroupBox.js index cc9b2c13..f3be74f7 100644 --- a/src/content/dependencies/generateAlbumSidebarGroupBox.js +++ b/src/content/dependencies/generateAlbumSidebarGroupBox.js @@ -77,45 +77,50 @@ export default { }, generate: (relations, slots, {html, language}) => - relations.box.slots({ - attributes: {class: 'individual-group-sidebar-box'}, - content: [ - html.tag('h1', - language.$('albumSidebar.groupBox.title', { - group: relations.groupLink, - })), - - slots.mode === 'album' && - relations.description - ?.slot('mode', 'multiline'), - - html.tag('p', - {[html.onlyIfContent]: true}, - - language.$('releaseInfo.visitOn', { - [language.onlyIfOptions]: ['links'], - - links: - language.formatDisjunctionList( - relations.externalLinks - .map(link => link.slot('context', 'group'))), - })), - - slots.mode === 'album' && - html.tag('p', {class: 'group-chronology-link'}, - {[html.onlyIfContent]: true}, - language.$('albumSidebar.groupBox.next', { - [language.onlyIfOptions]: ['album'], - album: relations.nextAlbumLink, + language.encapsulate('albumSidebar.groupBox', boxCapsule => + relations.box.slots({ + attributes: {class: 'individual-group-sidebar-box'}, + content: [ + html.tag('h1', + language.$(boxCapsule, 'title', { + group: relations.groupLink, })), - slots.mode === 'album' && - html.tag('p', {class: 'group-chronology-link'}, + slots.mode === 'album' && + relations.description + ?.slot('mode', 'multiline'), + + html.tag('p', {[html.onlyIfContent]: true}, - language.$('albumSidebar.groupBox.previous', { - [language.onlyIfOptions]: ['album'], - album: relations.previousAlbumLink, + + language.$('releaseInfo.visitOn', { + [language.onlyIfOptions]: ['links'], + + links: + language.formatDisjunctionList( + relations.externalLinks + .map(link => link.slot('context', 'group'))), })), - ], - }), + + slots.mode === 'album' && + html.tag('p', {class: 'group-chronology-link'}, + {[html.onlyIfContent]: true}, + + language.$(boxCapsule, 'next', { + [language.onlyIfOptions]: ['album'], + + album: relations.nextAlbumLink, + })), + + slots.mode === 'album' && + html.tag('p', {class: 'group-chronology-link'}, + {[html.onlyIfContent]: true}, + + language.$(boxCapsule, 'previous', { + [language.onlyIfOptions]: ['album'], + + album: relations.previousAlbumLink, + })), + ], + })), }; diff --git a/src/content/dependencies/generateAlbumSidebarTrackSection.js b/src/content/dependencies/generateAlbumSidebarTrackSection.js index aa5c723d..d59218b8 100644 --- a/src/content/dependencies/generateAlbumSidebarTrackSection.js +++ b/src/content/dependencies/generateAlbumSidebarTrackSection.js @@ -55,10 +55,12 @@ export default { }, generate(data, relations, slots, {getColors, html, language}) { + const capsule = language.encapsulate('albumSidebar.trackList'); + const sectionName = html.tag('span', {class: 'group-name'}, (data.isDefaultTrackSection - ? language.$('albumSidebar.trackList.fallbackSectionName') + ? language.$(capsule, 'fallbackSectionName') : data.name)); let colorStyle; @@ -78,7 +80,7 @@ export default { data.tracksAreMissingCommentary[index] && {class: 'no-commentary'}, - language.$('albumSidebar.trackList.item', { + language.$(capsule, 'item', { track: (slots.mode === 'commentary' && data.tracksAreMissingCommentary[index] ? trackLink.slots({ @@ -117,14 +119,17 @@ export default { colorStyle, html.tag('span', - (data.hasTrackNumbers - ? language.$('albumSidebar.trackList.group.withRange', { - group: sectionName, - range: `${data.firstTrackNumber}–${data.lastTrackNumber}` - }) - : language.$('albumSidebar.trackList.group', { - group: sectionName, - })))), + language.encapsulate(capsule, 'group', capsule => { + const options = {group: sectionName}; + + if (data.hasTrackNumbers) { + capsule += '.withRange'; + options.range = + `${data.firstTrackNumber}–${data.lastTrackNumber}`; + } + + return language.$(capsule, options); + }))), (data.hasTrackNumbers ? html.tag('ol', diff --git a/src/content/dependencies/generateAlbumSocialEmbed.js b/src/content/dependencies/generateAlbumSocialEmbed.js index c8b123fe..7500109e 100644 --- a/src/content/dependencies/generateAlbumSocialEmbed.js +++ b/src/content/dependencies/generateAlbumSocialEmbed.js @@ -41,34 +41,34 @@ export default { return data; }, - generate(data, relations, {absoluteTo, language, urls}) { - return relations.socialEmbed.slots({ - title: - language.$('albumPage.socialEmbed.title', { - album: data.albumName, - }), - - description: relations.description, - - headingContent: - (data.hasHeading - ? language.$('albumPage.socialEmbed.heading', { - group: data.headingGroupName, - }) - : null), - - headingLink: - (data.hasHeading - ? absoluteTo('localized.groupGallery', data.headingGroupDirectory) - : null), - - imagePath: - (data.hasImage - ? '/' + - urls - .from('shared.root') - .to('media.albumCover', data.coverArtDirectory, data.coverArtFileExtension) - : null), - }); - }, + generate: (data, relations, {absoluteTo, language, urls}) => + language.encapsulate('albumPage.socialEmbed', embedCapsule => + relations.socialEmbed.slots({ + title: + language.$(embedCapsule, 'title', { + album: data.albumName, + }), + + description: relations.description, + + headingContent: + (data.hasHeading + ? language.$(embedCapsule, 'heading', { + group: data.headingGroupName, + }) + : null), + + headingLink: + (data.hasHeading + ? absoluteTo('localized.groupGallery', data.headingGroupDirectory) + : null), + + imagePath: + (data.hasImage + ? '/' + + urls + .from('shared.root') + .to('media.albumCover', data.coverArtDirectory, data.coverArtFileExtension) + : null), + })), }; diff --git a/src/content/dependencies/generateAlbumTrackList.js b/src/content/dependencies/generateAlbumTrackList.js index dd3e85e3..a3435bea 100644 --- a/src/content/dependencies/generateAlbumTrackList.js +++ b/src/content/dependencies/generateAlbumTrackList.js @@ -147,27 +147,30 @@ export default { durationApproximate, startIndex, }) => [ - heading.slots({ - tag: 'dt', - - title: - (duration === 0 - ? language.$('trackList.section', { - section: name, - }) - : language.$('trackList.section.withDuration', { - section: name, - duration: + language.encapsulate('trackList.section', capsule => + heading.slots({ + tag: 'dt', + + title: + language.encapsulate(capsule, capsule => { + const options = {section: name}; + + if (duration !== 0) { + capsule += '.withDuration'; + options.duration = language.formatDuration(duration, { approximate: durationApproximate, - }), - })), - - stickyTitle: - language.$('trackList.section.sticky', { - section: name, - }), - }), + }); + } + + return language.$(capsule, options); + }), + + stickyTitle: + language.$(capsule, 'sticky', { + section: name, + }), + })), html.tag('dd', html.tag(listTag, diff --git a/src/content/dependencies/generateAlbumTrackListItem.js b/src/content/dependencies/generateAlbumTrackListItem.js index 7190fb4c..7d5d2c6e 100644 --- a/src/content/dependencies/generateAlbumTrackListItem.js +++ b/src/content/dependencies/generateAlbumTrackListItem.js @@ -80,54 +80,51 @@ export default { }, }, - generate(data, relations, slots, {getColors, html, language}) { - let colorStyle; - if (data.color) { - const {primary} = getColors(data.color); - colorStyle = {style: `--primary-color: ${primary}`}; - } - - const parts = ['trackList.item']; - const options = {}; - - options.track = - relations.trackLink - .slot('color', false); - - const collapseDuration = - (slots.collapseDurationScope === 'track' - ? !data.trackHasDuration - : slots.collapseDurationScope === 'section' - ? !data.sectionHasDuration - : slots.collapseDurationScope === 'album' - ? !data.albumHasDuration - : false); - - if (!collapseDuration) { - parts.push('withDuration'); - - options.duration = - (data.trackHasDuration - ? language.$('trackList.item.withDuration.duration', { - duration: - language.formatDuration(data.duration), - }) - : relations.missingDuration); - } - - if (data.showArtists) { - parts.push('withArtists'); - options.by = - html.tag('span', {class: 'by'}, - html.metatag('chunkwrap', {split: ','}, - html.resolve( - language.$('trackList.item.withArtists.by', { - artists: language.formatConjunctionList(relations.contributionLinks), - })))); - } - - return html.tag('li', - colorStyle, - language.formatString(...parts, options)); - }, + generate: (data, relations, slots, {getColors, html, language}) => + language.encapsulate('trackList.item', itemCapsule => + html.tag('li', + data.color && + {style: `--primary-color: ${getColors(data.color).primary}`}, + + language.encapsulate(itemCapsule, workingCapsule => { + const workingOptions = {}; + + workingOptions.track = + relations.trackLink + .slot('color', false); + + const collapseDuration = + (slots.collapseDurationScope === 'track' + ? !data.trackHasDuration + : slots.collapseDurationScope === 'section' + ? !data.sectionHasDuration + : slots.collapseDurationScope === 'album' + ? !data.albumHasDuration + : false); + + if (!collapseDuration) { + workingCapsule += '.withDuration'; + workingOptions.duration = + (data.trackHasDuration + ? language.$(itemCapsule, 'withDuration.duration', { + duration: + language.formatDuration(data.duration), + }) + : relations.missingDuration); + } + + if (data.showArtists) { + workingCapsule += '.withArtists'; + workingOptions.by = + html.tag('span', {class: 'by'}, + html.metatag('chunkwrap', {split: ','}, + html.resolve( + language.$(itemCapsule, 'withArtists.by', { + artists: + language.formatConjunctionList(relations.contributionLinks), + })))); + } + + return language.$(workingCapsule, workingOptions); + }))), }; diff --git a/src/content/dependencies/generateAlbumTrackListMissingDuration.js b/src/content/dependencies/generateAlbumTrackListMissingDuration.js index 6d4a6ec8..b5917982 100644 --- a/src/content/dependencies/generateAlbumTrackListMissingDuration.js +++ b/src/content/dependencies/generateAlbumTrackListMissingDuration.js @@ -11,23 +11,25 @@ export default { }), generate: (relations, {html, language}) => - relations.textWithTooltip.slots({ - attributes: {class: 'missing-duration'}, - customInteractionCue: true, + language.encapsulate('trackList.item.withDuration', itemCapsule => + language.encapsulate(itemCapsule, 'duration', durationCapsule => + relations.textWithTooltip.slots({ + attributes: {class: 'missing-duration'}, + customInteractionCue: true, - text: - language.$('trackList.item.withDuration.duration', { - duration: - html.tag('span', {class: 'text-with-tooltip-interaction-cue'}, - language.$('trackList.item.withDuration.duration.missing')), - }), + text: + language.$(durationCapsule, { + duration: + html.tag('span', {class: 'text-with-tooltip-interaction-cue'}, + language.$(durationCapsule, 'missing')), + }), - tooltip: - relations.tooltip.slots({ - attributes: {class: 'missing-duration-tooltip'}, + tooltip: + relations.tooltip.slots({ + attributes: {class: 'missing-duration-tooltip'}, - content: - language.$('trackList.item.withDuration.duration.missing.info'), - }), - }), + content: + language.$(durationCapsule, 'missing.info'), + }), + }))), }; diff --git a/src/content/dependencies/generateArtTagGalleryPage.js b/src/content/dependencies/generateArtTagGalleryPage.js index eae48f05..c51faeba 100644 --- a/src/content/dependencies/generateArtTagGalleryPage.js +++ b/src/content/dependencies/generateArtTagGalleryPage.js @@ -85,11 +85,11 @@ export default { return data; }, - generate(data, relations, {html, language}) { - return relations.layout - .slots({ + generate: (data, relations, {html, language}) => + language.encapsulate('tagPage', pageCapsule => + relations.layout.slots({ title: - language.$('tagPage.title', { + language.$(pageCapsule, 'title', { tag: data.name, }), @@ -100,7 +100,7 @@ export default { mainClasses: ['top-index'], mainContent: [ html.tag('p', {class: 'quick-info'}, - language.$('tagPage.infoLine', { + language.$(pageCapsule, 'infoLine', { coverArts: language.countCoverArts(data.numArtworks, { unit: true, }), @@ -143,11 +143,10 @@ export default { { html: - language.$('tagPage.nav.tag', { + language.$(pageCapsule, 'nav.tag', { tag: relations.artTagMainLink, }), }, ], - }); - }, + })), }; diff --git a/src/content/dependencies/generateArtistGalleryPage.js b/src/content/dependencies/generateArtistGalleryPage.js index 26a894c6..28f06a21 100644 --- a/src/content/dependencies/generateArtistGalleryPage.js +++ b/src/content/dependencies/generateArtistGalleryPage.js @@ -84,11 +84,11 @@ export default { return data; }, - generate(data, relations, {html, language}) { - return relations.layout - .slots({ + generate: (data, relations, {html, language}) => + language.encapsulate('artistGalleryPage', pageCapsule => + relations.layout.slots({ title: - language.$('artistGalleryPage.title', { + language.$(pageCapsule, 'title', { artist: data.name, }), @@ -97,10 +97,11 @@ export default { mainClasses: ['top-index'], mainContent: [ html.tag('p', {class: 'quick-info'}, - language.$('artistGalleryPage.infoLine', { - coverArts: language.countCoverArts(data.numArtworks, { - unit: true, - }), + language.$(pageCapsule, 'infoLine', { + coverArts: + language.countCoverArts(data.numArtworks, { + unit: true, + }), })), relations.coverGrid @@ -119,6 +120,7 @@ export default { dimensions, })), + // TODO: Can this be [language.onlyIfOptions]? info: data.otherCoverArtists.map(names => (names === null @@ -137,6 +139,5 @@ export default { currentExtra: 'gallery', }) .content, - }) - }, + })), } diff --git a/src/content/dependencies/generateArtistGroupContributionsInfo.js b/src/content/dependencies/generateArtistGroupContributionsInfo.js index ef81739d..f84d00de 100644 --- a/src/content/dependencies/generateArtistGroupContributionsInfo.js +++ b/src/content/dependencies/generateArtistGroupContributionsInfo.js @@ -131,100 +131,104 @@ export default { countUnit: {validate: v => v.is('tracks', 'artworks')}, }, - generate(data, relations, slots, {html, language}) { - if (slots.sort === 'count' && empty(relations.groupLinksSortedByCount)) { - return html.blank(); - } else if (slots.sort === 'duration' && empty(relations.groupLinksSortedByDuration)) { - return html.blank(); - } + generate: (data, relations, slots, {html, language}) => + language.encapsulate('artistPage.groupContributions', capsule => { + if (slots.sort === 'count' && empty(relations.groupLinksSortedByCount)) { + return html.blank(); + } else if (slots.sort === 'duration' && empty(relations.groupLinksSortedByDuration)) { + return html.blank(); + } - const getCounts = counts => - counts.map(count => { - switch (slots.countUnit) { - case 'tracks': return language.countTracks(count, {unit: true}); - case 'artworks': return language.countArtworks(count, {unit: true}); - } - }); - - // We aren't displaying the "~" approximate symbol here for now. - // The general notion that these sums aren't going to be 100% accurate - // is made clear by the "XYZ has contributed ~1:23:45 hours of music..." - // line that's always displayed above this table. - const getDurations = (durations, approximate) => - stitchArrays({ - duration: durations, - approximate: approximate, - }).map(({duration}) => language.formatDuration(duration)); - - const topLevelClasses = [ - 'group-contributions-sorted-by-' + slots.sort, - slots.visible && 'visible', - ]; - - // TODO: It feels pretty awkward that this component is the only one that - // has enough knowledge to decide if the sort button is even applicable... - const switchingSortPossible = - !empty(relations.groupLinksSortedByCount) && - !empty(relations.groupLinksSortedByDuration); - - return html.tags([ - html.tag('dt', {class: topLevelClasses}, - (switchingSortPossible && slots.showSortButton - ? language.$('artistPage.groupContributions.title.withSortButton', { - title: slots.title, - sort: - html.tag('a', {class: 'group-contributions-sort-button'}, - {href: '#'}, - - (slots.sort === 'count' - ? language.$('artistPage.groupContributions.title.sorting.count') - : language.$('artistPage.groupContributions.title.sorting.duration'))), - }) - : slots.title)), - - html.tag('dd', {class: topLevelClasses}, - html.tag('ul', {class: 'group-contributions-table'}, - {role: 'list'}, - - (slots.sort === 'count' - ? stitchArrays({ - group: relations.groupLinksSortedByCount, - count: getCounts(data.groupCountsSortedByCount), - duration: - getDurations( - data.groupDurationsSortedByCount, - data.groupDurationsApproximateSortedByCount), - }).map(({group, count, duration}) => - html.tag('li', - html.tag('div', {class: 'group-contributions-row'}, [ - group, - html.tag('span', {class: 'group-contributions-metrics'}, - // When sorting by count, duration details aren't necessarily - // available for all items. - (slots.showBothColumns && duration - ? language.$('artistPage.groupContributions.item.countDurationAccent', {count, duration}) - : language.$('artistPage.groupContributions.item.countAccent', {count}))), - ]))) - - : stitchArrays({ - group: relations.groupLinksSortedByDuration, - count: getCounts(data.groupCountsSortedByDuration), - duration: - getDurations( - data.groupDurationsSortedByDuration, - data.groupDurationsApproximateSortedByDuration), - }).map(({group, count, duration}) => - html.tag('li', - html.tag('div', {class: 'group-contributions-row'}, [ - group, - html.tag('span', {class: 'group-contributions-metrics'}, - // Count details are always available, since they're just the - // number of contributions directly. And duration details are - // guaranteed for every item when sorting by duration. - (slots.showBothColumns - ? language.$('artistPage.groupContributions.item.durationCountAccent', {duration, count}) - : language.$('artistPage.groupContributions.item.durationAccent', {duration}))), - ])))))), - ]); - }, + const getCounts = counts => + counts.map(count => { + switch (slots.countUnit) { + case 'tracks': return language.countTracks(count, {unit: true}); + case 'artworks': return language.countArtworks(count, {unit: true}); + } + }); + + // We aren't displaying the "~" approximate symbol here for now. + // The general notion that these sums aren't going to be 100% accurate + // is made clear by the "XYZ has contributed ~1:23:45 hours of music..." + // line that's always displayed above this table. + const getDurations = (durations, approximate) => + stitchArrays({ + duration: durations, + approximate: approximate, + }).map(({duration}) => language.formatDuration(duration)); + + const topLevelClasses = [ + 'group-contributions-sorted-by-' + slots.sort, + slots.visible && 'visible', + ]; + + // TODO: It feels pretty awkward that this component is the only one that + // has enough knowledge to decide if the sort button is even applicable... + const switchingSortPossible = + !empty(relations.groupLinksSortedByCount) && + !empty(relations.groupLinksSortedByDuration); + + return html.tags([ + html.tag('dt', {class: topLevelClasses}, + language.encapsulate(capsule, 'title', capsule => + (switchingSortPossible && slots.showSortButton + ? language.$(capsule, 'withSortButton', { + title: slots.title, + sort: + html.tag('a', {class: 'group-contributions-sort-button'}, + {href: '#'}, + + (slots.sort === 'count' + ? language.$(capsule, 'sorting.count') + : language.$(capsule, 'sorting.duration'))), + }) + : slots.title))), + + html.tag('dd', {class: topLevelClasses}, + html.tag('ul', {class: 'group-contributions-table'}, + {role: 'list'}, + + (slots.sort === 'count' + ? stitchArrays({ + group: relations.groupLinksSortedByCount, + count: getCounts(data.groupCountsSortedByCount), + duration: + getDurations( + data.groupDurationsSortedByCount, + data.groupDurationsApproximateSortedByCount), + }).map(({group, count, duration}) => + language.encapsulate(capsule, 'item', capsule => + html.tag('li', + html.tag('div', {class: 'group-contributions-row'}, [ + group, + html.tag('span', {class: 'group-contributions-metrics'}, + // When sorting by count, duration details aren't necessarily + // available for all items. + (slots.showBothColumns && duration + ? language.$(capsule, 'countDurationAccent', {count, duration}) + : language.$(capsule, 'countAccent', {count}))), + ])))) + + : stitchArrays({ + group: relations.groupLinksSortedByDuration, + count: getCounts(data.groupCountsSortedByDuration), + duration: + getDurations( + data.groupDurationsSortedByDuration, + data.groupDurationsApproximateSortedByDuration), + }).map(({group, count, duration}) => + language.encapsulate(capsule, 'item', capsule => + html.tag('li', + html.tag('div', {class: 'group-contributions-row'}, [ + group, + html.tag('span', {class: 'group-contributions-metrics'}, + // Count details are always available, since they're just the + // number of contributions directly. And duration details are + // guaranteed for every item when sorting by duration. + (slots.showBothColumns + ? language.$(capsule, 'durationCountAccent', {duration, count}) + : language.$(capsule, 'durationAccent', {duration}))), + ]))))))), + ]); + }), }; diff --git a/src/content/dependencies/generateArtistInfoPage.js b/src/content/dependencies/generateArtistInfoPage.js index dd56b757..f9ce7e3b 100644 --- a/src/content/dependencies/generateArtistInfoPage.js +++ b/src/content/dependencies/generateArtistInfoPage.js @@ -115,185 +115,198 @@ export default { }), generate: (data, relations, {html, language}) => - relations.layout.slots({ - title: data.name, - headingMode: 'sticky', - - cover: - (relations.cover - ? relations.cover.slots({ - path: [ - 'media.artistAvatar', - data.directory, - data.avatarFileExtension, - ], - }) - : null), + language.encapsulate('artistPage', pageCapsule => + relations.layout.slots({ + title: data.name, + headingMode: 'sticky', + + cover: + (relations.cover + ? relations.cover.slots({ + path: [ + 'media.artistAvatar', + data.directory, + data.avatarFileExtension, + ], + }) + : null), + + mainContent: [ + html.tags([ + html.tag('p', + {[html.onlyIfSiblings]: true}, + language.$('releaseInfo.note')), + + html.tag('blockquote', + {[html.onlyIfContent]: true}, + relations.contextNotes), + ]), - mainContent: [ - html.tags([ html.tag('p', - {[html.onlyIfSiblings]: true}, - language.$('releaseInfo.note')), + {[html.onlyIfContent]: true}, - html.tag('blockquote', + language.$('releaseInfo.visitOn', { + [language.onlyIfOptions]: ['links'], + + links: + language.formatDisjunctionList( + relations.visitLinks + .map(link => link.slot('context', 'artist'))), + })), + + html.tag('p', {[html.onlyIfContent]: true}, - relations.contextNotes), - ]), - - html.tag('p', - {[html.onlyIfContent]: true}, - language.$('releaseInfo.visitOn', { - [language.onlyIfOptions]: ['links'], - links: - language.formatDisjunctionList( - relations.visitLinks - .map(link => link.slot('context', 'artist'))), - })), - - html.tag('p', - {[html.onlyIfContent]: true}, - language.$('artistPage.viewArtGallery', { - [language.onlyIfOptions]: ['link'], - link: - relations.artistGalleryLink?.slots({ - content: language.$('artistPage.viewArtGallery.link'), - }), - })), - - html.tag('p', - {[html.onlyIfContent]: true}, - language.$('misc.jumpTo.withLinks', { - [language.onlyIfOptions]: ['links'], - links: - language.formatUnitList([ - !html.isBlank(relations.tracksChunkedList) && - html.tag('a', - {href: '#tracks'}, - language.$('artistPage.trackList.title')), - - !html.isBlank(relations.artworksChunkedList) && - html.tag('a', - {href: '#art'}, - language.$('artistPage.artList.title')), - - !html.isBlank(relations.flashesChunkedList) && - html.tag('a', - {href: '#flashes'}, - language.$('artistPage.flashList.title')), - - !html.isBlank(relations.commentaryChunkedList) && - html.tag('a', - {href: '#commentary'}, - language.$('artistPage.commentaryList.title')), - ].filter(Boolean)), - })), - - html.tags([ - relations.contentHeading.clone() - .slots({ - tag: 'h2', - attributes: {id: 'tracks'}, - title: language.$('artistPage.trackList.title'), - }), - data.totalDuration > 0 && - html.tag('p', - {[html.onlyIfSiblings]: true}, - language.$('artistPage.contributedDurationLine', { - artist: data.name, - duration: - language.formatDuration(data.totalDuration, { - approximate: data.totalTrackCount > 1, - unit: true, + language.encapsulate(pageCapsule, 'viewArtGallery', capsule => + language.$(capsule, { + [language.onlyIfOptions]: ['link'], + + link: + relations.artistGalleryLink?.slots({ + content: + language.$(capsule, 'link'), }), - })), - - relations.tracksChunkedList.slots({ - groupInfo: [ - relations.tracksGroupInfo - .clone() - .slots({ - title: language.$('artistPage.groupContributions.title.music'), - showSortButton: true, - sort: 'count', - countUnit: 'tracks', - visible: true, - }), - - relations.tracksGroupInfo - .clone() - .slots({ - title: language.$('artistPage.groupContributions.title.music'), - showSortButton: true, - sort: 'duration', - countUnit: 'tracks', - visible: false, - }), - ], - }), - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - tag: 'h2', - attributes: {id: 'art'}, - title: language.$('artistPage.artList.title'), - }), + }))), html.tag('p', {[html.onlyIfContent]: true}, - language.$('artistPage.viewArtGallery.orBrowseList', { - [language.onlyIfOptions]: ['link'], - link: - relations.artistGalleryLink?.slots({ - content: language.$('artistPage.viewArtGallery.link'), - }), + + language.$('misc.jumpTo.withLinks', { + [language.onlyIfOptions]: ['links'], + + links: + language.formatUnitList([ + !html.isBlank(relations.tracksChunkedList) && + html.tag('a', + {href: '#tracks'}, + language.$(pageCapsule, 'trackList.title')), + + !html.isBlank(relations.artworksChunkedList) && + html.tag('a', + {href: '#art'}, + language.$(pageCapsule, 'artList.title')), + + !html.isBlank(relations.flashesChunkedList) && + html.tag('a', + {href: '#flashes'}, + language.$(pageCapsule, 'flashList.title')), + + !html.isBlank(relations.commentaryChunkedList) && + html.tag('a', + {href: '#commentary'}, + language.$(pageCapsule, 'commentaryList.title')), + ].filter(Boolean)), })), - relations.artworksChunkedList - .slots({ + html.tags([ + relations.contentHeading.clone() + .slots({ + tag: 'h2', + attributes: {id: 'tracks'}, + title: language.$(pageCapsule, 'trackList.title'), + }), + + data.totalDuration > 0 && + html.tag('p', + {[html.onlyIfSiblings]: true}, + + language.$(pageCapsule, 'contributedDurationLine', { + artist: data.name, + duration: + language.formatDuration(data.totalDuration, { + approximate: data.totalTrackCount > 1, + unit: true, + }), + })), + + relations.tracksChunkedList.slots({ groupInfo: - relations.artworksGroupInfo - .slots({ - title: language.$('artistPage.groupContributions.title.artworks'), - showBothColumns: false, - sort: 'count', - countUnit: 'artworks', - }), + language.encapsulate(pageCapsule, 'groupContributions', capsule => [ + relations.tracksGroupInfo.clone() + .slots({ + title: language.$(capsule, 'title.music'), + showSortButton: true, + sort: 'count', + countUnit: 'tracks', + visible: true, + }), + + relations.tracksGroupInfo.clone() + .slots({ + title: language.$(capsule, 'title.music'), + showSortButton: true, + sort: 'duration', + countUnit: 'tracks', + visible: false, + }), + ]), }), - ]), + ]), + + html.tags([ + relations.contentHeading.clone() + .slots({ + tag: 'h2', + attributes: {id: 'art'}, + title: language.$(pageCapsule, 'artList.title'), + }), - html.tags([ - relations.contentHeading.clone() - .slots({ - tag: 'h2', - attributes: {id: 'flashes'}, - title: language.$('artistPage.flashList.title'), - }), + html.tag('p', + {[html.onlyIfContent]: true}, + + language.encapsulate(pageCapsule, 'viewArtGallery', capsule => + language.$(capsule, 'orBrowseList', { + [language.onlyIfOptions]: ['link'], + + link: + relations.artistGalleryLink?.slots({ + content: language.$(capsule, 'link'), + }), + }))), + + relations.artworksChunkedList + .slots({ + groupInfo: + language.encapsulate(pageCapsule, 'groupContributions', capsule => + relations.artworksGroupInfo + .slots({ + title: language.$(capsule, 'title.artworks'), + showBothColumns: false, + sort: 'count', + countUnit: 'artworks', + })), + }), + ]), + + html.tags([ + relations.contentHeading.clone() + .slots({ + tag: 'h2', + attributes: {id: 'flashes'}, + title: language.$(pageCapsule, 'flashList.title'), + }), - relations.flashesChunkedList, - ]), + relations.flashesChunkedList, + ]), - html.tags([ - relations.contentHeading.clone() - .slots({ - tag: 'h2', - attributes: {id: 'commentary'}, - title: language.$('artistPage.commentaryList.title'), - }), + html.tags([ + relations.contentHeading.clone() + .slots({ + tag: 'h2', + attributes: {id: 'commentary'}, + title: language.$(pageCapsule, 'commentaryList.title'), + }), + + relations.commentaryChunkedList, + ]), + ], - relations.commentaryChunkedList, - ]), - ], - - navLinkStyle: 'hierarchical', - navLinks: - relations.artistNavLinks - .slots({ - showExtraLinks: true, - }) - .content, - }), + navLinkStyle: 'hierarchical', + navLinks: + relations.artistNavLinks + .slots({ + showExtraLinks: true, + }) + .content, + })), }; diff --git a/src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js b/src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js index 098b9e8f..e8d887b1 100644 --- a/src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js +++ b/src/content/dependencies/generateArtistInfoPageArtworksChunkItem.js @@ -46,16 +46,17 @@ export default { annotation: data.annotation, content: - (data.kind === 'track-cover' - ? language.$('artistPage.creditList.entry.track', { - track: relations.trackLink, - }) - : html.tag('i', - language.$('artistPage.creditList.entry.album', - { - 'wallpaper': 'wallpaperArt', - 'banner': 'bannerArt', - 'album-cover': 'coverArt', - }[data.kind]))), + language.encapsulate('artistPage.creditList.entry', capsule => + (data.kind === 'track-cover' + ? language.$(capsule, 'track', { + track: relations.trackLink, + }) + : html.tag('i', + language.encapsulate(capsule, 'album', capsule => + (data.kind === 'wallpaper' + ? language.$(capsule, 'wallpaperArt') + : data.kind === 'banner' + ? language.$(capsule, 'bannerArt') + : language.$(capsule, 'coverArt')))))), }), }; diff --git a/src/content/dependencies/generateArtistInfoPageChunkItem.js b/src/content/dependencies/generateArtistInfoPageChunkItem.js index ee172f48..9d406c67 100644 --- a/src/content/dependencies/generateArtistInfoPageChunkItem.js +++ b/src/content/dependencies/generateArtistInfoPageChunkItem.js @@ -21,42 +21,38 @@ export default { rerelease: {type: 'boolean'}, }, - generate(slots, {html, language}) { - let accentedContent = slots.content; - - accent: { - if (slots.rerelease) { - accentedContent = - language.$('artistPage.creditList.entry.rerelease', { - entry: accentedContent, - }); - - break accent; - } - - const parts = ['artistPage.creditList.entry']; - const options = {entry: accentedContent}; - - if (!empty(slots.otherArtistLinks)) { - parts.push('withArtists'); - options.artists = language.formatConjunctionList(slots.otherArtistLinks); - } - - if (!html.isBlank(slots.annotation)) { - parts.push('withAnnotation'); - options.annotation = slots.annotation; - } - - if (parts.length === 1) { - break accent; - } - - accentedContent = language.formatString(...parts, options); - } - - return ( + generate: (slots, {html, language}) => + language.encapsulate('artistPage.creditList.entry', entryCapsule => html.tag('li', slots.rerelease && {class: 'rerelease'}, - accentedContent)); - }, + + language.encapsulate(entryCapsule, workingCapsule => { + const workingOptions = {entry: slots.content}; + + if (slots.rerelease) { + workingCapsule += '.rerelease'; + return language.$(workingCapsule, workingOptions); + } + + let anyAccent = false; + + if (!empty(slots.otherArtistLinks)) { + anyAccent = true; + workingCapsule += '.withArtists'; + workingOptions.artists = + language.formatConjunctionList(slots.otherArtistLinks); + } + + if (!html.isBlank(slots.annotation)) { + anyAccent = true; + workingCapsule += '.withAnnotation'; + workingOptions.annotation = slots.annotation; + } + + if (anyAccent) { + return language.$(workingCapsule, workingOptions); + } else { + return slots.content; + } + }))), }; diff --git a/src/content/dependencies/generateArtistInfoPageCommentaryChunkedList.js b/src/content/dependencies/generateArtistInfoPageCommentaryChunkedList.js index f4413197..72bbf1b6 100644 --- a/src/content/dependencies/generateArtistInfoPageCommentaryChunkedList.js +++ b/src/content/dependencies/generateArtistInfoPageCommentaryChunkedList.js @@ -216,53 +216,52 @@ export default { itemAnnotations, itemTypes, }) => - (chunkType === 'album' - ? chunk.slots({ - mode: 'album', - albumLink: chunkLink, - items: - stitchArrays({ - item: items, - link: itemLinks, - annotation: itemAnnotations, - type: itemTypes, - }).map(({item, link, annotation, type}) => - item.slots({ - annotation: - (annotation - ? annotation.slot('mode', 'inline') - : null), - - content: - (type === 'album' - ? html.tag('i', - language.$('artistPage.creditList.entry.album.commentary')) - : language.$('artistPage.creditList.entry.track', { - track: link, - })), - })), - }) - : chunkType === 'flash-act' - ? chunk.slots({ - mode: 'flash', - flashActLink: chunkLink, - items: - stitchArrays({ - item: items, - link: itemLinks, - annotation: itemAnnotations, - }).map(({item, link, annotation}) => - item.slots({ - annotation: - (annotation - ? annotation.slot('mode', 'inline') - : null), - - content: - language.$('artistPage.creditList.entry.flash', { - flash: link, - }), - })), - }) - : null))), + language.encapsulate('artistPage.creditList.entry', capsule => + (chunkType === 'album' + ? chunk.slots({ + mode: 'album', + albumLink: chunkLink, + items: + stitchArrays({ + item: items, + link: itemLinks, + annotation: itemAnnotations, + type: itemTypes, + }).map(({item, link, annotation, type}) => + item.slots({ + annotation: + (annotation + ? annotation.slot('mode', 'inline') + : null), + + content: + (type === 'album' + ? html.tag('i', + language.$(capsule, 'album.commentary')) + : language.$(capsule, 'track', {track: link})), + })), + }) + : chunkType === 'flash-act' + ? chunk.slots({ + mode: 'flash', + flashActLink: chunkLink, + items: + stitchArrays({ + item: items, + link: itemLinks, + annotation: itemAnnotations, + }).map(({item, link, annotation}) => + item.slots({ + annotation: + (annotation + ? annotation.slot('mode', 'inline') + : null), + + content: + language.$(capsule, 'flash', { + flash: link, + }), + })), + }) + : null)))), }; diff --git a/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js b/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js index d7460c80..d526f97a 100644 --- a/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js +++ b/src/content/dependencies/generateArtistInfoPageTracksChunkItem.js @@ -100,13 +100,16 @@ export default { : html.blank()), content: - (data.duration - ? language.$('artistPage.creditList.entry.track.withDuration', { - track: relations.trackLink, - duration: language.formatDuration(data.duration), - }) - : language.$('artistPage.creditList.entry.track', { - track: relations.trackLink, - })), + language.encapsulate('artistPage.creditList.entry.track', capsule => { + const options = {track: relations.trackLink}; + + if (data.duration) { + capsule += '.withDuration'; + options.duration = + language.formatDuration(data.duration); + } + + return language.$(capsule, options); + }), }), }; diff --git a/src/content/dependencies/generateChronologyLinksScopeSwitcher.js b/src/content/dependencies/generateChronologyLinksScopeSwitcher.js index 23c44268..4a1b67a7 100644 --- a/src/content/dependencies/generateChronologyLinksScopeSwitcher.js +++ b/src/content/dependencies/generateChronologyLinksScopeSwitcher.js @@ -32,18 +32,19 @@ export default { {class: 'underline-white'}, html.tag('span', - language.$('trackPage.nav.chronology.scope.title', { - scope: - slots.scopes.map((scope, index) => - html.tag('a', {class: 'switcher-link'}, - {href: '#'}, + language.encapsulate('trackPage.nav.chronology.scope', capsule => + language.$(capsule, 'title', { + scope: + slots.scopes.map((scope, index) => + html.tag('a', {class: 'switcher-link'}, + {href: '#'}, - (index === 0 - ? {style: 'display: inline'} - : {style: 'display: none'}), + (index === 0 + ? {style: 'display: inline'} + : {style: 'display: none'}), - language.$('trackPage.nav.chronology.scope', scope))), - }))); + language.$(capsule, scope))), + })))); const scopeContents = stitchArrays({ diff --git a/src/content/dependencies/generateCommentaryEntry.js b/src/content/dependencies/generateCommentaryEntry.js index 036f8a6f..7c4aed80 100644 --- a/src/content/dependencies/generateCommentaryEntry.js +++ b/src/content/dependencies/generateCommentaryEntry.js @@ -43,60 +43,71 @@ export default { color: {validate: v => v.isColor}, }, - generate(data, relations, slots, {html, language}) { - const artistsSpan = - html.tag('span', {class: 'commentary-entry-artists'}, - (relations.artistsContent - ? relations.artistsContent.slot('mode', 'inline') - : relations.artistLinks - ? language.formatConjunctionList(relations.artistLinks) - : language.$('misc.artistCommentary.entry.title.noArtists'))); - - const accentParts = ['misc.artistCommentary.entry.title.accent']; - const accentOptions = {}; - - if (relations.annotationContent) { - accentParts.push('withAnnotation'); - accentOptions.annotation = - relations.annotationContent.slot('mode', 'inline'); - } - - const accent = - (accentParts.length > 1 - ? html.tag('span', {class: 'commentary-entry-accent'}, - language.$(...accentParts, accentOptions)) - : null); - - const titlePrefix = 'misc.artistCommentary.entry.title'; - const titleParts = [titlePrefix]; - const titleOptions = {artists: artistsSpan}; - - if (accent) { - titleParts.push('withAccent'); - titleOptions.accent = accent; - } - - const style = - slots.color && - relations.colorStyle.slot('color', slots.color); - - return html.tags([ - html.tag('p', {class: 'commentary-entry-heading'}, - style, - [ - html.tag('time', - {[html.onlyIfContent]: true}, - language.$(titlePrefix, 'date', { - [language.onlyIfOptions]: ['date'], - date: language.formatDate(data.date), - })), - - language.$(...titleParts, titleOptions), - ]), - - html.tag('blockquote', {class: 'commentary-entry-body'}, - style, - relations.bodyContent.slot('mode', 'multiline')), - ]); - }, + generate: (data, relations, slots, {html, language}) => + language.encapsulate('misc.artistCommentary.entry', entryCapsule => + html.tags([ + html.tag('p', {class: 'commentary-entry-heading'}, + slots.color && + relations.colorStyle.clone() + .slot('color', slots.color), + + language.encapsulate(entryCapsule, 'title', titleCapsule => [ + html.tag('time', + {[html.onlyIfContent]: true}, + + language.$(titleCapsule, 'date', { + [language.onlyIfOptions]: ['date'], + + date: + language.formatDate(data.date), + })), + + language.encapsulate(titleCapsule, workingCapsule => { + const workingOptions = {}; + + workingOptions.artists = + html.tag('span', {class: 'commentary-entry-artists'}, + (relations.artistsContent + ? relations.artistsContent.slot('mode', 'inline') + : relations.artistLinks + ? language.formatConjunctionList(relations.artistLinks) + : language.$(titleCapsule, 'noArtists'))); + + const accent = + html.tag('span', {class: 'commentary-entry-accent'}, + {[html.onlyIfContent]: true}, + + language.encapsulate(titleCapsule, 'accent', accentCapsule => + language.encapsulate(accentCapsule, workingCapsule => { + const workingOptions = {}; + + if (relations.annotationContent) { + workingCapsule += '.withAnnotation'; + workingOptions.annotation = + relations.annotationContent.slot('mode', 'inline'); + } + + if (workingCapsule === accentCapsule) { + return html.blank(); + } else { + return language.$(workingCapsule, workingOptions); + } + }))); + + if (!html.isBlank(accent)) { + workingCapsule += '.withAccent'; + workingOptions.accent = accent; + } + + return language.$(workingCapsule, workingOptions); + }), + ])), + + html.tag('blockquote', {class: 'commentary-entry-body'}, + slots.color && + relations.colorStyle.clone() + .slot('color', slots.color), + + relations.bodyContent.slot('mode', 'multiline')), + ])), }; diff --git a/src/content/dependencies/generateCommentaryIndexPage.js b/src/content/dependencies/generateCommentaryIndexPage.js index 3c3504d2..d68ba42e 100644 --- a/src/content/dependencies/generateCommentaryIndexPage.js +++ b/src/content/dependencies/generateCommentaryIndexPage.js @@ -57,46 +57,48 @@ export default { }; }, - generate(data, relations, {html, language}) { - return relations.layout.slots({ - title: language.$('commentaryIndex.title'), - - headingMode: 'static', - - mainClasses: ['long-content'], - mainContent: [ - html.tag('p', language.$('commentaryIndex.infoLine', { - words: - html.tag('b', - language.formatWordCount(data.totalWordCount, {unit: true})), - - entries: - html.tag('b', - language.countCommentaryEntries(data.totalEntryCount, {unit: true})), - })), - - html.tag('p', - language.$('commentaryIndex.albumList.title')), - - html.tag('ul', - stitchArrays({ - albumLink: relations.albumLinks, - wordCount: data.wordCounts, - entryCount: data.entryCounts, - }).map(({albumLink, wordCount, entryCount}) => - html.tag('li', - language.$('commentaryIndex.albumList.item', { - album: albumLink, - words: language.formatWordCount(wordCount, {unit: true}), - entries: language.countCommentaryEntries(entryCount, {unit: true}), - })))), - ], - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {auto: 'current'}, - ], - }); - }, + generate: (data, relations, {html, language}) => + language.encapsulate('commentaryIndex', pageCapsule => + relations.layout.slots({ + title: language.$(pageCapsule, 'title'), + + headingMode: 'static', + + mainClasses: ['long-content'], + mainContent: [ + html.tag('p', language.$(pageCapsule, 'infoLine', { + words: + html.tag('b', + language.formatWordCount(data.totalWordCount, {unit: true})), + + entries: + html.tag('b', + language.countCommentaryEntries(data.totalEntryCount, {unit: true})), + })), + + language.encapsulate(pageCapsule, 'albumList', listCapsule => [ + html.tag('p', + language.$(listCapsule, 'title')), + + html.tag('ul', + stitchArrays({ + albumLink: relations.albumLinks, + wordCount: data.wordCounts, + entryCount: data.entryCounts, + }).map(({albumLink, wordCount, entryCount}) => + html.tag('li', + language.$(listCapsule, 'item', { + album: albumLink, + words: language.formatWordCount(wordCount, {unit: true}), + entries: language.countCommentaryEntries(entryCount, {unit: true}), + })))), + ]), + ], + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + {auto: 'current'}, + ], + })), }; diff --git a/src/content/dependencies/generateFlashActGalleryPage.js b/src/content/dependencies/generateFlashActGalleryPage.js index 17078124..1fa6de51 100644 --- a/src/content/dependencies/generateFlashActGalleryPage.js +++ b/src/content/dependencies/generateFlashActGalleryPage.js @@ -11,7 +11,7 @@ export default { 'linkFlashIndex', ], - extraDependencies: ['html', 'language'], + extraDependencies: ['language'], relations: (relation, act) => ({ layout: @@ -50,42 +50,42 @@ export default { ['media.flashArt', flash.directory, flash.coverArtFileExtension]) }), - generate(data, relations, {html, language}) { - return relations.layout.slots({ - title: - language.$('flashPage.title', { - flash: new html.Tag(null, null, data.name), - }), - - color: data.color, - headingMode: 'static', - - mainClasses: ['flash-index'], - mainContent: [ - relations.coverGrid.slots({ - links: relations.flashLinks, - names: data.flashNames, - lazy: 6, - - images: - stitchArrays({ - image: relations.coverGridImages, - path: data.flashCoverPaths, - }).map(({image, path}) => - image.slot('path', path)), - }), - ], - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {html: relations.flashIndexLink}, - {auto: 'current'}, - ], - - navBottomRowContent: relations.flashActNavAccent, - - leftSidebar: relations.sidebar, - }); - }, + generate: (data, relations, {language}) => + language.encapsulate('flashPage', pageCapsule => + relations.layout.slots({ + title: + language.$(pageCapsule, 'title', { + flash: data.name, + }), + + color: data.color, + headingMode: 'static', + + mainClasses: ['flash-index'], + mainContent: [ + relations.coverGrid.slots({ + links: relations.flashLinks, + names: data.flashNames, + lazy: 6, + + images: + stitchArrays({ + image: relations.coverGridImages, + path: data.flashCoverPaths, + }).map(({image, path}) => + image.slot('path', path)), + }), + ], + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + {html: relations.flashIndexLink}, + {auto: 'current'}, + ], + + navBottomRowContent: relations.flashActNavAccent, + + leftSidebar: relations.sidebar, + })), }; diff --git a/src/content/dependencies/generateFlashIndexPage.js b/src/content/dependencies/generateFlashIndexPage.js index eaea7e9c..a21bb49e 100644 --- a/src/content/dependencies/generateFlashIndexPage.js +++ b/src/content/dependencies/generateFlashIndexPage.js @@ -81,76 +81,77 @@ export default { }), generate: (data, relations, {html, language}) => - relations.layout.slots({ - title: language.$('flashIndex.title'), - headingMode: 'static', - - mainClasses: ['flash-index'], - mainContent: [ - html.tags([ - html.tag('p', {class: 'quick-info'}, - {[html.onlyIfSiblings]: true}, - language.$('misc.jumpTo')), - - html.tag('ul', {class: 'quick-info'}, - {[html.onlyIfContent]: true}, - stitchArrays({ - colorStyle: relations.jumpLinkColorStyles, - anchor: data.jumpLinkAnchors, - label: data.jumpLinkLabels, - }).map(({colorStyle, anchor, label}) => - html.tag('li', - html.tag('a', - {href: '#' + anchor}, - colorStyle, - label)))), - ]), - - stitchArrays({ - colorStyle: relations.actColorStyles, - actLink: relations.actLinks, - anchor: data.actAnchors, - - coverGrid: relations.actCoverGrids, - coverGridImages: relations.actCoverGridImages, - coverGridLinks: relations.actCoverGridLinks, - coverGridNames: data.actCoverGridNames, - coverGridPaths: data.actCoverGridPaths, - }).map(({ - colorStyle, - actLink, - anchor, - - coverGrid, - coverGridImages, - coverGridLinks, - coverGridNames, - coverGridPaths, - }, index) => [ - html.tag('h2', - {id: anchor}, - colorStyle, - actLink), - - coverGrid.slots({ - links: coverGridLinks, - names: coverGridNames, - lazy: index === 0 ? 4 : true, - - images: - stitchArrays({ - image: coverGridImages, - path: coverGridPaths, - }).map(({image, path}) => - image.slot('path', path)), - }), + language.encapsulate('flashIndex', pageCapsule => + relations.layout.slots({ + title: language.$(pageCapsule, 'title'), + headingMode: 'static', + + mainClasses: ['flash-index'], + mainContent: [ + html.tags([ + html.tag('p', {class: 'quick-info'}, + {[html.onlyIfSiblings]: true}, + language.$('misc.jumpTo')), + + html.tag('ul', {class: 'quick-info'}, + {[html.onlyIfContent]: true}, + stitchArrays({ + colorStyle: relations.jumpLinkColorStyles, + anchor: data.jumpLinkAnchors, + label: data.jumpLinkLabels, + }).map(({colorStyle, anchor, label}) => + html.tag('li', + html.tag('a', + {href: '#' + anchor}, + colorStyle, + label)))), ]), - ], - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {auto: 'current'}, - ], - }), + + stitchArrays({ + colorStyle: relations.actColorStyles, + actLink: relations.actLinks, + anchor: data.actAnchors, + + coverGrid: relations.actCoverGrids, + coverGridImages: relations.actCoverGridImages, + coverGridLinks: relations.actCoverGridLinks, + coverGridNames: data.actCoverGridNames, + coverGridPaths: data.actCoverGridPaths, + }).map(({ + colorStyle, + actLink, + anchor, + + coverGrid, + coverGridImages, + coverGridLinks, + coverGridNames, + coverGridPaths, + }, index) => [ + html.tag('h2', + {id: anchor}, + colorStyle, + actLink), + + coverGrid.slots({ + links: coverGridLinks, + names: coverGridNames, + lazy: index === 0 ? 4 : true, + + images: + stitchArrays({ + image: coverGridImages, + path: coverGridPaths, + }).map(({image, path}) => + image.slot('path', path)), + }), + ]), + ], + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + {auto: 'current'}, + ], + })), }; diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js index d6066a95..96337d83 100644 --- a/src/content/dependencies/generateFlashInfoPage.js +++ b/src/content/dependencies/generateFlashInfoPage.js @@ -77,86 +77,91 @@ export default { }), generate: (data, relations, {html, language}) => - relations.layout.slots({ - title: - language.$('flashPage.title', { - flash: data.name, - }), - - color: data.color, - headingMode: 'sticky', - - cover: - (relations.cover - ? relations.cover.slots({ - alt: language.$('misc.alt.flashArt'), - }) - : null), - - mainContent: [ - html.tag('p', - language.$('releaseInfo.released', { - date: language.formatDate(data.date), - })), - - html.tag('p', - {[html.onlyIfContent]: true}, - language.$('releaseInfo.playOn', { - [language.onlyIfOptions]: ['links'], - links: - language.formatDisjunctionList( - relations.externalLinks - .map(link => link.slot('context', 'flash'))), - })), - - html.tag('p', - {[html.onlyIfContent]: true}, - {[html.joinChildren]: html.tag('br')}, - - [ - !html.isBlank(relations.artistCommentarySection) && - language.$('releaseInfo.readCommentary', { - link: html.tag('a', - {href: '#artist-commentary'}, - language.$('releaseInfo.readCommentary.link')), + language.encapsulate('flashPage', pageCapsule => + relations.layout.slots({ + title: + language.$(pageCapsule, 'title', { + flash: data.name, + }), + + color: data.color, + headingMode: 'sticky', + + cover: + (relations.cover + ? relations.cover.slots({ + alt: language.$('misc.alt.flashArt'), + }) + : null), + + mainContent: [ + html.tag('p', + language.$('releaseInfo.released', { + date: language.formatDate(data.date), + })), + + html.tag('p', + {[html.onlyIfContent]: true}, + + language.$('releaseInfo.playOn', { + [language.onlyIfOptions]: ['links'], + + links: + language.formatDisjunctionList( + relations.externalLinks + .map(link => link.slot('context', 'flash'))), + })), + + html.tag('p', + {[html.onlyIfContent]: true}, + {[html.joinChildren]: html.tag('br')}, + + language.encapsulate('releaseInfo', capsule => [ + !html.isBlank(relations.artistCommentarySection) && + language.encapsulate(capsule, 'readCommentary', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#artist-commentary'}, + language.$(capsule, 'link')), + })), + ])), + + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'features'}, + title: + language.$('releaseInfo.tracksFeatured', { + flash: html.tag('i', data.name), + }), }), + + relations.featuredTracksList, + ]), + + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'contributors'}, + title: language.$('releaseInfo.contributors'), + }), + + relations.contributorContributionList, ]), - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'features'}, - title: - language.$('releaseInfo.tracksFeatured', { - flash: html.tag('i', data.name), - }), - }), - - relations.featuredTracksList, - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'contributors'}, - title: language.$('releaseInfo.contributors'), - }), - - relations.contributorContributionList, - ]), - - relations.artistCommentarySection, - ], - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {html: relations.flashActLink.slot('color', false)}, - {auto: 'current'}, - ], - - navBottomRowContent: relations.flashNavAccent, - - leftSidebar: relations.sidebar, - }), + relations.artistCommentarySection, + ], + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + {html: relations.flashActLink.slot('color', false)}, + {auto: 'current'}, + ], + + navBottomRowContent: relations.flashNavAccent, + + leftSidebar: relations.sidebar, + })), }; diff --git a/src/content/dependencies/generateGroupGalleryPage.js b/src/content/dependencies/generateGroupGalleryPage.js index 34c789b3..ceb54322 100644 --- a/src/content/dependencies/generateGroupGalleryPage.js +++ b/src/content/dependencies/generateGroupGalleryPage.js @@ -111,10 +111,10 @@ export default { return data; }, - generate(data, relations, {html, language}) { - return relations.layout - .slots({ - title: language.$('groupGalleryPage.title', {group: data.name}), + generate: (data, relations, {html, language}) => + language.encapsulate('groupGalleryPage', pageCapsule => + relations.layout.slots({ + title: language.$(pageCapsule, 'title', {group: data.name}), headingMode: 'static', color: data.color, @@ -135,7 +135,7 @@ export default { relations.quickDescription, html.tag('p', {class: 'quick-info'}, - language.$('groupGalleryPage.infoLine', { + language.$(pageCapsule, 'infoLine', { tracks: html.tag('b', language.countTracks(data.numTracks, { @@ -199,6 +199,5 @@ export default { secondaryNav: relations.secondaryNav ?? null, - }); - }, + })), }; diff --git a/src/content/dependencies/generateGroupInfoPage.js b/src/content/dependencies/generateGroupInfoPage.js index 956d56d8..87f35656 100644 --- a/src/content/dependencies/generateGroupInfoPage.js +++ b/src/content/dependencies/generateGroupInfoPage.js @@ -53,38 +53,41 @@ export default { }), generate: (data, relations, {html, language}) => - relations.layout.slots({ - title: language.$('groupInfoPage.title', {group: data.name}), - headingMode: 'sticky', - color: data.color, - - mainContent: [ - html.tag('p', - {[html.onlyIfContent]: true}, - language.$('releaseInfo.visitOn', { - [language.onlyIfOptions]: ['links'], - links: - language.formatDisjunctionList( - relations.visitLinks - .map(link => link.slot('context', 'group'))), - })), - - html.tag('blockquote', - {[html.onlyIfContent]: true}, - relations.description.slot('mode', 'multiline')), - - relations.albumSection, - ], - - leftSidebar: - (relations.sidebar - ? relations.sidebar - .content /* TODO: Kludge. */ - : null), - - navLinkStyle: 'hierarchical', - navLinks: relations.navLinks.content, - - secondaryNav: relations.secondaryNav ?? null, - }), + language.encapsulate('groupInfoPage', pageCapsule => + relations.layout.slots({ + title: language.$(pageCapsule, 'title', {group: data.name}), + headingMode: 'sticky', + color: data.color, + + mainContent: [ + html.tag('p', + {[html.onlyIfContent]: true}, + + language.$('releaseInfo.visitOn', { + [language.onlyIfOptions]: ['links'], + + links: + language.formatDisjunctionList( + relations.visitLinks + .map(link => link.slot('context', 'group'))), + })), + + html.tag('blockquote', + {[html.onlyIfContent]: true}, + relations.description.slot('mode', 'multiline')), + + relations.albumSection, + ], + + leftSidebar: + (relations.sidebar + ? relations.sidebar + .content /* TODO: Kludge. */ + : null), + + navLinkStyle: 'hierarchical', + navLinks: relations.navLinks.content, + + secondaryNav: relations.secondaryNav ?? null, + })), }; diff --git a/src/content/dependencies/generateGroupInfoPageAlbumsSection.js b/src/content/dependencies/generateGroupInfoPageAlbumsSection.js index d1dab542..8899e98e 100644 --- a/src/content/dependencies/generateGroupInfoPageAlbumsSection.js +++ b/src/content/dependencies/generateGroupInfoPageAlbumsSection.js @@ -66,67 +66,71 @@ export default { }), generate: (relations, {html, language}) => - html.tags([ - relations.contentHeading - .slots({ - tag: 'h2', - title: language.$('groupInfoPage.albumList.title'), - }), - - html.tag('p', - {[html.onlyIfSiblings]: true}, - language.$('groupInfoPage.viewAlbumGallery', { - link: - relations.galleryLink - .slot('content', language.$('groupInfoPage.viewAlbumGallery.link')), - })), - - html.tag('ul', - {[html.onlyIfContent]: true}, - - stitchArrays({ - albumLink: relations.albumLinks, - otherGroupLinks: relations.otherGroupLinks, - datetimestamp: relations.datetimestamps, - albumColorStyle: relations.albumColorStyles, - }).map(({ - albumLink, - otherGroupLinks, - datetimestamp, - albumColorStyle, - }) => { - const prefix = 'groupInfoPage.albumList.item'; - const parts = [prefix]; - const options = {}; - - options.album = - albumLink.slot('color', false); - - if (datetimestamp) { - parts.push('withYear'); - options.yearAccent = - language.$(prefix, 'yearAccent', { - year: - datetimestamp.slots({style: 'year', tooltip: true}), - }); - } - - if (!empty(otherGroupLinks)) { - parts.push('withOtherGroup'); - options.otherGroupAccent = - html.tag('span', {class: 'other-group-accent'}, - language.$(prefix, 'otherGroupAccent', { - groups: - language.formatConjunctionList( - otherGroupLinks.map(groupLink => - groupLink.slot('color', false))), - })); - } - - return ( - html.tag('li', + language.encapsulate('groupInfoPage', pageCapsule => + language.encapsulate(pageCapsule, 'albumList', listCapsule => + html.tags([ + relations.contentHeading + .slots({ + tag: 'h2', + title: language.$(listCapsule, 'title'), + }), + + html.tag('p', + {[html.onlyIfSiblings]: true}, + + language.encapsulate(pageCapsule, 'viewAlbumGallery', capsule => + language.$(capsule, { + link: + relations.galleryLink + .slot('content', language.$(capsule, 'link')), + }))), + + html.tag('ul', + {[html.onlyIfContent]: true}, + + stitchArrays({ + albumLink: relations.albumLinks, + otherGroupLinks: relations.otherGroupLinks, + datetimestamp: relations.datetimestamps, + albumColorStyle: relations.albumColorStyles, + }).map(({ + albumLink, + otherGroupLinks, + datetimestamp, albumColorStyle, - language.$(...parts, options))); - })), - ]), + }) => + html.tag('li', + albumColorStyle, + + language.encapsulate(listCapsule, 'item', itemCapsule => + language.encapsulate(itemCapsule, workingCapsule => { + const workingOptions = {}; + + workingOptions.album = + albumLink.slot('color', false); + + if (datetimestamp) { + workingCapsule += '.withYear'; + workingOptions.yearAccent = + language.$(itemCapsule, 'yearAccent', { + year: + datetimestamp.slots({style: 'year', tooltip: true}), + }); + } + + if (!empty(otherGroupLinks)) { + workingCapsule += '.withOtherGroup'; + workingOptions.otherGroupAccent = + html.tag('span', {class: 'other-group-accent'}, + language.$(itemCapsule, 'otherGroupAccent', { + groups: + language.formatConjunctionList( + otherGroupLinks.map(groupLink => + groupLink.slot('color', false))), + })); + } + + return language.$(workingCapsule, workingOptions); + }))))), + ]))), }; diff --git a/src/content/dependencies/generateGroupSidebarCategoryDetails.js b/src/content/dependencies/generateGroupSidebarCategoryDetails.js index 69de373b..d52c77b8 100644 --- a/src/content/dependencies/generateGroupSidebarCategoryDetails.js +++ b/src/content/dependencies/generateGroupSidebarCategoryDetails.js @@ -46,37 +46,37 @@ export default { }, }, - generate(data, relations, slots, {html, language}) { - return html.tag('details', - data.isCurrentCategory && - {class: 'current', open: true}, - - [ - html.tag('summary', - relations.colorStyle, - - html.tag('span', - language.$('groupSidebar.groupList.category', { - category: - html.tag('span', {class: 'group-name'}, - data.name), - }))), - - html.tag('ul', - stitchArrays(({ - infoLink: relations.groupInfoLinks, - galleryLink: relations.groupGalleryLinks, - })).map(({infoLink, galleryLink}, index) => - html.tag('li', - index === data.currentGroupIndex && - {class: 'current'}, - - language.$('groupSidebar.groupList.item', { - group: - (slots.currentExtra === 'gallery' - ? galleryLink ?? infoLink - : infoLink), - })))), - ]); - }, + generate: (data, relations, slots, {html, language}) => + language.encapsulate('groupSidebar.groupList', capsule => + html.tag('details', + data.isCurrentCategory && + {class: 'current', open: true}, + + [ + html.tag('summary', + relations.colorStyle, + + html.tag('span', + language.$(capsule, 'category', { + category: + html.tag('span', {class: 'group-name'}, + data.name), + }))), + + html.tag('ul', + stitchArrays(({ + infoLink: relations.groupInfoLinks, + galleryLink: relations.groupGalleryLinks, + })).map(({infoLink, galleryLink}, index) => + html.tag('li', + index === data.currentGroupIndex && + {class: 'current'}, + + language.$(capsule, 'item', { + group: + (slots.currentExtra === 'gallery' + ? galleryLink ?? infoLink + : infoLink), + })))), + ])), }; diff --git a/src/content/dependencies/generateNewsEntryPage.js b/src/content/dependencies/generateNewsEntryPage.js index bcba7194..2c382cfa 100644 --- a/src/content/dependencies/generateNewsEntryPage.js +++ b/src/content/dependencies/generateNewsEntryPage.js @@ -91,41 +91,41 @@ export default { }; }, - generate(data, relations, {html, language}) { - return relations.layout.slots({ - title: - language.$('newsEntryPage.title', { - entry: data.name, - }), - - headingMode: 'sticky', - - mainClasses: ['long-content'], - mainContent: [ - html.tag('p', - language.$('newsEntryPage.published', { - date: language.formatDate(data.date), - })), - - relations.content, - relations.readAnotherLinks, - ], - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {html: relations.newsIndexLink}, - { - auto: 'current', - accent: - (relations.previousNextLinks - ? `(${language.formatUnitList(relations.previousNextLinks.slots({ - previousLink: relations.previousEntryNavLink ?? null, - nextLink: relations.nextEntryNavLink ?? null, - }).content)})` - : null), - }, - ], - }); - }, + generate: (data, relations, {html, language}) => + language.encapsulate('newsEntryPage', pageCapsule => + relations.layout.slots({ + title: + language.$(pageCapsule, 'title', { + entry: data.name, + }), + + headingMode: 'sticky', + + mainClasses: ['long-content'], + mainContent: [ + html.tag('p', + language.$(pageCapsule, 'published', { + date: language.formatDate(data.date), + })), + + relations.content, + relations.readAnotherLinks, + ], + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + {html: relations.newsIndexLink}, + { + auto: 'current', + accent: + (relations.previousNextLinks + ? `(${language.formatUnitList(relations.previousNextLinks.slots({ + previousLink: relations.previousEntryNavLink ?? null, + nextLink: relations.nextEntryNavLink ?? null, + }).content)})` + : null), + }, + ], + })), }; diff --git a/src/content/dependencies/generateNewsIndexPage.js b/src/content/dependencies/generateNewsIndexPage.js index 539af804..02964ce8 100644 --- a/src/content/dependencies/generateNewsIndexPage.js +++ b/src/content/dependencies/generateNewsIndexPage.js @@ -57,37 +57,38 @@ export default { }; }, - generate(data, relations, {html, language}) { - return relations.layout.slots({ - title: language.$('newsIndex.title'), - headingMode: 'sticky', - - mainClasses: ['long-content', 'news-index'], - mainContent: - stitchArrays({ - entryLink: relations.entryLinks, - viewRestLink: relations.viewRestLinks, - content: relations.entryContents, - date: data.entryDates, - directory: data.entryDirectories, - }).map(({entryLink, viewRestLink, content, date, directory}) => - html.tag('article', {id: directory}, [ - html.tag('h2', [ - html.tag('time', language.formatDate(date)), - entryLink, - ]), - - content, - - viewRestLink - ?.slot('content', language.$('newsIndex.entry.viewRest')), - ])), - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {auto: 'current'}, - ], - }); - }, + generate: (data, relations, {html, language}) => + language.encapsulate('newsIndex', pageCapsule => + relations.layout.slots({ + title: language.$(pageCapsule, 'title'), + headingMode: 'sticky', + + mainClasses: ['long-content', 'news-index'], + mainContent: + stitchArrays({ + entryLink: relations.entryLinks, + viewRestLink: relations.viewRestLinks, + content: relations.entryContents, + date: data.entryDates, + directory: data.entryDirectories, + }).map(({entryLink, viewRestLink, content, date, directory}) => + language.encapsulate(pageCapsule, 'entry', entryCapsule => + html.tag('article', {id: directory}, [ + html.tag('h2', [ + html.tag('time', language.formatDate(date)), + entryLink, + ]), + + content, + + viewRestLink + ?.slot('content', language.$(entryCapsule, 'viewRest')), + ]))), + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + {auto: 'current'}, + ], + })), }; diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index e138a981..7e9e49a0 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -506,41 +506,43 @@ export default { html.tag('img', {id: 'image-overlay-image'}), html.tag('img', {id: 'image-overlay-image-thumb'}), ]), - html.tag('div', {id: 'image-overlay-action-container'}, [ - html.tag('div', {id: 'image-overlay-action-content-without-size'}, - language.$('releaseInfo.viewOriginalFile', { - link: html.tag('a', {class: 'image-overlay-view-original'}, - language.$('releaseInfo.viewOriginalFile.link')), - })), - - html.tag('div', {id: 'image-overlay-action-content-with-size'}, [ - language.$('releaseInfo.viewOriginalFile.withSize', { - link: - html.tag('a', {class: 'image-overlay-view-original'}, - language.$('releaseInfo.viewOriginalFile.link')), - - size: - html.tag('span', - {[html.joinChildren]: ''}, - [ - html.tag('span', {id: 'image-overlay-file-size-kilobytes'}, - language.$('count.fileSize.kilobytes', { - kilobytes: - html.tag('span', {class: 'image-overlay-file-size-count'}), - })), - - html.tag('span', {id: 'image-overlay-file-size-megabytes'}, - language.$('count.fileSize.megabytes', { - megabytes: - html.tag('span', {class: 'image-overlay-file-size-count'}), - })), - ]), - }), - html.tag('span', {id: 'image-overlay-file-size-warning'}, - language.$('releaseInfo.viewOriginalFile.sizeWarning')), - ]), - ]), + html.tag('div', {id: 'image-overlay-action-container'}, + language.encapsulate('releaseInfo.viewOriginalFile', capsule => [ + html.tag('div', {id: 'image-overlay-action-content-without-size'}, + language.$(capsule, { + link: html.tag('a', {class: 'image-overlay-view-original'}, + language.$(capsule, 'link')), + })), + + html.tag('div', {id: 'image-overlay-action-content-with-size'}, [ + language.$(capsule, 'withSize', { + link: + html.tag('a', {class: 'image-overlay-view-original'}, + language.$(capsule, 'link')), + + size: + html.tag('span', + {[html.joinChildren]: ''}, + [ + html.tag('span', {id: 'image-overlay-file-size-kilobytes'}, + language.$('count.fileSize.kilobytes', { + kilobytes: + html.tag('span', {class: 'image-overlay-file-size-count'}), + })), + + html.tag('span', {id: 'image-overlay-file-size-megabytes'}, + language.$('count.fileSize.megabytes', { + megabytes: + html.tag('span', {class: 'image-overlay-file-size-count'}), + })), + ]), + }), + + html.tag('span', {id: 'image-overlay-file-size-warning'}, + language.$(capsule, 'sizeWarning')), + ]), + ])), ])); const layoutHTML = [ diff --git a/src/content/dependencies/generateSearchSidebarBox.js b/src/content/dependencies/generateSearchSidebarBox.js index 6607c789..8b18cfae 100644 --- a/src/content/dependencies/generateSearchSidebarBox.js +++ b/src/content/dependencies/generateSearchSidebarBox.js @@ -8,50 +8,53 @@ export default { }), generate: (relations, {html, language}) => - relations.sidebarBox.slots({ - attributes: {class: 'wiki-search-sidebar-box'}, - collapsible: false, + language.encapsulate('misc.search', capsule => + relations.sidebarBox.slots({ + attributes: {class: 'wiki-search-sidebar-box'}, + collapsible: false, - content: [ - html.tag('input', {class: 'wiki-search-input'}, - { - placeholder: - language.$('misc.search.placeholder').toString(), - }, - {type: 'search'}), + content: [ + html.tag('input', {class: 'wiki-search-input'}, + { + placeholder: + language.$(capsule, 'placeholder').toString(), + }, + {type: 'search'}), - html.tag('template', {class: 'wiki-search-preparing-string'}, - language.$('misc.search.preparing')), + html.tag('template', {class: 'wiki-search-preparing-string'}, + language.$(capsule, 'preparing')), - html.tag('template', {class: 'wiki-search-loading-data-string'}, - language.$('misc.search.loadingData')), + html.tag('template', {class: 'wiki-search-loading-data-string'}, + language.$(capsule, 'loadingData')), - html.tag('template', {class: 'wiki-search-searching-string'}, - language.$('misc.search.searching')), + html.tag('template', {class: 'wiki-search-searching-string'}, + language.$(capsule, 'searching')), - html.tag('template', {class: 'wiki-search-failed-string'}, - language.$('misc.search.failed')), + html.tag('template', {class: 'wiki-search-failed-string'}, + language.$(capsule, 'failed')), - html.tag('template', {class: 'wiki-search-no-results-string'}, - language.$('misc.search.noResults')), + html.tag('template', {class: 'wiki-search-no-results-string'}, + language.$(capsule, 'noResults')), - html.tag('template', {class: 'wiki-search-current-result-string'}, - language.$('misc.search.currentResult')), + html.tag('template', {class: 'wiki-search-current-result-string'}, + language.$(capsule, 'currentResult')), - html.tag('template', {class: 'wiki-search-end-search-string'}, - language.$('misc.search.endSearch')), + html.tag('template', {class: 'wiki-search-end-search-string'}, + language.$(capsule, 'endSearch')), - html.tag('template', {class: 'wiki-search-album-result-kind-string'}, - language.$('misc.search.resultKind.album')), + language.encapsulate(capsule, 'resultKind', capsule => [ + html.tag('template', {class: 'wiki-search-album-result-kind-string'}, + language.$(capsule, 'album')), - html.tag('template', {class: 'wiki-search-artist-result-kind-string'}, - language.$('misc.search.resultKind.artist')), + html.tag('template', {class: 'wiki-search-artist-result-kind-string'}, + language.$(capsule, 'artist')), - html.tag('template', {class: 'wiki-search-group-result-kind-string'}, - language.$('misc.search.resultKind.group')), + html.tag('template', {class: 'wiki-search-group-result-kind-string'}, + language.$(capsule, 'group')), - html.tag('template', {class: 'wiki-search-tag-result-kind-string'}, - language.$('misc.search.resultKind.artTag')), - ], - }), + html.tag('template', {class: 'wiki-search-tag-result-kind-string'}, + language.$(capsule, 'artTag')), + ]), + ], + })), }; diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js index 1cbbc8a8..95eaf35b 100644 --- a/src/content/dependencies/generateTrackInfoPage.js +++ b/src/content/dependencies/generateTrackInfoPage.js @@ -134,251 +134,278 @@ export default { }), generate: (data, relations, {html, language}) => - relations.layout.slots({ - title: language.$('trackPage.title', {track: data.name}), - headingMode: 'sticky', - - additionalNames: relations.additionalNamesBox, - - color: data.color, - styleRules: [relations.albumStyleRules], - - cover: - (relations.cover - ? relations.cover.slots({ - alt: language.$('misc.alt.trackCover'), - }) - : null), - - mainContent: [ - relations.releaseInfo, - - html.tag('p', - {[html.onlyIfContent]: true}, - {[html.joinChildren]: html.tag('br')}, - - [ - !html.isBlank(relations.sheetMusicFilesList) && - language.$('releaseInfo.sheetMusicFiles.shortcut', { - link: html.tag('a', - {href: '#sheet-music-files'}, - language.$('releaseInfo.sheetMusicFiles.shortcut.link')), - }), + language.encapsulate('trackPage', pageCapsule => + relations.layout.slots({ + title: + language.$(pageCapsule, 'title', { + track: data.name, + }), - !html.isBlank(relations.midiProjectFilesList) && - language.$('releaseInfo.midiProjectFiles.shortcut', { - link: html.tag('a', - {href: '#midi-project-files'}, - language.$('releaseInfo.midiProjectFiles.shortcut.link')), - }), + headingMode: 'sticky', - !html.isBlank(relations.additionalFilesList) && - language.$('releaseInfo.additionalFiles.shortcut', { - link: html.tag('a', - {href: '#midi-project-files'}, - language.$('releaseInfo.additionalFiles.shortcut.link')), - }), + additionalNames: relations.additionalNamesBox, + + color: data.color, + styleRules: [relations.albumStyleRules], + + cover: + (relations.cover + ? relations.cover.slots({ + alt: language.$('misc.alt.trackCover'), + }) + : null), + + mainContent: [ + relations.releaseInfo, - !html.isBlank(relations.artistCommentarySection) && - language.$('releaseInfo.readCommentary', { - link: html.tag('a', - {href: '#artist-commentary'}, - language.$('releaseInfo.readCommentary.link')), + html.tag('p', + {[html.onlyIfContent]: true}, + {[html.joinChildren]: html.tag('br')}, + + language.encapsulate('releaseInfo', capsule => [ + !html.isBlank(relations.sheetMusicFilesList) && + language.encapsulate(capsule, 'sheetMusicFiles.shortcut', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#sheet-music-files'}, + language.$(capsule, 'link')), + })), + + !html.isBlank(relations.midiProjectFilesList) && + language.encapsulate(capsule, 'midiProjectFiles.shortcut', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#midi-project-files'}, + language.$(capsule, 'link')), + })), + + !html.isBlank(relations.additionalFilesList) && + language.encapsulate(capsule, 'additionalFiles.shortcut', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#midi-project-files'}, + language.$(capsule, 'link')), + })), + + !html.isBlank(relations.artistCommentarySection) && + language.encapsulate(capsule, 'readCommentary', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#artist-commentary'}, + language.$(capsule, 'link')), + })), + ])), + + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'also-released-as'}, + title: language.$('releaseInfo.alsoReleasedAs'), }), + + relations.otherReleasesList, ]), - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'also-released-as'}, - title: language.$('releaseInfo.alsoReleasedAs'), - }), - - relations.otherReleasesList, - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'contributors'}, - title: language.$('releaseInfo.contributors'), - }), - - relations.contributorContributionList, - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'references'}, - - title: - language.$('releaseInfo.tracksReferenced', { - track: html.tag('i', data.name), - }), + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'contributors'}, + title: language.$('releaseInfo.contributors'), + }), - stickyTitle: - language.$('releaseInfo.tracksReferenced.sticky'), - }), + relations.contributorContributionList, + ]), - relations.referencedTracksList, - ]), + html.tags([ + language.encapsulate('releaseInfo.tracksReferenced', capsule => + relations.contentHeading.clone() + .slots({ + attributes: {id: 'references'}, - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'samples'}, + title: + language.$(capsule, { + track: + html.tag('i', data.name), + }), - title: - language.$('releaseInfo.tracksSampled', { - track: html.tag('i', data.name), - }), + stickyTitle: + language.$(capsule, 'sticky'), + })), - stickyTitle: - language.$('releaseInfo.tracksSampled.sticky'), - }), + relations.referencedTracksList, + ]), - relations.sampledTracksList, - ]), + html.tags([ + language.encapsulate('releaseInfo.tracksSampled', capsule => + relations.contentHeading.clone() + .slots({ + attributes: {id: 'samples'}, - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'referenced-by'}, + title: + language.$(capsule, { + track: + html.tag('i', data.name), + }), - title: - language.$('releaseInfo.tracksThatReference', { - track: html.tag('i', data.name), - }), + stickyTitle: + language.$(capsule, 'sticky'), + })), - stickyTitle: - language.$('releaseInfo.tracksThatReference.sticky'), - }), + relations.sampledTracksList, + ]), - relations.referencedByTracksList - .slots({ - headingString: 'releaseInfo.tracksThatReference', - }), - ]), + language.encapsulate('releaseInfo.tracksThatReference', capsule => + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'referenced-by'}, - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'sampled-by'}, + title: + language.$(capsule, { + track: html.tag('i', data.name), + }), - title: - language.$('releaseInfo.tracksThatSample', { - track: html.tag('i', data.name), + stickyTitle: + language.$(capsule, 'sticky'), }), - stickyTitle: - language.$('releaseInfo.tracksThatSample.sticky'), - }), + relations.referencedByTracksList + .slots({ + headingString: capsule, + }), + ])), - relations.sampledByTracksList - .slots({ - headingString: 'releaseInfo.tracksThatSample', - }), - ]), + language.encapsulate('releaseInfo.tracksThatSample', capsule => + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'sampled-by'}, - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'featured-in'}, + title: + language.$(capsule, { + track: html.tag('i', data.name), + }), - title: - language.$('releaseInfo.flashesThatFeature', { - track: html.tag('i', data.name), + stickyTitle: + language.$(capsule, 'sticky'), }), - stickyTitle: - language.$('releaseInfo.flashesThatFeature.sticky'), - }), + relations.sampledByTracksList + .slots({ + headingString: capsule, + }), + ])), - relations.flashesThatFeatureList, - ]), + html.tags([ + language.encapsulate('releaseInfo.flashesThatFeature', capsule => + relations.contentHeading.clone() + .slots({ + attributes: {id: 'featured-in'}, - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'lyrics'}, - title: language.$('releaseInfo.lyrics'), - }), + title: + language.$(capsule, { + track: html.tag('i', data.name), + }), - html.tag('blockquote', - {[html.onlyIfContent]: true}, - relations.lyrics.slot('mode', 'lyrics')), - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'sheet-music-files'}, - title: language.$('releaseInfo.sheetMusicFiles.heading'), - }), - - relations.sheetMusicFilesList, - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'midi-project-files'}, - title: language.$('releaseInfo.midiProjectFiles.heading'), - }), - - relations.midiProjectFilesList, - ]), - - html.tags([ - relations.contentHeading.clone() - .slots({ - attributes: {id: 'additional-files'}, - title: language.$('releaseInfo.additionalFiles.heading'), - }), - - relations.additionalFilesList, - ]), - - relations.artistCommentarySection, - ], - - navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {html: relations.albumLink.slot('color', false)}, - { - html: - (data.hasTrackNumbers - ? language.$('trackPage.nav.track.withNumber', { - number: data.trackNumber, - track: relations.trackLink - .slot('attributes', {class: 'current'}), - }) - : language.$('trackPage.nav.track', { - track: relations.trackLink - .slot('attributes', {class: 'current'}), + stickyTitle: + language.$(capsule, 'sticky'), })), - }, - ], - navBottomRowContent: - relations.albumNavAccent.slots({ - showTrackNavigation: true, - showExtraLinks: false, - }), + relations.flashesThatFeatureList, + ]), - navContent: - relations.chronologyLinks, + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'lyrics'}, + title: language.$('releaseInfo.lyrics'), + }), - secondaryNav: - relations.secondaryNav - .slot('mode', 'track'), + html.tag('blockquote', + {[html.onlyIfContent]: true}, + relations.lyrics.slot('mode', 'lyrics')), + ]), - leftSidebar: relations.sidebar, + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'sheet-music-files'}, + title: language.$('releaseInfo.sheetMusicFiles.heading'), + }), - socialEmbed: relations.socialEmbed, - }), + relations.sheetMusicFilesList, + ]), + + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'midi-project-files'}, + title: language.$('releaseInfo.midiProjectFiles.heading'), + }), + + relations.midiProjectFilesList, + ]), + + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'additional-files'}, + title: language.$('releaseInfo.additionalFiles.heading'), + }), + + relations.additionalFilesList, + ]), + + relations.artistCommentarySection, + ], + + navLinkStyle: 'hierarchical', + + navLinks: [ + {auto: 'home'}, + + {html: relations.albumLink.slot('color', false)}, + + { + html: + language.encapsulate(pageCapsule, 'nav.track', capsule => { + const options = {}; + + options.track = + relations.trackLink + .slot('attributes', {class: 'current'}); + + if (data.hasTrackNumbers) { + capsule += '.withNumber'; + options.number = data.trackNumber; + } + + return language.$(capsule, options); + }), + }, + ], + + navBottomRowContent: + relations.albumNavAccent.slots({ + showTrackNavigation: true, + showExtraLinks: false, + }), + + navContent: + relations.chronologyLinks, + + secondaryNav: + relations.secondaryNav + .slot('mode', 'track'), + + leftSidebar: relations.sidebar, + + socialEmbed: relations.socialEmbed, + })), }; /* diff --git a/src/content/dependencies/generateTrackList.js b/src/content/dependencies/generateTrackList.js index 4760ff2f..bc3b6035 100644 --- a/src/content/dependencies/generateTrackList.js +++ b/src/content/dependencies/generateTrackList.js @@ -31,14 +31,16 @@ export default { contributionLinks: relations.contributionLinks, }).map(({trackLink, contributionLinks}) => html.tag('li', - (empty(contributionLinks) - ? trackLink - : language.$('trackList.item.withArtists', { - track: trackLink, - by: + language.encapsulate('trackList.item', itemCapsule => + language.encapsulate(itemCapsule, workingCapsule => { + const workingOptions = {track: trackLink}; + + if (!empty(contributionLinks)) { + workingCapsule += '.withArtists'; + workingOptions.by = html.tag('span', {class: 'by'}, html.metatag('chunkwrap', {split: ','}, - language.$('trackList.item.withArtists.by', { + language.$(itemCapsule, 'withArtists.by', { artists: language.formatConjunctionList( contributionLinks.map(link => @@ -46,6 +48,9 @@ export default { showContribution: slots.showContribution, showIcons: slots.showIcons, }))), - }))), - }))))), + }))); + } + + return language.$(workingCapsule, workingOptions); + }))))), }; diff --git a/src/content/dependencies/generateTrackListDividedByGroups.js b/src/content/dependencies/generateTrackListDividedByGroups.js index 21dc9ac1..3cba479e 100644 --- a/src/content/dependencies/generateTrackListDividedByGroups.js +++ b/src/content/dependencies/generateTrackListDividedByGroups.js @@ -80,53 +80,59 @@ export default { generate: (data, relations, slots, {html, language}) => relations.flatList ?? - html.tag('dl', {[html.onlyIfContent]: true}, [ - stitchArrays({ - groupName: data.groupNames, - groupLink: relations.groupLinks, - trackList: relations.groupedTrackLists, - }).map(({ - groupName, - groupLink, - trackList, - }) => [ - (slots.headingString - ? relations.contentHeading.clone().slots({ - tag: 'dt', - - title: - language.$('trackList.fromGroup', { - group: groupLink - }), - - stickyTitle: - language.$(slots.headingString, 'sticky', 'fromGroup', { - group: groupName, - }), - }) - : html.tag('dt', - language.$('trackList.fromGroup', { - group: groupLink - }))), - - html.tag('dd', trackList), - ]), - - relations.ungroupedTrackList && [ - (slots.headingString - ? relations.contentHeading.clone().slots({ - tag: 'dt', - - title: - language.$('trackList.fromOther'), - - stickyTitle: - language.$(slots.headingString, 'sticky', 'fromOther'), - }) - : html.tag('dt', - language.$('trackList.fromOther'))), - - html.tag('dd', relations.ungroupedTrackList), - ], - ]), + + html.tag('dl', + {[html.onlyIfContent]: true}, + + language.encapsulate('trackList', listCapsule => [ + stitchArrays({ + groupName: data.groupNames, + groupLink: relations.groupLinks, + trackList: relations.groupedTrackLists, + }).map(({ + groupName, + groupLink, + trackList, + }) => [ + language.encapsulate(listCapsule, 'fromGroup', capsule => + (slots.headingString + ? relations.contentHeading.clone().slots({ + tag: 'dt', + + title: + language.$(capsule, { + group: groupLink + }), + + stickyTitle: + language.$(slots.headingString, 'sticky', 'fromGroup', { + group: groupName, + }), + }) + : html.tag('dt', + language.$(capsule, { + group: groupLink + })))), + + html.tag('dd', trackList), + ]), + + relations.ungroupedTrackList && [ + language.encapsulate(listCapsule, 'fromOther', capsule => + (slots.headingString + ? relations.contentHeading.clone().slots({ + tag: 'dt', + + title: + language.$(capsule), + + stickyTitle: + language.$(slots.headingString, 'sticky', 'fromOther'), + }) + : html.tag('dt', + language.$(capsule)))), + + html.tag('dd', relations.ungroupedTrackList), + ], + ])), }; diff --git a/src/content/dependencies/generateTrackReleaseInfo.js b/src/content/dependencies/generateTrackReleaseInfo.js index 88a4cdc7..e234dd5d 100644 --- a/src/content/dependencies/generateTrackReleaseInfo.js +++ b/src/content/dependencies/generateTrackReleaseInfo.js @@ -47,44 +47,47 @@ export default { }, generate: (data, relations, {html, language}) => - html.tags([ - html.tag('p', - {[html.onlyIfContent]: true}, - {[html.joinChildren]: html.tag('br')}, - - [ - relations.artistContributionLinks - .slots({stringKey: 'releaseInfo.by'}), - - relations.coverArtistContributionsLine - ?.slots({stringKey: 'releaseInfo.coverArtBy'}), - - language.$('releaseInfo.released', { - [language.onlyIfOptions]: ['date'], - date: language.formatDate(data.date), - }), - - language.$('releaseInfo.artReleased', { - [language.onlyIfOptions]: ['date'], - date: language.formatDate(data.coverArtDate), - }), - - language.$('releaseInfo.duration', { - [language.onlyIfOptions]: ['duration'], - duration: language.formatDuration(data.duration), - }), - ]), - - html.tag('p', - (relations.externalLinks - ? language.$('releaseInfo.listenOn', { - links: - language.formatDisjunctionList( - relations.externalLinks - .map(link => link.slot('context', 'track'))), - }) - : language.$('releaseInfo.listenOn.noLinks', { - name: html.tag('i', data.name), - }))), - ]), + language.encapsulate('releaseInfo', capsule => + html.tags([ + html.tag('p', + {[html.onlyIfContent]: true}, + {[html.joinChildren]: html.tag('br')}, + + [ + relations.artistContributionLinks + .slots({stringKey: capsule + '.by'}), + + relations.coverArtistContributionsLine + ?.slots({stringKey: capsule + '.coverArtBy'}), + + language.$(capsule, 'released', { + [language.onlyIfOptions]: ['date'], + date: language.formatDate(data.date), + }), + + language.$(capsule, 'artReleased', { + [language.onlyIfOptions]: ['date'], + date: language.formatDate(data.coverArtDate), + }), + + language.$(capsule, 'duration', { + [language.onlyIfOptions]: ['duration'], + duration: language.formatDuration(data.duration), + }), + ]), + + html.tag('p', + language.encapsulate(capsule, 'listenOn', capsule => + (relations.externalLinks + ? language.$(capsule, { + links: + language.formatDisjunctionList( + relations.externalLinks + .map(link => link.slot('context', 'track'))), + }) + : language.$(capsule, 'noLinks', { + name: + html.tag('i', data.name), + })))), + ])), }; diff --git a/src/content/dependencies/generateTrackSocialEmbed.js b/src/content/dependencies/generateTrackSocialEmbed.js index 0337fc46..9868f0e2 100644 --- a/src/content/dependencies/generateTrackSocialEmbed.js +++ b/src/content/dependencies/generateTrackSocialEmbed.js @@ -39,35 +39,35 @@ export default { return data; }, - generate(data, relations, {absoluteTo, language, urls}) { - return relations.socialEmbed.slots({ - title: - language.$('trackPage.socialEmbed.title', { - track: data.trackName, - }), + generate: (data, relations, {absoluteTo, language, urls}) => + language.encapsulate('trackPage.socialEmbed', embedCapsule => + relations.socialEmbed.slots({ + title: + language.$(embedCapsule, 'title', { + track: data.trackName, + }), - headingContent: - language.$('trackPage.socialEmbed.heading', { - album: data.albumName, - }), + headingContent: + language.$(embedCapsule, 'heading', { + album: data.albumName, + }), - headingLink: - absoluteTo('localized.album', data.albumDirectory), + headingLink: + absoluteTo('localized.album', data.albumDirectory), - imagePath: - (data.imageSource === 'album' - ? '/' + - urls - .from('shared.root') - .to('media.albumCover', data.albumDirectory, data.coverArtFileExtension) - : data.imageSource === 'track' - ? '/' + - urls - .from('shared.root') - .to('media.trackCover', data.albumDirectory, data.trackDirectory, data.coverArtFileExtension) - : null), - }); - }, + imagePath: + (data.imageSource === 'album' + ? '/' + + urls + .from('shared.root') + .to('media.albumCover', data.albumDirectory, data.coverArtFileExtension) + : data.imageSource === 'track' + ? '/' + + urls + .from('shared.root') + .to('media.trackCover', data.albumDirectory, data.trackDirectory, data.coverArtFileExtension) + : null), + })), }; /* diff --git a/src/content/dependencies/generateWikiHomeNewsBox.js b/src/content/dependencies/generateWikiHomeNewsBox.js index bd0e4797..83a27695 100644 --- a/src/content/dependencies/generateWikiHomeNewsBox.js +++ b/src/content/dependencies/generateWikiHomeNewsBox.js @@ -1,4 +1,4 @@ -import {empty, stitchArrays} from '#sugar'; +import {stitchArrays} from '#sugar'; export default { contentDependencies: [ @@ -39,49 +39,48 @@ export default { .map(entry => entry.date), }), - generate(data, relations, {html, language}) { - if (empty(relations.entryContents)) { - return html.blank(); - } + generate: (data, relations, {html, language}) => + language.encapsulate('homepage.news', boxCapsule => + relations.box.slots({ + attributes: {class: 'latest-news-sidebar-box'}, + collapsible: false, - return relations.box.slots({ - attributes: {class: 'latest-news-sidebar-box'}, - collapsible: false, + content: [ + html.tag('h1', + {[html.onlyIfSiblings]: true}, + language.$(boxCapsule, 'title')), - content: [ - html.tag('h1', language.$('homepage.news.title')), + stitchArrays({ + date: data.entryDates, + content: relations.entryContents, + mainLink: relations.entryMainLinks, + readMoreLink: relations.entryReadMoreLinks, + }).map(({ + date, + content, + mainLink, + readMoreLink, + }, index) => + language.encapsulate(boxCapsule, 'entry', entryCapsule => + html.tag('article', {class: 'news-entry'}, + index === 0 && + {class: 'first-news-entry'}, - stitchArrays({ - date: data.entryDates, - content: relations.entryContents, - mainLink: relations.entryMainLinks, - readMoreLink: relations.entryReadMoreLinks, - }).map(({ - date, - content, - mainLink, - readMoreLink, - }, index) => - html.tag('article', {class: 'news-entry'}, - index === 0 && - {class: 'first-news-entry'}, + [ + html.tag('h2', [ + html.tag('time', language.formatDate(date)), + mainLink, + ]), - [ - html.tag('h2', [ - html.tag('time', language.formatDate(date)), - mainLink, - ]), + content.slot('thumb', 'medium'), - content.slot('thumb', 'medium'), - - html.tag('p', - {[html.onlyIfContent]: true}, - readMoreLink - ?.slots({ - content: language.$('homepage.news.entry.viewRest'), - })), - ])), - ], - }); - }, + html.tag('p', + {[html.onlyIfContent]: true}, + readMoreLink + ?.slots({ + content: language.$(entryCapsule, 'viewRest'), + })), + ]))), + ], + })), }; diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index ab2eca93..79bba441 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -74,20 +74,22 @@ export default { }, generate(data, relations, {html, language}) { + const capsule = language.encapsulate('listingPage.other.randomPages'); + const miscellaneousChunkRows = [ - { + language.encapsulate(capsule, 'chunk.item.randomArtist', capsule => ({ stringsKey: 'randomArtist', mainLink: html.tag('a', {href: '#', 'data-random': 'artist'}, - language.$('listingPage.other.randomPages.chunk.item.randomArtist.mainLink')), + language.$(capsule, 'mainLink')), atLeastTwoContributions: html.tag('a', {href: '#', 'data-random': 'artist-more-than-one-contrib'}, - language.$('listingPage.other.randomPages.chunk.item.randomArtist.atLeastTwoContributions')), - }, + language.$(capsule, 'atLeastTwoContributions')), + })), {stringsKey: 'randomAlbumWholeSite'}, {stringsKey: 'randomTrackWholeSite'}, @@ -104,24 +106,25 @@ export default { content: [ html.tag('p', - language.$('listingPage.other.randomPages.chooseLinkLine', { - fromPart: - (relations.groupLinks - ? language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.dividedByGroups') - : language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.notDividedByGroups')), + language.encapsulate(capsule, 'chooseLinkLine', capsule => + language.$(capsule, { + fromPart: + (relations.groupLinks + ? language.$(capsule, 'fromPart.dividedByGroups') + : language.$(capsule, 'fromPart.notDividedByGroups')), - browserSupportPart: - language.$('listingPage.other.randomPages.chooseLinkLine.browserSupportPart'), - })), + browserSupportPart: + language.$(capsule, 'browserSupportPart'), + }))), html.tag('p', {id: 'data-loading-line'}, - language.$('listingPage.other.randomPages.dataLoadingLine')), + language.$(capsule, 'dataLoadingLine')), html.tag('p', {id: 'data-loaded-line'}, - language.$('listingPage.other.randomPages.dataLoadedLine')), + language.$(capsule, 'dataLoadedLine')), html.tag('p', {id: 'data-error-line'}, - language.$('listingPage.other.randomPages.dataErrorLine')), + language.$(capsule, 'dataErrorLine')), ], showSkipToSection: true, @@ -148,17 +151,18 @@ export default { ... (relations.groupLinks - ? relations.groupLinks.map(() => ({ - randomAlbum: - html.tag('a', - {href: '#', 'data-random': 'album-in-group-dl'}, - language.$('listingPage.other.randomPages.chunk.title.fromGroup.accent.randomAlbum')), - - randomTrack: - html.tag('a', - {href: '#', 'data-random': 'track-in-group-dl'}, - language.$('listingPage.other.randomPages.chunk.title.fromGroup.accent.randomTrack')), - })) + ? relations.groupLinks.map(() => + language.encapsulate(capsule, 'chunk.title.fromGroup.accent', capsule => ({ + randomAlbum: + html.tag('a', + {href: '#', 'data-random': 'album-in-group-dl'}, + language.$(capsule, 'randomAlbum')), + + randomTrack: + html.tag('a', + {href: '#', 'data-random': 'track-in-group-dl'}, + language.$(capsule, 'randomTrack')), + }))) : [null]), ], diff --git a/src/content/dependencies/transformContent.js b/src/content/dependencies/transformContent.js index ee2c3938..5f803a3b 100644 --- a/src/content/dependencies/transformContent.js +++ b/src/content/dependencies/transformContent.js @@ -279,15 +279,16 @@ export default { {class: 'align-center'}, {title: - language.$('misc.external.opensInNewTab', { - link: - language.formatExternalLink(link, { - style: 'platform', - }), - - annotation: - language.$('misc.external.opensInNewTab.annotation'), - }).toString()}, + language.encapsulate('misc.external.opensInNewTab', capsule => + language.$(capsule, { + link: + language.formatExternalLink(link, { + style: 'platform', + }), + + annotation: + language.$(capsule, 'annotation'), + }).toString())}, content); } |