« 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/content/dependencies/generateArtistInfoPageChunkItem.js2
-rw-r--r--src/content/dependencies/generateChronologyLinks.js4
-rw-r--r--src/content/dependencies/generateCoverCarousel.js4
-rw-r--r--src/content/dependencies/generateCoverGrid.js8
-rw-r--r--src/content/dependencies/generateListingPage.js6
-rw-r--r--src/content/dependencies/generatePageLayout.js110
-rw-r--r--src/content/dependencies/generateSecondaryNav.js2
-rw-r--r--src/data/things/validators.js12
8 files changed, 80 insertions, 68 deletions
diff --git a/src/content/dependencies/generateArtistInfoPageChunkItem.js b/src/content/dependencies/generateArtistInfoPageChunkItem.js
index 9004f18a..36f0ebcc 100644
--- a/src/content/dependencies/generateArtistInfoPageChunkItem.js
+++ b/src/content/dependencies/generateArtistInfoPageChunkItem.js
@@ -4,7 +4,7 @@ export default {
   slots: {
     content: {type: 'html'},
 
-    otherArtistLinks: {validate: v => v.arrayOf(v.isHTML)},
+    otherArtistLinks: {validate: v => v.strictArrayOf(v.isHTML)},
     contribution: {type: 'string'},
     rerelease: {type: 'boolean'},
   },
diff --git a/src/content/dependencies/generateChronologyLinks.js b/src/content/dependencies/generateChronologyLinks.js
index 15c0898c..f411b938 100644
--- a/src/content/dependencies/generateChronologyLinks.js
+++ b/src/content/dependencies/generateChronologyLinks.js
@@ -6,10 +6,10 @@ export default {
   slots: {
     chronologyInfoSets: {
       validate: v =>
-        v.arrayOf(
+        v.strictArrayOf(
           v.validateProperties({
             headingString: v.isString,
-            contributions: v.arrayOf(v.validateProperties({
+            contributions: v.strictArrayOf(v.validateProperties({
               index: v.isCountingNumber,
               artistLink: v.isHTML,
               previousLink: v.isHTML,
diff --git a/src/content/dependencies/generateCoverCarousel.js b/src/content/dependencies/generateCoverCarousel.js
index 2a2503ac..e854113e 100644
--- a/src/content/dependencies/generateCoverCarousel.js
+++ b/src/content/dependencies/generateCoverCarousel.js
@@ -5,8 +5,8 @@ export default {
   extraDependencies: ['html'],
 
   slots: {
-    images: {validate: v => v.arrayOf(v.isHTML)},
-    links: {validate: v => v.arrayOf(v.isHTML)},
+    images: {validate: v => v.strictArrayOf(v.isHTML)},
+    links: {validate: v => v.strictArrayOf(v.isHTML)},
 
     lazy: {validate: v => v.oneOf(v.isWholeNumber, v.isBoolean)},
   },
diff --git a/src/content/dependencies/generateCoverGrid.js b/src/content/dependencies/generateCoverGrid.js
index 20130c5e..c7713cce 100644
--- a/src/content/dependencies/generateCoverGrid.js
+++ b/src/content/dependencies/generateCoverGrid.js
@@ -4,10 +4,10 @@ export default {
   extraDependencies: ['html'],
 
   slots: {
-    images: {validate: v => v.arrayOf(v.isHTML)},
-    links: {validate: v => v.arrayOf(v.isHTML)},
-    names: {validate: v => v.arrayOf(v.isHTML)},
-    info: {validate: v => v.arrayOf(v.isHTML)},
+    images: {validate: v => v.strictArrayOf(v.isHTML)},
+    links: {validate: v => v.strictArrayOf(v.isHTML)},
+    names: {validate: v => v.strictArrayOf(v.isHTML)},
+    info: {validate: v => v.strictArrayOf(v.isHTML)},
 
     lazy: {validate: v => v.oneOf(v.isWholeNumber, v.isBoolean)},
   },
diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js
index cab80a7f..c01d3b35 100644
--- a/src/content/dependencies/generateListingPage.js
+++ b/src/content/dependencies/generateListingPage.js
@@ -60,10 +60,10 @@ export default {
   slots: {
     type: {validate: v => v.is('rows', 'chunks', 'custom')},
 
-    rows: {validate: v => v.arrayOf(v.isObject)},
+    rows: {validate: v => v.strictArrayOf(v.isObject)},
 
-    chunkTitles: {validate: v => v.arrayOf(v.isObject)},
-    chunkRows: {validate: v => v.arrayOf(v.isObject)},
+    chunkTitles: {validate: v => v.strictArrayOf(v.isObject)},
+    chunkRows: {validate: v => v.strictArrayOf(v.isObject)},
 
     content: {type: 'html'},
   },
diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js
index 794b430b..b764595a 100644
--- a/src/content/dependencies/generatePageLayout.js
+++ b/src/content/dependencies/generatePageLayout.js
@@ -10,7 +10,7 @@ function sidebarSlots(side) {
     // will generate one sidebar section.
     [side + 'Multiple']: {
       validate: v =>
-        v.arrayOf(
+        v.sparseArrayOf(
           v.validateProperties({
             content: v.isHTML,
           })),
@@ -100,17 +100,17 @@ export default {
     socialEmbed: {type: 'html'},
 
     colorStyleRules: {
-      validate: v => v.arrayOf(v.isString),
+      validate: v => v.sparseArrayOf(v.isString),
       default: [],
     },
 
     additionalStyleRules: {
-      validate: v => v.arrayOf(v.isString),
+      validate: v => v.sparseArrayOf(v.isString),
       default: [],
     },
 
     mainClasses: {
-      validate: v => v.arrayOf(v.isString),
+      validate: v => v.sparseArrayOf(v.isString),
       default: [],
     },
 
@@ -148,7 +148,7 @@ export default {
 
     navLinks: {
       validate: v =>
-        v.arrayOf(object => {
+        v.sparseArrayOf(object => {
           v.isObject(object);
 
           const aggregate = openAggregate({message: `Errors validating navigation link`});
@@ -176,7 +176,7 @@ export default {
             }
           } else {
             aggregate.call(v.validateProperties({
-              path: v.arrayOf(v.isString),
+              path: v.strictArrayOf(v.isString),
               title: v.isString,
             }), {
               path: object.path,
@@ -275,58 +275,60 @@ export default {
               'nav-links-' + slots.navLinkStyle,
             ],
           },
-          slots.navLinks?.map((cur, i) => {
-            let content;
-
-            if (cur.html) {
-              content = cur.html;
-            } else {
-              let title;
-              let href;
-
-              switch (cur.auto) {
-                case 'home':
-                  title = data.wikiName;
-                  href = to('localized.home');
-                  break;
-                case 'current':
-                  title = slots.title;
-                  href = '';
-                  break;
-                case null:
-                case undefined:
-                  title = cur.title;
-                  href = to(...cur.path);
-                  break;
+          slots.navLinks
+            ?.filter(Boolean)
+            ?.map((cur, i) => {
+              let content;
+
+              if (cur.html) {
+                content = cur.html;
+              } else {
+                let title;
+                let href;
+
+                switch (cur.auto) {
+                  case 'home':
+                    title = data.wikiName;
+                    href = to('localized.home');
+                    break;
+                  case 'current':
+                    title = slots.title;
+                    href = '';
+                    break;
+                  case null:
+                  case undefined:
+                    title = cur.title;
+                    href = to(...cur.path);
+                    break;
+                }
+
+                content = html.tag('a',
+                  {href},
+                  title);
               }
 
-              content = html.tag('a',
-                {href},
-                title);
-            }
+              let className;
 
-            let className;
-
-            if (cur.auto === 'current') {
-              className = 'current';
-            } else if (
-              slots.navLinkStyle === 'hierarchical' &&
-              i === slots.navLinks.length - 1
-            ) {
-              className = 'current';
-            }
+              if (cur.auto === 'current') {
+                className = 'current';
+              } else if (
+                slots.navLinkStyle === 'hierarchical' &&
+                i === slots.navLinks.length - 1
+              ) {
+                className = 'current';
+              }
 
-            return html.tag('span',
-              {class: className},
-              [
-                html.tag('span',
-                  {class: 'nav-link-content'},
-                  content),
-                html.tag('span',
-                  {[html.onlyIfContent]: true, class: 'nav-link-accent'},
-                  cur.accent),
-              ]);
-          })),
+              return html.tag('span',
+                {class: className},
+                [
+                  html.tag('span',
+                    {class: 'nav-link-content'},
+                    content),
+                  html.tag('span',
+                    {[html.onlyIfContent]: true, class: 'nav-link-accent'},
+                    cur.accent),
+                ]);
+            })),
 
         html.tag('div',
           {[html.onlyIfContent]: true, class: 'nav-bottom-row'},
diff --git a/src/content/dependencies/generateSecondaryNav.js b/src/content/dependencies/generateSecondaryNav.js
index 6fdfd428..e62016bd 100644
--- a/src/content/dependencies/generateSecondaryNav.js
+++ b/src/content/dependencies/generateSecondaryNav.js
@@ -5,7 +5,7 @@ export default {
     content: {type: 'html'},
 
     class: {
-      validate: v => v.oneOf(v.isString, v.arrayOf(v.isString)),
+      validate: v => v.oneOf(v.isString, v.sparseArrayOf(v.isString)),
     },
   },
 
diff --git a/src/data/things/validators.js b/src/data/things/validators.js
index 14092102..1754adf3 100644
--- a/src/data/things/validators.js
+++ b/src/data/things/validators.js
@@ -195,10 +195,20 @@ export function validateArrayItems(itemValidator) {
   };
 }
 
-export function arrayOf(itemValidator) {
+export function strictArrayOf(itemValidator) {
   return validateArrayItems(itemValidator);
 }
 
+export function sparseArrayOf(itemValidator) {
+  return validateArrayItems(item => {
+    if (item === false || item === null) {
+      return true;
+    }
+
+    return itemValidator(item);
+  });
+}
+
 export function validateInstanceOf(constructor) {
   return (object) => isInstance(object, constructor);
 }