@karaoke-cms/theme-blog 0.9.2 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,79 +1,87 @@
|
|
|
1
1
|
# @karaoke-cms/theme-blog
|
|
2
2
|
|
|
3
|
-
Editorial blog theme for karaoke-cms
|
|
3
|
+
Editorial blog theme for karaoke-cms — featured hero post, card grid, and cover image support. Blog-only: no docs or knowledge-base routes.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install @karaoke-cms/theme-blog
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
8
12
|
|
|
9
13
|
```ts
|
|
10
14
|
// karaoke.config.ts
|
|
15
|
+
import { defineConfig } from '@karaoke-cms/astro';
|
|
11
16
|
import { loadEnv } from '@karaoke-cms/astro/env';
|
|
12
|
-
const { KARAOKE_VAULT } = loadEnv(new URL('.', import.meta.url));
|
|
13
|
-
|
|
14
|
-
export default {
|
|
15
|
-
vault: KARAOKE_VAULT,
|
|
16
|
-
theme: '@karaoke-cms/theme-blog',
|
|
17
|
-
};
|
|
18
|
-
```
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
const env = loadEnv(new URL('.', import.meta.url));
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
export default defineConfig({
|
|
21
|
+
vault: env.KARAOKE_VAULT,
|
|
22
|
+
title: 'My Blog',
|
|
23
|
+
// theme-blog uses the legacy integration API — import the default export
|
|
24
|
+
// and register it directly in astro.config.mjs
|
|
25
|
+
});
|
|
26
|
+
```
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
> **Note:** `theme-blog` currently uses the legacy theme API and does not yet expose a `themeBlog()` factory. Register it in `astro.config.mjs`:
|
|
29
|
+
>
|
|
30
|
+
> ```js
|
|
31
|
+
> // astro.config.mjs
|
|
32
|
+
> import { defineConfig } from 'astro/config';
|
|
33
|
+
> import karaoke from '@karaoke-cms/astro';
|
|
34
|
+
> import themeBlog from '@karaoke-cms/theme-blog';
|
|
35
|
+
> import karaokeConfig from './karaoke.config.ts';
|
|
36
|
+
>
|
|
37
|
+
> export default defineConfig({
|
|
38
|
+
> site: 'https://your-site.pages.dev',
|
|
39
|
+
> integrations: [karaoke({ ...karaokeConfig, theme: themeBlog })],
|
|
40
|
+
> });
|
|
41
|
+
> ```
|
|
42
|
+
|
|
43
|
+
## Routes
|
|
44
|
+
|
|
45
|
+
| Route | Description |
|
|
46
|
+
|-------|-------------|
|
|
47
|
+
| `/` | Home — featured hero post + recent posts grid |
|
|
48
|
+
| `/blog` | All published posts |
|
|
49
|
+
| `/blog/[slug]` | Post page with cover image |
|
|
29
50
|
| `/tags` | Tags index |
|
|
30
|
-
| `/tags/[tag]` |
|
|
51
|
+
| `/tags/[tag]` | Posts by tag |
|
|
31
52
|
| `/404` | Not found page |
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
No `/docs` routes — use `theme-default` for mixed blog + docs sites.
|
|
34
55
|
|
|
35
|
-
|
|
56
|
+
## Extended frontmatter
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
Pass `blogThemeExtension` to `makeCollections()` to unlock cover image and featured-post fields:
|
|
38
59
|
|
|
39
60
|
```ts
|
|
40
61
|
// src/content.config.ts
|
|
41
62
|
import { makeCollections, blogThemeExtension } from '@karaoke-cms/astro/collections';
|
|
63
|
+
import { loadEnv } from '@karaoke-cms/astro/env';
|
|
42
64
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
65
|
+
const env = loadEnv(new URL('..', import.meta.url));
|
|
66
|
+
export const collections = makeCollections(
|
|
67
|
+
new URL('..', import.meta.url),
|
|
68
|
+
env.KARAOKE_VAULT,
|
|
69
|
+
{ blogSchema: blogThemeExtension },
|
|
70
|
+
);
|
|
46
71
|
```
|
|
47
72
|
|
|
48
73
|
Extra fields (all optional):
|
|
49
74
|
|
|
50
|
-
| Field | Type |
|
|
51
|
-
|
|
75
|
+
| Field | Type | Description |
|
|
76
|
+
|-------|------|-------------|
|
|
52
77
|
| `cover_image` | `string` | Path or URL to the post's cover image |
|
|
53
|
-
| `featured` | `boolean` |
|
|
78
|
+
| `featured` | `boolean` | Pin this post as the hero on the home page |
|
|
54
79
|
| `abstract` | `string` | Override the description shown in cards and the hero |
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### Components
|
|
59
|
-
|
|
60
|
-
- **`FeaturedHero`** — large hero block for the featured post with cover image overlay, title, date, and abstract
|
|
61
|
-
- **`PostCard`** — card with cover image, title, date, reading time, and abstract for the grid
|
|
62
|
-
|
|
63
|
-
### Design system
|
|
64
|
-
|
|
65
|
-
`src/styles.css` defines tokens on `:root`:
|
|
66
|
-
|
|
67
|
-
- **Typography**: `--font-body`, `--font-mono`, `--font-size-base/sm/lg/xl`
|
|
68
|
-
- **Color**: `--color-bg`, `--color-text`, `--color-muted`, `--color-border`, `--color-link`, `--color-link-hover`, `--color-link-visited`, `--color-card-bg`, `--color-hero-overlay`
|
|
69
|
-
- **Spacing**: `--spacing-xs/sm/md/lg/xl`
|
|
70
|
-
- **Sizing**: `--width-content` (700px), `--width-site` (1100px), `--radius-card` (8px), `--radius-sm` (4px)
|
|
81
|
+
## Design system
|
|
71
82
|
|
|
72
|
-
Dark mode via `@media (prefers-color-scheme: dark)`.
|
|
83
|
+
Tokens on `:root`: `--font-body`, `--font-mono`, `--color-bg`, `--color-text`, `--color-muted`, `--color-card-bg`, `--color-hero-overlay`, `--width-content` (700px), `--width-site` (1100px), `--radius-card` (8px). Dark mode via `@media (prefers-color-scheme: dark)`.
|
|
73
84
|
|
|
74
|
-
##
|
|
85
|
+
## What's new in 0.9.5
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
- Home page behavior changes significantly: instead of a two-column blog + docs grid, it renders a featured hero and card grid.
|
|
78
|
-
- Does not support docs — vault content in `docs/` is collected but has no public routes. Use `theme-default` if you need docs.
|
|
79
|
-
- `featured: true` on a post controls the home page hero. If no post is marked featured, the most recent post is promoted automatically.
|
|
87
|
+
No user-facing changes in this release — version bumped for lockstep with the monorepo.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@karaoke-cms/theme-blog",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.5",
|
|
5
5
|
"description": "Blog theme for karaoke-cms — editorial layout with featured hero, card grid, and cover images",
|
|
6
6
|
"main": "./src/index.ts",
|
|
7
7
|
"exports": {
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
],
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"astro": ">=6.0.0",
|
|
21
|
-
"@karaoke-cms/astro": "^0.9.
|
|
21
|
+
"@karaoke-cms/astro": "^0.9.5"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"astro": "
|
|
25
|
-
"
|
|
24
|
+
"@karaoke-cms/astro": "workspace:*",
|
|
25
|
+
"astro": "^6.0.8"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"test": "echo \"Stub — no tests\""
|
|
29
29
|
}
|
|
30
|
-
}
|
|
30
|
+
}
|
package/src/pages/404.astro
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
2
|
+
import DefaultPage from '@karaoke-cms/astro/layouts/DefaultPage.astro';
|
|
3
3
|
import { siteTitle } from 'virtual:karaoke-cms/config';
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<
|
|
6
|
+
<DefaultPage title={`404 — ${siteTitle}`}>
|
|
7
7
|
<div style="padding: 4rem 0; text-align: center;">
|
|
8
8
|
<h1 style="font-size: 5rem; margin-bottom: 0.5rem; letter-spacing: -0.04em;">404</h1>
|
|
9
9
|
<p style="color: var(--color-muted); margin-bottom: 2rem;">Page not found.</p>
|
|
10
10
|
<a href="/">← Home</a>
|
|
11
11
|
</div>
|
|
12
|
-
</
|
|
12
|
+
</DefaultPage>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
|
-
import
|
|
3
|
+
import DefaultPage from '@karaoke-cms/astro/layouts/DefaultPage.astro';
|
|
4
4
|
import ModuleLoader from '@karaoke-cms/astro/components/ModuleLoader.astro';
|
|
5
5
|
import { siteTitle } from 'virtual:karaoke-cms/config';
|
|
6
6
|
|
|
@@ -29,7 +29,7 @@ const related = relatedIds.length > 0
|
|
|
29
29
|
: [];
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
<
|
|
32
|
+
<DefaultPage title={`${entry.data.title} — ${siteTitle}`} description={entry.data.description} type="article">
|
|
33
33
|
<article>
|
|
34
34
|
{coverImage && <img src={coverImage} alt="" class="post-cover" />}
|
|
35
35
|
<div class="post-header">
|
|
@@ -66,4 +66,4 @@ const related = relatedIds.length > 0
|
|
|
66
66
|
</div>
|
|
67
67
|
</article>
|
|
68
68
|
<ModuleLoader comments={entry.data.comments} />
|
|
69
|
-
</
|
|
69
|
+
</DefaultPage>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
|
-
import
|
|
3
|
+
import DefaultPage from '@karaoke-cms/astro/layouts/DefaultPage.astro';
|
|
4
4
|
import PostCard from '../../components/PostCard.astro';
|
|
5
5
|
import { siteTitle } from 'virtual:karaoke-cms/config';
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ const posts = (await getCollection('blog', ({ data }) => data.publish === true))
|
|
|
10
10
|
type Extended = { cover_image?: string; abstract?: string };
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
<
|
|
13
|
+
<DefaultPage title={`Blog — ${siteTitle}`}>
|
|
14
14
|
<div class="listing-header">
|
|
15
15
|
<h1>Blog</h1>
|
|
16
16
|
</div>
|
|
@@ -33,4 +33,4 @@ type Extended = { cover_image?: string; abstract?: string };
|
|
|
33
33
|
<p>Create a Markdown file in your vault's <code>blog/</code> folder and set <code>publish: true</code>.</p>
|
|
34
34
|
</div>
|
|
35
35
|
)}
|
|
36
|
-
</
|
|
36
|
+
</DefaultPage>
|
package/src/pages/index.astro
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
|
-
import
|
|
3
|
+
import DefaultPage from '@karaoke-cms/astro/layouts/DefaultPage.astro';
|
|
4
4
|
import FeaturedHero from '../components/FeaturedHero.astro';
|
|
5
5
|
import PostCard from '../components/PostCard.astro';
|
|
6
6
|
import { siteTitle, siteDescription } from 'virtual:karaoke-cms/config';
|
|
@@ -18,7 +18,7 @@ const gridPosts = featuredPost
|
|
|
18
18
|
: allPosts.slice(0, 6);
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
<
|
|
21
|
+
<DefaultPage title={siteTitle} description={siteDescription}>
|
|
22
22
|
{featuredPost && (
|
|
23
23
|
<FeaturedHero
|
|
24
24
|
title={featuredPost.data.title}
|
|
@@ -52,5 +52,5 @@ const gridPosts = featuredPost
|
|
|
52
52
|
<p>Add a Markdown file to your vault's <code>blog/</code> folder with <code>publish: true</code>.</p>
|
|
53
53
|
</div>
|
|
54
54
|
)}
|
|
55
|
-
</
|
|
55
|
+
</DefaultPage>
|
|
56
56
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
|
-
import
|
|
3
|
+
import DefaultPage from '@karaoke-cms/astro/layouts/DefaultPage.astro';
|
|
4
4
|
import { siteTitle } from 'virtual:karaoke-cms/config';
|
|
5
5
|
|
|
6
6
|
export async function getStaticPaths() {
|
|
@@ -25,7 +25,7 @@ export async function getStaticPaths() {
|
|
|
25
25
|
const { tag, entries } = Astro.props;
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
<
|
|
28
|
+
<DefaultPage title={`#${tag} — ${siteTitle}`}>
|
|
29
29
|
<div class="listing-header">
|
|
30
30
|
<h1>#{tag}</h1>
|
|
31
31
|
<p><a href="/tags">← All tags</a></p>
|
|
@@ -40,4 +40,4 @@ const { tag, entries } = Astro.props;
|
|
|
40
40
|
</li>
|
|
41
41
|
))}
|
|
42
42
|
</ul>
|
|
43
|
-
</
|
|
43
|
+
</DefaultPage>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
|
-
import
|
|
3
|
+
import DefaultPage from '@karaoke-cms/astro/layouts/DefaultPage.astro';
|
|
4
4
|
import { siteTitle } from 'virtual:karaoke-cms/config';
|
|
5
5
|
|
|
6
6
|
const posts = await getCollection('blog', ({ data }) => data.publish === true);
|
|
@@ -15,7 +15,7 @@ for (const entry of posts) {
|
|
|
15
15
|
const tags = [...counts.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
-
<
|
|
18
|
+
<DefaultPage title={`Tags — ${siteTitle}`}>
|
|
19
19
|
<div class="listing-header">
|
|
20
20
|
<h1>Tags</h1>
|
|
21
21
|
</div>
|
|
@@ -34,4 +34,4 @@ const tags = [...counts.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
|
34
34
|
<p>Tags are added to posts via the <code>tags</code> frontmatter field.</p>
|
|
35
35
|
</div>
|
|
36
36
|
)}
|
|
37
|
-
</
|
|
37
|
+
</DefaultPage>
|