Add multi-page Ontology Guide documentation#12
Conversation
Add a 5-chapter beginner-friendly guide under /docs/guide covering ontology definitions, types, formats, syntaxes, and vocabularies with sidebar navigation, prev/next links, and code examples. Closes #11 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughIntroduces a comprehensive multi-page "Ontology Guide" under Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
app/docs/guide/layout.tsx (1)
1-8: Keep this layout server-rendered.This file doesn't use hooks or browser APIs, so the client directive looks unnecessary.
GuideSidebarcan stay client while the layout itself remains a Server Component.♻️ Proposed simplification
-"use client"; - import { GuideSidebar } from "@/components/docs/GuideSidebar"; export default function GuideLayout({ children }: { children: React.ReactNode }) { return (🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/docs/guide/layout.tsx` around lines 1 - 8, The file incorrectly declares the layout as a Client Component via the "use client" directive even though it doesn't use hooks or browser APIs; remove the "use client" line so GuideLayout becomes a Server Component, keep the import of GuideSidebar (which can remain a client component) and ensure nothing else introduces client-only APIs in the GuideLayout function or its returned JSX.components/docs/GuideSidebar.tsx (1)
21-29: Expose the active chapter to assistive tech.The selected state is visual only right now. Adding
aria-current="page"to the active link makes the current chapter clear to screen-reader users too.♿ Proposed tweak
<Link key={chapter.slug} href={href} + aria-current={isActive ? "page" : undefined} className={cn( "flex items-start gap-2.5 px-3 py-2 rounded-md text-sm transition-colors", isActive🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/docs/GuideSidebar.tsx` around lines 21 - 29, The active link is only visual; update the Link rendering (the Link with key={chapter.slug} that uses href and className and the isActive variable) to set aria-current="page" when isActive is true (omit the attribute or set it to undefined/false when not active) so assistive tech can announce the current chapter; ensure the attribute is applied to the same Link element that receives the conditional classes.app/docs/guide/vocabularies/page.tsx (1)
211-217: Consider addingscopeattributes to table headers for improved accessibility.Same suggestion as the Types page — adding
scope="col"to the header cells improves screen reader navigation.♿ Suggested accessibility improvement
<thead className="bg-slate-50 dark:bg-slate-700"> <tr> - <th className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Vocabulary</th> - <th className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Prefix</th> - <th className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Purpose</th> + <th scope="col" className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Vocabulary</th> + <th scope="col" className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Prefix</th> + <th scope="col" className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Purpose</th> </tr> </thead>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/docs/guide/vocabularies/page.tsx` around lines 211 - 217, The table header cells in the vocabularies page's JSX (the three <th> elements in the table header row inside page.tsx) are missing accessibility scope attributes; update each header element (the "Vocabulary", "Prefix", and "Purpose" <th> nodes) to include scope="col" so screen readers can correctly associate column headers with data cells, ensuring you use the JSX/TSX attribute syntax (scope="col") on those specific <th> elements.app/docs/guide/types/page.tsx (1)
130-137: Consider addingscopeattributes to table headers for improved accessibility.Screen readers benefit from explicit
scope="col"on column headers to better associate data cells with their headers.♿ Suggested accessibility improvement
<thead className="bg-slate-50 dark:bg-slate-700"> <tr> - <th className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Type</th> - <th className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Expressiveness</th> - <th className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Reasoning</th> - <th className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Example</th> + <th scope="col" className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Type</th> + <th scope="col" className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Expressiveness</th> + <th scope="col" className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Reasoning</th> + <th scope="col" className="px-4 py-3 text-left font-medium text-slate-900 dark:text-white">Example</th> </tr> </thead>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/docs/guide/types/page.tsx` around lines 130 - 137, The table header cells in the Types guide component (the <table> block with header <thead> and <th> elements) are missing scope attributes for accessibility; update each column header (<th> elements for "Type", "Expressiveness", "Reasoning", "Example") to include scope="col" so screen readers can correctly associate headers with data cells—modify the <th> elements in the page.tsx table header to add scope="col" to each header.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/docs/guide-chapters.ts`:
- Around line 8-52: getAdjacentChapters currently treats a missing slug
(findIndex === -1) as index -1 and returns prev:null but next:
guideChapters[0]; update getAdjacentChapters to check for index === -1 first and
return { prev: null, next: null } (or another explicit sentinel) before
computing neighbors so typos or unknown slugs do not incorrectly show the first
chapter; modify the function using the existing guideChapters and the index
variable to implement this early-return.
---
Nitpick comments:
In `@app/docs/guide/layout.tsx`:
- Around line 1-8: The file incorrectly declares the layout as a Client
Component via the "use client" directive even though it doesn't use hooks or
browser APIs; remove the "use client" line so GuideLayout becomes a Server
Component, keep the import of GuideSidebar (which can remain a client component)
and ensure nothing else introduces client-only APIs in the GuideLayout function
or its returned JSX.
In `@app/docs/guide/types/page.tsx`:
- Around line 130-137: The table header cells in the Types guide component (the
<table> block with header <thead> and <th> elements) are missing scope
attributes for accessibility; update each column header (<th> elements for
"Type", "Expressiveness", "Reasoning", "Example") to include scope="col" so
screen readers can correctly associate headers with data cells—modify the <th>
elements in the page.tsx table header to add scope="col" to each header.
In `@app/docs/guide/vocabularies/page.tsx`:
- Around line 211-217: The table header cells in the vocabularies page's JSX
(the three <th> elements in the table header row inside page.tsx) are missing
accessibility scope attributes; update each header element (the "Vocabulary",
"Prefix", and "Purpose" <th> nodes) to include scope="col" so screen readers can
correctly associate column headers with data cells, ensuring you use the JSX/TSX
attribute syntax (scope="col") on those specific <th> elements.
In `@components/docs/GuideSidebar.tsx`:
- Around line 21-29: The active link is only visual; update the Link rendering
(the Link with key={chapter.slug} that uses href and className and the isActive
variable) to set aria-current="page" when isActive is true (omit the attribute
or set it to undefined/false when not active) so assistive tech can announce the
current chapter; ensure the attribute is applied to the same Link element that
receives the conditional classes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1b060e37-5120-473c-83db-7c78b58c753e
📒 Files selected for processing (11)
app/docs/guide/formats/page.tsxapp/docs/guide/introduction/page.tsxapp/docs/guide/layout.tsxapp/docs/guide/page.tsxapp/docs/guide/syntax/page.tsxapp/docs/guide/types/page.tsxapp/docs/guide/vocabularies/page.tsxapp/docs/layout.tsxcomponents/docs/GuidePrevNext.tsxcomponents/docs/GuideSidebar.tsxlib/docs/guide-chapters.ts
| export const guideChapters: GuideChapter[] = [ | ||
| { | ||
| slug: "introduction", | ||
| title: "What is an Ontology?", | ||
| shortTitle: "Introduction", | ||
| description: | ||
| "Learn what ontologies are, why they matter, and how they power the Semantic Web.", | ||
| }, | ||
| { | ||
| slug: "types", | ||
| title: "What are the Types of Ontologies?", | ||
| shortTitle: "Types", | ||
| description: | ||
| "Explore the spectrum from lightweight taxonomies to heavyweight formal ontologies.", | ||
| }, | ||
| { | ||
| slug: "formats", | ||
| title: "What are the Ontology Formats?", | ||
| shortTitle: "Formats", | ||
| description: | ||
| "Understand RDF serialization formats like Turtle, RDF/XML, JSON-LD, and more.", | ||
| }, | ||
| { | ||
| slug: "syntax", | ||
| title: "What is an Ontology Syntax?", | ||
| shortTitle: "Syntax", | ||
| description: | ||
| "Compare Manchester Syntax, Functional Syntax, OWL/XML, and Turtle for expressing OWL.", | ||
| }, | ||
| { | ||
| slug: "vocabularies", | ||
| title: "What is an Ontology Vocabulary?", | ||
| shortTitle: "Vocabularies", | ||
| description: | ||
| "Discover standard vocabularies like RDFS, Dublin Core, SKOS, FOAF, and Schema.org.", | ||
| }, | ||
| ]; | ||
|
|
||
| export function getAdjacentChapters(currentSlug: string) { | ||
| const index = guideChapters.findIndex((c) => c.slug === currentSlug); | ||
| return { | ||
| prev: index > 0 ? guideChapters[index - 1] : null, | ||
| next: index < guideChapters.length - 1 ? guideChapters[index + 1] : null, | ||
| }; | ||
| } |
There was a problem hiding this comment.
Handle unknown slugs before computing neighbors.
findIndex() returns -1 for an unknown slug, so this helper currently returns { prev: null, next: guideChapters[0] }. A typo in currentSlug would silently render “Introduction” as the next chapter instead of no pagination.
💡 Proposed fix
export interface GuideChapter {
slug: string;
title: string;
shortTitle: string;
description: string;
}
-export const guideChapters: GuideChapter[] = [
+export const guideChapters = [
{
slug: "introduction",
title: "What is an Ontology?",
shortTitle: "Introduction",
@@
{
slug: "vocabularies",
title: "What is an Ontology Vocabulary?",
shortTitle: "Vocabularies",
description:
"Discover standard vocabularies like RDFS, Dublin Core, SKOS, FOAF, and Schema.org.",
},
-];
+ ] as const satisfies readonly GuideChapter[];
+
+export type GuideChapterSlug = (typeof guideChapters)[number]["slug"];
-export function getAdjacentChapters(currentSlug: string) {
+export function getAdjacentChapters(currentSlug: GuideChapterSlug) {
const index = guideChapters.findIndex((c) => c.slug === currentSlug);
+ if (index === -1) {
+ return { prev: null, next: null };
+ }
+
return {
prev: index > 0 ? guideChapters[index - 1] : null,
next: index < guideChapters.length - 1 ? guideChapters[index + 1] : null,
};
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const guideChapters: GuideChapter[] = [ | |
| { | |
| slug: "introduction", | |
| title: "What is an Ontology?", | |
| shortTitle: "Introduction", | |
| description: | |
| "Learn what ontologies are, why they matter, and how they power the Semantic Web.", | |
| }, | |
| { | |
| slug: "types", | |
| title: "What are the Types of Ontologies?", | |
| shortTitle: "Types", | |
| description: | |
| "Explore the spectrum from lightweight taxonomies to heavyweight formal ontologies.", | |
| }, | |
| { | |
| slug: "formats", | |
| title: "What are the Ontology Formats?", | |
| shortTitle: "Formats", | |
| description: | |
| "Understand RDF serialization formats like Turtle, RDF/XML, JSON-LD, and more.", | |
| }, | |
| { | |
| slug: "syntax", | |
| title: "What is an Ontology Syntax?", | |
| shortTitle: "Syntax", | |
| description: | |
| "Compare Manchester Syntax, Functional Syntax, OWL/XML, and Turtle for expressing OWL.", | |
| }, | |
| { | |
| slug: "vocabularies", | |
| title: "What is an Ontology Vocabulary?", | |
| shortTitle: "Vocabularies", | |
| description: | |
| "Discover standard vocabularies like RDFS, Dublin Core, SKOS, FOAF, and Schema.org.", | |
| }, | |
| ]; | |
| export function getAdjacentChapters(currentSlug: string) { | |
| const index = guideChapters.findIndex((c) => c.slug === currentSlug); | |
| return { | |
| prev: index > 0 ? guideChapters[index - 1] : null, | |
| next: index < guideChapters.length - 1 ? guideChapters[index + 1] : null, | |
| }; | |
| } | |
| export const guideChapters = [ | |
| { | |
| slug: "introduction", | |
| title: "What is an Ontology?", | |
| shortTitle: "Introduction", | |
| description: | |
| "Learn what ontologies are, why they matter, and how they power the Semantic Web.", | |
| }, | |
| { | |
| slug: "types", | |
| title: "What are the Types of Ontologies?", | |
| shortTitle: "Types", | |
| description: | |
| "Explore the spectrum from lightweight taxonomies to heavyweight formal ontologies.", | |
| }, | |
| { | |
| slug: "formats", | |
| title: "What are the Ontology Formats?", | |
| shortTitle: "Formats", | |
| description: | |
| "Understand RDF serialization formats like Turtle, RDF/XML, JSON-LD, and more.", | |
| }, | |
| { | |
| slug: "syntax", | |
| title: "What is an Ontology Syntax?", | |
| shortTitle: "Syntax", | |
| description: | |
| "Compare Manchester Syntax, Functional Syntax, OWL/XML, and Turtle for expressing OWL.", | |
| }, | |
| { | |
| slug: "vocabularies", | |
| title: "What is an Ontology Vocabulary?", | |
| shortTitle: "Vocabularies", | |
| description: | |
| "Discover standard vocabularies like RDFS, Dublin Core, SKOS, FOAF, and Schema.org.", | |
| }, | |
| ] as const satisfies readonly GuideChapter[]; | |
| export type GuideChapterSlug = (typeof guideChapters)[number]["slug"]; | |
| export function getAdjacentChapters(currentSlug: GuideChapterSlug) { | |
| const index = guideChapters.findIndex((c) => c.slug === currentSlug); | |
| if (index === -1) { | |
| return { prev: null, next: null }; | |
| } | |
| return { | |
| prev: index > 0 ? guideChapters[index - 1] : null, | |
| next: index < guideChapters.length - 1 ? guideChapters[index + 1] : null, | |
| }; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@lib/docs/guide-chapters.ts` around lines 8 - 52, getAdjacentChapters
currently treats a missing slug (findIndex === -1) as index -1 and returns
prev:null but next: guideChapters[0]; update getAdjacentChapters to check for
index === -1 first and return { prev: null, next: null } (or another explicit
sentinel) before computing neighbors so typos or unknown slugs do not
incorrectly show the first chapter; modify the function using the existing
guideChapters and the index variable to implement this early-return.
Summary
/docs/guidewith sidebar navigation and prev/next chapter linksCloses #11
Test plan
/docs/guidelanding page renders card grid with all 5 chaptersnpm run lint && npm run type-check && npm run build— all pass🤖 Generated with Claude Code
Summary by CodeRabbit