add basic sitemap generator

This commit is contained in:
adueck 2023-02-09 14:26:51 +05:00
parent a6e3d24672
commit ebe039d71c
5 changed files with 225 additions and 169 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
/src/words/raw-words.ts
public/sitemap.xml
# Logs
logs

View File

@ -6,11 +6,12 @@
"scripts": {
"dev": "vite",
"dev-w-user": "REACT_APP_ENV=dev vite",
"build": "yarn get-words && tsc && vite build",
"build": "yarn get-words && yarn make-sitemap && tsc && vite build",
"preview": "vite preview",
"infup": "yarn upgrade @lingdocs/ps-react --latest",
"bump-dep": "yarn install && git add . && git commit -m up && git push origin master",
"get-words": "node scripts/get-words.js"
"get-words": "node scripts/get-words.js",
"make-sitemap": "node scripts/make-sitemap.js"
},
"dependencies": {
"@formkit/auto-animate": "^1.0.0-beta.6",
@ -58,6 +59,7 @@
"@types/react-scrollspy": "^3.3.5",
"@types/react-swipeable": "^5.2.0",
"@vitejs/plugin-react": "^3.0.0",
"loose-json": "^1.1.2",
"node-fetch": "2.6.1",
"typescript": "^4.9.3",
"vite": "^4.0.0",

38
scripts/make-sitemap.js Normal file
View File

@ -0,0 +1,38 @@
import fs from "fs";
const base = "https://grammar.lingdocs.com";
console.log("generating sitemap.xml");
const indexText = fs.readFileSync("./src/content/index.ts", "utf-8");
const contentTreeRaw = indexText.split("/* content-tree */")[1];
const safeContentTreeText = contentTreeRaw
.split("\n")
.filter(l => !l.includes(`"import":`))
.join("\n");
const contentTree = JSON.parse(safeContentTreeText);
const urls = contentTree.reduce((acc, section) => {
if ("slug" in section) {
return [
...acc,
`${base}/${section.slug}`,
];
} else {
return [
...acc,
...section.chapters.map(x => `${base}/${section.subdirectory}/${x.slug}`),
];
}
}, [base]);
const siteMap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(u => ` <url>
<loc>${u}</loc>
</url>
`).join("")}
</urlset>
`
fs.writeFileSync("./public/sitemap.xml", siteMap);

View File

@ -137,288 +137,291 @@ type ChaptersSection = {
chapters: ChapterSection[],
};
const contentTree: (ChapterSection | ChaptersSection)[] = [
// for the super hacky sitemap generator to work this array needs to be
// - in valid JSON and surrounded by these comments
// - the import statements have to be at the top of the objects in a seperate line
export const contentTree: (ChapterSection | ChaptersSection)[] = /* content-tree */[
{
import: intro,
slug: "intro",
"import": intro,
"slug": "intro"
},
{
import: games,
slug: "games",
"import": games,
"slug": "games"
},
{
import: phraseBuilder,
slug: "phrase-builder",
"import": phraseBuilder,
"slug": "phrase-builder"
},
{
heading: "Equatives",
subdirectory: "equatives",
chapters: [
"heading": "Equatives",
"subdirectory": "equatives",
"chapters": [
{
import: presentEquative,
slug: "present-equative",
"import": presentEquative,
"slug": "present-equative"
},
{
import: habitualEquative,
slug: "habitual-equative",
"import": habitualEquative,
"slug": "habitual-equative"
},
{
import: otherEquatives,
slug: "other-equatives",
},
],
"import": otherEquatives,
"slug": "other-equatives"
}
]
},
{
heading: "Nouns",
subdirectory: "nouns",
chapters: [
"heading": "Nouns",
"subdirectory": "nouns",
"chapters": [
{
import: nounsGender,
slug: "nouns-gender",
"import": nounsGender,
"slug": "nouns-gender"
},
{
import: nounsUnisex,
slug: "nouns-unisex",
"import": nounsUnisex,
"slug": "nouns-unisex"
},
{
import: nounsPlural,
slug: "nouns-plural",
"import": nounsPlural,
"slug": "nouns-plural"
},
{
import: arabicPlurals,
slug: "arabic-plurals",
"import": arabicPlurals,
"slug": "arabic-plurals"
},
{
import: bundledPlurals,
slug: "bundled-plurals",
},
],
"import": bundledPlurals,
"slug": "bundled-plurals"
}
]
},
{
heading: "Phrase Structure 🧱",
subdirectory: "phrase-structure",
chapters: [
"heading": "Phrase Structure 🧱",
"subdirectory": "phrase-structure",
"chapters": [
{
import: BlocksAndKids,
slug: "blocks-and-kids",
"import": BlocksAndKids,
"slug": "blocks-and-kids"
},
{
import: NPIntro,
slug: "np",
"import": NPIntro,
"slug": "np"
},
{
import: APIntro,
slug: "ap",
"import": APIntro,
"slug": "ap"
},
{
import: EPIntro,
slug: "ep",
"import": EPIntro,
"slug": "ep"
},
{
import: VPIntro,
slug: "vp",
"import": VPIntro,
"slug": "vp"
},
{
import: Complement,
slug: "complement",
"import": Complement,
"slug": "complement"
},
{
import: ShorteningVPs,
slug: "shortening-vps",
},
],
"import": ShorteningVPs,
"slug": "shortening-vps"
}
]
},
{
heading: "Verbs",
subdirectory: "verbs",
chapters: [
"heading": "Verbs",
"subdirectory": "verbs",
"chapters": [
{
import: verbsIntro,
slug: "verbs-intro",
"import": verbsIntro,
"slug": "verbs-intro"
},
{
import: verbAspect,
slug: "verb-aspect",
"import": verbAspect,
"slug": "verb-aspect"
},
{
import: rootsAndStems,
slug: "roots-and-stems",
"import": rootsAndStems,
"slug": "roots-and-stems"
},
{
import: presentVerbs,
slug: "present-verbs",
"import": presentVerbs,
"slug": "present-verbs"
},
{
import: subjunctiveVerbs,
slug: "subjunctive-verbs",
"import": subjunctiveVerbs,
"slug": "subjunctive-verbs"
},
{
import: futureVerbs,
slug: "future-verbs",
"import": futureVerbs,
"slug": "future-verbs"
},
{
import: imperativeVerbs,
slug: "imperative-verbs",
"import": imperativeVerbs,
"slug": "imperative-verbs"
},
{
import: pastVerbs,
slug: "past-verbs",
"import": pastVerbs,
"slug": "past-verbs"
},
{
import: perfectVerbsIntro,
slug: "perfect-verbs-intro",
"import": perfectVerbsIntro,
"slug": "perfect-verbs-intro"
},
{
import: allPerfectVerbs,
slug: "all-perfect-verbs",
"import": allPerfectVerbs,
"slug": "all-perfect-verbs"
},
{
import: negativeVerbs,
slug: "negative-verbs",
"import": negativeVerbs,
"slug": "negative-verbs"
},
{
import: ability,
slug: "ability",
"import": ability,
"slug": "ability"
},
{
import: passiveVoice,
slug: "passive-voice",
"import": passiveVoice,
"slug": "passive-voice"
},
{
import: verbEndings,
slug: "verb-endings",
"import": verbEndings,
"slug": "verb-endings"
},
{
import: masterChart,
slug: "master-chart",
},
],
"import": masterChart,
"slug": "master-chart"
}
]
},
{
heading: "Compound Verbs",
subdirectory: "compound-verbs",
chapters: [
"heading": "Compound Verbs",
"subdirectory": "compound-verbs",
"chapters": [
{
import: compoundVerbsIntro,
slug: "intro",
"import": compoundVerbsIntro,
"slug": "intro"
},
{
import: helperVerbs,
slug: "helper-verbs",
"import": helperVerbs,
"slug": "helper-verbs"
},
{
import: stativeCompounds,
slug: "stative-compounds",
"import": stativeCompounds,
"slug": "stative-compounds"
},
{
import: dynamicCompounds,
slug: "dynamic-compounds",
"import": dynamicCompounds,
"slug": "dynamic-compounds"
},
{
import: moreOnCompounds,
slug: "more-on-compounds",
},
],
"import": moreOnCompounds,
"slug": "more-on-compounds"
}
]
},
{
heading: "Participles",
subdirectory: "participles",
chapters: [
"heading": "Participles",
"subdirectory": "participles",
"chapters": [
{
import: introToParticiples,
slug: "intro",
},
],
"import": introToParticiples,
"slug": "intro"
}
]
},
{
heading: "Pronouns",
subdirectory: "pronouns",
chapters: [
"heading": "Pronouns",
"subdirectory": "pronouns",
"chapters": [
{
import: pronounsBasic,
slug: "pronouns-basic",
"import": pronounsBasic,
"slug": "pronouns-basic"
},
{
import: pronounsMini,
slug: "pronouns-mini",
"import": pronounsMini,
"slug": "pronouns-mini"
},
{
import: directionalPronouns,
slug: "pronouns-directional",
},
],
"import": directionalPronouns,
"slug": "pronouns-directional"
}
]
},
{
heading: "Inflection 🔘",
subdirectory: "inflection",
chapters: [
"heading": "Inflection 🔘",
"subdirectory": "inflection",
"chapters": [
{
import: inflectionIntro,
slug: "inflection-intro",
"import": inflectionIntro,
"slug": "inflection-intro"
},
{
import: inflectionPatterns,
slug: "inflection-patterns",
},
],
"import": inflectionPatterns,
"slug": "inflection-patterns"
}
]
},
{
heading: "Sandwiches 🥪",
subdirectory: "sandwiches",
chapters: [
"heading": "Sandwiches 🥪",
"subdirectory": "sandwiches",
"chapters": [
{
import: sandwiches,
slug: "sandwiches",
},
],
"import": sandwiches,
"slug": "sandwiches"
}
]
},
{
heading: "Writing 🖊",
subdirectory: "writing",
chapters: [
"heading": "Writing 🖊",
"subdirectory": "writing",
"chapters": [
{
import: phonetics,
slug: "phonetics",
"import": phonetics,
"slug": "phonetics"
},
{
import: diacritics,
slug: "diacritics",
"import": diacritics,
"slug": "diacritics"
},
{
import: theFiveYeys,
slug: "the-five-yeys",
"import": theFiveYeys,
"slug": "the-five-yeys"
},
{
import: typingIssues,
slug: "typing-issues",
},
],
"import": typingIssues,
"slug": "typing-issues"
}
]
},
{
heading: "Recipes 👩‍🍳",
subdirectory: "recipes",
chapters: [
"heading": "Recipes 👩‍🍳",
"subdirectory": "recipes",
"chapters": [
{
import: unrealConditionals,
slug: "unreal-conditionals",
},
],
"import": unrealConditionals,
"slug": "unreal-conditionals"
}
]
},
{
heading: "Practice Tools 🔧",
subdirectory: "practice-tools",
chapters: [
"heading": "Practice Tools 🔧",
"subdirectory": "practice-tools",
"chapters": [
{
import: pronounPicker,
slug: "pronoun-picker",
},
],
"import": pronounPicker,
"slug": "pronoun-picker"
}
]
},
{
slug: "dictionary",
import: dictionary,
},
];
"import": dictionary,
"slug": "dictionary"
}
]/* content-tree */;
export const content = contentTree.map((item) => {
function prepareChapter(chp: any, subdir?: any) {

View File

@ -2356,6 +2356,11 @@ escape-string-regexp@^5.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
esprima@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.4.1.tgz#83059c751e9e9c41d228a41aaa1eef0ccce384ba"
integrity sha512-oQ5niex1XEkpjZhmW1zsozCG515481U0s+A1n6xU9usjkLSy7ZDvfuaAR+CKAKujczvEy7sOPIiX/GO+MZPk8Q==
estree-util-attach-comments@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz#ee44f4ff6890ee7dfb3237ac7810154c94c63f84"
@ -3272,6 +3277,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
loose-json@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/loose-json/-/loose-json-1.1.2.tgz#e86186d087c7ff81bc74067febfeaa747e1384e3"
integrity sha512-PzphlTCZdoR/cfXWN6TOKwxk9MibQmmQO6Rj4fblas+IbIWUwXhnad7E7qnWOE6ZuMZhwpmLWIUWiVy9C6UiMQ==
dependencies:
esprima "2.4.1"
lottie-web@^5.5.7:
version "5.10.2"
resolved "https://registry.yarnpkg.com/lottie-web/-/lottie-web-5.10.2.tgz#a1c952b6734759fcd369eba73b6b7e3d9a76ce0b"