@astrojs/starlight 0.2.0 → 0.3.1
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/404.astro +32 -51
- package/CHANGELOG.md +33 -0
- package/components/EmptyMarkdown.md +0 -0
- package/components/Search.astro +2 -3
- package/index.astro +3 -110
- package/layout/Page.astro +116 -0
- package/package.json +1 -1
- package/schemas/i18n.ts +8 -0
- package/translations/cs.json +22 -0
- package/translations/de.json +3 -1
- package/translations/en.json +3 -1
- package/translations/es.json +3 -1
- package/translations/fr.json +3 -1
- package/translations/index.ts +2 -1
- package/translations/it.json +3 -1
- package/translations/ja.json +3 -1
- package/translations/pt.json +3 -1
- package/utils/navigation.ts +16 -11
- package/utils/routing.ts +5 -0
- package/utils/slugs.ts +21 -0
package/404.astro
CHANGED
|
@@ -1,58 +1,39 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { getEntry } from 'astro:content';
|
|
2
3
|
import config from 'virtual:starlight/user-config';
|
|
3
|
-
import
|
|
4
|
+
import EmptyContent from './components/EmptyMarkdown.md';
|
|
5
|
+
import Page from './layout/Page.astro';
|
|
6
|
+
import type { StarlightDocsEntry } from './utils/routing';
|
|
7
|
+
import { useTranslations } from './utils/translations';
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import './style/shiki.css';
|
|
9
|
-
import './style/util.css';
|
|
10
|
-
|
|
11
|
-
// Layout
|
|
12
|
-
import PageFrame from './layout/PageFrame.astro';
|
|
13
|
-
|
|
14
|
-
// Components
|
|
15
|
-
import Header from './components/Header.astro';
|
|
16
|
-
import MarkdownContent from './components/MarkdownContent.astro';
|
|
17
|
-
import ThemeProvider from './components/ThemeProvider.astro';
|
|
18
|
-
import SkipLink from './components/SkipLink.astro';
|
|
9
|
+
const { lang = 'en', dir = 'ltr', locale } = config.defaultLocale || {};
|
|
10
|
+
const entryMeta = { dir, lang, locale };
|
|
11
|
+
const t = useTranslations(locale);
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
const fallbackEntry: StarlightDocsEntry = {
|
|
14
|
+
slug: '404',
|
|
15
|
+
id: '404.md' as StarlightDocsEntry['id'],
|
|
16
|
+
body: '',
|
|
17
|
+
collection: 'docs',
|
|
18
|
+
data: {
|
|
19
|
+
title: '404',
|
|
20
|
+
template: 'splash',
|
|
21
|
+
editUrl: false,
|
|
22
|
+
head: [],
|
|
23
|
+
hero: { tagline: t('404.text'), actions: [] },
|
|
24
|
+
},
|
|
25
|
+
render: async () => ({
|
|
26
|
+
Content: EmptyContent,
|
|
27
|
+
headings: [],
|
|
28
|
+
remarkPluginFrontmatter: {},
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
22
31
|
|
|
23
|
-
const
|
|
32
|
+
const userEntry = await getEntry('docs', '404');
|
|
33
|
+
const entry = userEntry || fallbackEntry;
|
|
34
|
+
const { Content, headings } = await entry.render();
|
|
24
35
|
---
|
|
25
36
|
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
<meta name="viewport" content="width=device-width" />
|
|
30
|
-
<title>Not found</title>
|
|
31
|
-
</head>
|
|
32
|
-
<body>
|
|
33
|
-
<ThemeProvider />
|
|
34
|
-
<SkipLink {locale} />
|
|
35
|
-
<PageFrame {locale} hasSidebar={false}>
|
|
36
|
-
<Header slot="header" {locale} />
|
|
37
|
-
<main>
|
|
38
|
-
<MarkdownContent>
|
|
39
|
-
<h1 id="_top" data-page-title>404</h1>
|
|
40
|
-
<p>Houston, we have a problem.</p>
|
|
41
|
-
<p>
|
|
42
|
-
We couldn’t find that link. Check the address or
|
|
43
|
-
<a href={pathWithBase('/')}>head back home</a>.
|
|
44
|
-
</p>
|
|
45
|
-
</MarkdownContent>
|
|
46
|
-
</main>
|
|
47
|
-
</PageFrame>
|
|
48
|
-
|
|
49
|
-
<style>
|
|
50
|
-
main {
|
|
51
|
-
margin: auto;
|
|
52
|
-
padding: clamp(2rem, 10vmin, 6rem) var(--sl-nav-pad-x);
|
|
53
|
-
max-width: var(--sl-content-width);
|
|
54
|
-
max-width: max-content;
|
|
55
|
-
}
|
|
56
|
-
</style>
|
|
57
|
-
</body>
|
|
58
|
-
</html>
|
|
37
|
+
<Page {headings} entry={entry} slug={entry.slug} {...entryMeta} {entryMeta}>
|
|
38
|
+
<Content />
|
|
39
|
+
</Page>
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @astrojs/starlight
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#257](https://github.com/withastro/starlight/pull/257) [`0502327`](https://github.com/withastro/starlight/commit/050232770c8a2d22f317def8e734e4abb36387c6) Thanks [@JosefJezek](https://github.com/JosefJezek)! - Add Czech language support
|
|
8
|
+
|
|
9
|
+
- [#261](https://github.com/withastro/starlight/pull/261) [`2062b9e`](https://github.com/withastro/starlight/commit/2062b9e21695b5dc3f116731dbfdf609e495018c) Thanks [@delucis](https://github.com/delucis)! - Fix autogenerated navigation for pages using fallback content
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [#237](https://github.com/withastro/starlight/pull/237) [`4279d75`](https://github.com/withastro/starlight/commit/4279d7512a8261b576056471f5aa1ede1e6aae4a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Use path instead of slugified path for auto-generated sidebar item configuration
|
|
16
|
+
|
|
17
|
+
⚠️ Potentially breaking change. If your docs directory names don’t match their URLs, for example they contain whitespace like `docs/my docs/`, and you were referencing these in an `autogenerate` sidebar group as `my-docs`, update your config to reference these with the directory name instead of the slugified version:
|
|
18
|
+
|
|
19
|
+
```diff
|
|
20
|
+
autogenerate: {
|
|
21
|
+
- directory: 'my-docs',
|
|
22
|
+
+ directory: 'my docs',
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- [#226](https://github.com/withastro/starlight/pull/226) [`1aa2187`](https://github.com/withastro/starlight/commit/1aa2187944dde4419e523f0087139f5a21efd826) Thanks [@delucis](https://github.com/delucis)! - Add support for custom 404 pages.
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- [#234](https://github.com/withastro/starlight/pull/234) [`91309ae`](https://github.com/withastro/starlight/commit/91309ae13250c5fd9f91a8e1843f16430773ff15) Thanks [@morinokami](https://github.com/morinokami)! - Add Japanese translation for `search.devWarning`
|
|
31
|
+
|
|
32
|
+
- [#227](https://github.com/withastro/starlight/pull/227) [`fbdecfa`](https://github.com/withastro/starlight/commit/fbdecfab47effb0cba7cbc9233a7b6bffdded320) Thanks [@Yan-Thomas](https://github.com/Yan-Thomas)! - Add missing i18n support to the Search component's dev warning.
|
|
33
|
+
|
|
34
|
+
- [#244](https://github.com/withastro/starlight/pull/244) [`f1bcbeb`](https://github.com/withastro/starlight/commit/f1bcbebeb441b6bb9ed6a1ab2414791e9d5de6ef) Thanks [@Waxer59](https://github.com/Waxer59)! - Add Spanish translation for `search.devWarning`
|
|
35
|
+
|
|
3
36
|
## 0.2.0
|
|
4
37
|
|
|
5
38
|
### Minor Changes
|
|
File without changes
|
package/components/Search.astro
CHANGED
|
@@ -43,9 +43,8 @@ const pagefindTranslations = {
|
|
|
43
43
|
</button>
|
|
44
44
|
{
|
|
45
45
|
import.meta.env.DEV ? (
|
|
46
|
-
<div style="margin: auto; text-align: center;" dir="ltr">
|
|
47
|
-
<p>
|
|
48
|
-
<p>Try building and previewing the site to test it out locally.</p>
|
|
46
|
+
<div style="margin: auto; text-align: center; white-space: pre-line;" dir="ltr">
|
|
47
|
+
<p>{t("search.devWarning")}</p>
|
|
49
48
|
</div>
|
|
50
49
|
) : (
|
|
51
50
|
<div class="search-container">
|
package/index.astro
CHANGED
|
@@ -1,122 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { InferGetStaticPropsType } from 'astro';
|
|
3
|
-
import config from 'virtual:starlight/user-config';
|
|
4
|
-
|
|
5
|
-
import { getSidebar } from './utils/navigation';
|
|
6
3
|
import { paths } from './utils/routing';
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
import './style/props.css';
|
|
10
|
-
import './style/reset.css';
|
|
11
|
-
import './style/shiki.css';
|
|
12
|
-
import './style/util.css';
|
|
13
|
-
|
|
14
|
-
// Components — can override built-in CSS, but not user CSS.
|
|
15
|
-
import ContentPanel from './components/ContentPanel.astro';
|
|
16
|
-
import FallbackContentNotice from './components/FallbackContentNotice.astro';
|
|
17
|
-
import HeadSEO from './components/HeadSEO.astro';
|
|
18
|
-
import Header from './components/Header.astro';
|
|
19
|
-
import Footer from './components/Footer.astro';
|
|
20
|
-
import MarkdownContent from './components/MarkdownContent.astro';
|
|
21
|
-
import RightSidebar from './components/RightSidebar.astro';
|
|
22
|
-
import Sidebar from './components/Sidebar.astro';
|
|
23
|
-
import SkipLink from './components/SkipLink.astro';
|
|
24
|
-
import ThemeProvider from './components/ThemeProvider.astro';
|
|
25
|
-
import PageFrame from './layout/PageFrame.astro';
|
|
26
|
-
import TwoColumnContent from './layout/TwoColumnContent.astro';
|
|
27
|
-
import Hero from './components/Hero.astro';
|
|
28
|
-
|
|
29
|
-
// Remark component CSS (needs to override `MarkdownContent.astro`)
|
|
30
|
-
import './style/asides.css';
|
|
31
|
-
|
|
32
|
-
// Important that this is the last import so it can override built-in styles.
|
|
33
|
-
import 'virtual:starlight/user-css';
|
|
5
|
+
import Page from './layout/Page.astro';
|
|
34
6
|
|
|
35
7
|
export async function getStaticPaths() {
|
|
36
8
|
return paths;
|
|
37
9
|
}
|
|
38
10
|
|
|
39
11
|
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
|
40
|
-
|
|
41
|
-
const { dir, entry, entryMeta, isFallback, lang, locale } = Astro.props;
|
|
42
|
-
const { Content, headings } = await entry.render();
|
|
43
|
-
const sidebar = getSidebar(Astro.url.pathname, locale);
|
|
44
|
-
|
|
45
|
-
const hasSidebar = entry.data.template !== 'splash';
|
|
46
|
-
const tocConfig = !hasSidebar
|
|
47
|
-
? false
|
|
48
|
-
: entry.data.tableOfContents !== undefined
|
|
49
|
-
? entry.data.tableOfContents
|
|
50
|
-
: config.tableOfContents;
|
|
51
|
-
const hasToC = Boolean(tocConfig);
|
|
52
|
-
const hasHero = Boolean(entry.data.hero);
|
|
12
|
+
const { Content, headings } = await Astro.props.entry.render();
|
|
53
13
|
---
|
|
54
14
|
|
|
55
|
-
<
|
|
56
|
-
<head>
|
|
57
|
-
<HeadSEO data={entry.data} lang={lang} />
|
|
58
|
-
<style>
|
|
59
|
-
html:not([data-has-toc]) {
|
|
60
|
-
--sl-mobile-toc-height: 0rem;
|
|
61
|
-
}
|
|
62
|
-
html:not([data-has-sidebar]) {
|
|
63
|
-
--sl-content-width: 67.5rem;
|
|
64
|
-
}
|
|
65
|
-
/* Add scroll padding to ensure anchor headings aren't obscured by nav */
|
|
66
|
-
html {
|
|
67
|
-
/* Additional padding is needed to account for the mobile TOC */
|
|
68
|
-
scroll-padding-top: calc(
|
|
69
|
-
1.5rem + var(--sl-nav-height) + var(--sl-mobile-toc-height)
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
main {
|
|
73
|
-
padding-bottom: 3vh;
|
|
74
|
-
}
|
|
75
|
-
@media (min-width: 50em) {
|
|
76
|
-
[data-has-sidebar] {
|
|
77
|
-
--sl-content-inline-start: var(--sl-sidebar-width);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
@media (min-width: 72em) {
|
|
81
|
-
html {
|
|
82
|
-
scroll-padding-top: calc(1.5rem + var(--sl-nav-height));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
</style>
|
|
86
|
-
</head>
|
|
87
|
-
<body>
|
|
88
|
-
<ThemeProvider />
|
|
89
|
-
<SkipLink {locale} />
|
|
90
|
-
<PageFrame {locale} {hasSidebar}>
|
|
91
|
-
<Header slot="header" {locale} />
|
|
92
|
-
{hasSidebar && <Sidebar slot="sidebar" {sidebar} {locale} />}
|
|
93
|
-
<TwoColumnContent {hasToC}>
|
|
94
|
-
<RightSidebar slot="right-sidebar" {headings} {locale} {tocConfig} />
|
|
95
|
-
<main data-pagefind-body lang={entryMeta.lang} dir={entryMeta.dir}>
|
|
96
|
-
{/* TODO: Revisit how this logic flows. */}
|
|
97
|
-
{entry.data.hero ? (
|
|
98
|
-
<ContentPanel>
|
|
99
|
-
<Hero hero={entry.data.hero} fallbackTitle={entry.data.title} />
|
|
100
|
-
<MarkdownContent><Content /></MarkdownContent>
|
|
101
|
-
</ContentPanel>
|
|
102
|
-
) : (
|
|
103
|
-
<ContentPanel>
|
|
104
|
-
<h1
|
|
105
|
-
id="_top"
|
|
106
|
-
data-page-title
|
|
107
|
-
style="font-size: var(--sl-text-h1); line-height: var(--sl-line-height-headings); font-weight: 600; color: var(--sl-color-white); margin-top: 1rem;"
|
|
108
|
-
>
|
|
109
|
-
{entry.data.title}
|
|
110
|
-
</h1>
|
|
111
|
-
{isFallback && <FallbackContentNotice {locale} />}
|
|
112
|
-
</ContentPanel>
|
|
113
|
-
<ContentPanel>
|
|
114
|
-
<MarkdownContent><Content /></MarkdownContent>
|
|
115
|
-
<Footer {...{ entry, dir, lang, locale, sidebar }} />
|
|
116
|
-
</ContentPanel>
|
|
117
|
-
)}
|
|
118
|
-
</main>
|
|
119
|
-
</TwoColumnContent>
|
|
120
|
-
</PageFrame>
|
|
121
|
-
</body>
|
|
122
|
-
</html>
|
|
15
|
+
<Page {...Astro.props} {headings}><Content /></Page>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
import config from 'virtual:starlight/user-config';
|
|
3
|
+
import type { MarkdownHeading } from 'astro';
|
|
4
|
+
import { getSidebar } from '../utils/navigation';
|
|
5
|
+
import type { Route } from '../utils/routing';
|
|
6
|
+
|
|
7
|
+
// Built-in CSS styles.
|
|
8
|
+
import '../style/props.css';
|
|
9
|
+
import '../style/reset.css';
|
|
10
|
+
import '../style/shiki.css';
|
|
11
|
+
import '../style/util.css';
|
|
12
|
+
|
|
13
|
+
// Components — can override built-in CSS, but not user CSS.
|
|
14
|
+
import ContentPanel from '../components/ContentPanel.astro';
|
|
15
|
+
import FallbackContentNotice from '../components/FallbackContentNotice.astro';
|
|
16
|
+
import Footer from '../components/Footer.astro';
|
|
17
|
+
import HeadSEO from '../components/HeadSEO.astro';
|
|
18
|
+
import Header from '../components/Header.astro';
|
|
19
|
+
import Hero from '../components/Hero.astro';
|
|
20
|
+
import MarkdownContent from '../components/MarkdownContent.astro';
|
|
21
|
+
import RightSidebar from '../components/RightSidebar.astro';
|
|
22
|
+
import Sidebar from '../components/Sidebar.astro';
|
|
23
|
+
import SkipLink from '../components/SkipLink.astro';
|
|
24
|
+
import ThemeProvider from '../components/ThemeProvider.astro';
|
|
25
|
+
import PageFrame from '../layout/PageFrame.astro';
|
|
26
|
+
import TwoColumnContent from '../layout/TwoColumnContent.astro';
|
|
27
|
+
|
|
28
|
+
// Remark component CSS (needs to override `MarkdownContent.astro`)
|
|
29
|
+
import '../style/asides.css';
|
|
30
|
+
|
|
31
|
+
// Important that this is the last import so it can override built-in styles.
|
|
32
|
+
import 'virtual:starlight/user-css';
|
|
33
|
+
|
|
34
|
+
type Props = Route & { headings: MarkdownHeading[] };
|
|
35
|
+
|
|
36
|
+
const { dir, entry, entryMeta, headings, isFallback, lang, locale } = Astro.props;
|
|
37
|
+
const sidebar = getSidebar(Astro.url.pathname, locale);
|
|
38
|
+
|
|
39
|
+
const hasSidebar = entry.data.template !== 'splash';
|
|
40
|
+
const tocConfig = !hasSidebar
|
|
41
|
+
? false
|
|
42
|
+
: entry.data.tableOfContents !== undefined
|
|
43
|
+
? entry.data.tableOfContents
|
|
44
|
+
: config.tableOfContents;
|
|
45
|
+
const hasToC = Boolean(tocConfig);
|
|
46
|
+
const hasHero = Boolean(entry.data.hero);
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
<html lang={lang} dir={dir} data-has-toc={hasToC} data-has-sidebar={hasSidebar} data-has-hero={hasHero}>
|
|
50
|
+
<head>
|
|
51
|
+
<HeadSEO data={entry.data} lang={lang} />
|
|
52
|
+
<style>
|
|
53
|
+
html:not([data-has-toc]) {
|
|
54
|
+
--sl-mobile-toc-height: 0rem;
|
|
55
|
+
}
|
|
56
|
+
html:not([data-has-sidebar]) {
|
|
57
|
+
--sl-content-width: 67.5rem;
|
|
58
|
+
}
|
|
59
|
+
/* Add scroll padding to ensure anchor headings aren't obscured by nav */
|
|
60
|
+
html {
|
|
61
|
+
/* Additional padding is needed to account for the mobile TOC */
|
|
62
|
+
scroll-padding-top: calc(
|
|
63
|
+
1.5rem + var(--sl-nav-height) + var(--sl-mobile-toc-height)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
main {
|
|
67
|
+
padding-bottom: 3vh;
|
|
68
|
+
}
|
|
69
|
+
@media (min-width: 50em) {
|
|
70
|
+
[data-has-sidebar] {
|
|
71
|
+
--sl-content-inline-start: var(--sl-sidebar-width);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
@media (min-width: 72em) {
|
|
75
|
+
html {
|
|
76
|
+
scroll-padding-top: calc(1.5rem + var(--sl-nav-height));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</style>
|
|
80
|
+
</head>
|
|
81
|
+
<body>
|
|
82
|
+
<ThemeProvider />
|
|
83
|
+
<SkipLink {locale} />
|
|
84
|
+
<PageFrame {locale} {hasSidebar}>
|
|
85
|
+
<Header slot="header" {locale} />
|
|
86
|
+
{hasSidebar && <Sidebar slot="sidebar" {sidebar} {locale} />}
|
|
87
|
+
<TwoColumnContent {hasToC}>
|
|
88
|
+
<RightSidebar slot="right-sidebar" {headings} {locale} {tocConfig} />
|
|
89
|
+
<main data-pagefind-body={entry.slug !== '404'} lang={entryMeta.lang} dir={entryMeta.dir}>
|
|
90
|
+
{/* TODO: Revisit how this logic flows. */}
|
|
91
|
+
{entry.data.hero ? (
|
|
92
|
+
<ContentPanel>
|
|
93
|
+
<Hero hero={entry.data.hero} fallbackTitle={entry.data.title} />
|
|
94
|
+
<MarkdownContent><slot /></MarkdownContent>
|
|
95
|
+
</ContentPanel>
|
|
96
|
+
) : (
|
|
97
|
+
<ContentPanel>
|
|
98
|
+
<h1
|
|
99
|
+
id="_top"
|
|
100
|
+
data-page-title
|
|
101
|
+
style="font-size: var(--sl-text-h1); line-height: var(--sl-line-height-headings); font-weight: 600; color: var(--sl-color-white); margin-top: 1rem;"
|
|
102
|
+
>
|
|
103
|
+
{entry.data.title}
|
|
104
|
+
</h1>
|
|
105
|
+
{isFallback && <FallbackContentNotice {locale} />}
|
|
106
|
+
</ContentPanel>
|
|
107
|
+
<ContentPanel>
|
|
108
|
+
<MarkdownContent><slot /></MarkdownContent>
|
|
109
|
+
<Footer {...{ entry, dir, lang, locale, sidebar }} />
|
|
110
|
+
</ContentPanel>
|
|
111
|
+
)}
|
|
112
|
+
</main>
|
|
113
|
+
</TwoColumnContent>
|
|
114
|
+
</PageFrame>
|
|
115
|
+
</body>
|
|
116
|
+
</html>
|
package/package.json
CHANGED
package/schemas/i18n.ts
CHANGED
|
@@ -29,6 +29,10 @@ function starlightI18nSchema() {
|
|
|
29
29
|
.string()
|
|
30
30
|
.describe('Text for the “Cancel” button that closes the search modal.'),
|
|
31
31
|
|
|
32
|
+
'search.devWarning': z
|
|
33
|
+
.string()
|
|
34
|
+
.describe('Warning displayed when opening the Search in a dev environment.'),
|
|
35
|
+
|
|
32
36
|
'themeSelect.accessibleLabel': z
|
|
33
37
|
.string()
|
|
34
38
|
.describe('Accessible label for the theme selection dropdown.'),
|
|
@@ -94,6 +98,10 @@ function starlightI18nSchema() {
|
|
|
94
98
|
.describe(
|
|
95
99
|
'Label shown on the “next page” pagination arrow in the page footer.'
|
|
96
100
|
),
|
|
101
|
+
|
|
102
|
+
'404.text': z
|
|
103
|
+
.string()
|
|
104
|
+
.describe('Text shown on Starlight’s default 404 page'),
|
|
97
105
|
})
|
|
98
106
|
.partial();
|
|
99
107
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skipLink.label": "Přeskočit na obsah",
|
|
3
|
+
"search.label": "Hledat",
|
|
4
|
+
"search.shortcutLabel": "(Vyhledejte stisknutím /)",
|
|
5
|
+
"search.cancelLabel": "Zrušit",
|
|
6
|
+
"search.devWarning": "Vyhledávání je dostupné pouze v produkčních sestaveních. \nZkuste sestavit a zobrazit náhled webu a otestovat jej lokálně.",
|
|
7
|
+
"themeSelect.accessibleLabel": "Vyberte motiv",
|
|
8
|
+
"themeSelect.dark": "Tmavý",
|
|
9
|
+
"themeSelect.light": "Světlý",
|
|
10
|
+
"themeSelect.auto": "Auto",
|
|
11
|
+
"languageSelect.accessibleLabel": "Vyberte jazyk",
|
|
12
|
+
"menuButton.accessibleLabel": "Nabídka",
|
|
13
|
+
"sidebarNav.accessibleLabel": "Hlavní",
|
|
14
|
+
"tableOfContents.onThisPage": "Na této stránce",
|
|
15
|
+
"tableOfContents.overview": "Přehled",
|
|
16
|
+
"i18n.untranslatedContent": "Tento obsah zatím není dostupný ve vašem jazyce.",
|
|
17
|
+
"page.editLink": "Upravit stránku",
|
|
18
|
+
"page.lastUpdated": "Poslední aktualizace:",
|
|
19
|
+
"page.previousLink": "Předchozí",
|
|
20
|
+
"page.nextLink": "Další",
|
|
21
|
+
"404.text": "Stránka nenalezena. Zkontrolujte adresu URL nebo zkuste použít vyhledávací pole."
|
|
22
|
+
}
|
package/translations/de.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Suchen",
|
|
4
4
|
"search.shortcutLabel": "(Drücke / zum Suchen)",
|
|
5
5
|
"search.cancelLabel": "Abbrechen",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Farbschema wählen",
|
|
7
8
|
"themeSelect.dark": "Dunkel",
|
|
8
9
|
"themeSelect.light": "Hell",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Seite bearbeiten",
|
|
17
18
|
"page.lastUpdated": "Zuletzt bearbeitet:",
|
|
18
19
|
"page.previousLink": "Vorherige Seite",
|
|
19
|
-
"page.nextLink": "Nächste Seite"
|
|
20
|
+
"page.nextLink": "Nächste Seite",
|
|
21
|
+
"404.text": "Seite nicht gefunden. Überprüfe die URL oder nutze die Suchleiste."
|
|
20
22
|
}
|
package/translations/en.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Search",
|
|
4
4
|
"search.shortcutLabel": "(Press / to Search)",
|
|
5
5
|
"search.cancelLabel": "Cancel",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Select theme",
|
|
7
8
|
"themeSelect.dark": "Dark",
|
|
8
9
|
"themeSelect.light": "Light",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Edit page",
|
|
17
18
|
"page.lastUpdated": "Last updated:",
|
|
18
19
|
"page.previousLink": "Previous",
|
|
19
|
-
"page.nextLink": "Next"
|
|
20
|
+
"page.nextLink": "Next",
|
|
21
|
+
"404.text": "Page not found. Check the URL or try using the search bar."
|
|
20
22
|
}
|
package/translations/es.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Buscar",
|
|
4
4
|
"search.shortcutLabel": "(Presiona / para buscar)",
|
|
5
5
|
"search.cancelLabel": "Interrumpir",
|
|
6
|
+
"search.devWarning": "La búsqueda solo está disponible en las versiones de producción. \nIntenta construir y previsualizar el sitio para probarlo localmente.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Seleccionar tema",
|
|
7
8
|
"themeSelect.dark": "Oscuro",
|
|
8
9
|
"themeSelect.light": "Claro",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Edita esta página",
|
|
17
18
|
"page.lastUpdated": "Última actualización:",
|
|
18
19
|
"page.previousLink": "Página anterior",
|
|
19
|
-
"page.nextLink": "Siguiente página"
|
|
20
|
+
"page.nextLink": "Siguiente página",
|
|
21
|
+
"404.text": "Página no encontrada. Verifique la URL o intente usar la barra de búsqueda."
|
|
20
22
|
}
|
package/translations/fr.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Rechercher",
|
|
4
4
|
"search.shortcutLabel": "(Presser / pour rechercher)",
|
|
5
5
|
"search.cancelLabel": "Annuler",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Selectionner le thème",
|
|
7
8
|
"themeSelect.dark": "Dark",
|
|
8
9
|
"themeSelect.light": "Light",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Editer la page",
|
|
17
18
|
"page.lastUpdated": "Dernière mise à jour :",
|
|
18
19
|
"page.previousLink": "Précédent",
|
|
19
|
-
"page.nextLink": "Suivant"
|
|
20
|
+
"page.nextLink": "Suivant",
|
|
21
|
+
"404.text": "Page non trouvée. Vérifiez l'URL ou essayez d'utiliser la barre de recherche."
|
|
20
22
|
}
|
package/translations/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { builtinI18nSchema } from '../schemas/i18n';
|
|
2
|
+
import cs from './cs.json';
|
|
2
3
|
import en from './en.json';
|
|
3
4
|
import es from './es.json';
|
|
4
5
|
import de from './de.json';
|
|
@@ -10,5 +11,5 @@ import it from './it.json';
|
|
|
10
11
|
const { parse } = builtinI18nSchema();
|
|
11
12
|
|
|
12
13
|
export default Object.fromEntries(
|
|
13
|
-
Object.entries({ en, es, de, ja, pt, fr, it }).map(([key, dict]) => [key, parse(dict)])
|
|
14
|
+
Object.entries({ cs, en, es, de, ja, pt, fr, it }).map(([key, dict]) => [key, parse(dict)])
|
|
14
15
|
);
|
package/translations/it.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Cerca",
|
|
4
4
|
"search.shortcutLabel": "(Usa / per cercare)",
|
|
5
5
|
"search.cancelLabel": "Cancella",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Seleziona tema",
|
|
7
8
|
"themeSelect.dark": "Scuro",
|
|
8
9
|
"themeSelect.light": "Chiaro",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Modifica pagina",
|
|
17
18
|
"page.lastUpdated": "Ultimo aggiornamento:",
|
|
18
19
|
"page.previousLink": "Indietro",
|
|
19
|
-
"page.nextLink": "Avanti"
|
|
20
|
+
"page.nextLink": "Avanti",
|
|
21
|
+
"404.text": "Pagina non trovata. Verifica l'URL o prova a utilizzare la barra di ricerca."
|
|
20
22
|
}
|
package/translations/ja.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "検索",
|
|
4
4
|
"search.shortcutLabel": "(/を押して検索)",
|
|
5
5
|
"search.cancelLabel": "キャンセル",
|
|
6
|
+
"search.devWarning": "検索はプロダクションビルドでのみ利用可能です。\nローカルでテストするには、サイトをビルドしてプレビューしてください。",
|
|
6
7
|
"themeSelect.accessibleLabel": "テーマの選択",
|
|
7
8
|
"themeSelect.dark": "ダーク",
|
|
8
9
|
"themeSelect.light": "ライト",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "ページを編集",
|
|
17
18
|
"page.lastUpdated": "最終更新日:",
|
|
18
19
|
"page.previousLink": "前へ",
|
|
19
|
-
"page.nextLink": "次へ"
|
|
20
|
+
"page.nextLink": "次へ",
|
|
21
|
+
"404.text": "ページが見つかりません。 URL を確認するか、検索バーを使用してみてください。"
|
|
20
22
|
}
|
package/translations/pt.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Pesquisar",
|
|
4
4
|
"search.shortcutLabel": "(Pressione / para Pesquisar)",
|
|
5
5
|
"search.cancelLabel": "Cancelar",
|
|
6
|
+
"search.devWarning": "A pesquisa está disponível apenas em builds em produção. \nTente fazer a build e pré-visualize o site para testar localmente.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Selecionar tema",
|
|
7
8
|
"themeSelect.dark": "Escuro",
|
|
8
9
|
"themeSelect.light": "Claro",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Editar página",
|
|
17
18
|
"page.lastUpdated": "Última atualização:",
|
|
18
19
|
"page.previousLink": "Anterior",
|
|
19
|
-
"page.nextLink": "Próximo"
|
|
20
|
+
"page.nextLink": "Próximo",
|
|
21
|
+
"404.text": "Página não encontrada. Verifique o URL ou tente usar a barra de pesquisa."
|
|
20
22
|
}
|
package/utils/navigation.ts
CHANGED
|
@@ -69,9 +69,9 @@ function groupFromAutogenerateConfig(
|
|
|
69
69
|
const dirDocs = routes.filter(
|
|
70
70
|
(doc) =>
|
|
71
71
|
// Match against `foo.md` or `foo/index.md`.
|
|
72
|
-
doc.
|
|
72
|
+
stripExtension(doc.id) === localeDir ||
|
|
73
73
|
// Match against `foo/anything/else.md`.
|
|
74
|
-
doc.
|
|
74
|
+
doc.id.startsWith(localeDir + '/')
|
|
75
75
|
);
|
|
76
76
|
const tree = treeify(dirDocs, localeDir);
|
|
77
77
|
return {
|
|
@@ -115,16 +115,18 @@ function makeLink(href: string, label: string, currentPathname: string): Link {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/** Get the segments leading to a page. */
|
|
118
|
-
function getBreadcrumbs(
|
|
119
|
-
//
|
|
120
|
-
|
|
118
|
+
function getBreadcrumbs(path: string, baseDir: string): string[] {
|
|
119
|
+
// Strip extension from path.
|
|
120
|
+
const pathWithoutExt = stripExtension(path);
|
|
121
|
+
// Index paths will match `baseDir` and don’t include breadcrumbs.
|
|
122
|
+
if (pathWithoutExt === baseDir) return [];
|
|
121
123
|
// Ensure base directory ends in a trailing slash.
|
|
122
124
|
if (!baseDir.endsWith('/')) baseDir += '/';
|
|
123
|
-
// Strip base directory from
|
|
124
|
-
const
|
|
125
|
-
?
|
|
126
|
-
:
|
|
127
|
-
let dir = dirname(
|
|
125
|
+
// Strip base directory from path if present.
|
|
126
|
+
const relativePath = pathWithoutExt.startsWith(baseDir)
|
|
127
|
+
? pathWithoutExt.replace(baseDir, '')
|
|
128
|
+
: pathWithoutExt;
|
|
129
|
+
let dir = dirname(relativePath);
|
|
128
130
|
// Return no breadcrumbs for items in the root directory.
|
|
129
131
|
if (dir === '.') return [];
|
|
130
132
|
return dir.split('/');
|
|
@@ -134,7 +136,7 @@ function getBreadcrumbs(slug: string, baseDir: string): string[] {
|
|
|
134
136
|
function treeify(routes: Route[], baseDir: string): Dir {
|
|
135
137
|
const treeRoot: Dir = {};
|
|
136
138
|
routes.forEach((doc) => {
|
|
137
|
-
const breadcrumbs = getBreadcrumbs(doc.
|
|
139
|
+
const breadcrumbs = getBreadcrumbs(doc.id, baseDir);
|
|
138
140
|
|
|
139
141
|
// Walk down the route’s path to generate the tree.
|
|
140
142
|
let currentDir = treeRoot;
|
|
@@ -236,3 +238,6 @@ export function getPrevNextLinks(sidebar: SidebarEntry[]): {
|
|
|
236
238
|
const next = currentIndex > -1 ? entries[currentIndex + 1] : undefined;
|
|
237
239
|
return { prev, next };
|
|
238
240
|
}
|
|
241
|
+
|
|
242
|
+
/** Remove the extension from a path. */
|
|
243
|
+
const stripExtension = (path: string) => path.replace(/\.\w+$/, '');
|
package/utils/routing.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { CollectionEntry, getCollection } from 'astro:content';
|
|
|
3
3
|
import config from 'virtual:starlight/user-config';
|
|
4
4
|
import {
|
|
5
5
|
LocaleData,
|
|
6
|
+
localizedId,
|
|
6
7
|
localizedSlug,
|
|
7
8
|
slugToLocaleData,
|
|
8
9
|
slugToParam,
|
|
@@ -16,6 +17,7 @@ export interface Route extends LocaleData {
|
|
|
16
17
|
entry: StarlightDocsEntry;
|
|
17
18
|
entryMeta: LocaleData;
|
|
18
19
|
slug: string;
|
|
20
|
+
id: string;
|
|
19
21
|
isFallback?: true;
|
|
20
22
|
[key: string]: unknown;
|
|
21
23
|
}
|
|
@@ -41,6 +43,7 @@ function getRoutes(): Route[] {
|
|
|
41
43
|
const routes: Route[] = docs.map((entry) => ({
|
|
42
44
|
entry,
|
|
43
45
|
slug: entry.slug,
|
|
46
|
+
id: entry.id,
|
|
44
47
|
entryMeta: slugToLocaleData(entry.slug),
|
|
45
48
|
...slugToLocaleData(entry.slug),
|
|
46
49
|
}));
|
|
@@ -61,11 +64,13 @@ function getRoutes(): Route[] {
|
|
|
61
64
|
const localeDocs = getLocaleDocs(locale);
|
|
62
65
|
for (const fallback of defaultLocaleDocs) {
|
|
63
66
|
const slug = localizedSlug(fallback.slug, locale);
|
|
67
|
+
const id = localizedId(fallback.id, locale);
|
|
64
68
|
const doesNotNeedFallback = localeDocs.some((doc) => doc.slug === slug);
|
|
65
69
|
if (doesNotNeedFallback) continue;
|
|
66
70
|
routes.push({
|
|
67
71
|
entry: fallback,
|
|
68
72
|
slug,
|
|
73
|
+
id,
|
|
69
74
|
isFallback: true,
|
|
70
75
|
lang: localeConfig.lang || 'en',
|
|
71
76
|
locale,
|
package/utils/slugs.ts
CHANGED
|
@@ -90,3 +90,24 @@ export function localizedSlug(
|
|
|
90
90
|
}
|
|
91
91
|
return slug ? locale + '/' + slug : locale;
|
|
92
92
|
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Convert a collection entry ID to a different locale.
|
|
96
|
+
* For example, passing an ID of `en/home.md` and a locale of `fr` results in `fr/home.md`.
|
|
97
|
+
* An undefined locale is treated as the root locale, resulting in `home.md`.
|
|
98
|
+
* @param id A collection entry ID
|
|
99
|
+
* @param locale The target locale
|
|
100
|
+
* @example
|
|
101
|
+
* localizedSlug('en/home.md', 'fr') // => 'fr/home.md'
|
|
102
|
+
* localizedSlug('en/home.md', undefined) // => 'home.md'
|
|
103
|
+
*/
|
|
104
|
+
export function localizedId(id: string, locale: string | undefined): string {
|
|
105
|
+
const idLocale = slugToLocale(id);
|
|
106
|
+
if (idLocale) {
|
|
107
|
+
return id.replace(idLocale + '/', locale ? locale + '/' : '');
|
|
108
|
+
} else if (locale) {
|
|
109
|
+
return locale + '/' + id;
|
|
110
|
+
} else {
|
|
111
|
+
return id;
|
|
112
|
+
}
|
|
113
|
+
}
|