UNPKG

@rr0/cms

Version:

RR0 Content Management System (CMS)

154 lines (153 loc) 6.45 kB
import path from "path"; import assert from "assert"; /** * Insert content in context file, according to data found in .json files aside of it. */ export class DataContentVisitor { constructor(service, eventRenderer, timeElementFactory) { this.service = service; this.eventRenderer = eventRenderer; this.timeElementFactory = timeElementFactory; } async visit(context) { const dirName = path.dirname(context.file.name); const dataList = await this.service.getFromDir(dirName, ["people", "case", "sighting", "api", "product", "org"], ["index.json", "case.json", "people.json", "api.json", "org.json"]); if (dataList.length > 0) { for (const data of dataList) { switch (data.type) { case "people": context.people = data; break; } await this.process(context, data); } } } async process(context, data) { this.processTitle(context, data); this.processURL(context, data); const events = data.events.sort((event1, event2) => event1.time ? event2.time ? event1.time.isBefore(event2.time) ? -1 : 1 : -1 : 1); for (const event of events) { await this.processEvent(context, event, data); } context.file.contents = context.file.serialize(); } async processEvent(context, event, data) { switch (event.eventType) { case "birth": await this.processBirth(context, event, data); break; case "book": await this.processBook(context, event); break; case "image": await this.processImage(context, event); break; case "death": await this.processDeath(context, event, data); break; default: const { eventP, timeEl } = this.timeParagraph(context, event); await this.eventRenderer.render(context, event, eventP); context.file.document.append(eventP); } } timeParagraph(context, event) { const container = context.file.document.createElement("p"); const eventContext = context.clone(); const eventTime = eventContext.time.date = event.time; assert.ok(eventTime, `Event of type "${event.type}" has no time for paragraph`); container.dataset.time = eventTime.toString(); const timeEl = this.timeElementFactory.create(eventContext, context); return { eventP: container, timeEl }; } async processImage(context, imageData) { const doc = context.file.document; const contents = doc.querySelector(".contents"); if (contents) { const imgEl = contents.querySelector("img"); const caption = imageData.name; const src = imageData.url; if ((imgEl === null || imgEl === void 0 ? void 0 : imgEl.src) !== src) { const imgEl = doc.createElement("img"); imgEl.src = src; imgEl.alt = imageData.title; const figcaptionEl = doc.createElement("figcaption"); figcaptionEl.innerHTML = caption; await this.eventRenderer.renderEnd(context, imageData, figcaptionEl); const figureEl = doc.createElement("figure"); figureEl.append(imgEl); figureEl.append(figcaptionEl); const insertEl = contents.querySelector("*"); contents.insertBefore(figureEl, insertEl); } } } async processBirth(context, event, entity) { const parentEl = context.file.document.querySelector(".contents"); if (parentEl) { const { eventP, timeEl } = this.timeParagraph(context, event); const name = entity.surname ? `"${entity.surname}"` : entity.name || entity.title; eventP.append(name); eventP.append(context.messages[entity.type].birth); eventP.append(timeEl); const eventPlace = event.place; if (eventPlace) { eventP.append(" à "); eventP.append(this.eventRenderer.placeElement(context, eventPlace)); } await this.eventRenderer.renderEnd(context, event, eventP); const insertEl = parentEl.firstElementChild; parentEl.insertBefore(eventP, insertEl); } else { context.warn("no .content in", context.file.name); } } async processDeath(context, event, entity) { const { eventP, timeEl } = this.timeParagraph(context, event); const name = entity.name; eventP.append(name); eventP.append(context.messages[entity.type].death); eventP.append(timeEl); if (event.place) { eventP.append(" à "); const birthPlace = this.eventRenderer.placeElement(context, event.place); eventP.append(birthPlace); } await this.eventRenderer.renderEnd(context, event, eventP); const insertEl = context.file.document.querySelector(".contents > p:last-of-type"); if (insertEl) { insertEl.parentNode.append(eventP); } } async processBook(context, bookData) { const doc = context.file.document; const parentEl = doc.querySelector(".contents"); if (parentEl) { const bookEl = doc.createElement("p"); const people = context.people; const birthContext = context.clone(); const bookDateEl = this.timeElementFactory.create(birthContext, context); bookEl.append(bookDateEl, " "); bookEl.append((people.gender === "female" ? "elle" : "il") + " écrit un livre"); await this.eventRenderer.renderEnd(context, bookData, bookEl); parentEl.append(bookEl); } else { context.warn("no .content in " + context.file.name); } } processTitle(context, data) { const doc = context.file.document; if (!doc.title) { context.file.title = doc.title = data.title; } } processURL(context, data) { const url = data.url; if (url && !context.file.meta.url) { context.file.meta.url = url; } } }