Skip to content

Commit a09ad27

Browse files
committed
feat: piml for stories
1 parent 5eb80f4 commit a09ad27

File tree

6 files changed

+139
-87
lines changed

6 files changed

+139
-87
lines changed

public/stories/README.md

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,79 @@
11
# fezcodex.stories
22

3-
This directory contains the stories content for Fezcodex, structured to be easily consumed by the application.
3+
This directory contains the **stories** content for Fezcodex, structured to be easily consumed by the application.
44

55
## Directory Structure
66

77
The content is organized as follows:
88

99
```
1010
public/stories/
11-
├── books.json
11+
├── books.piml
1212
└── [book-directory-name]/
1313
├── episode1.txt
1414
└── episode2.txt
1515
└── ...
1616
```
1717

18-
* `books.json`: This JSON file serves as the main index for all D&D books and their respective episodes.
18+
* `books.piml`: This PIML file serves as the main index for all story books, authors, and their respective episodes.
1919
* `[book-directory-name]/`: Each book's individual episode content files are stored in their own dedicated subdirectories. For example, `book-one/` would contain episodes for "Book One".
2020
* `episodeX.txt`: These are plain text files containing the actual narrative content for each episode.
2121

22-
## Book Structure (books.json)
23-
24-
The `books.json` file is an array of book objects. Each book object defines a collection of episodes and their metadata.
25-
26-
```json
27-
[
28-
{
29-
"bookId": 1,
30-
"bookTitle": "Book One: The Shadowed Path",
31-
"episodes": [
32-
{
33-
"id": 1,
34-
"filename": "book-one/episode1.txt",
35-
"title": "Episode 1: The Whispering Woods",
36-
"author": "fezcode"
37-
},
38-
{
39-
"id": 2,
40-
"filename": "book-one/episode2.txt",
41-
"title": "Episode 2: The Goblin Ambush",
42-
"author": "fezcode"
43-
}
44-
],
45-
"overlay": "red"
46-
},
47-
// ... more book objects
48-
]
22+
## Book and Author Structure (books.piml)
23+
24+
The `books.piml` file is a PIML document that, when parsed, results in an object containing `authors` and `books` arrays.
25+
26+
```piml
27+
(authors)
28+
> (author)
29+
(name) fezcode
30+
(website) https://fezcode.com
31+
32+
(books)
33+
> (book)
34+
(bookId) 1
35+
(bookTitle) Book One: The Shadowed Path
36+
(episodes)
37+
> (item)
38+
(id) 1
39+
(filename) book-one/episode1.txt
40+
(title) Episode 1: The Whispering Woods
41+
(author) fezcode
42+
> (item)
43+
(id) 2
44+
(filename) book-one/episode2.txt
45+
(title) Episode 2: The Goblin Ambush
46+
(author) fezcode
47+
(overlay) red
48+
49+
> (book)
50+
(bookId) 2
51+
(bookTitle) Book Two: Separated Riches
52+
(episodes)
53+
> (item)
54+
(id) 1
55+
(filename) book-one/episode1.txt
56+
(title) Episode 1: The Whispering Woods
57+
(author) fezcode
58+
> (item)
59+
(id) 2
60+
(filename) book-one/episode2.txt
61+
(title) Episode 2: The Goblin Ambush
62+
(author) fezcode
63+
(overlay) blue
64+
# ... more book objects
4965
```
5066

67+
### Root Object Properties:
68+
69+
* `authors` (Array): An array of author objects.
70+
* `books` (Array): An array of book objects.
71+
72+
### Author Object Properties:
73+
74+
* `name` (String): The name of the author.
75+
* `website` (String, Optional): The website or URL associated with the author.
76+
5177
### Book Object Properties:
5278

5379
* `bookId` (Number): A unique identifier for the book.
@@ -62,4 +88,4 @@ The `books.json` file is an array of book objects. Each book object defines a co
6288
* `title` (String): The title of the episode.
6389
* `author` (String): The author of the episode.
6490

65-
This structure allows the application to dynamically load and display D&D campaign content, organizing it into books and episodes with associated metadata.
91+
This structure allows the application to dynamically load and display story content, organizing it into books and episodes with associated metadata, and also provides a central place for author information.

public/stories/books.json

Lines changed: 0 additions & 49 deletions
This file was deleted.

public/stories/books.piml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
(authors)
2+
> (author)
3+
(name) fezcode
4+
(website) https://fezcode.com
5+
6+
(books)
7+
> (book)
8+
(bookId) 1
9+
(bookTitle) Book One: The Shadowed Path
10+
(episodes)
11+
> (item)
12+
(id) 1
13+
(filename) book-one/episode1.txt
14+
(title) Episode 1: The Whispering Woods
15+
(author) fezcode
16+
> (item)
17+
(id) 2
18+
(filename) book-one/episode2.txt
19+
(title) Episode 2: The Goblin Ambush
20+
(author) fezcode
21+
(overlay) red
22+
23+
> (book)
24+
(bookId) 2
25+
(bookTitle) Book Two: Separated Riches
26+
(episodes)
27+
> (item)
28+
(id) 1
29+
(filename) book-one/episode1.txt
30+
(title) Episode 1: The Whispering Woods
31+
(author) fezcode
32+
> (item)
33+
(id) 2
34+
(filename) book-one/episode2.txt
35+
(title) Episode 2: The Goblin Ambush
36+
(author) fezcode
37+
(overlay) blue
38+
39+
> (book)
40+
(bookId) 3
41+
(bookTitle) Book Three: Separated Riches
42+
(episodes)
43+
> (item)
44+
(id) 1
45+
(filename) book-one/episode1.txt
46+
(title) Episode 1: The Whispering Woods
47+
(author) fezcode
48+
> (item)
49+
(id) 2
50+
(filename) book-one/episode2.txt
51+
(title) Episode 2: The Goblin Ambush
52+
(author) fezcode
53+
(overlay) black
54+
55+
> (book)
56+
(bookId) 4
57+
(bookTitle) Book Four: Separated Riches
58+
(episodes)
59+
> (item)
60+
(id) 1
61+
(filename) book-one/episode1.txt
62+
(title) Episode 1: The Whispering Woods
63+
(author) fezcode
64+
> (item)
65+
(id) 2
66+
(filename) book-one/episode2.txt
67+
(title) Episode 2: The Goblin Ambush
68+
(author) fezcode
69+
(overlay) green

src/pages/DndBookPage.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { DndContext } from '../context/DndContext'; // Import DndContext
66
import { parseWallpaperName } from '../utils/dndUtils'; // Import parseWallpaperName
77
import dndWallpapers from '../utils/dndWallpapers';
88
import useSeo from "../hooks/useSeo";
9+
import piml from 'piml';
910

1011
const pageVariants = {
1112
initial: {
@@ -48,11 +49,12 @@ function DndBookPage() {
4849
useEffect(() => {
4950
const fetchBookData = async () => {
5051
try {
51-
const response = await fetch(`${process.env.PUBLIC_URL}/stories/books.json`);
52+
const response = await fetch(`${process.env.PUBLIC_URL}/stories/books.piml`);
5253
if (!response.ok) {
5354
throw new Error(`HTTP error! status: ${response.status}`);
5455
}
55-
const data = await response.json();
56+
const pimlText = await response.text();
57+
const data = piml.parse(pimlText);
5658
const foundBook = data.books.find(b => b.bookId === parseInt(bookId));
5759
if (foundBook) {
5860
setBook(foundBook);

src/pages/DndEpisodePage.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { DndContext } from '../context/DndContext'; // Import DndContext
66
import { parseWallpaperName } from '../utils/dndUtils'; // Import parseWallpaperName
77
import dndWallpapers from '../utils/dndWallpapers';
88
import useSeo from "../hooks/useSeo";
9+
import piml from 'piml';
910

1011
const pageVariants = {
1112
initial: {
@@ -58,11 +59,12 @@ function DndEpisodePage() {
5859
useEffect(() => {
5960
const fetchAllBooks = async () => { // Renamed function
6061
try {
61-
const response = await fetch(`${process.env.PUBLIC_URL}/stories/books.json`);
62+
const response = await fetch(`${process.env.PUBLIC_URL}/stories/books.piml`);
6263
if (!response.ok) {
6364
throw new Error(`HTTP error! status: ${response.status}`);
6465
}
65-
const data = await response.json();
66+
const pimlText = await response.text();
67+
const data = piml.parse(pimlText);
6668
setAllBooks(data.books);
6769
} catch (error) {
6870
console.error("Failed to fetch all books:", error);
@@ -90,7 +92,7 @@ function DndEpisodePage() {
9092
// Fetch episode content
9193
const fetchEpisodeContent = async () => {
9294
try {
93-
const response = await fetch(`${process.env.PUBLIC_URL}/dnd/${currentEpisode.filename}`);
95+
const response = await fetch(`${process.env.PUBLIC_URL}/stories/${currentEpisode.filename}`);
9496
if (!response.ok) {
9597
throw new Error(`HTTP error! status: ${response.status}`);
9698
}

src/pages/DndLorePage.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Slider from 'react-slick'; // Import Slider
1010
import 'slick-carousel/slick/slick.css'; // Import slick-carousel CSS
1111
import 'slick-carousel/slick/slick-theme.css'; // Import slick-carousel theme CSS
1212
import useSeo from "../hooks/useSeo";
13+
import piml from 'piml';
1314

1415
const pageVariants = {
1516
initial: {
@@ -60,11 +61,12 @@ function DndLorePage() {
6061
useEffect(() => {
6162
const fetchEpisodes = async () => {
6263
try {
63-
const response = await fetch(`${process.env.PUBLIC_URL}/stories/books.json`);
64+
const response = await fetch(`${process.env.PUBLIC_URL}/stories/books.piml`);
6465
if (!response.ok) {
6566
throw new Error(`HTTP error! status: ${response.status}`);
6667
}
67-
const data = await response.json();
68+
const pimlText = await response.text();
69+
const data = piml.parse(pimlText);
6870
setEpisodes(data.books);
6971
} catch (error) {
7072
console.error("Failed to fetch episodes:", error);

0 commit comments

Comments
 (0)