diff --git a/gatsby-node.js b/gatsby-node.js index dca742fc..d1bb1f83 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -65,7 +65,7 @@ exports.onPreBootstrap = async ({createContentDigest, actions}) => { const ttlFiles = getTurtleFiles('./data', []) console.info(`Found these turtle files:`) ttlFiles.forEach(e => console.info(e)) - ttlFiles.forEach(async f => { + for (const f of ttlFiles) { const ttlString = fs.readFileSync(f).toString() const doc = await jsonld.fromRDF(ttlString, { format: 'text/turtle' }) const compacted = await jsonld.compact(doc, context.jsonld) @@ -73,10 +73,10 @@ exports.onPreBootstrap = async ({createContentDigest, actions}) => { const { narrower, narrowerTransitive, narrowMatch, broader, broaderTransitive, broadMatch, exactMatch, closeMatch, related, relatedMatch, - inScheme, topConceptOf, hasTopConcept, ...properties + inScheme, topConceptOf, hasTopConcept, member, ...properties } = graph const type = Array.isArray(properties.type) - ? properties.type.find(t => ['Concept', 'ConceptScheme']) + ? properties.type.find(t => ['Concept', 'ConceptScheme', 'Collection']) : properties.type const node = { ...properties, @@ -99,14 +99,15 @@ exports.onPreBootstrap = async ({createContentDigest, actions}) => { internal: { contentDigest: createContentDigest(graph), type, - } + }, + member___NODE: (member || []).map(member => member.id) } if (type === 'Concept') { Object.assign(node, {}) } - ['Concept', 'ConceptScheme'].includes(type) && createNode(node) + ['Concept', 'ConceptScheme', 'Collection'].includes(type) && createNode(node) }) - }) + } } exports.sourceNodes = async ({ actions }) => { @@ -115,7 +116,56 @@ exports.sourceNodes = async ({ actions }) => { } exports.createPages = async ({ graphql, actions: { createPage } }) => { - const actorUrlTemplate = urlTemplate.parse(process.env.ACTOR) + + const memberOf = {} + + // Build collection pages + const collections = await graphql(queries.allCollection(languages)) + await Promise.all(collections.data.allCollection.edges.map(async ({ node: collection }) => { + const indexes = Object.fromEntries([...languages].map(l => { + const index = flexsearch.create({ + tokenize: "full", + }) + index.addMatcher({ + '[Ää]': "a", // replaces all 'ä' to 'a' + '[Öö]': "o", + '[Üü]': "u", + }) + return [l, index] + })) + + // store collection membership for concepts + collection.member.forEach((m) => { + if (memberOf.hasOwnProperty(m.id)) { + memberOf[m.id].push(collection); + } else { + memberOf[m.id] = [collection]; + } + }) + + const json = omitEmpty(Object.assign({}, collection, context.jsonld)) + const jsonld = omitEmpty(Object.assign({}, collection, context.jsonld)) + languages.forEach(language => createPage({ + path: getFilePath(collection.id, `${language}.html`), + component: path.resolve(`./src/components/Collection.js`), + context: { + language, + languages: Array.from(languages), + node: collection, + baseURL: process.env.BASEURL || '' + } + })) + createData({ + path: getFilePath(collection.id, 'json'), + data: JSON.stringify(json, null, 2) + }) + createData({ + path: getFilePath(collection.id, 'jsonld'), + data: JSON.stringify(jsonld, null, 2) + }) + languages.forEach(language => indexes[language].add(collection.id, i18n(language)(collection.prefLabel))) + })) + const conceptSchemes = await graphql(queries.allConceptScheme(languages)) conceptSchemes.errors && console.error(conceptSchemes.errors) @@ -151,6 +201,7 @@ exports.createPages = async ({ graphql, actions: { createPage } }) => { language, languages: Array.from(languages), node: concept, + collections: memberOf.hasOwnProperty(concept.id) ? memberOf[concept.id] : [], baseURL: process.env.BASEURL || '' } })) diff --git a/src/components/Collection.js b/src/components/Collection.js new file mode 100644 index 00000000..339bbef8 --- /dev/null +++ b/src/components/Collection.js @@ -0,0 +1,26 @@ +/** @jsx jsx */ +import { jsx } from '@emotion/react' +import { Link } from 'gatsby' +import { i18n, getFilePath } from '../common' +import JsonLink from './JsonLink' + +const Collection = ({ pageContext: { node: collection, language, baseURL } }) => ( +
+

{i18n(language)(collection.prefLabel)}

+

{collection.id}

+ + +
+) + +export default Collection diff --git a/src/components/Concept.js b/src/components/Concept.js index 09c378db..64d0c3b0 100644 --- a/src/components/Concept.js +++ b/src/components/Concept.js @@ -6,7 +6,7 @@ import JsonLink from './JsonLink' import { i18n, getDomId, getFilePath } from '../common' -const Concept = ({ pageContext: { node: concept, language, baseURL } }) => ( +const Concept = ({ pageContext: { node: concept, language, collections, baseURL } }) => (

{concept.notation && @@ -140,6 +140,20 @@ const Concept = ({ pageContext: { node: concept, language, baseURL } }) => (

)} + {collections && collections.length > 0 && ( +
+

in Collections

+ +
+ )} ) diff --git a/src/queries.js b/src/queries.js index 31cef243..c7f75492 100644 --- a/src/queries.js +++ b/src/queries.js @@ -1,3 +1,25 @@ +module.exports.allCollection = (languages) => ` +{ + allCollection { + edges { + node { + id + type + prefLabel { + ${[...languages].join(' ')} + } + member { + id + prefLabel { + ${[...languages].join(' ')} + } + } + } + } + } +} +` + module.exports.allConcept = (inScheme, languages) => ` { allConcept( diff --git a/src/templates/App.js b/src/templates/App.js index 34d2a4f4..f3692b21 100644 --- a/src/templates/App.js +++ b/src/templates/App.js @@ -13,7 +13,7 @@ import SEO from '../components/seo' import { style } from '../styles/concepts.css.js' const App = ({pageContext, children}) => { - const conceptSchemeId = pageContext.node.type === 'ConceptScheme' + const conceptSchemeId = (pageContext.node.type === 'ConceptScheme' || pageContext.node.type === 'Collection') ? pageContext.node.id : pageContext.node.inScheme.id const [index, setIndex] = useState(FlexSearch.create()) @@ -28,7 +28,7 @@ const App = ({pageContext, children}) => { const idx = FlexSearch.create() // add custom matcher to match umlaute at beginning of string idx.addMatcher({ - '[Aä]': "a", // replaces all 'ä' to 'a' + '[Ää]': "a", // replaces all 'ä' to 'a' '[Öö]': "o", '[Üü]': "u", }) diff --git a/src/types.js b/src/types.js index 3967cbc1..9a57a8d6 100644 --- a/src/types.js +++ b/src/types.js @@ -1,4 +1,11 @@ module.exports = (languages) => ` + + type Collection implements Node { + type: String, + prefLabel: LanguageMap, + member: [Concept] @link(from: "member___NODE") + } + type ConceptScheme implements Node { type: String, title: LanguageMap,