« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content/dependencies/generateListingPage.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/dependencies/generateListingPage.js')
-rw-r--r--src/content/dependencies/generateListingPage.js142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js
new file mode 100644
index 00000000..cab80a7f
--- /dev/null
+++ b/src/content/dependencies/generateListingPage.js
@@ -0,0 +1,142 @@
+import {empty, stitchArrays} from '../../util/sugar.js';
+
+export default {
+  contentDependencies: [
+    'generateContentHeading',
+    'generateListingSidebar',
+    'generatePageLayout',
+    'linkListing',
+    'linkListingIndex',
+  ],
+
+  extraDependencies: ['html', 'language', 'wikiData'],
+
+  relations(relation, listing) {
+    const relations = {};
+
+    relations.layout =
+      relation('generatePageLayout');
+
+    relations.sidebar =
+      relation('generateListingSidebar', listing);
+
+    relations.listingsIndexLink =
+      relation('linkListingIndex');
+
+    relations.chunkHeading =
+      relation('generateContentHeading');
+
+    if (listing.target.listings.length > 1) {
+      relations.sameTargetListingLinks =
+        listing.target.listings
+          .map(listing => relation('linkListing', listing));
+    }
+
+    if (!empty(listing.seeAlso)) {
+      relations.seeAlsoLinks =
+        listing.seeAlso
+          .map(listing => relation('linkListing', listing));
+    }
+
+    return relations;
+  },
+
+  data(listing) {
+    return {
+      stringsKey: listing.stringsKey,
+
+      targetStringsKey: listing.target.stringsKey,
+
+      sameTargetListingStringsKeys:
+        listing.target.listings
+          .map(listing => listing.stringsKey),
+
+      sameTargetListingsCurrentIndex:
+        listing.target.listings
+          .indexOf(listing),
+    };
+  },
+
+  slots: {
+    type: {validate: v => v.is('rows', 'chunks', 'custom')},
+
+    rows: {validate: v => v.arrayOf(v.isObject)},
+
+    chunkTitles: {validate: v => v.arrayOf(v.isObject)},
+    chunkRows: {validate: v => v.arrayOf(v.isObject)},
+
+    content: {type: 'html'},
+  },
+
+  generate(data, relations, slots, {html, language}) {
+    return relations.layout.slots({
+      title: language.$(`listingPage.${data.stringsKey}.title`),
+      headingMode: 'sticky',
+
+      mainContent: [
+        relations.sameTargetListingLinks &&
+          html.tag('p',
+            language.$('listingPage.listingsFor', {
+              target: language.$(`listingPage.target.${data.targetStringsKey}`),
+              listings:
+                language.formatUnitList(
+                  stitchArrays({
+                    link: relations.sameTargetListingLinks,
+                    stringsKey: data.sameTargetListingStringsKeys,
+                  }).map(({link, stringsKey}, index) =>
+                      html.tag('span',
+                        {class: index === data.sameTargetListingsCurrentIndex && 'current'},
+                        link.slots({
+                          attributes: {class: 'nowrap'},
+                          content: language.$(`listingPage.${stringsKey}.title.short`),
+                        })))),
+            })),
+
+        relations.seeAlsoLinks &&
+          html.tag('p',
+            language.$('listingPage.seeAlso', {
+              listings: language.formatUnitList(relations.seeAlsoLinks),
+            })),
+
+        slots.type === 'rows' &&
+          html.tag('ul',
+            slots.rows.map(row =>
+              html.tag('li',
+                language.$(`listingPage.${data.stringsKey}.item`, row)))),
+
+        slots.type === 'chunks' &&
+          html.tag('dl',
+            stitchArrays({
+              title: slots.chunkTitles,
+              rows: slots.chunkRows,
+            }).map(({title, rows}) => [
+                relations.chunkHeading
+                  .clone()
+                  .slots({
+                    tag: 'dt',
+                    title:
+                      language.$(`listingPage.${data.stringsKey}.chunk.title`, title),
+                  }),
+
+                html.tag('dd',
+                  html.tag('ul',
+                    rows.map(row =>
+                      html.tag('li',
+                        language.$(`listingPage.${data.stringsKey}.chunk.item`, row))))),
+              ])),
+
+        slots.type === 'custom' &&
+          slots.content,
+      ],
+
+      navLinkStyle: 'hierarchical',
+      navLinks: [
+        {auto: 'home'},
+        {html: relations.listingsIndexLink},
+        {auto: 'current'},
+      ],
+
+      ...relations.sidebar,
+    });
+  },
+};