Skip to content

Commit 518887e

Browse files
committed
feat(astro): support lessons without parts or chapters
1 parent ad6ad6b commit 518887e

17 files changed

+812
-464
lines changed

docs/tutorialkit.dev/src/content/docs/guides/creating-content.mdx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: Content creation
33
description: 'Creating content in TutorialKit.'
44
---
55
import { FileTree } from '@astrojs/starlight/components';
6+
import { Tabs, TabItem } from '@astrojs/starlight/components';
67

78
From an information architecture perspective, tutorial content is divided into **parts**, which are further divided into **chapters**, each consisting of **lessons**.
89

@@ -36,6 +37,65 @@ This structure is reflected in the directory structure of your TutorialKit proje
3637

3738
Navigate into one of these folders to see another folder that represents a **chapter**. Inside the chapter folder, you will find one or more **lesson** folders.
3839

40+
You can also omit parts and chapters, if your tutorial doesn't need that deep hierarchy.
41+
42+
<Tabs>
43+
<TabItem label="Structure">
44+
```plaintext
45+
- Lesson 1: Getting started
46+
- Lesson 2: Adding pages
47+
```
48+
</TabItem>
49+
50+
<TabItem label="File tree">
51+
<FileTree>
52+
- src
53+
- content
54+
- tutorial
55+
- getting-started
56+
- _files/
57+
- _solution/
58+
- content.md
59+
- adding-pages/
60+
- meta.md
61+
- config.ts
62+
- templates/
63+
</FileTree>
64+
</TabItem>
65+
</Tabs>
66+
67+
<Tabs>
68+
<TabItem label="Structure">
69+
```plaintext
70+
- Part 1: Introduction
71+
- Lesson 1: What is Vite?
72+
- Lesson 2: Installing
73+
- …
74+
- Part 2: Project structure
75+
- …
76+
```
77+
</TabItem>
78+
79+
<TabItem label="File tree">
80+
<FileTree>
81+
- src
82+
- content
83+
- tutorial
84+
- introduction/
85+
- what-is-vite/
86+
- _files/
87+
- _solution/
88+
- content.md
89+
- installing/
90+
- project-structure/
91+
- meta.md
92+
- config.ts
93+
- templates/
94+
</FileTree>
95+
</TabItem>
96+
</Tabs>
97+
98+
3999
## A lesson content file
40100

41101
Navigate to the `src/content/tutorial/1-basics/1-introduction/1-welcome` folder and open the `content.md` in your editor. You will see a file structured like this:

packages/astro/src/default/pages/index.astro

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,13 @@ import { joinPaths } from '../utils/url';
44
55
const tutorial = await getTutorial();
66
7-
const part = tutorial.parts[tutorial.firstPartId!];
8-
const chapter = part.chapters[part.firstChapterId!];
9-
const lesson = tutorial.lessons.find((l) => l.id === chapter.firstLessonId)!;
7+
const lesson = tutorial.lessons[0];
8+
const part = lesson.part && tutorial.parts[lesson.part.id];
9+
const chapter = lesson.chapter && part?.chapters[lesson.chapter.id];
1010
11-
if (!lesson) {
12-
throw new Error(
13-
`Unable to find lesson for ${JSON.stringify(
14-
{
15-
partId: tutorial.firstPartId || null,
16-
chapterId: part.firstChapterId || null,
17-
lessonId: chapter.firstLessonId || null,
18-
},
19-
null,
20-
2,
21-
)}`,
22-
);
23-
}
11+
const slug = [part?.slug, chapter?.slug, lesson.slug].filter(Boolean).join('/');
2412
25-
const redirect = joinPaths(import.meta.env.BASE_URL, `/${part.slug}/${chapter.slug}/${lesson.slug}`);
13+
const redirect = joinPaths(import.meta.env.BASE_URL, `/${slug}`);
2614
---
2715

2816
<!doctype html>

