Skip to content

feat(astro): add custom configuration option for passing custom fields #378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,28 @@ type TemplateType = "html" | "node" | "angular-cli" | "create-react-app" | "java

```

##### `custom`

Assign custom fields to a chapter/part/lesson.
<PropertyTable inherited type="Record<string,any>" />

This is useful when you want to consume items for the default `tutorial` collection
in order to implement custom features.

```yaml
custom:
publishedAt: 2024-16-10
tags: tutorialkit,astro,vite
```

```ts
import { getCollection } from 'astro:content';
const collection = await getCollection('tutorial');
for (const entry of collection) {
console.log("This part was published at:", entry.data?.custom?.publishedAt)
}
```

## Configure the Tutorialkit Astro integration

`@tutorialkit/astro` is an integration for Astro. You can configure the integration in your `astro.config.ts` file.
Expand Down
11 changes: 11 additions & 0 deletions e2e/src/components/CustomMetadata.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
import { getCollection } from 'astro:content';
const collection = await getCollection('tutorial');

const lesson = collection.find((c) => c.data.type === 'lesson' && c.slug.startsWith(Astro.params.slug!))!;
const { custom } = lesson.data;
---

<h2>Custom metadata</h2>

<pre>{JSON.stringify(custom, null,2)}</pre>
15 changes: 15 additions & 0 deletions e2e/src/content/tutorial/tests/metadata/custom/content.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
type: lesson
title: Custom
terminal:
panels: terminal
custom:
custom-message: 'Hello world'
numeric-field: 5173
---

import CustomMetaData from "@components/CustomMetadata.astro"

# Metadata test - Custom

<CustomMetaData />
4 changes: 4 additions & 0 deletions e2e/src/content/tutorial/tests/metadata/meta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
type: chapter
title: Metadata
---
13 changes: 13 additions & 0 deletions e2e/test/metadata.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { test, expect } from '@playwright/test';

const BASE_URL = '/tests/metadata';

test('developer can pass custom metadata to lesson', async ({ page }) => {
await page.goto(`${BASE_URL}/custom`);
await expect(page.getByRole('heading', { level: 1, name: 'Metadata test - Custom' })).toBeVisible();

await expect(page.getByRole('heading', { level: 2, name: 'Custom metadata' })).toBeVisible();

await expect(page.getByText('"custom-message": "Hello world"')).toBeVisible();
await expect(page.getByText('"numeric-field": 5173')).toBeVisible();
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ prepareCommands:
terminal:
panels: ['terminal', 'output']
meta:
description: "This is lesson 1"
image: "/logo.svg"
description: "This is lesson 1"
image: "/logo.svg"
custom:
publishedAt: "2024-10-16"

---

# Kitchen Sink [Heading 1]
Expand Down
4 changes: 3 additions & 1 deletion packages/types/src/entities/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { I18nSchema } from '../schemas/i18n.js';
import type { ChapterSchema, LessonSchema, PartSchema } from '../schemas/index.js';
import type { ChapterSchema, CustomSchema, LessonSchema, PartSchema } from '../schemas/index.js';
import type { MetaTagsSchema } from '../schemas/metatags.js';

export type * from './nav.js';
Expand Down Expand Up @@ -60,6 +60,8 @@ export type I18n = Required<NonNullable<I18nSchema>>;

export type MetaTagsConfig = MetaTagsSchema;

export type CustomConfig = CustomSchema;

export interface Tutorial {
logoLink?: string;
firstPartId?: string;
Expand Down
5 changes: 5 additions & 0 deletions packages/types/src/schemas/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,18 @@ export const editorSchema = z.union([
}),
]);

const customSchema = z.record(z.string(), z.any());

export type TerminalPanelType = z.infer<typeof panelTypeSchema>;
export type TerminalSchema = z.infer<typeof terminalSchema>;
export type EditorSchema = z.infer<typeof editorSchema>;
export type CustomSchema = z.infer<typeof customSchema>;

export const webcontainerSchema = commandsSchema.extend({
meta: metaTagsSchema.optional(),

custom: customSchema.optional().describe('Assign custom fields to a chapter/part/lesson in the Astro collection'),

previews: previewSchema
.optional()
.describe(
Expand Down