Skip to content

Commit

Permalink
feat: 🧑‍💻 Add dynamic tutorial lists (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
fergcb authored Sep 19, 2023
1 parent 40bba28 commit f9bde99
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
11 changes: 7 additions & 4 deletions docs/tutorials/index.md → docs/tutorials/index.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import TutorialsList from "@site/src/components/TutorialsList"

# Tutorials

Welcome to the tutorials section of the documentation. Here you will find a collection of tutorials that will help you get started with the API.
Expand All @@ -8,17 +10,18 @@ The currently available tutorials are:

Beginner tutorials are designed to help you get started programming using the API as a learning environment. They are intended for people who have done little to no programming and are completely new to APIs.

- [Getting Started](./beginner/getting-started.md)
<TutorialsList category="beginner" />

## Basic

Basic tutorials are designed to help you get started with the API. They are intended for people who have done some programming and are new to the API.

- [Discover D&D Races with Shell Scripting](./basic/discover-dnd-races-with-shell-scripting.mdx)
<TutorialsList category="basic" />


## Advanced

Advanced tutorials are designed to help you build more complex applications with the API. They are intended for developers who are comfortable with programming and want to build more advanced applications.

- [Monster Search with Javascript](./advanced/monster-search-with-javascript.mdx)
- [Terminal Spellbook with Python](./advanced/terminal-spellbook-with-python.mdx)
<TutorialsList category="advanced" />

4 changes: 3 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ const config = {
}),
],
],

plugins: [
"./src/plugins/dynamic-tutorials-list"
],
themeConfig:
/** @type {import('docusaurus-preset-openapi').ThemeConfig} */
({
Expand Down
16 changes: 16 additions & 0 deletions src/components/TutorialsList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'
import { usePluginData } from '@docusaurus/useGlobalData'

export default function TutorialsList({ category }) {
const { categories } = usePluginData('dynamic-tutorials-list');

return (
<ul>
{ categories[category].map(tutorial => (
<li key={tutorial.name}>
<a href={tutorial.href}>{ tutorial.title }</a>
</li>
)) }
</ul>
)
}
43 changes: 43 additions & 0 deletions src/plugins/dynamic-tutorials-list/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const path = require('path')
const fs = require('fs')

function makeTitle(name) {
return name.split(/\W+/)
.map(word => word.length > 3 ? word.charAt(0).toUpperCase() + word.substring(1) : word)
.join(" ")
}

function readCategories(dir) {
return Object.fromEntries(
fs.readdirSync(dir, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => [dirent.name, readCategory(dirent)])
);
}

function readCategory(dirent) {
const dir = path.join(dirent.path, dirent.name);

return fs.readdirSync(dir)
.filter(file => /\.mdx?/.test(file))
.map(file => {
const name = file.substring(0, file.lastIndexOf('.'));
const filePath = path.join(dir, file);
const contents = fs.readFileSync(filePath).toString();
const title = contents.match(/\#[^\r\n]+/)?.[0]?.substring(1)?.trim()
?? makeTitle(name);
const href = `/docs/docs/tutorials/${dirent.name}/${name}`
return { name, title, href };
})
}

module.exports = async function dynamicTutorialsPlugin({ siteDir }) {
return {
name: 'dynamic-tutorials-list',
async contentLoaded({ actions }) {
const tutorialsDir = path.join(siteDir, '/docs/tutorials');
const categories = readCategories(tutorialsDir);
actions.setGlobalData({ categories });
}
}
}

0 comments on commit f9bde99

Please sign in to comment.