create-riebeckite 0.0.19 → 0.0.21
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 +3 -3
- package/README_ja.md +1 -1
- package/dist/src/index.js +24 -24
- package/dist/src/scaffold/index.js +24 -24
- package/dist/src/scaffold/version.d.ts +1 -1
- package/dist/src/scaffold/wrangler-defaults.d.ts +1 -1
- package/package.json +2 -2
- package/templates/scaffold/base/app/global.d.ts +9 -3
- package/templates/scaffold/base/app/server.ts +2 -2
- package/templates/scaffold/base/vite.config.ts +3 -25
- package/templates/scaffold/presets/empty/app/routes/_404.tsx +18 -0
- package/templates/scaffold/presets/empty/app/routes/_renderer.tsx +1 -1
- package/templates/scaffold/presets/empty/app/routes/index.tsx +1 -1
- package/templates/scaffold/presets/empty/app/style.css +11 -0
- package/templates/scaffold/presets/minimal/app/routes/[slug{.+}].tsx +13 -32
- package/templates/scaffold/presets/minimal/app/routes/_404.tsx +18 -0
- package/templates/scaffold/presets/minimal/app/routes/_renderer.tsx +17 -53
- package/templates/scaffold/presets/minimal/app/routes/index.tsx +9 -19
- package/templates/scaffold/presets/minimal/app/style.css +13 -21
- package/templates/scaffold/presets/minimal/content/index.en.md +16 -6
- package/templates/scaffold/presets/showcase/app/components/site-header.tsx +10 -64
- package/templates/scaffold/presets/showcase/app/routes/[slug{.+}].tsx +15 -34
- package/templates/scaffold/presets/showcase/app/routes/_404.tsx +18 -0
- package/templates/scaffold/presets/showcase/app/routes/_renderer.tsx +31 -49
- package/templates/scaffold/presets/showcase/app/routes/index.tsx +19 -25
- package/templates/scaffold/presets/showcase/app/style.css +26 -42
- package/templates/scaffold/presets/showcase/content/Daily/2026-09-28.md +8 -0
- package/templates/scaffold/presets/showcase/content/Daily/2026-09-30.md +8 -0
- package/templates/scaffold/presets/showcase/content/Daily/2026-10-02.md +11 -0
- package/templates/scaffold/presets/showcase/content/index.de.md +16 -5
- package/templates/scaffold/presets/showcase/content/index.en.md +16 -5
- package/templates/scaffold/presets/showcase/content/index.es.md +16 -5
- package/templates/scaffold/presets/showcase/content/index.fr.md +16 -5
- package/templates/scaffold/presets/showcase/content/index.ja.md +16 -5
- package/templates/scaffold/presets/showcase/content/index.ko.md +16 -5
- package/templates/scaffold/presets/showcase/content/index.zh-CN.md +16 -5
- package/templates/scaffold/presets/starter/app/components/site-header.tsx +10 -64
- package/templates/scaffold/presets/starter/app/routes/[slug{.+}].tsx +15 -34
- package/templates/scaffold/presets/starter/app/routes/_404.tsx +18 -0
- package/templates/scaffold/presets/starter/app/routes/_renderer.tsx +31 -49
- package/templates/scaffold/presets/starter/app/routes/index.tsx +17 -25
- package/templates/scaffold/presets/starter/app/style.css +26 -42
- package/templates/scaffold/base/app/config.ts +0 -18
- package/templates/scaffold/base/app/constants/paths.ts +0 -10
- package/templates/scaffold/base/app/content.ts +0 -12
|
@@ -1,59 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { RiebeckiteHead, ThemeRoot } from "@riebeckite/honox/ui";
|
|
2
2
|
import { jsxRenderer } from "hono/jsx-renderer";
|
|
3
|
-
import {
|
|
4
|
-
import { config } from "../config";
|
|
5
|
-
|
|
6
|
-
function themeAttributes() {
|
|
7
|
-
const { theme } = config;
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
...theme.attributes,
|
|
11
|
-
"data-theme": theme.colorMode === "system" ? undefined : theme.colorMode,
|
|
12
|
-
"data-theme-name": theme.name,
|
|
13
|
-
"data-typography": theme.typography,
|
|
14
|
-
"data-article-layout": theme.articleLayout,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
3
|
+
import { config } from "virtual:riebeckite/config";
|
|
17
4
|
|
|
18
5
|
// Riebeckite plugin client entries need the HonoX client bundle even without
|
|
19
6
|
// an island component.
|
|
20
7
|
export const __importing_islands = true;
|
|
21
8
|
|
|
22
|
-
export default jsxRenderer(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<Script src="/app/client.ts" async />
|
|
38
|
-
</head>
|
|
39
|
-
<body class="riebeckite-page rb-site">
|
|
40
|
-
{children}
|
|
41
|
-
</body>
|
|
42
|
-
</html>
|
|
43
|
-
);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
function renderHeadTag(tag: PluginHeadTag, index: number) {
|
|
47
|
-
const key = `${tag.tag}-${index}`;
|
|
48
|
-
if (tag.tag === "meta") return <meta {...tag.attrs} key={key} />;
|
|
49
|
-
if (tag.tag === "link") return <link {...tag.attrs} key={key} />;
|
|
50
|
-
return (
|
|
51
|
-
<script
|
|
52
|
-
{...tag.attrs}
|
|
53
|
-
key={key}
|
|
54
|
-
dangerouslySetInnerHTML={
|
|
55
|
-
tag.children ? { __html: tag.children } : undefined
|
|
56
|
-
}
|
|
57
|
-
/>
|
|
58
|
-
);
|
|
59
|
-
}
|
|
9
|
+
export default jsxRenderer(({ children }, c) => (
|
|
10
|
+
<ThemeRoot
|
|
11
|
+
theme={config.theme}
|
|
12
|
+
lang={c.get("htmlLanguage") ?? config.site.locale}
|
|
13
|
+
>
|
|
14
|
+
<head>
|
|
15
|
+
<RiebeckiteHead
|
|
16
|
+
title={config.site.title}
|
|
17
|
+
headTags={c.get("headTags") ?? []}
|
|
18
|
+
colorModeScript={false}
|
|
19
|
+
/>
|
|
20
|
+
</head>
|
|
21
|
+
<body class="riebeckite-page rb-site">{children}</body>
|
|
22
|
+
</ThemeRoot>
|
|
23
|
+
));
|
|
@@ -1,29 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveRiebeckiteHomeRequest } from "@riebeckite/honox/server";
|
|
2
|
+
import { PageBody } from "@riebeckite/honox/ui";
|
|
2
3
|
import { createRoute } from "honox/factory";
|
|
3
4
|
import { SiteArticle } from "../components/article";
|
|
4
|
-
import { content } from "
|
|
5
|
+
import { content } from "virtual:riebeckite/content";
|
|
5
6
|
|
|
6
7
|
export default createRoute(async (c) => {
|
|
7
|
-
const
|
|
8
|
-
const indexEntry = manifest.bySlug.get("index");
|
|
9
|
-
if (indexEntry && indexEntry.permalink !== "/") {
|
|
10
|
-
return c.redirect(indexEntry.permalink, 308);
|
|
11
|
-
}
|
|
8
|
+
const home = await resolveRiebeckiteHomeRequest(c, content);
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
if (indexEntry?.publishing?.routable === false) {
|
|
15
|
-
return c.notFound();
|
|
16
|
-
}
|
|
10
|
+
if (home.kind === "response") return home.response;
|
|
17
11
|
|
|
18
|
-
if (
|
|
19
|
-
c.
|
|
20
|
-
c.set("headTags", indexEntry.headTags ?? []);
|
|
12
|
+
if (home.kind === "page") {
|
|
13
|
+
return c.render(<PageBody html={home.page.body} />);
|
|
21
14
|
}
|
|
22
15
|
|
|
23
16
|
return c.render(
|
|
24
|
-
<SiteArticle
|
|
25
|
-
post={post}
|
|
26
|
-
bodySlots={indexEntry?.bodySlots}
|
|
27
|
-
/>,
|
|
17
|
+
<SiteArticle post={home.post} bodySlots={home.entry.bodySlots} />,
|
|
28
18
|
);
|
|
29
|
-
});
|
|
19
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
@import "./.riebeckite/framework-styles.css";
|
|
1
2
|
@import "./.riebeckite/plugin-styles.css";
|
|
2
3
|
@import "./.riebeckite/theme-styles.css";
|
|
3
4
|
|
|
@@ -28,13 +29,6 @@ body {
|
|
|
28
29
|
margin: 0 auto;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
.rb-article-layout {
|
|
32
|
-
display: grid;
|
|
33
|
-
grid-template-columns: minmax(0, var(--rb-layout-article-max, 48rem));
|
|
34
|
-
justify-content: center;
|
|
35
|
-
column-gap: var(--rb-layout-gap, 2rem);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
32
|
.rb-article-body,
|
|
39
33
|
.site-article__footer {
|
|
40
34
|
min-width: 0;
|
|
@@ -46,16 +40,6 @@ body {
|
|
|
46
40
|
}
|
|
47
41
|
|
|
48
42
|
@media (min-width: 88rem) {
|
|
49
|
-
:is(:root, .rb-theme-root)[data-article-layout="article"] .rb-article-layout {
|
|
50
|
-
grid-template-columns: minmax(0, var(--rb-layout-article-max, 48rem));
|
|
51
|
-
position: relative;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
:is(:root, .rb-theme-root)[data-article-layout="article"] .rb-article-body {
|
|
55
|
-
grid-column: 1;
|
|
56
|
-
grid-row: 1;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
43
|
:is(:root, .rb-theme-root)[data-article-layout="article"] .site-article__footer {
|
|
60
44
|
grid-column: 1;
|
|
61
45
|
}
|
|
@@ -64,18 +48,26 @@ body {
|
|
|
64
48
|
display: block;
|
|
65
49
|
grid-column: 1;
|
|
66
50
|
grid-row: 1;
|
|
67
|
-
position: sticky;
|
|
68
|
-
top: 4rem;
|
|
69
51
|
align-self: start;
|
|
70
52
|
width: var(--rb-layout-sidebar, 14rem);
|
|
71
|
-
max-height: calc(100dvh - 8rem);
|
|
72
53
|
margin-inline-start: calc(
|
|
73
54
|
-1 * var(--rb-layout-sidebar, 14rem) -
|
|
74
55
|
var(--rb-layout-gap, 2rem)
|
|
75
56
|
);
|
|
76
|
-
overflow: auto;
|
|
77
57
|
padding-inline-end: 1rem;
|
|
78
58
|
border-inline-end: 1px solid
|
|
79
59
|
color-mix(in oklab, currentColor 18%, transparent);
|
|
80
60
|
}
|
|
81
61
|
}
|
|
62
|
+
|
|
63
|
+
.not-found {
|
|
64
|
+
width: min(100% - 2rem, var(--rb-layout-article-max, 48rem));
|
|
65
|
+
margin-block: auto;
|
|
66
|
+
padding-block: 2rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.not-found__status {
|
|
70
|
+
margin: 0;
|
|
71
|
+
color: var(--rb-color-accent);
|
|
72
|
+
font-weight: 700;
|
|
73
|
+
}
|
|
@@ -3,10 +3,20 @@ publish: true
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# {{title}}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
|
|
7
|
+
Welcome to your Riebeckite site. This is the smallest useful preset: one page, one plugin, and the `minimal` theme.
|
|
8
|
+
|
|
9
|
+
## How this site is built
|
|
10
|
+
|
|
11
|
+
- `app/routes/_renderer.tsx` wraps every page in the shared HTML shell.
|
|
12
|
+
- `app/routes/index.tsx` renders this page, and `app/routes/[slug{.+}].tsx` renders every other page.
|
|
13
|
+
- `app/components/article.tsx` lays out an article.
|
|
14
|
+
- `riebeckite.config.ts` registers the plugin and the theme.
|
|
15
|
+
|
|
10
16
|
## Edit this site
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
|
|
18
|
+
Content lives in `content/` as plain Markdown. Change this file and the browser updates while you write. Add another `.md` file with `publish: true` in its frontmatter and it becomes a page.
|
|
19
|
+
|
|
20
|
+
## Add a feature
|
|
21
|
+
|
|
22
|
+
Install a plugin package and register its factory in `riebeckite.config.ts`. The `starter` preset shows a practical plugin set, and `showcase` demonstrates the complete ecosystem.
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { SiteNav } from "@riebeckite/plugin-navigation";
|
|
1
2
|
import type { NavigationItem } from "@riebeckite/plugin-navigation";
|
|
2
3
|
import { ColorModeToggle } from "@riebeckite/plugin-color-mode";
|
|
3
|
-
import { config } from "
|
|
4
|
+
import { config } from "virtual:riebeckite/config";
|
|
4
5
|
|
|
5
6
|
export function SiteHeader({
|
|
6
7
|
path,
|
|
7
8
|
items,
|
|
9
|
+
language,
|
|
8
10
|
}: {
|
|
9
11
|
path: string;
|
|
10
12
|
items: readonly NavigationItem[];
|
|
13
|
+
language?: string;
|
|
11
14
|
}) {
|
|
12
15
|
const navigation = items.filter((item) => item.href !== "/");
|
|
13
16
|
|
|
@@ -25,10 +28,10 @@ export function SiteHeader({
|
|
|
25
28
|
</a>
|
|
26
29
|
{navigation.length > 0 ? (
|
|
27
30
|
<>
|
|
28
|
-
<
|
|
29
|
-
<details class="
|
|
31
|
+
<SiteNav items={navigation} path={path} language={language} />
|
|
32
|
+
<details class="rb-nav__mobile">
|
|
30
33
|
<summary class="rb-nav__toggle">Menu</summary>
|
|
31
|
-
<
|
|
34
|
+
<SiteNav items={navigation} path={path} language={language} />
|
|
32
35
|
</details>
|
|
33
36
|
</>
|
|
34
37
|
) : null}
|
|
@@ -40,74 +43,17 @@ export function SiteHeader({
|
|
|
40
43
|
export function SiteFooter({
|
|
41
44
|
path,
|
|
42
45
|
items,
|
|
46
|
+
language,
|
|
43
47
|
}: {
|
|
44
48
|
path: string;
|
|
45
49
|
items: readonly NavigationItem[];
|
|
50
|
+
language?: string;
|
|
46
51
|
}) {
|
|
47
52
|
if (items.length === 0) return null;
|
|
48
53
|
|
|
49
54
|
return (
|
|
50
55
|
<footer class="site-footer rb-site-footer">
|
|
51
|
-
<
|
|
56
|
+
<SiteNav items={items} path={path} language={language} />
|
|
52
57
|
</footer>
|
|
53
58
|
);
|
|
54
59
|
}
|
|
55
|
-
|
|
56
|
-
function SiteNavigation({
|
|
57
|
-
items,
|
|
58
|
-
path,
|
|
59
|
-
}: {
|
|
60
|
-
items: readonly NavigationItem[];
|
|
61
|
-
path: string;
|
|
62
|
-
}) {
|
|
63
|
-
return (
|
|
64
|
-
<nav class="site-navigation rb-nav" aria-label="Site navigation">
|
|
65
|
-
<NavigationItems items={items} path={path} />
|
|
66
|
-
</nav>
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function NavigationItems({
|
|
71
|
-
items,
|
|
72
|
-
path,
|
|
73
|
-
isChildList = false,
|
|
74
|
-
}: {
|
|
75
|
-
items: readonly NavigationItem[];
|
|
76
|
-
path: string;
|
|
77
|
-
isChildList?: boolean;
|
|
78
|
-
}) {
|
|
79
|
-
return (
|
|
80
|
-
<ul class={isChildList ? "site-navigation__list rb-nav__list rb-nav__children" : "site-navigation__list rb-nav__list"}>
|
|
81
|
-
{items.map((item) => {
|
|
82
|
-
const active = item.href ? isActive(item.href, path) : false;
|
|
83
|
-
return (
|
|
84
|
-
<li class="site-navigation__item rb-nav__item">
|
|
85
|
-
{item.href ? (
|
|
86
|
-
<a
|
|
87
|
-
href={item.href}
|
|
88
|
-
class={active ? "site-navigation__link rb-nav__link rb-nav__link--active is-active" : "site-navigation__link rb-nav__link"}
|
|
89
|
-
aria-current={active ? "page" : undefined}
|
|
90
|
-
target={item.external ? "_blank" : undefined}
|
|
91
|
-
rel={item.external ? "noreferrer" : undefined}
|
|
92
|
-
>
|
|
93
|
-
{item.label}
|
|
94
|
-
</a>
|
|
95
|
-
) : (
|
|
96
|
-
<span class="site-navigation__label rb-nav__label">{item.label}</span>
|
|
97
|
-
)}
|
|
98
|
-
{item.children && item.children.length > 0 ? (
|
|
99
|
-
<NavigationItems items={item.children} path={path} isChildList />
|
|
100
|
-
) : null}
|
|
101
|
-
</li>
|
|
102
|
-
);
|
|
103
|
-
})}
|
|
104
|
-
</ul>
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function isActive(href: string, path: string): boolean {
|
|
109
|
-
if (!href.startsWith("/")) return false;
|
|
110
|
-
const target = href.replace(/\/+$/, "") || "/";
|
|
111
|
-
const current = path.replace(/^\/[a-z]{2}(?:-[A-Z]{2})?(?=\/|$)/, "").replace(/\/+$/, "") || "/";
|
|
112
|
-
return target === "/" ? current === target : current === target || current.startsWith(`${target}/`);
|
|
113
|
-
}
|
|
@@ -1,52 +1,33 @@
|
|
|
1
|
-
import { getEntryLanguage } from "@riebeckite/core";
|
|
2
1
|
import {
|
|
3
2
|
contentRouteSsgParams,
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
resolveRiebeckiteContentRequest,
|
|
4
|
+
riebeckiteSsgParams,
|
|
6
5
|
} from "@riebeckite/honox/server";
|
|
6
|
+
import { PageBody } from "@riebeckite/honox/ui";
|
|
7
7
|
import { extractTableOfContents, TableOfContents } from "@riebeckite/plugin-toc";
|
|
8
8
|
import { createRoute } from "honox/factory";
|
|
9
9
|
import { SiteArticle } from "../components/article";
|
|
10
|
-
import { content } from "
|
|
10
|
+
import { content } from "virtual:riebeckite/content";
|
|
11
11
|
|
|
12
12
|
export default createRoute(
|
|
13
|
-
contentRouteSsgParams("/:slug{.+}",
|
|
14
|
-
const manifest = await content.getManifest();
|
|
15
|
-
const contentPaths = manifest.publicEntries
|
|
16
|
-
.filter((entry) => entry.permalink !== "/")
|
|
17
|
-
.map((entry) => ({ slug: entry.permalink.replace(/^\/+/, "") }));
|
|
18
|
-
return [...contentPaths, ...(await pluginPageSsgParams(content))];
|
|
19
|
-
}),
|
|
13
|
+
contentRouteSsgParams("/:slug{.+}", () => riebeckiteSsgParams(content)),
|
|
20
14
|
async (c) => {
|
|
21
|
-
const
|
|
22
|
-
if (!requestedSlug) return c.notFound();
|
|
23
|
-
if (/\.[a-zA-Z0-9]+$/.test(requestedSlug)) return c.notFound();
|
|
15
|
+
const resolved = await resolveRiebeckiteContentRequest(c, content);
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
if (!route) return c.notFound();
|
|
27
|
-
if (route.kind === "redirect")
|
|
28
|
-
return c.redirect(route.location, route.status);
|
|
29
|
-
if (route.kind === "page") {
|
|
30
|
-
c.set("headTags", route.page.headTags ?? []);
|
|
31
|
-
c.set("htmlLanguage", route.page.language);
|
|
32
|
-
return c.render(
|
|
33
|
-
<div dangerouslySetInnerHTML={{ __html: route.page.body }} />,
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const post = await content.getProcessedContent(route.entry.slug);
|
|
17
|
+
if (resolved.kind === "response") return resolved.response;
|
|
38
18
|
|
|
39
|
-
|
|
19
|
+
if (resolved.kind === "page") {
|
|
20
|
+
return c.render(<PageBody html={resolved.page.body} />);
|
|
21
|
+
}
|
|
40
22
|
|
|
41
|
-
|
|
42
|
-
c.set("headTags", route.entry.headTags ?? []);
|
|
23
|
+
const tableOfContents = extractTableOfContents(resolved.post.html ?? "");
|
|
43
24
|
|
|
44
25
|
return c.render(
|
|
45
26
|
<SiteArticle
|
|
46
|
-
post={post}
|
|
47
|
-
bodySlots={
|
|
48
|
-
asideContent={<TableOfContents className="table-of-contents--desktop" items={tableOfContents} />}
|
|
27
|
+
post={resolved.post}
|
|
28
|
+
bodySlots={resolved.entry.bodySlots}
|
|
29
|
+
asideContent={<TableOfContents className="rr-table-of-contents--desktop" items={tableOfContents} />}
|
|
49
30
|
/>,
|
|
50
31
|
);
|
|
51
32
|
},
|
|
52
|
-
);
|
|
33
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { NotFoundHandler } from "hono";
|
|
2
|
+
|
|
3
|
+
const handler: NotFoundHandler = (c) => {
|
|
4
|
+
c.status(404);
|
|
5
|
+
|
|
6
|
+
return c.render(
|
|
7
|
+
<div class="not-found">
|
|
8
|
+
<p class="not-found__status">404</p>
|
|
9
|
+
<h1>Page not found</h1>
|
|
10
|
+
<p>The page you requested does not exist or is not available.</p>
|
|
11
|
+
<p>
|
|
12
|
+
<a href="/">Back to home</a>
|
|
13
|
+
</p>
|
|
14
|
+
</div>,
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default handler;
|
|
@@ -1,69 +1,51 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { RiebeckiteHead, ThemeRoot } from "@riebeckite/honox/ui";
|
|
2
2
|
import { jsxRenderer } from "hono/jsx-renderer";
|
|
3
|
-
import { Link, Script } from "honox/server";
|
|
4
|
-
import { ColorModeScript } from "@riebeckite/plugin-color-mode";
|
|
5
|
-
import { SearchBar } from "@riebeckite/plugin-search";
|
|
6
3
|
import { resolveSiteNavigation } from "@riebeckite/plugin-navigation";
|
|
4
|
+
import { SearchBar } from "@riebeckite/plugin-search";
|
|
7
5
|
import { SiteFooter, SiteHeader } from "../components/site-header";
|
|
8
|
-
import { content } from "
|
|
9
|
-
import { config } from "
|
|
10
|
-
|
|
11
|
-
function themeAttributes() {
|
|
12
|
-
const { theme } = config;
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
...theme.attributes,
|
|
16
|
-
"data-theme": theme.colorMode === "system" ? undefined : theme.colorMode,
|
|
17
|
-
"data-theme-name": theme.name,
|
|
18
|
-
"data-typography": theme.typography,
|
|
19
|
-
"data-article-layout": theme.articleLayout,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
6
|
+
import { content } from "virtual:riebeckite/content";
|
|
7
|
+
import { config } from "virtual:riebeckite/config";
|
|
22
8
|
|
|
23
9
|
// Riebeckite plugin client entries need the HonoX client bundle even without
|
|
24
10
|
// an island component.
|
|
25
11
|
export const __importing_islands = true;
|
|
26
12
|
|
|
27
13
|
export default jsxRenderer(async ({ children }, c) => {
|
|
28
|
-
const
|
|
29
|
-
|
|
14
|
+
const navigation =
|
|
15
|
+
resolveSiteNavigation(
|
|
16
|
+
config,
|
|
17
|
+
await content.getManifest(),
|
|
18
|
+
c.get("htmlLanguage"),
|
|
19
|
+
) ?? { primary: [], secondary: [] };
|
|
30
20
|
|
|
31
21
|
return (
|
|
32
|
-
<
|
|
22
|
+
<ThemeRoot
|
|
23
|
+
theme={config.theme}
|
|
33
24
|
lang={c.get("htmlLanguage") ?? config.site.locale}
|
|
34
|
-
{...themeAttributes()}
|
|
35
25
|
>
|
|
36
26
|
<head>
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
<ColorModeScript />
|
|
42
|
-
<Link href="/app/style.css" rel="stylesheet" />
|
|
43
|
-
{headTags.map(renderHeadTag)}
|
|
44
|
-
<Script src="/app/client.ts" async />
|
|
27
|
+
<RiebeckiteHead
|
|
28
|
+
title={config.site.title}
|
|
29
|
+
headTags={c.get("headTags") ?? []}
|
|
30
|
+
/>
|
|
45
31
|
</head>
|
|
46
32
|
<body class="riebeckite-page rb-site">
|
|
47
|
-
|
|
33
|
+
<a class="rb-skip-link" href="#main-content">Skip to main content</a>
|
|
34
|
+
<SiteHeader
|
|
35
|
+
path={c.req.path}
|
|
36
|
+
items={navigation.primary}
|
|
37
|
+
language={c.get("htmlLanguage")}
|
|
38
|
+
/>
|
|
48
39
|
<SearchBar />
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
<main id="main-content" tabindex="-1" class="riebeckite-main">
|
|
41
|
+
{children}
|
|
42
|
+
</main>
|
|
43
|
+
<SiteFooter
|
|
44
|
+
path={c.req.path}
|
|
45
|
+
items={navigation.secondary}
|
|
46
|
+
language={c.get("htmlLanguage")}
|
|
47
|
+
/>
|
|
51
48
|
</body>
|
|
52
|
-
</
|
|
49
|
+
</ThemeRoot>
|
|
53
50
|
);
|
|
54
51
|
});
|
|
55
|
-
|
|
56
|
-
function renderHeadTag(tag: PluginHeadTag, index: number) {
|
|
57
|
-
const key = `${tag.tag}-${index}`;
|
|
58
|
-
if (tag.tag === "meta") return <meta {...tag.attrs} key={key} />;
|
|
59
|
-
if (tag.tag === "link") return <link {...tag.attrs} key={key} />;
|
|
60
|
-
return (
|
|
61
|
-
<script
|
|
62
|
-
{...tag.attrs}
|
|
63
|
-
key={key}
|
|
64
|
-
dangerouslySetInnerHTML={
|
|
65
|
-
tag.children ? { __html: tag.children } : undefined
|
|
66
|
-
}
|
|
67
|
-
/>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
@@ -1,39 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { resolveRiebeckiteHomeRequest } from "@riebeckite/honox/server";
|
|
2
|
+
import { PageBody } from "@riebeckite/honox/ui";
|
|
3
3
|
import { DailyNotes, getDailyNotes } from "@riebeckite/plugin-daily-notes";
|
|
4
|
-
import {
|
|
4
|
+
import { getRecentPosts, RecentPosts } from "@riebeckite/plugin-recent-posts";
|
|
5
5
|
import { extractTableOfContents, TableOfContents } from "@riebeckite/plugin-toc";
|
|
6
|
+
import { createRoute } from "honox/factory";
|
|
6
7
|
import { SiteArticle } from "../components/article";
|
|
7
|
-
import { config } from "
|
|
8
|
-
import { content } from "
|
|
8
|
+
import { config } from "virtual:riebeckite/config";
|
|
9
|
+
import { content } from "virtual:riebeckite/content";
|
|
9
10
|
|
|
10
11
|
export default createRoute(async (c) => {
|
|
11
|
-
const
|
|
12
|
-
const indexEntry = manifest.bySlug.get("index");
|
|
13
|
-
if (indexEntry && indexEntry.permalink !== "/") {
|
|
14
|
-
return c.redirect(indexEntry.permalink, 308);
|
|
15
|
-
}
|
|
12
|
+
const home = await resolveRiebeckiteHomeRequest(c, content);
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
if (home.kind === "response") return home.response;
|
|
15
|
+
|
|
16
|
+
if (home.kind === "page") {
|
|
17
|
+
return c.render(<PageBody html={home.page.body} />);
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
const
|
|
20
|
+
const manifest = await content.getManifest();
|
|
21
|
+
const recentPosts = getRecentPosts({ manifest });
|
|
23
22
|
const dailyNotes = getDailyNotes({ manifest, config });
|
|
24
|
-
const tableOfContents = extractTableOfContents(post.html ?? "");
|
|
25
|
-
|
|
26
|
-
if (indexEntry) {
|
|
27
|
-
c.set("htmlLanguage", getEntryLanguage(indexEntry));
|
|
28
|
-
c.set("headTags", indexEntry.headTags ?? []);
|
|
29
|
-
}
|
|
23
|
+
const tableOfContents = extractTableOfContents(home.post.html ?? "");
|
|
30
24
|
|
|
31
25
|
return c.render(
|
|
32
26
|
<SiteArticle
|
|
33
|
-
post={post}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
post={home.post}
|
|
28
|
+
bodySlots={home.entry.bodySlots}
|
|
29
|
+
asideContent={<TableOfContents className="rr-table-of-contents--desktop" items={tableOfContents} />}
|
|
30
|
+
afterContent={<><RecentPosts posts={recentPosts} /><DailyNotes notes={dailyNotes} /></>}
|
|
37
31
|
/>,
|
|
38
32
|
);
|
|
39
|
-
});
|
|
33
|
+
});
|