refactor: enhance theme configuration and path handling

- Update config.ts with more descriptive comments and simplified settings
- Remove about page content section
- Add new path utility functions for localization and page type detection
- Introduce SiteTitle component for mobile post page navigation
- Modify Header and Layout components to use new path utilities
- Adjust title spacing and font sizes
- Update VSCode settings with new dictionary words
This commit is contained in:
radishzzz 2025-02-04 18:56:34 +00:00
parent 35b2542ec8
commit f8bf077948
8 changed files with 130 additions and 93 deletions

13
.vscode/settings.json vendored
View file

@ -62,13 +62,24 @@
"antfu",
"astrojs",
"attributify",
"bmoji",
"gtag",
"katex",
"Lightbox",
"mdast",
"msrc",
"msvalidate",
"overlayscrollbars",
"partytown",
"photoswipe",
"pswp",
"radishzz",
"rehype",
"Retypeset",
"Umami",
"unocss",
"vite"
"vite",
"waline",
"weibo"
]
}

View file

@ -1,25 +1,29 @@
---
import themeConfig from '@/config'
import { getPagePath } from '@/utils/path'
const { title, subtitle } = themeConfig.site
const { titleSpace } = themeConfig.global
const currentPath = Astro.url.pathname
const { getLocalizedPath } = getPagePath(currentPath)
const marginBottom = {
1: 'mb-1',
2: 'mb-2',
3: 'mb-3',
4: 'mb-4',
2: 'mb-3',
3: 'mb-5',
}[titleSpace] || 'mb-3'
---
<header>
<h1 class={`${marginBottom} mt--5.2 text-12 c-primary font-bold font-title`}>
<a href="/">
<h1 class={`${marginBottom} mt--5 text-12.8 c-primary font-bold font-title`}>
<a href={getLocalizedPath('/')}>
{title}
</a>
</h1>
<h2 class="text-5.6 c-secondary font-navbar">
{subtitle}
</h2>
{subtitle && (
<h2 class="text-5.6 c-secondary font-navbar">
{subtitle}
</h2>
)}
</header>

View file

@ -1,49 +1,14 @@
---
import themeConfig from '@/config'
import { getPagePath } from '@/utils/path'
import { ui } from '@/utils/ui'
const defaultLocale = themeConfig.global.locale
const moreLocales = themeConfig.global.moreLocale
const currentPath = Astro.url.pathname
const cleanPath = (path: string) => path.replace(/^\/+|\/+$/g, '')
function getLangFromPath(path: string) {
const secondaryLang = moreLocales.find(lang =>
path.startsWith(`/${lang}/`) || path === `/${lang}` || path === `/${lang}/`,
)
return secondaryLang || defaultLocale
}
const currentLang = getLangFromPath(currentPath)
const { currentLang, isHome, isPost, isTag, isAbout, getLocalizedPath } = getPagePath(currentPath)
const currentUI = ui[currentLang as keyof typeof ui]
function getLocalizedPath(path: string) {
const clean = cleanPath(path)
return currentLang === defaultLocale ? `/${clean}` : `/${currentLang}/${clean}`
}
function isHomePage(path: string) {
const clean = cleanPath(path)
return clean === '' || moreLocales.includes(clean)
}
function isPostPage(path: string) {
const clean = cleanPath(path)
return clean.startsWith('posts') || moreLocales.some(lang => clean.startsWith(`${lang}/posts`))
}
function isTagPage(path: string) {
const clean = cleanPath(path)
return clean.startsWith('tags') || moreLocales.some(lang => clean.startsWith(`${lang}/tags`))
}
function isAboutPage(path: string) {
const clean = cleanPath(path)
return clean.startsWith('about') || moreLocales.some(lang => clean.startsWith(`${lang}/about`))
}
const isPostActive = isHomePage(currentPath) || isPostPage(currentPath)
const isTagActive = isTagPage(currentPath)
const isAboutActive = isAboutPage(currentPath)
const isPostActive = isHome || isPost
const isTagActive = isTag
const isAboutActive = isAbout
---
<nav class="mb-16 mt-13 text-5.6 font-semibold leading-13 font-navbar">

View file

@ -0,0 +1,15 @@
---
import themeConfig from '@/config'
import { getPagePath } from '@/utils/path'
const { title } = themeConfig.site
const currentPath = Astro.url.pathname
const { getLocalizedPath } = getPagePath(currentPath)
---
<a
class="mt--1.4 text-8.32 c-secondary font-bold font-title"
href={getLocalizedPath('/')}
>
{title}
</a>

