diff options
Diffstat (limited to 'src/page')
-rw-r--r-- | src/page/index.js | 33 | ||||
-rw-r--r-- | src/page/news.js | 129 |
2 files changed, 153 insertions, 9 deletions
diff --git a/src/page/index.js b/src/page/index.js index d74dad57..384b4193 100644 --- a/src/page/index.js +++ b/src/page/index.js @@ -3,7 +3,14 @@ // homepage.js for that. // // Each module published in this list should follow a particular format, -// including the following exports: +// including any of the following exports: +// +// condition({wikiData}) +// Returns a boolean indicating whether to process targets/writes (true) or +// skip this page spec altogether (false). This is usually used for +// selectively toggling pages according to site feature flags, though it may +// also be used to e.g. skip out if no targets would be found (preventing +// writeTargetless from generating an empty index page). // // targets({wikiData}) // Gets the objects which this page's write() function should be called on. @@ -11,14 +18,21 @@ // but it may also apply filter/map/etc if useful. // // write(thing, {wikiData}) -// Gets descriptors for any page and data writes associated with the given -// thing (which will be a value from the targets() array). This includes -// page (HTML) writes, data (JSON) writes, etc. Notably, this function does -// not perform any file operations itself; it only describes the operations -// which will be processed elsewhere, once for each translation language. -// The write function also immediately transforms any data which will be -// reused across writes of the same page, so that this data is effectively -// cached (rather than recalculated for each language/write). +// Provides descriptors for any page and data writes associated with the +// given thing (which will be a value from the targets() array). This +// includes page (HTML) writes, data (JSON) writes, etc. Notably, this +// function does not perform any file operations itself; it only describes +// the operations which will be processed elsewhere, once for each +// translation language. The write function also immediately transforms +// any data which will be reused across writes of the same page, so that +// this data is effectively cached (rather than recalculated for each +// language/write). +// +// writeTargetless({wikiData}) +// Provides descriptors for page/data/etc writes which will be used +// without concern for targets. This is usually used for writing index pages +// which should be generated just once (rather than corresponding to +// targets). // // As these modules are effectively the HTML templates for all site layout, // common patterns may also be exported alongside the special exports above. @@ -29,4 +43,5 @@ export * as album from './album.js'; export * as artist from './artist.js'; export * as artistAlias from './artist-alias.js'; export * as group from './group.js'; +export * as news from './news.js'; export * as track from './track.js'; diff --git a/src/page/news.js b/src/page/news.js new file mode 100644 index 00000000..99cbe8d5 --- /dev/null +++ b/src/page/news.js @@ -0,0 +1,129 @@ +// News entry & index page specifications. + +// Imports + +import fixWS from 'fix-whitespace'; + +// Page exports + +export function condition({wikiData}) { + return wikiData.wikiInfo.features.news; +} + +export function targets({wikiData}) { + return wikiData.newsData; +} + +export function write(entry, {wikiData}) { + const page = { + type: 'page', + path: ['newsEntry', entry.directory], + page: ({ + generatePreviousNextLinks, + link, + strings, + transformMultiline, + }) => ({ + title: strings('newsEntryPage.title', {entry: entry.name}), + + main: { + content: fixWS` + <div class="long-content"> + <h1>${strings('newsEntryPage.title', {entry: entry.name})}</h1> + <p>${strings('newsEntryPage.published', {date: strings.count.date(entry.date)})}</p> + ${transformMultiline(entry.body)} + </div> + ` + }, + + nav: generateNewsEntryNav(entry, { + generatePreviousNextLinks, + link, + strings, + wikiData + }) + }) + }; + + return [page]; +} + +export function writeTargetless({wikiData}) { + const { newsData } = wikiData; + + const page = { + type: 'page', + path: ['newsIndex'], + page: ({ + link, + strings, + transformMultiline + }) => ({ + title: strings('newsIndex.title'), + + main: { + content: fixWS` + <div class="long-content news-index"> + <h1>${strings('newsIndex.title')}</h1> + ${newsData.map(entry => fixWS` + <article id="${entry.directory}"> + <h2><time>${strings.count.date(entry.date)}</time> ${link.newsEntry(entry)}</h2> + ${transformMultiline(entry.bodyShort)} + ${entry.bodyShort !== entry.body && `<p>${link.newsEntry(entry, { + text: strings('newsIndex.entry.viewRest') + })}</p>`} + </article> + `).join('\n')} + </div> + ` + }, + + nav: {simple: true} + }) + }; + + return [page]; +} + +// Utility functions + +function generateNewsEntryNav(entry, { + generatePreviousNextLinks, + link, + strings, + wikiData +}) { + const { wikiInfo, newsData } = wikiData; + + // The newsData list is sorted reverse chronologically (newest ones first), + // so the way we find next/previous entries is flipped from normal. + const previousNextLinks = generatePreviousNextLinks(entry, { + link, strings, + data: newsData.slice().reverse(), + linkKey: 'newsEntry' + }); + + return { + links: [ + { + path: ['localized.home'], + title: wikiInfo.shortName + }, + { + path: ['localized.newsIndex'], + title: strings('newsEntryPage.nav.news') + }, + { + html: strings('newsEntryPage.nav.entry', { + date: strings.count.date(entry.date), + entry: link.newsEntry(entry, {class: 'current'}) + }) + }, + previousNextLinks && + { + divider: false, + html: `(${previousNextLinks})` + } + ] + }; +} |