Skip to content

Commit 0eeb366

Browse files
authored
feat: implement base dictionary - second iteration (#51)
This Pull Request implements the second iteration of the base dictionary, it refactors the dictionary word directory, implements the dictionary api `v1` and refactors all related integration in acknowledgement of the change. ### Changes Made - Moved all words from the `pages/browse` directory to the `content/dictionary` directory as required for content collection - Implemented static output builder in the `pages/browse/[...slug]` path of the directory via integration of Astro Content Collection (with `getCollection` and `getStaticPaths`); hence converting the `pages/browse` to a directory that holds routes auto generated from the `content/dictionary` directory at build time. - Replace `Astro.glob` with `getCollection` as function used to compute value for the `dictionary` object consumed by the `search` island in `word.astro` layout and homepage. - Modified computation of `editUrl` value on the `word.astro` layout in acknowledgement of the new integration - Modified the `search` island dictionary index store in acknowledgement of the new integration - Implemented the basic `v1` of the jargons browser (dictionary) api with 2 endpoints/routes - `api/v1/browse` - this endpoint returns a list of all words/jargons in the dictionary - `api/v1/browse/[...slug]` - this endpoint take the specified `slug` and returns a word with matching slug in the dictionary ### Screencast [screencast-bpconcjcammlapcogcnnelfmaeghhagj-2024.04.20-21_57_44.webm](https://github.com/babblebey/jargons.dev/assets/25631971/9948b9aa-51fd-4119-8188-3ad7c7965e11) 📖
1 parent 904bb11 commit 0eeb366

12 files changed

Lines changed: 95 additions & 14 deletions

File tree

src/components/islands/search.jsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const searchIndex = new Flexsearch.Document({
1111
cache: 100,
1212
document: {
1313
index: "title",
14-
store: ["title", "url"]
14+
store: ["title", "slug"]
1515
},
1616
tokenize: "full"
1717
});
@@ -23,14 +23,12 @@ const searchIndex = new Flexsearch.Document({
2323
export default function Search({ triggerSize, dictionary }) {
2424
const isSearchOpen = useStore($isSearchOpen);
2525

26-
let idx = 0;
2726
for (const word of dictionary) {
2827
searchIndex.add({
29-
id: idx,
30-
title: word.frontmatter.title,
31-
url: word.url
28+
id: word.id,
29+
title: word.data.title,
30+
slug: word.slug
3231
});
33-
idx++;
3432
}
3533

3634
return (
@@ -226,7 +224,7 @@ const SearchInfo = () => (
226224

227225
/**
228226
* Search result
229-
* @param {{ result: Array<{ id: number, doc: { title: string, url: string }, searchTerm: string }> }} props
227+
* @param {{ result: Array<{ id: number, doc: { title: string, slug: string }, searchTerm: string }> }} props
230228
*/
231229
function SearchResult({ result = [], cursor, searchTerm }) {
232230
const router = useRouter();
@@ -241,7 +239,10 @@ function SearchResult({ result = [], cursor, searchTerm }) {
241239
) : (
242240
result.map(({ doc }, i) => (
243241
<a key={i}
244-
href={doc.url}
242+
/**
243+
* @todo find better ways - don't hardcode `browse` string to the word slug
244+
*/
245+
href={`browse/${doc.slug}`}
245246
onClick={(e) => {
246247
e.preventDefault();
247248
$addToRecentSearchesFn({
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/layouts/word.astro

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
---
22
import BaseLayout from "./base.astro";
3+
import { getCollection } from "astro:content";
34
import Navbar from "../components/navbar.astro";
45
import Search from "../components/islands/search.jsx";
56
67
const { frontmatter } = Astro.props;
7-
const dictionary = await Astro.glob("../pages/browse/*.mdx");
8-
const editUrl = `/editor/edit/${frontmatter.url.split("/")[2]}`;
8+
const dictionary = await getCollection("dictionary");
9+
10+
/**
11+
* @todo implement a better way to resolve the `slug` used in the `editUrl`
12+
* `frontmatter.url.split("/")*****` will not scale when we bring in internationalization
13+
*/
14+
const editUrl = `/editor/edit/${frontmatter.url.split("/")[3].split(".")[0]}`;
915
---
1016

1117
<BaseLayout pageTitle={ frontmatter.title }>

src/lib/templates/word.md.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ export default `---
22
layout: ../../layouts/word.astro
33
title: "$title"
44
---
5-
65
$content`

src/lib/word-editor.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export async function writeNewWord(userOctokit, forkedRepoDetails, { title, cont
2323
owner: repoOwner,
2424
repo: repoName,
2525
branch,
26-
path: `src/pages/browse/${normalizeAsUrl(title)}.mdx`,
26+
path: `src/content/dictionary/${normalizeAsUrl(title)}.mdx`,
2727
content: content_encoded,
2828
message: `word: commit to "${title}"`
2929
});
@@ -83,7 +83,7 @@ export async function getExistingWord(userOctokit, repoDetails, wordTitle) {
8383
owner: repoOwner,
8484
repo: repoName,
8585
ref: repoBranchRef,
86-
path: `src/pages/browse/${normalizeAsUrl(wordTitle)}.mdx`,
86+
path: `src/content/dictionary/${normalizeAsUrl(wordTitle)}.mdx`,
8787
});
8888

8989
const { content, ...responseData } = response.data;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { getEntry } from "astro:content";
2+
3+
/**
4+
* Get a jargon (word) from the dictionary
5+
* @param {import("astro").APIContext} context
6+
*/
7+
export async function GET({ params: { slug } }) {
8+
const word = await getEntry("dictionary", slug);
9+
10+
if (!word) {
11+
return new Response(JSON.stringify({ message: "Not Found" }), {
12+
status: 404,
13+
headers: {
14+
"Content-type": "application/json"
15+
}
16+
});
17+
}
18+
19+
const response = {
20+
slug: word.slug,
21+
title: word.data.title,
22+
content: word.body
23+
}
24+
25+
return new Response(JSON.stringify(response), {
26+
status: 200,
27+
headers: {
28+
"Content-type": "application/json"
29+
}
30+
});
31+
}

src/pages/api/v1/browse/index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { getCollection } from "astro:content";
2+
3+
/**
4+
* Get all jargons (word) from the dictionary
5+
* @param {import("astro").APIContext} context
6+
*
7+
* @todo implement pagination
8+
*/
9+
export async function GET() {
10+
const dictionary = await getCollection("dictionary");
11+
const response = dictionary.map(word => {
12+
return {
13+
slug: word.slug,
14+
title: word.data.title,
15+
content: word.body
16+
}
17+
});
18+
19+
return new Response(JSON.stringify(response), {
20+
status: 200,
21+
headers: {
22+
"Content-type": "application/json"
23+
}
24+
});
25+
}

0 commit comments

Comments
 (0)