packages/astro/src/default/utils/__snapshots__/multiple-parts.json

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,6 @@
8181
"id": "1-first",
8282
"filepath": "1-part/1-chapter/1-first/content.md",
8383
"order": 0,
84-
"part": {
85-
"id": "1-part",
86-
"title": "Basics"
87-
},
88-
"chapter": {
89-
"id": "1-chapter",
90-
"title": "The first chapter in part 1"
91-
},
9284
"Markdown": "Markdown for tutorial",
9385
"slug": "lesson-slug",
9486
"files": [
@@ -99,6 +91,14 @@
9991
"1-part-1-chapter-1-first-solution.json",
10092
[]
10193
],
94+
"part": {
95+
"id": "1-part",
96+
"title": "Basics"
97+
},
98+
"chapter": {
99+
"id": "1-chapter",
100+
"title": "The first chapter in part 1"
101+
},
102102
"next": {
103103
"title": "Welcome to TutorialKit",
104104
"href": "/part-slug/chapter-slug/lesson-slug"
@@ -116,15 +116,7 @@
116116
},
117117
"id": "1-second",
118118
"filepath": "2-part/2-chapter/1-second/content.md",
119-
"order": 0,
120-
"part": {
121-
"id": "2-part",
122-
"title": "Basics"
123-
},
124-
"chapter": {
125-
"id": "2-chapter",
126-
"title": "The first chapter in part 1"
127-
},
119+
"order": 1,
128120
"Markdown": "Markdown for tutorial",
129121
"slug": "lesson-slug",
130122
"files": [
@@ -135,6 +127,14 @@
135127
"2-part-2-chapter-1-second-solution.json",
136128
[]
137129
],
130+
"part": {
131+
"id": "2-part",
132+
"title": "Basics"
133+
},
134+
"chapter": {
135+
"id": "2-chapter",
136+
"title": "The first chapter in part 1"
137+
},
138138
"prev": {
139139
"title": "Welcome to TutorialKit",
140140
"href": "/part-slug/chapter-slug/lesson-slug"
@@ -156,15 +156,7 @@
156156
},
157157
"id": "1-third",
158158
"filepath": "3-part/3-chapter/1-third/content.md",
159-
"order": 0,
160-
"part": {
161-
"id": "3-part",
162-
"title": "Basics"
163-
},
164-
"chapter": {
165-
"id": "3-chapter",
166-
"title": "The first chapter in part 1"
167-
},
159+
"order": 2,
168160
"Markdown": "Markdown for tutorial",
169161
"slug": "lesson-slug",
170162
"files": [
@@ -175,6 +167,14 @@
175167
"3-part-3-chapter-1-third-solution.json",
176168
[]
177169
],
170+
"part": {
171+
"id": "3-part",
172+
"title": "Basics"
173+
},
174+
"chapter": {
175+
"id": "3-chapter",
176+
"title": "The first chapter in part 1"
177+
},
178178
"prev": {
179179
"title": "Welcome to TutorialKit",
180180
"href": "/part-slug/chapter-slug/lesson-slug"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"parts": {},
3+
"lessons": [
4+
{
5+
"data": {
6+
"type": "lesson",
7+
"title": "Welcome to TutorialKit",
8+
"template": "default",
9+
"i18n": {
10+
"mocked": "default localization"
11+
},
12+
"openInStackBlitz": true
13+
},
14+
"id": "1-lesson",
15+
"filepath": "1-lesson/content.md",
16+
"order": 0,
17+
"Markdown": "Markdown for tutorial",
18+
"slug": "lesson-slug",
19+
"files": [
20+
"1-lesson-files.json",
21+
[]
22+
],
23+
"solution": [
24+
"1-lesson-solution.json",
25+
[]
26+
]
27+
}
28+
]
29+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"parts": {
3+
"1-part": {
4+
"id": "1-part",
5+
"order": 0,
6+
"data": {
7+
"type": "part",
8+
"title": "Basics"
9+
},
10+
"slug": "part-slug",
11+
"chapters": {}
12+
}
13+
},
14+
"lessons": [
15+
{
16+
"data": {
17+
"type": "lesson",
18+
"title": "Welcome to TutorialKit",
19+
"template": "default",
20+
"i18n": {
21+
"mocked": "default localization"
22+
},
23+
"openInStackBlitz": true
24+
},
25+
"id": "1-lesson",
26+
"filepath": "1-part/1-lesson/content.md",
27+
"order": 0,
28+
"Markdown": "Markdown for tutorial",
29+
"slug": "lesson-slug",
30+
"files": [
31+
"1-part-1-lesson-files.json",
32+
[]
33+
],
34+
"solution": [
35+
"1-part-1-lesson-solution.json",
36+
[]
37+
],
38+
"part": {
39+
"id": "1-part",
40+
"title": "Basics"
41+
}
42+
}
43+
],
44+
"firstPartId": "1-part"
45+
}

