« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/misc-templates.js13
-rw-r--r--src/util/urls.js109
-rw-r--r--src/write/build-modes/live-dev-server.js42
-rw-r--r--src/write/build-modes/static-build.js93
-rw-r--r--src/write/page-template.js11
5 files changed, 106 insertions, 162 deletions
diff --git a/src/misc-templates.js b/src/misc-templates.js
index 6659d72b..794b6920 100644
--- a/src/misc-templates.js
+++ b/src/misc-templates.js
@@ -973,10 +973,8 @@ function unbound_getFooterLocalizationLinks(pathname, {
   defaultLanguage,
   language,
   languages,
+  pagePath,
   to,
-
-  pageSubKey,
-  urlArgs,
 }) {
   const links = Object.entries(languages)
     .filter(([code, language]) => code !== 'default' && !language.hidden)
@@ -989,11 +987,12 @@ function unbound_getFooterLocalizationLinks(pathname, {
             href:
               language === defaultLanguage
                 ? to(
-                    'localizedDefaultLanguage.' + pageSubKey,
-                    ...urlArgs)
+                    'localizedDefaultLanguage.' + pagePath[0],
+                    ...pagePath.slice(1))
                 : to(
-                    'localizedWithBaseDirectory.' + pageSubKey,
-                    language.code, ...urlArgs),
+                    'localizedWithBaseDirectory.' + pagePath[0],
+                    language.code,
+                    ...pagePath.slice(1)),
           },
           language.name)));
 