View file

@ -4,26 +4,26 @@ export const themeConfig: ThemeConfig = {
// SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
site: {
title: 'Retypeset', // site title
subtitle: '再现版式之美', // site subtitle
subtitle: '再现版式之美', // site subtitle (optional)
description: 'This is Retypeset, an elegant and open-source Astro blog theme, help you rediscover the beauty of typography.', // site description for SEO
author: 'radishzz', // author name
url: 'https://retypeset.radishzz.cc', // site url
favicon: '/image/logo.svg', // or https://image.example.com/logo.svg. Support only webp, svg, png
favicon: '/image/logo.svg', // or https://example.com/logo.svg. Support webp, svg or png
},
// SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
// COLOR SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
color: {
mode: 'light', // light, dark. Matches system theme by default, falls back to configured theme mode if not available.
mode: 'light', // light or dark. Matches system theme by default, falls back to configured theme mode if not available.
light: {
primary: '#17191A', // title font color
secondary: '#505050', // post font color
primary: '#17191A', // accent color for title
secondary: '#505050', // secondary color for text
background: '#FAEDE4', // background color
codeTheme: 'github-light', // code block theme. See more at https://shiki.style/themes and https://vscodethemes.com/
},
dark: {
primary: '#BEBEBE', // title font color
secondary: '#A0A09F', // post font color
primary: '#BEBEBE', // accent color for title
secondary: '#A0A09F', // secondary color for text
background: '#161616', // background color
codeTheme: 'github-dark', // code block theme. See more at https://shiki.style/themes and https://vscodethemes.com/
},
@ -32,23 +32,23 @@ export const themeConfig: ThemeConfig = {
// GLOBAL SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
global: {
locale: 'zh', // support only zh, zh-tw, ja, en, es, ru. Default language setting
moreLocale: ['zh-tw', 'ja', 'en', 'es', 'ru'], // ['zh', 'zh-tw', 'ja', 'en', 'es', 'ru']. NOT fill in the default locale code again
fontStyle: 'sans', // support only sans, serif. Choose the font style for posts
titleSpace: 4, // support only 1, 2, 3, 4. Space between title and subtitle, 1 is the smallest, 4 is the largest
locale: 'zh', // support 'zh', 'zh-tw', 'ja', 'en', 'es', 'ru'. Default language setting
moreLocale: ['zh-tw', 'ja', 'en', 'es', 'ru'], // ['zh', 'zh-tw', 'ja', 'en', 'es', 'ru']. Not fill in the default locale code again
fontStyle: 'sans', // support sans or serif. Font styles for post content
titleSpace: 3, // support 1, 2 or 3. Space between title and subtitle
},
// GLOBAL SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
// COMMENT SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
comment: {
waline: {
serverURL: '',
serverURL: '', // Waline server URL
emoji: [
'',
'',
],
search: true,
imageUploader: true,
'//unpkg.com/@waline/emojis@1.2.0/bmoji',
'//unpkg.com/@waline/emojis@1.2.0/weibo',
], // see more at https://waline.js.org/guide/features/emoji.html
search: false, // whether to enable GIF search
imageUploader: false, // whether to enable image uploader
},
},
// COMMENT SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
@ -56,17 +56,14 @@ export const themeConfig: ThemeConfig = {
// SEO SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
seo: {
twitterID: '', // @twitter ID
// site verification
verification: {
google: '', // Google Search Console: https://search.google.com/search-console
bing: '', // Bing Webmaster Tools: https://www.bing.com/webmasters
yandex: '', // Yandex Webmaster: https://webmaster.yandex.com
baidu: '', // Baidu Search: https://ziyuan.baidu.com
},
// site analytics
googleAnalyticsID: '', // Google Analytics: https://analytics.google.com
umamiAnalyticsID: '', // Umami Analytics: https://cloud.umami.is
// follow verification
follow: {
feedID: '', // feed ID
userID: '', // user ID
@ -101,19 +98,6 @@ export const themeConfig: ThemeConfig = {
customUmamiAnalyticsJS: '', // https://custom.example.com/custom.js
},
// PRELOAD SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
// ABOUT PAGE CONTENT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
about: {
// Required: Content for about page in default language
'[locale]': '关于我',
// Optional: Content for about page in other languages. If not set, will fallback to [locale] content
'zh-tw': '關於我',
'ja': '私について',
'en': 'About me',
'es': 'Sobre mí',
'ru': 'Обо мне',
},
// ABOUT PAGE CONTENT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END
}
export default themeConfig

View file

@ -5,9 +5,11 @@ import LanguageSwitcher from '@/components/LanguageSwitcher.astro'
import Navigation from '@/components/Navbar.astro'
import PhotoSwipe from '@/components/PhotoSwipe.astro'
import Scrollbar from '@/components/Scrollbar.astro'
import SiteTitle from '@/components/SiteTitle.astro'
import ThemeToggle from '@/components/ThemeToggle.astro'
import themeConfig from '@/config'
import Head from '@/layouts/Head.astro'
import { getPagePath } from '@/utils/path'
import '@/styles/font.css'
import '@/styles/global.css'
import '@/styles/photoswipe.css'
@ -20,6 +22,7 @@ interface Props {
const { postTitle, postDescription, postImage } = Astro.props
const fontStyle = `font-${themeConfig.global.fontStyle}`
const { isHome, isPost } = getPagePath(Astro.url.pathname);
---
<html
@ -34,16 +37,21 @@ const fontStyle = `font-${themeConfig.global.fontStyle}`
p="x-[calc(9.94vw-1.1784rem)] y-[calc(5.42vw+2.4488rem)] lg:(x-36 y-10.4167dvh)"
lg="grid cols-[1fr_22rem] rows-1 gap-[min(calc(16.8269vw-6.2727rem),18rem)]"
>
<div>
<div class={!isHome && isPost ? 'hidden lg:block' : ''}>
<Header />
<Navigation />
<Footer />
</div>
{!isHome && isPost && (
<div class="lg:hidden">
<SiteTitle />
</div>
)}
<main class="col-start-1 row-start-1">
<slot />
</main>
</div>
<ThemeToggle />
<LanguageSwitcher />
@ -51,4 +59,3 @@ const fontStyle = `font-${themeConfig.global.fontStyle}`
<PhotoSwipe />
</body>
</html>

View file

@ -33,7 +33,7 @@ export interface ThemeConfig {
locale: typeof langPath[number]
moreLocale: typeof langPath[number][]
fontStyle: 'sans' | 'serif'
titleSpace: 1 | 2 | 3 | 4
titleSpace: 1 | 2 | 3
}
comment?: {
@ -83,12 +83,6 @@ export interface ThemeConfig {
customUmamiAnalyticsURL?: string
customUmamiAnalyticsJS?: string
}
about: {
[key in ThemeConfig['global']['locale']]: string
} & {
[key in ThemeConfig['global']['moreLocale'][number]]?: string
}
}
export default ThemeConfig

57
src/utils/path.ts Normal file
View file

@ -0,0 +1,57 @@
import themeConfig from '@/config'
const defaultLocale = themeConfig.global.locale
const moreLocales = themeConfig.global.moreLocale
export function cleanPath(path: string) {
return path.replace(/^\/+|\/+$/g, '')
}
export function getLangFromPath(path: string) {
const secondaryLang = moreLocales.find(
lang =>
path.startsWith(`/${lang}/`)
|| path === `/${lang}`
|| path === `/${lang}/`,
)
return secondaryLang || defaultLocale
}
export function getLocalizedPath(path: string, currentLang?: string) {
const clean = cleanPath(path)
const lang = currentLang || getLangFromPath(path)
return lang === defaultLocale ? `/${clean}` : `/${lang}/${clean}`
}
export function isHomePage(path: string) {
const clean = cleanPath(path)
return clean === '' || moreLocales.includes(clean)
}
export function isPostPage(path: string) {
const clean = cleanPath(path)
return clean.startsWith('posts') || moreLocales.some(lang => clean.startsWith(`${lang}/posts`))
}
export function isTagPage(path: string) {
const clean = cleanPath(path)
return clean.startsWith('tags') || moreLocales.some(lang => clean.startsWith(`${lang}/tags`))
}
export function isAboutPage(path: string) {
const clean = cleanPath(path)
return clean.startsWith('about') || moreLocales.some(lang => clean.startsWith(`${lang}/about`))
}
export function getPagePath(path: string) {
const currentLang = getLangFromPath(path)
return {
currentLang,
isHome: isHomePage(path),
isPost: isPostPage(path),
isTag: isTagPage(path),
isAbout: isAboutPage(path),
getLocalizedPath: (targetPath: string) => getLocalizedPath(targetPath, currentLang),
}
}