packages/astro/src/default/utils/__snapshots__/single-part-chapter-and-lesson.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,6 @@
3737
"id": "1-lesson",
3838
"filepath": "1-part/1-chapter/1-lesson/content.md",
3939
"order": 0,
40-
"part": {
41-
"id": "1-part",
42-
"title": "Basics"
43-
},
44-
"chapter": {
45-
"id": "1-chapter",
46-
"title": "The first chapter in part 1"
47-
},
4840
"Markdown": "Markdown for tutorial",
4941
"slug": "lesson-slug",
5042
"files": [
@@ -54,7 +46,15 @@
5446
"solution": [
5547
"1-part-1-chapter-1-lesson-solution.json",
5648
[]
57-
]
49+
],
50+
"part": {
51+
"id": "1-part",
52+
"title": "Basics"
53+
},
54+
"chapter": {
55+
"id": "1-chapter",
56+
"title": "The first chapter in part 1"
57+
}
5858
}
5959
],
6060
"firstPartId": "1-part"

packages/astro/src/default/utils/__snapshots__/single-part-chapter-and-multiple-lessons.json

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,6 @@
3737
"id": "1-first",
3838
"filepath": "1-part/1-chapter/1-first/content.md",
3939
"order": 0,
40-
"part": {
41-
"id": "1-part",
42-
"title": "Basics"
43-
},
44-
"chapter": {
45-
"id": "1-chapter",
46-
"title": "The first chapter in part 1"
47-
},
4840
"Markdown": "Markdown for tutorial",
4941
"slug": "lesson-slug",
5042
"files": [
@@ -55,6 +47,14 @@
5547
"1-part-1-chapter-1-first-solution.json",
5648
[]
5749
],
50+
"part": {
51+
"id": "1-part",
52+
"title": "Basics"
53+
},
54+
"chapter": {
55+
"id": "1-chapter",
56+
"title": "The first chapter in part 1"
57+
},
5858
"next": {
5959
"title": "Welcome to TutorialKit",
6060
"href": "/part-slug/chapter-slug/lesson-slug"
@@ -73,14 +73,6 @@
7373
"id": "2-second",
7474
"filepath": "1-part/1-chapter/2-second/content.md",
7575
"order": 1,
76-
"part": {
77-
"id": "1-part",
78-
"title": "Basics"
79-
},
80-
"chapter": {
81-
"id": "1-chapter",
82-
"title": "The first chapter in part 1"
83-
},
8476
"Markdown": "Markdown for tutorial",
8577
"slug": "lesson-slug",
8678
"files": [
@@ -91,6 +83,14 @@
9183
"1-part-1-chapter-2-second-solution.json",
9284
[]
9385
],
86+
"part": {
87+
"id": "1-part",
88+
"title": "Basics"
89+
},
90+
"chapter": {
91+
"id": "1-chapter",
92+
"title": "The first chapter in part 1"
93+
},
9494
"prev": {
9595
"title": "Welcome to TutorialKit",
9696
"href": "/part-slug/chapter-slug/lesson-slug"
@@ -113,14 +113,6 @@
113113
"id": "3-third",
114114
"filepath": "1-part/1-chapter/3-third/content.md",
115115
"order": 2,
116-
"part": {
117-
"id": "1-part",
118-
"title": "Basics"
119-
},
120-
"chapter": {
121-
"id": "1-chapter",
122-
"title": "The first chapter in part 1"
123-
},
124116
"Markdown": "Markdown for tutorial",
125117
"slug": "lesson-slug",
126118
"files": [
@@ -131,6 +123,14 @@
131123
"1-part-1-chapter-3-third-solution.json",
132124
[]
133125
],
126+
"part": {
127+
"id": "1-part",
128+
"title": "Basics"
129+
},
130+
"chapter": {
131+
"id": "1-chapter",
132+
"title": "The first chapter in part 1"
133+
},
134134
"prev": {
135135
"title": "Welcome to TutorialKit",
136136
"href": "/part-slug/chapter-slug/lesson-slug"

0 commit comments

Comments
 (0)