diff --git a/src/util/urls.js b/src/util/urls.js
index 4672c6a2..c2119b8d 100644
--- a/src/util/urls.js
+++ b/src/util/urls.js
@@ -140,18 +140,16 @@ export const thumb = {
 // Makes the generally-used and wiki-specialized "to" page utility.
 // "to" returns a relative path from the current page to the target.
 export function getURLsFrom({
-  urls,
-
   baseDirectory,
-  pageSubKey,
-  subdirectoryPrefix,
+  pagePath,
+  urls,
 }) {
+  const pageSubKey = pagePath[0];
+  const subdirectoryPrefix = getPageSubdirectoryPrefix({pagePath});
+
   return (targetFullKey, ...args) => {
     const [groupKey, subKey] = targetFullKey.split('.');
-    let path = subdirectoryPrefix;
-
-    let from;
-    let to;
+    let from, to;
 
     // When linking to *outside* the localized area of the site, we need to
     // make sure the result is correctly relative to the 8ase directory.
@@ -180,9 +178,9 @@ export function getURLsFrom({
       to = targetFullKey;
     }
 
-    path += urls.from(from).to(to, ...args);
-
-    return path;
+    return (
+      subdirectoryPrefix +
+      urls.from(from).to(to, ...args));
   };
 }
 
@@ -193,19 +191,19 @@ export function getURLsFromRoot({
   baseDirectory,
   urls,
 }) {
-  const from = urls.from('shared.root');
+  const {to} = urls.from('shared.root');
 
   return (targetFullKey, ...args) => {
     const [groupKey, subKey] = targetFullKey.split('.');
     return (
       '/' +
       (groupKey === 'localized' && baseDirectory
-        ? from.to(
+        ? to(
             'localizedWithBaseDirectory.' + subKey,
             baseDirectory,
             ...args
           )
-        : from.to(targetFullKey, ...args))
+        : to(targetFullKey, ...args))
     );
   };
 }
@@ -213,61 +211,46 @@ export function getURLsFromRoot({
 export function getPagePathname({
   baseDirectory,
   device = false,
-  fullKey,
-  urlArgs,
+  pagePath,
   urls,
 }) {
-  const [groupKey, subKey] = fullKey.split('.');
-
-  const toKey = device ? 'toDevice' : 'to';
-
-  return (groupKey === 'localized' && baseDirectory
-    ? urls
-        .from('shared.root')[toKey](
-          'localizedWithBaseDirectory.' + subKey,
-          baseDirectory,
-          ...urlArgs)
-    : urls
-        .from('shared.root')[toKey](
-          fullKey,
-          ...urlArgs));
-}
+  const {[device ? 'toDevice' : 'to']: to} = urls.from('shared.root');
 
-// Needed for the rare path arguments which themselves contains one or more
-// slashes, e.g. for listings, with arguments like 'albums/by-name'.
-export function getPageSubdirectoryPrefix({urlArgs}) {
-  return '../'.repeat(urlArgs.join('/').split('/').length - 1);
+  return (baseDirectory
+    ? to('localizedWithBaseDirectory.' + pagePath[0], baseDirectory, ...pagePath.slice(1))
+    : to('localized.' + pagePath[0], ...pagePath.slice(1)));
 }
 
-export function getPagePaths({
-  baseDirectory,
-  fullKey,
-  outputPath,
-  urlArgs,
+export function getPagePathnameAcrossLanguages({
+  defaultLanguage,
+  languages,
+  pagePath,
   urls,
 }) {
-  const [groupKey, subKey] = fullKey.split('.');
-
-  const pathname = getPagePathname({
-    baseDirectory,
-    device: true,
-    fullKey,
-    urlArgs,
-    urls,
-  });
-
-  const outputDirectory = path.join(outputPath, pathname);
-
-  const output = {
-    directory: outputDirectory,
-    documentHTML: path.join(outputDirectory, 'index.html'),
-    oEmbedJSON: path.join(outputDirectory, 'oembed.json'),
-  };
-
-  return {
-    urlPath: [fullKey, ...urlArgs],
+  return withEntries(languages, entries => entries
+    .filter(([key, language]) => key !== 'default' && !language.hidden)
+    .map(([_key, language]) => [
+      language.code,
+      getPagePathname({
+        baseDirectory:
+          (language === defaultLanguage
+            ? ''
+            : language.code),
+        pagePath,
+        urls,
+      }),
+    ]));
+}
 
-    output,
-    pathname,
-  };
+// Needed for the rare path arguments which themselves contains one or more
+// slashes, e.g. for listings, with arguments like 'albums/by-name'.
+export function getPageSubdirectoryPrefix({
+  pagePath,
+}) {
+  const timesNestedDeeply = (pagePath
+    .slice(1) // skip URL key, only check arguments
+    .join('/')
+    .split('/')
+    .length - 1);
+  return '../'.repeat(timesNestedDeeply);
 }
diff --git a/src/write/build-modes/live-dev-server.js b/src/write/build-modes/live-dev-server.js
index b6bf662b..a4c4c871 100644
--- a/src/write/build-modes/live-dev-server.js
+++ b/src/write/build-modes/live-dev-server.js
@@ -11,11 +11,10 @@ import {serializeThings} from '../../data/serialize.js';
 import * as pageSpecs from '../../page/index.js';
 
 import {logInfo, logWarn, progressCallAll} from '../../util/cli.js';
-import {withEntries} from '../../util/sugar.js';
 
 import {
   getPagePathname,
-  getPageSubdirectoryPrefix,
+  getPagePathnameAcrossLanguages,
   getURLsFrom,
   getURLsFromRoot,
 } from '../../util/urls.js';
@@ -83,17 +82,13 @@ export async function go({
       else if (page.type === 'redirect')
         servePath = page.fromPath;
 
-      const fullKey = 'localized.' + servePath[0];
-      const urlArgs = servePath.slice(1);
-
       return Object.values(languages).map(language => {
         const baseDirectory =
           language === defaultLanguage ? '' : language.code;
 
         const pathname = getPagePathname({
           baseDirectory,
-          fullKey,
-          urlArgs,
+          pagePath: servePath,
           urls,
         });
 
@@ -249,12 +244,9 @@ export async function go({
     } = urlToPageMap[pathnameKey];
 
     const to = getURLsFrom({
-      urls,
       baseDirectory,
-      pageSubKey: servePath[0],
-      subdirectoryPrefix: getPageSubdirectoryPrefix({
-        urlArgs: servePath.slice(1),
-      }),
+      pagePath: servePath,
+      urls,
     });
 
     const absoluteTo = getURLsFromRoot({
@@ -263,9 +255,6 @@ export async function go({
     });
 
     try {
-      const pageSubKey = servePath[0];
-      const urlArgs = servePath.slice(1);
-
       if (page.type === 'redirect') {
         response.writeHead(301, contentTypeHTML);
 
@@ -280,20 +269,12 @@ export async function go({
 
       response.writeHead(200, contentTypeHTML);
 
-      const localizedPathnames = withEntries(languages, entries => entries
-        .filter(([key, language]) => key !== 'default' && !language.hidden)
-        .map(([_key, language]) => [
-          language.code,
-          getPagePathname({
-            baseDirectory:
-              (language === defaultLanguage
-                ? ''
-                : language.code),
-            fullKey: 'localized.' + pageSubKey,
-            urlArgs,
-            urls,
-          }),
-        ]));
+      const localizedPathnames = getPagePathnameAcrossLanguages({
+        defaultLanguage,
+        languages,
+        pagePath: servePath,
+        urls,
+      });
 
       const bound = bindUtilities({
         absoluteTo,
@@ -315,9 +296,8 @@ export async function go({
         languages,
         localizedPathnames,
         oEmbedJSONHref: null, // No oEmbed support for live dev server
-        pageSubKey,
+        pagePath: servePath,
         pathname,
-        urlArgs,
         to,
         transformMultiline: bound.transformMultiline,
         wikiData,
diff --git a/src/write/build-modes/static-build.js b/src/write/build-modes/static-build.js
index 90fc38ae..23c6470a 100644
--- a/src/write/build-modes/static-build.js
+++ b/src/write/build-modes/static-build.js
@@ -15,7 +15,7 @@ import {serializeThings} from '../../data/serialize.js';
 import * as pageSpecs from '../../page/index.js';
 
 import link from '../../util/link.js';
-import {empty, queue, withEntries} from '../../util/sugar.js';
+import {empty, queue} from '../../util/sugar.js';
 
 import {
   logError,
@@ -27,8 +27,7 @@ import {
 
 import {
   getPagePathname,
-  getPagePaths,
-  getPageSubdirectoryPrefix,
+  getPagePathnameAcrossLanguages,
   getURLsFrom,
   getURLsFromRoot,
 } from '../../util/urls.js';
@@ -265,40 +264,25 @@ export async function go({
 
     await progressPromiseAll(`Writing ${language.code}`, queue([
       ...pageWrites.map(page => () => {
-        const pageSubKey = page.path[0];
-        const urlArgs = page.path.slice(1);
-
-        const localizedPathnames = withEntries(languages, entries => entries
-          .filter(([key, language]) => key !== 'default' && !language.hidden)
-          .map(([_key, language]) => [
-            language.code,
-            getPagePathname({
-              baseDirectory:
-                (language === defaultLanguage
-                  ? ''
-                  : language.code),
-              fullKey: 'localized.' + pageSubKey,
-              urlArgs,
-              urls,
-            }),
-          ]));
-
-        const paths = getPagePaths({
-          outputPath,
+        const pagePath = page.path;
+
+        const localizedPathnames = getPagePathnameAcrossLanguages({
+          defaultLanguage,
+          languages,
+          pagePath,
           urls,
+        });
 
+        const pathname = getPagePathname({
           baseDirectory,
-          fullKey: 'localized.' + pageSubKey,
-          urlArgs,
+          pagePath,
+          urls,
         });
 
         const to = getURLsFrom({
-          urls,
           baseDirectory,
-          pageSubKey,
-          subdirectoryPrefix: getPageSubdirectoryPrefix({
-            urlArgs: page.path.slice(1),
-          }),
+          pagePath,
+          urls,
         });
 
         const absoluteTo = getURLsFromRoot({
@@ -328,7 +312,7 @@ export async function go({
           wikiData.wikiInfo.canonicalBase +
             urls
               .from('shared.root')
-              .to('shared.path', paths.pathname + 'oembed.json');
+              .to('shared.path', pathname + 'oembed.json');
 
         const pageHTML = generateDocumentHTML(pageInfo, {
           cachebust,
@@ -339,18 +323,22 @@ export async function go({
           languages,
           localizedPathnames,
           oEmbedJSONHref,
-          pageSubKey,
-          pathname: paths.pathname,
+          pagePath,
+          pathname,
           to,
           transformMultiline: bound.transformMultiline,
-          urlArgs,
           wikiData,
         });
 
         return writePage({
           html: pageHTML,
           oEmbedJSON,
-          paths,
+          outputDirectory: path.join(outputPath, getPagePathname({
+            baseDirectory,
+            device: true,
+            pagePath,
+            urls,
+          })),
         });
       }),
       ...redirectWrites.map(({fromPath, toPath, title: titleFn}) => () => {
@@ -358,27 +346,24 @@ export async function go({
           language,
         });
 
-        const from = getPagePaths({
-          outputPath,
-          urls,
-
-          baseDirectory,
-          fullKey: 'localized.' + fromPath[0],
-          urlArgs: fromPath.slice(1),
-        });
-
         const to = getURLsFrom({
-          urls,
           baseDirectory,
-          pageSubKey: fromPath[0],
-          subdirectoryPrefix: getPageSubdirectoryPrefix({
-            urlArgs: fromPath.slice(1),
-          }),
+          pagePath: fromPath,
+          urls,
         });
 
         const target = to('localized.' + toPath[0], ...toPath.slice(1));
         const html = generateRedirectHTML(title, target, {language});
-        return writePage({html, paths: from});
+
+        return writePage({
+          html,
+          outputDirectory: path.join(outputPath, getPagePathname({
+            baseDirectory,
+            device: true,
+            pagePath: fromPath,
+            urls,
+          })),
+        });
       }),
     ], queueSize));
   };
@@ -424,15 +409,15 @@ import {
 async function writePage({
   html,
   oEmbedJSON = '',
-  paths,
+  outputDirectory,
 }) {
-  await mkdir(paths.output.directory, {recursive: true});
+  await mkdir(outputDirectory, {recursive: true});
 
   await Promise.all([
-    writeFile(paths.output.documentHTML, html),
+    writeFile(path.join(outputDirectory, 'index.html'), html),
 
     oEmbedJSON &&
-      writeFile(paths.output.oEmbedJSON, oEmbedJSON),
+      writeFile(path.join(outputDirectory, 'oembed.json'), oEmbedJSON),
   ].filter(Boolean));
 }
 
diff --git a/src/write/page-template.js b/src/write/page-template.js
index 88d81c23..7c2f0c66 100644
--- a/src/write/page-template.js
+++ b/src/write/page-template.js
@@ -55,11 +55,10 @@ export function generateDocumentHTML(pageInfo, {
   languages,
   localizedPathnames,
   oEmbedJSONHref,
-  pageSubKey,
+  pagePath,
   pathname,
   to,
   transformMultiline,
-  urlArgs,
   wikiData,
 }) {
   const {wikiInfo} = wikiData;
@@ -169,9 +168,8 @@ export function generateDocumentHTML(pageInfo, {
           html,
           language,
           languages,
-          pageSubKey,
+          pagePath,
           to,
-          urlArgs,
         }),
       ]);
 
@@ -450,10 +448,9 @@ export function generateDocumentHTML(pageInfo, {
     {
       lang: language.intlCode,
       'data-language-code': language.code,
-      'data-url-key': 'localized.' + pageSubKey,
+      'data-url-key': 'localized.' + pagePath[0],
       ...Object.fromEntries(
-        urlArgs.map((v, i) => [['data-url-value' + i], v])
-      ),
+        pagePath.slice(1).map((v, i) => [['data-url-value' + i], v])),
       'data-rebase-localized': to('localized.root'),
       'data-rebase-shared': to('shared.root'),
       'data-rebase-media': to('media.root'),