@jet-w/astro-blog 0.2.5 → 0.2.7
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/package.json +1 -1
- package/src/components/blog/Hero.astro +9 -6
- package/src/components/blog/PostCard.astro +4 -8
- package/src/components/home/FeaturedPostsSection.astro +9 -4
- package/src/components/home/QuickNavSection.astro +9 -4
- package/src/components/home/RecentPostsSection.astro +9 -4
- package/src/components/home/StatsSection.astro +9 -3
- package/src/components/layout/Footer.astro +16 -7
- package/src/components/layout/Header.astro +15 -12
- package/src/components/layout/Sidebar.astro +11 -6
- package/src/components/media/Slides.astro +22 -6
- package/src/components/ui/LanguageSwitcher.vue +24 -12
- package/src/components/ui/MobileMenu.vue +20 -3
- package/src/layouts/BaseLayout.astro +14 -7
- package/src/layouts/PageLayout.astro +9 -3
- package/src/layouts/SlidesLayout.astro +34 -16
- package/src/pages/archives/[year]/[month]/page/[page].astro +42 -18
- package/src/pages/archives/[year]/[month].astro +7 -2
- package/src/pages/archives/index.astro +7 -3
- package/src/pages/categories/[category]/page/[page].astro +40 -18
- package/src/pages/categories/[category].astro +7 -2
- package/src/pages/categories/index.astro +7 -3
- package/src/pages/posts/[...slug].astro +79 -4
- package/src/pages/posts/index.astro +7 -3
- package/src/pages/posts/page/[page].astro +7 -2
- package/src/pages/search.astro +9 -3
- package/src/pages/slides/index.astro +7 -3
- package/src/pages/tags/[tag]/page/[page].astro +39 -17
- package/src/pages/tags/[tag].astro +7 -2
- package/src/pages/tags/index.astro +7 -3
- package/src/plugins/rehype-relative-links.mjs +90 -14
- package/templates/default/.claude/ralph-loop.local.md +2 -32
- package/templates/default/Makefile +37 -0
- package/templates/default/astro.config.mjs +7 -3
- package/templates/default/package.prod.json +31 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import { siteConfig } from '@jet-w/astro-blog/config';
|
|
|
3
3
|
import type { I18nConfig } from '../../config/i18n';
|
|
4
4
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
5
5
|
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
6
|
-
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, withBase } from '../../utils/i18n';
|
|
6
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, withBase, removeBase } from '../../utils/i18n';
|
|
7
7
|
|
|
8
8
|
export interface Props {
|
|
9
9
|
i18nConfig?: I18nConfig;
|
|
@@ -11,13 +11,16 @@ export interface Props {
|
|
|
11
11
|
|
|
12
12
|
const { i18nConfig = virtualI18nConfig || defaultI18nConfig } = Astro.props;
|
|
13
13
|
|
|
14
|
-
// Get current locale from URL
|
|
15
|
-
const currentLocale = getLocaleFromPath(Astro.url.pathname, i18nConfig);
|
|
16
|
-
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
17
|
-
const ui = localeConfig.ui;
|
|
18
|
-
|
|
19
14
|
// Get base URL for prefixing links
|
|
20
15
|
const base = import.meta.env.BASE_URL;
|
|
16
|
+
|
|
17
|
+
// Remove base URL from current path for locale detection
|
|
18
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
19
|
+
|
|
20
|
+
// Get current locale from URL (use path without base)
|
|
21
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
22
|
+
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
23
|
+
const ui = localeConfig.ui;
|
|
21
24
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
22
25
|
---
|
|
23
26
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
---
|
|
2
|
-
import { withBase } from '../../utils/i18n';
|
|
3
|
-
|
|
4
2
|
export interface Props {
|
|
5
3
|
post: {
|
|
6
4
|
slug: string;
|
|
@@ -32,8 +30,6 @@ const {
|
|
|
32
30
|
ui = { readMore: '阅读更多', minuteRead: '分钟' }
|
|
33
31
|
} = Astro.props;
|
|
34
32
|
|
|
35
|
-
const base = import.meta.env.BASE_URL;
|
|
36
|
-
|
|
37
33
|
const formattedDate = post.pubDate
|
|
38
34
|
? new Intl.DateTimeFormat(locale, {
|
|
39
35
|
year: 'numeric',
|
|
@@ -49,10 +45,10 @@ const tagToSlug = (tag: string) => tag.toLowerCase().replace(/\s+/g, '-');
|
|
|
49
45
|
// 将分类名转换为 slug 格式
|
|
50
46
|
const categoryToSlug = (category: string) => category.toLowerCase().replace(/\s+/g, '-');
|
|
51
47
|
|
|
52
|
-
// Build URLs with locale prefix
|
|
53
|
-
const postUrl =
|
|
54
|
-
const tagUrl = (tag: string) =>
|
|
55
|
-
const categoryUrl = (category: string) =>
|
|
48
|
+
// Build URLs with locale prefix (localePrefix already contains base URL)
|
|
49
|
+
const postUrl = `${localePrefix}/posts/${post.slug}`;
|
|
50
|
+
const tagUrl = (tag: string) => `${localePrefix}/tags/${tagToSlug(tag)}`;
|
|
51
|
+
const categoryUrl = (category: string) => `${localePrefix}/categories/${categoryToSlug(category)}`;
|
|
56
52
|
---
|
|
57
53
|
|
|
58
54
|
<article class={`group card hover:shadow-lg transform hover:-translate-y-1 transition-all duration-300 ${isHorizontal ? 'flex gap-6 items-center' : 'block'}`}>
|
|
@@ -7,7 +7,7 @@ import { getCollection } from 'astro:content';
|
|
|
7
7
|
import type { I18nConfig } from '../../config/i18n';
|
|
8
8
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
9
9
|
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
10
|
-
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale } from '../../utils/i18n';
|
|
10
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale, removeBase } from '../../utils/i18n';
|
|
11
11
|
|
|
12
12
|
export interface Props {
|
|
13
13
|
count?: number;
|
|
@@ -16,11 +16,16 @@ export interface Props {
|
|
|
16
16
|
|
|
17
17
|
const { count = 3, i18nConfig = virtualI18nConfig || defaultI18nConfig } = Astro.props;
|
|
18
18
|
|
|
19
|
-
// Get
|
|
20
|
-
const
|
|
19
|
+
// Get base URL for prefixing links
|
|
20
|
+
const base = import.meta.env.BASE_URL;
|
|
21
|
+
|
|
22
|
+
// Remove base URL from current path for locale detection
|
|
23
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
24
|
+
|
|
25
|
+
// Get current locale from URL (use path without base)
|
|
26
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
21
27
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
22
28
|
const ui = localeConfig.ui;
|
|
23
|
-
const base = import.meta.env.BASE_URL;
|
|
24
29
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
25
30
|
|
|
26
31
|
const allPosts = await getCollection('posts');
|
|
@@ -7,7 +7,7 @@ import { getCollection } from 'astro:content';
|
|
|
7
7
|
import type { I18nConfig } from '../../config/i18n';
|
|
8
8
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
9
9
|
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
10
|
-
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale } from '../../utils/i18n';
|
|
10
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale, removeBase } from '../../utils/i18n';
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
13
|
i18nConfig?: I18nConfig;
|
|
@@ -15,11 +15,16 @@ interface Props {
|
|
|
15
15
|
|
|
16
16
|
const { i18nConfig = virtualI18nConfig || defaultI18nConfig } = Astro.props;
|
|
17
17
|
|
|
18
|
-
// Get
|
|
19
|
-
const
|
|
18
|
+
// Get base URL for prefixing links
|
|
19
|
+
const base = import.meta.env.BASE_URL;
|
|
20
|
+
|
|
21
|
+
// Remove base URL from current path for locale detection
|
|
22
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
23
|
+
|
|
24
|
+
// Get current locale and translations (use path without base)
|
|
25
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
20
26
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
21
27
|
const ui = localeConfig.ui;
|
|
22
|
-
const base = import.meta.env.BASE_URL;
|
|
23
28
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
24
29
|
|
|
25
30
|
const allPosts = await getCollection('posts', ({ data }) => !data.draft);
|
|
@@ -7,7 +7,7 @@ import { getCollection } from 'astro:content';
|
|
|
7
7
|
import type { I18nConfig } from '../../config/i18n';
|
|
8
8
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
9
9
|
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
10
|
-
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale } from '../../utils/i18n';
|
|
10
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, filterPostsByLocale, removeBase } from '../../utils/i18n';
|
|
11
11
|
|
|
12
12
|
export interface Props {
|
|
13
13
|
count?: number;
|
|
@@ -16,11 +16,16 @@ export interface Props {
|
|
|
16
16
|
|
|
17
17
|
const { count = 6, i18nConfig = virtualI18nConfig || defaultI18nConfig } = Astro.props;
|
|
18
18
|
|
|
19
|
-
// Get
|
|
20
|
-
const
|
|
19
|
+
// Get base URL for prefixing links
|
|
20
|
+
const base = import.meta.env.BASE_URL;
|
|
21
|
+
|
|
22
|
+
// Remove base URL from current path for locale detection
|
|
23
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
24
|
+
|
|
25
|
+
// Get current locale from URL (use path without base)
|
|
26
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
21
27
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
22
28
|
const ui = localeConfig.ui;
|
|
23
|
-
const base = import.meta.env.BASE_URL;
|
|
24
29
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
25
30
|
|
|
26
31
|
const allPosts = await getCollection('posts');
|
|
@@ -6,7 +6,7 @@ import { getCollection } from 'astro:content';
|
|
|
6
6
|
import type { I18nConfig } from '../../config/i18n';
|
|
7
7
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
8
8
|
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
9
|
-
import { getLocaleFromPath, getLocaleConfig, filterPostsByLocale } from '../../utils/i18n';
|
|
9
|
+
import { getLocaleFromPath, getLocaleConfig, filterPostsByLocale, removeBase } from '../../utils/i18n';
|
|
10
10
|
|
|
11
11
|
export interface Props {
|
|
12
12
|
i18nConfig?: I18nConfig;
|
|
@@ -14,8 +14,14 @@ export interface Props {
|
|
|
14
14
|
|
|
15
15
|
const { i18nConfig = virtualI18nConfig || defaultI18nConfig } = Astro.props;
|
|
16
16
|
|
|
17
|
-
// Get
|
|
18
|
-
const
|
|
17
|
+
// Get base URL for prefixing links
|
|
18
|
+
const base = import.meta.env.BASE_URL;
|
|
19
|
+
|
|
20
|
+
// Remove base URL from current path for locale detection
|
|
21
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
22
|
+
|
|
23
|
+
// Get current locale from URL (use path without base)
|
|
24
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
19
25
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
20
26
|
const ui = localeConfig.ui;
|
|
21
27
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { siteConfig, footerConfig, defaultIcons } from '@jet-w/astro-blog/config';
|
|
3
3
|
import type { I18nConfig } from '../../config/i18n';
|
|
4
4
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
5
|
-
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix } from '../../utils/i18n';
|
|
5
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, removeBase, withBase } from '../../utils/i18n';
|
|
6
6
|
|
|
7
7
|
export interface Props {
|
|
8
8
|
i18nConfig?: I18nConfig;
|
|
@@ -10,7 +10,13 @@ export interface Props {
|
|
|
10
10
|
|
|
11
11
|
const { i18nConfig = defaultI18nConfig } = Astro.props;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
// Get base URL for prefixing links
|
|
14
|
+
const base = import.meta.env.BASE_URL;
|
|
15
|
+
|
|
16
|
+
// Remove base URL from current path for locale detection
|
|
17
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
18
|
+
|
|
19
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
14
20
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
15
21
|
const ui = localeConfig.ui;
|
|
16
22
|
|
|
@@ -24,10 +30,13 @@ function getIcon(link: { type: string; icon?: string }): string {
|
|
|
24
30
|
return link.icon || defaultIcons[link.type] || '';
|
|
25
31
|
}
|
|
26
32
|
|
|
27
|
-
// Get locale prefix for RSS link
|
|
28
|
-
const base = import.meta.env.BASE_URL;
|
|
33
|
+
// Get locale prefix for RSS link (already includes base)
|
|
29
34
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
30
|
-
|
|
35
|
+
// Apply withBase to rssUrl if it's a relative path
|
|
36
|
+
const configRssUrl = localeFooterConfig.rssUrl || footerConfig.rssUrl;
|
|
37
|
+
const rssUrl = configRssUrl
|
|
38
|
+
? (configRssUrl.startsWith('/') && !configRssUrl.startsWith(base) ? withBase(configRssUrl, base) : configRssUrl)
|
|
39
|
+
: `${localePrefix}/rss.xml`;
|
|
31
40
|
|
|
32
41
|
const copyright = (localeFooterConfig.copyright || footerConfig.copyright)
|
|
33
42
|
.replace('{year}', String(currentYear))
|
|
@@ -41,7 +50,7 @@ const copyright = (localeFooterConfig.copyright || footerConfig.copyright)
|
|
|
41
50
|
<div class="flex items-center space-x-3 mb-3">
|
|
42
51
|
{(localeSiteConfig.avatar || siteConfig.avatar) && (
|
|
43
52
|
<img
|
|
44
|
-
src={localeSiteConfig.avatar || siteConfig.avatar}
|
|
53
|
+
src={withBase(localeSiteConfig.avatar || siteConfig.avatar || '', base)}
|
|
45
54
|
alt={localeSiteConfig.title || siteConfig.title}
|
|
46
55
|
class="w-8 h-8 rounded-full"
|
|
47
56
|
/>
|
|
@@ -64,7 +73,7 @@ const copyright = (localeFooterConfig.copyright || footerConfig.copyright)
|
|
|
64
73
|
<div class="flex flex-wrap gap-x-4 gap-y-1">
|
|
65
74
|
{(localeFooterConfig.quickLinks || footerConfig.quickLinks).map((item) => (
|
|
66
75
|
<a
|
|
67
|
-
href={item.href}
|
|
76
|
+
href={withBase(item.href, base)}
|
|
68
77
|
class="text-sm text-slate-600 dark:text-slate-400 hover:text-primary-500 transition-colors"
|
|
69
78
|
>
|
|
70
79
|
{item.name}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getLocaleFromPath,
|
|
12
12
|
getLocaleConfig,
|
|
13
13
|
removeLocalePrefix,
|
|
14
|
+
removeBase,
|
|
14
15
|
isMultiLanguageEnabled,
|
|
15
16
|
withBase,
|
|
16
17
|
} from '../../utils/i18n';
|
|
@@ -22,7 +23,15 @@ export interface Props {
|
|
|
22
23
|
const { i18nConfig = virtualI18nConfig || defaultI18nConfig } = Astro.props;
|
|
23
24
|
|
|
24
25
|
const currentPath = Astro.url.pathname;
|
|
25
|
-
|
|
26
|
+
|
|
27
|
+
// Get base URL for prefixing links
|
|
28
|
+
const base = import.meta.env.BASE_URL;
|
|
29
|
+
|
|
30
|
+
// Get base path without base URL - needed for locale detection
|
|
31
|
+
const pathWithoutBase = removeBase(currentPath, base);
|
|
32
|
+
|
|
33
|
+
// Detect current locale from path (without base URL)
|
|
34
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
26
35
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
27
36
|
const ui = localeConfig.ui;
|
|
28
37
|
|
|
@@ -30,8 +39,8 @@ const ui = localeConfig.ui;
|
|
|
30
39
|
const localeSiteConfig = localeConfig.site;
|
|
31
40
|
const menu = localeConfig.menu;
|
|
32
41
|
|
|
33
|
-
// Get
|
|
34
|
-
const
|
|
42
|
+
// Get path without locale prefix for language switcher
|
|
43
|
+
const pathWithoutLocale = removeLocalePrefix(pathWithoutBase, i18nConfig);
|
|
35
44
|
|
|
36
45
|
// Check if multi-language is enabled
|
|
37
46
|
const showLanguageSwitcher = isMultiLanguageEnabled(i18nConfig);
|
|
@@ -41,9 +50,6 @@ const localesForSwitcher = i18nConfig.locales.map(l => ({
|
|
|
41
50
|
code: l.code,
|
|
42
51
|
name: l.name,
|
|
43
52
|
}));
|
|
44
|
-
|
|
45
|
-
// Get base URL for prefixing links
|
|
46
|
-
const base = import.meta.env.BASE_URL;
|
|
47
53
|
---
|
|
48
54
|
|
|
49
55
|
<header class="sticky top-0 z-50 bg-white/80 dark:bg-slate-900/80 backdrop-blur-sm border-b border-slate-200 dark:border-slate-700">
|
|
@@ -102,9 +108,10 @@ const base = import.meta.env.BASE_URL;
|
|
|
102
108
|
client:load
|
|
103
109
|
locales={localesForSwitcher}
|
|
104
110
|
currentLocale={currentLocale}
|
|
105
|
-
currentPath={
|
|
111
|
+
currentPath={pathWithoutLocale}
|
|
106
112
|
defaultLocale={i18nConfig.defaultLocale}
|
|
107
113
|
prefixDefaultLocale={i18nConfig.routing.prefixDefaultLocale}
|
|
114
|
+
base={base}
|
|
108
115
|
/>
|
|
109
116
|
</div>
|
|
110
117
|
)}
|
|
@@ -117,11 +124,7 @@ const base = import.meta.env.BASE_URL;
|
|
|
117
124
|
<MobileMenu
|
|
118
125
|
client:load
|
|
119
126
|
navigation={menu}
|
|
120
|
-
|
|
121
|
-
currentLocale={currentLocale}
|
|
122
|
-
currentPath={basePath}
|
|
123
|
-
defaultLocale={i18nConfig.defaultLocale}
|
|
124
|
-
prefixDefaultLocale={i18nConfig.routing.prefixDefaultLocale}
|
|
127
|
+
base={base}
|
|
125
128
|
/>
|
|
126
129
|
</div>
|
|
127
130
|
</div>
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from '@jet-w/astro-blog/utils/sidebar';
|
|
11
11
|
import type { I18nConfig } from '../../config/i18n';
|
|
12
12
|
import { defaultI18nConfig } from '../../config/i18n';
|
|
13
|
-
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, formatDate, filterPostsByLocale } from '../../utils/i18n';
|
|
13
|
+
import { getLocaleFromPath, getLocaleConfig, getLocalePrefix, formatDate, filterPostsByLocale, removeBase } from '../../utils/i18n';
|
|
14
14
|
|
|
15
15
|
interface Props {
|
|
16
16
|
currentPath?: string;
|
|
@@ -19,11 +19,16 @@ interface Props {
|
|
|
19
19
|
|
|
20
20
|
const { currentPath = Astro.url.pathname, i18nConfig = defaultI18nConfig } = Astro.props;
|
|
21
21
|
|
|
22
|
-
// Get
|
|
23
|
-
const
|
|
22
|
+
// Get base URL for prefixing links
|
|
23
|
+
const base = import.meta.env.BASE_URL;
|
|
24
|
+
|
|
25
|
+
// Remove base URL from current path for locale detection and path filtering
|
|
26
|
+
const pathWithoutBase = removeBase(currentPath, base);
|
|
27
|
+
|
|
28
|
+
// Get current locale and translations (use path without base)
|
|
29
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
24
30
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
25
31
|
const ui = localeConfig.ui;
|
|
26
|
-
const base = import.meta.env.BASE_URL;
|
|
27
32
|
const localePrefix = getLocalePrefix(currentLocale, i18nConfig, base);
|
|
28
33
|
|
|
29
34
|
// Get locale-specific sidebar config (already merged with defaults in getLocaleConfig)
|
|
@@ -35,8 +40,8 @@ const allPosts = await getCollection('posts', ({ data }) => !data.draft);
|
|
|
35
40
|
// Filter posts by current locale for sidebar widgets
|
|
36
41
|
const localePosts = filterPostsByLocale(allPosts, currentLocale, i18nConfig);
|
|
37
42
|
|
|
38
|
-
// 根据当前路径过滤侧边栏组
|
|
39
|
-
const filteredGroups = filterGroupsByPath(sidebarConfig.groups,
|
|
43
|
+
// 根据当前路径过滤侧边栏组 (use path without base for pattern matching)
|
|
44
|
+
const filteredGroups = filterGroupsByPath(sidebarConfig.groups, pathWithoutBase);
|
|
40
45
|
|
|
41
46
|
// 创建过滤后的配置
|
|
42
47
|
const filteredConfig = { ...sidebarConfig, groups: filteredGroups };
|
|
@@ -78,6 +78,9 @@ const revealConfig = JSON.stringify({
|
|
|
78
78
|
touch: true,
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
+
// Get base URL for static assets
|
|
82
|
+
const base = import.meta.env.BASE_URL;
|
|
83
|
+
|
|
81
84
|
// 获取 slot 内容
|
|
82
85
|
const slotContent = await Astro.slots.render('default');
|
|
83
86
|
const hasInlineContent = slotContent && slotContent.trim().length > 0;
|
|
@@ -164,13 +167,26 @@ const slidesData = hasInlineContent ? parseSlides(slotContent) : [];
|
|
|
164
167
|
</div>
|
|
165
168
|
|
|
166
169
|
<!-- Reveal.js 资源 -->
|
|
167
|
-
<link rel="stylesheet" href=
|
|
168
|
-
<link rel="stylesheet" href={
|
|
169
|
-
<link rel="stylesheet" href=
|
|
170
|
+
<link rel="stylesheet" href={`${base}slides/reveal.css`} />
|
|
171
|
+
<link rel="stylesheet" href={`${base}slides/theme/${theme}.css`} />
|
|
172
|
+
<link rel="stylesheet" href={`${base}slides/plugin/highlight/monokai.css`} />
|
|
170
173
|
|
|
171
|
-
|
|
172
|
-
<script is:inline
|
|
173
|
-
|
|
174
|
+
<!-- Reveal.js - dynamically loaded with base URL -->
|
|
175
|
+
<script is:inline define:vars={{ baseUrl: base }}>
|
|
176
|
+
(function() {
|
|
177
|
+
var scripts = [
|
|
178
|
+
baseUrl + 'slides/reveal.js',
|
|
179
|
+
baseUrl + 'slides/plugin/markdown/markdown.js',
|
|
180
|
+
baseUrl + 'slides/plugin/highlight/highlight.js'
|
|
181
|
+
];
|
|
182
|
+
scripts.forEach(function(src) {
|
|
183
|
+
var script = document.createElement('script');
|
|
184
|
+
script.src = src;
|
|
185
|
+
script.async = false;
|
|
186
|
+
document.head.appendChild(script);
|
|
187
|
+
});
|
|
188
|
+
})();
|
|
189
|
+
</script>
|
|
174
190
|
|
|
175
191
|
<script is:inline define:vars={{ slidesId, revealConfig }}>
|
|
176
192
|
(function() {
|
|
@@ -101,16 +101,19 @@ interface Props {
|
|
|
101
101
|
locales: LocaleInfo[];
|
|
102
102
|
/** Current locale code */
|
|
103
103
|
currentLocale: string;
|
|
104
|
-
/** Current page path (without locale prefix) */
|
|
104
|
+
/** Current page path (without locale prefix and without base) */
|
|
105
105
|
currentPath: string;
|
|
106
106
|
/** Default locale code */
|
|
107
107
|
defaultLocale: string;
|
|
108
108
|
/** Whether to prefix the default locale in URLs */
|
|
109
109
|
prefixDefaultLocale?: boolean;
|
|
110
|
+
/** Base URL for the site (e.g., '/jet-w.astro-blog') */
|
|
111
|
+
base?: string;
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
const props = withDefaults(defineProps<Props>(), {
|
|
113
115
|
prefixDefaultLocale: false,
|
|
116
|
+
base: '/',
|
|
114
117
|
});
|
|
115
118
|
|
|
116
119
|
const isOpen = ref(false);
|
|
@@ -138,23 +141,32 @@ function closeDropdown() {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
function getLocalizedUrl(targetLocale: string): string {
|
|
141
|
-
// Normalize the path
|
|
142
|
-
let
|
|
143
|
-
if (!
|
|
144
|
-
|
|
144
|
+
// Normalize the current path (without base and without locale)
|
|
145
|
+
let pagePath = props.currentPath;
|
|
146
|
+
if (!pagePath.startsWith('/')) {
|
|
147
|
+
pagePath = '/' + pagePath;
|
|
145
148
|
}
|
|
146
149
|
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
// Normalize base URL - remove trailing slash
|
|
151
|
+
const baseUrl = props.base?.replace(/\/$/, '') || '';
|
|
152
|
+
|
|
153
|
+
// Build locale prefix
|
|
154
|
+
let localePrefix = '';
|
|
155
|
+
if (targetLocale !== props.defaultLocale || props.prefixDefaultLocale) {
|
|
156
|
+
localePrefix = `/${targetLocale}`;
|
|
150
157
|
}
|
|
151
158
|
|
|
152
|
-
//
|
|
153
|
-
if (
|
|
154
|
-
|
|
159
|
+
// Combine: base + locale + path
|
|
160
|
+
if (pagePath === '/') {
|
|
161
|
+
// Home page
|
|
162
|
+
if (localePrefix) {
|
|
163
|
+
return baseUrl ? `${baseUrl}${localePrefix}/` : `${localePrefix}/`;
|
|
164
|
+
}
|
|
165
|
+
return baseUrl ? `${baseUrl}/` : '/';
|
|
155
166
|
}
|
|
156
167
|
|
|
157
|
-
|
|
168
|
+
// Other pages
|
|
169
|
+
return `${baseUrl}${localePrefix}${pagePath}`;
|
|
158
170
|
}
|
|
159
171
|
|
|
160
172
|
// Close dropdown when clicking outside
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<a
|
|
72
72
|
v-for="item in navigation"
|
|
73
73
|
:key="item.href"
|
|
74
|
-
:href="item.href"
|
|
74
|
+
:href="withBase(item.href)"
|
|
75
75
|
@click="isOpen = false"
|
|
76
76
|
class="flex items-center px-4 py-3 rounded-lg text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors"
|
|
77
77
|
:class="{ 'bg-primary-50 dark:bg-primary-900/20 text-primary-600 dark:text-primary-400': isActive(item.href) }"
|
|
@@ -98,16 +98,33 @@
|
|
|
98
98
|
</template>
|
|
99
99
|
|
|
100
100
|
<script setup lang="ts">
|
|
101
|
-
import { ref, onMounted, onUnmounted } from 'vue'
|
|
101
|
+
import { ref, onMounted, onUnmounted, withDefaults } from 'vue'
|
|
102
102
|
import type { NavigationItem } from '@jet-w/astro-blog/types'
|
|
103
103
|
import SearchBox from './SearchBox.vue'
|
|
104
104
|
import ThemeToggle from './ThemeToggle.vue'
|
|
105
105
|
|
|
106
106
|
interface Props {
|
|
107
107
|
navigation: NavigationItem[]
|
|
108
|
+
/** Base URL for the site (e.g., '/jet-w.astro-blog') */
|
|
109
|
+
base?: string
|
|
108
110
|
}
|
|
109
111
|
|
|
110
|
-
const props = defineProps<Props>()
|
|
112
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
113
|
+
base: '/',
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
// Helper function to add base URL to paths
|
|
117
|
+
function withBase(path: string): string {
|
|
118
|
+
const baseUrl = props.base?.replace(/\/$/, '') || '';
|
|
119
|
+
if (!baseUrl || baseUrl === '') {
|
|
120
|
+
return path;
|
|
121
|
+
}
|
|
122
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
123
|
+
if (normalizedPath === '/') {
|
|
124
|
+
return `${baseUrl}/`;
|
|
125
|
+
}
|
|
126
|
+
return `${baseUrl}${normalizedPath}`;
|
|
127
|
+
}
|
|
111
128
|
const isOpen = ref(false)
|
|
112
129
|
const currentPath = ref('')
|
|
113
130
|
const isMounted = ref(false)
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getTextDirection,
|
|
12
12
|
isMultiLanguageEnabled,
|
|
13
13
|
withBase,
|
|
14
|
+
removeBase,
|
|
14
15
|
t,
|
|
15
16
|
type I18nConfig,
|
|
16
17
|
} from '../utils/i18n';
|
|
@@ -40,8 +41,14 @@ const {
|
|
|
40
41
|
i18nConfig = virtualI18nConfig || defaultI18nConfig,
|
|
41
42
|
} = Astro.props;
|
|
42
43
|
|
|
43
|
-
// Get
|
|
44
|
-
const
|
|
44
|
+
// Get base URL for prefixing links
|
|
45
|
+
const base = import.meta.env.BASE_URL;
|
|
46
|
+
|
|
47
|
+
// Remove base URL from current path for locale detection
|
|
48
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
49
|
+
|
|
50
|
+
// Get current locale from URL (use path without base)
|
|
51
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
45
52
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
46
53
|
const localeData = localeConfig.locale;
|
|
47
54
|
const ui = localeConfig.ui;
|
|
@@ -55,9 +62,12 @@ const fullTitle = title === siteTitle ? title : `${title} | ${siteTitle}`;
|
|
|
55
62
|
const fullImage = new URL(image, Astro.site);
|
|
56
63
|
|
|
57
64
|
// Get alternate links for SEO (hreflang)
|
|
58
|
-
|
|
65
|
+
// We need to pass the pathname without base URL to getAlternateLinks
|
|
66
|
+
// Then the baseUrl for combining should include the base path
|
|
67
|
+
const siteUrl = Astro.site?.toString().replace(/\/$/, '') || '';
|
|
68
|
+
const baseUrlWithPath = base && base !== '/' ? `${siteUrl}${base.replace(/\/$/, '')}` : siteUrl;
|
|
59
69
|
const alternateLinks = isMultiLanguageEnabled(i18nConfig)
|
|
60
|
-
? getAlternateLinks(
|
|
70
|
+
? getAlternateLinks(pathWithoutBase, baseUrlWithPath, i18nConfig)
|
|
61
71
|
: [];
|
|
62
72
|
|
|
63
73
|
// Get locale prefix for RSS link
|
|
@@ -70,9 +80,6 @@ const faviconSvgExists = fs.existsSync(path.join(publicDir, 'favicon.svg'));
|
|
|
70
80
|
const faviconIcoExists = fs.existsSync(path.join(publicDir, 'favicon.ico'));
|
|
71
81
|
const faviconHref = faviconSvgExists ? '/favicon.svg' : faviconIcoExists ? '/favicon.ico' : siteConfig.avatar;
|
|
72
82
|
const faviconType = faviconSvgExists ? 'image/svg+xml' : faviconIcoExists ? 'image/x-icon' : 'image/jpeg';
|
|
73
|
-
|
|
74
|
-
// Get base URL for prefixing links
|
|
75
|
-
const base = import.meta.env.BASE_URL;
|
|
76
83
|
---
|
|
77
84
|
|
|
78
85
|
<!DOCTYPE html>
|
|
@@ -6,7 +6,7 @@ import Sidebar from '../components/layout/Sidebar.astro';
|
|
|
6
6
|
import SidebarToggle from '../components/ui/SidebarToggle.vue';
|
|
7
7
|
import type { I18nConfig } from '../config/i18n';
|
|
8
8
|
import { defaultI18nConfig } from '../config/i18n';
|
|
9
|
-
import { getLocaleFromPath, getLocaleConfig } from '../utils/i18n';
|
|
9
|
+
import { getLocaleFromPath, getLocaleConfig, removeBase } from '../utils/i18n';
|
|
10
10
|
// Import i18n config from virtual module (injected by integration)
|
|
11
11
|
import { i18nConfig as virtualI18nConfig } from 'virtual:astro-blog-i18n';
|
|
12
12
|
|
|
@@ -36,8 +36,14 @@ const {
|
|
|
36
36
|
i18nConfig = virtualI18nConfig || defaultI18nConfig,
|
|
37
37
|
} = Astro.props;
|
|
38
38
|
|
|
39
|
-
// Get
|
|
40
|
-
const
|
|
39
|
+
// Get base URL for prefixing links
|
|
40
|
+
const base = import.meta.env.BASE_URL;
|
|
41
|
+
|
|
42
|
+
// Remove base URL from current path for locale detection
|
|
43
|
+
const pathWithoutBase = removeBase(Astro.url.pathname, base);
|
|
44
|
+
|
|
45
|
+
// Get current locale (use path without base)
|
|
46
|
+
const currentLocale = getLocaleFromPath(pathWithoutBase, i18nConfig);
|
|
41
47
|
const localeConfig = getLocaleConfig(currentLocale, i18nConfig);
|
|
42
48
|
const ui = localeConfig.ui;
|
|
43
49
|
---
|