diff --git a/src/components/BaseLayout.astro b/src/components/BaseLayout.astro index 4722e68..5f68c66 100644 --- a/src/components/BaseLayout.astro +++ b/src/components/BaseLayout.astro @@ -1,6 +1,6 @@ --- import { IS_SITE_UNDER_CONSTRUCTION } from "@root/constants"; -import Header from "@components/Header/Header.astro"; +import Header from "@components/Header.astro"; import Footer from "@components/Footer.astro"; import SiteContent from "@components/SiteContent.astro"; import UnderConstruction from "./UnderConstruction.astro"; @@ -9,7 +9,9 @@ import UnderConstruction from "./UnderConstruction.astro"; { IS_SITE_UNDER_CONSTRUCTION && ( - 🚧  This web site is under development  🚧 + + 🚧  This web site is under development  🚧 + ) }
diff --git a/src/components/EmptyList.astro b/src/components/EmptyList.astro index 6150d7c..e929987 100644 --- a/src/components/EmptyList.astro +++ b/src/components/EmptyList.astro @@ -1,8 +1,9 @@ --- +import UIString from "@components/UIString.astro"; ---
-

Не найдено ни одной записи.

+

\ No newline at end of file + diff --git a/src/components/Header/HeaderLink.astro b/src/components/Header/HeaderLink.astro deleted file mode 100644 index 1841cf9..0000000 --- a/src/components/Header/HeaderLink.astro +++ /dev/null @@ -1,12 +0,0 @@ ---- -export interface Props extends astroHTML.JSX.AnchorHTMLAttributes {} - -const { href, class: className, ...props } = Astro.props; - -const { pathname } = Astro.url; -const isActive = href === pathname || href === pathname.replace(/\/$/, ""); ---- - - - - diff --git a/src/components/LanguageSelect.astro b/src/components/LanguageSelect.astro index e0f757b..4c4d483 100644 --- a/src/components/LanguageSelect.astro +++ b/src/components/LanguageSelect.astro @@ -1,6 +1,7 @@ --- import { Icon } from "astro-icon"; import { DEFAULT_LANGUAGE, SUPPORTED_LANGUAGES } from "@root/constants"; +import { URL_BLOG_PREFIX } from "@root/pages/[...blog].astro"; import { getLanguageFromURL } from "@i18n/utils"; const lang = getLanguageFromURL(Astro.url.pathname); @@ -19,6 +20,35 @@ const lang = getLanguageFromURL(Astro.url.pathname); + + - - diff --git a/src/components/RecentArticles.astro b/src/components/RecentArticles.astro index b51e126..ea980f6 100644 --- a/src/components/RecentArticles.astro +++ b/src/components/RecentArticles.astro @@ -1,20 +1,25 @@ --- import type { CollectionEntry } from "astro:content"; +import siteconfig from "siteconfig.json"; import ArticleItem from "@components/ArticleItem.astro"; import EmptyList from "@components/EmptyList.astro"; -import siteconfig from "siteconfig.json"; +import UIString from "@components/UIString.astro"; +import TranslatedLink from "@components/TranslatedLink.astro"; export interface Props { articles: CollectionEntry<"blog">[]; length?: number | undefined; } + const { articles, length = siteconfig.articles.recentLimit } = Astro.props as Props; const isEmpty = articles.length === 0; ---
-

недавние публикации

- смотреть все +

+ + +
diff --git a/src/components/TranslatedLink.astro b/src/components/TranslatedLink.astro new file mode 100644 index 0000000..e760d9c --- /dev/null +++ b/src/components/TranslatedLink.astro @@ -0,0 +1,16 @@ +--- +import { DEFAULT_LANGUAGE, SUPPORTED_LANGUAGES } from "@root/constants"; +import { getLanguageFromURL } from "@i18n/utils"; + +export interface Props extends astroHTML.JSX.AnchorHTMLAttributes { + to: string; +} + +let pageLang = getLanguageFromURL(Astro.url.pathname); +const { to, ...attrs } = Astro.props as Props; + +if (!SUPPORTED_LANGUAGES.includes(pageLang)) pageLang = DEFAULT_LANGUAGE; +const href = pageLang === DEFAULT_LANGUAGE ? to : `/${pageLang}${to}`; +--- + + diff --git a/src/components/UIString.astro b/src/components/UIString.astro new file mode 100644 index 0000000..32069ef --- /dev/null +++ b/src/components/UIString.astro @@ -0,0 +1,9 @@ +--- +import { useTranslation } from "@i18n/utils"; + +export interface Props { + key: UIDictionaryKeys; +} +--- + +{useTranslation(Astro)(Astro.props.key)} diff --git a/src/constants.ts b/src/constants.ts index 419fe12..8e4ffbb 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -9,4 +9,10 @@ export const SITE_METADATA: SiteMetadataType = { author: "Sergey Yarkov", themeColor: "#1e2327", contacts: siteconfig.contacts, + nav: [ + { key: "navigation.articles", url: "/articles/" }, + { key: "navigation.projects", url: "/projects/" }, + { key: "navigation.about", url: "/about/" }, + { key: "navigation.contacts", url: "/contacts/" }, + ], }; diff --git a/src/i18n/utils.ts b/src/i18n/utils.ts index eeff31f..65ad4a5 100644 --- a/src/i18n/utils.ts +++ b/src/i18n/utils.ts @@ -1,7 +1,8 @@ -import languages from "./languages"; +import type { AstroGlobal } from "astro"; import { DEFAULT_LANGUAGE, SUPPORTED_LANGUAGES } from "@root/constants"; +import languages from "./languages"; -function transformExports(modules: Record) { +function transformExports(modules: Record): Record { const translations: Record = {}; for (const [path, module] of Object.entries(modules)) { const [, lang] = path.split("/"); @@ -16,12 +17,29 @@ export function getLanguageKeys(): Array { ); } -export const getLanguageFromURL = (pathname: string): LanguageKeys => { +export function getLanguageFromURL(pathname: string): LanguageKeys { const lang = pathname.split("/")[1] as LanguageKeys; if (Object.hasOwn(languages, lang)) return lang; return DEFAULT_LANGUAGE; -}; +} -export const removeLangFromURL = (pathname: string): string => { +export function removeLangFromURL(pathname: string): string { return pathname.split("/").slice(2).join("/"); -}; +} + +const translations = transformExports(import.meta.glob("./*/ui.ts", { eager: true })); + +const s = translations["ru"]; + +function translate(key: UIDictionaryKeys, lang: LanguageKeys): string | undefined { + const value = translations[lang]?.[key] || translations[DEFAULT_LANGUAGE][key]; + if (value === undefined) console.log(`Cannot find any string for translation key "${key}".`); + return value; +} + +export function useTranslation( + Astro: Readonly +): (key: UIDictionaryKeys) => string | undefined { + const pageLang = getLanguageFromURL(Astro.url.pathname); + return (key: UIDictionaryKeys) => translate(key, pageLang); +} diff --git a/src/templates/Home.astro b/src/templates/Home.astro index 443bea2..e3770d2 100644 --- a/src/templates/Home.astro +++ b/src/templates/Home.astro @@ -2,10 +2,11 @@ import { getCollection } from "astro:content"; import PageLayout from "@layouts/default.astro"; import Splash from "@components/Splash/Splash.astro"; -import SplashHeading from "@root/components/Splash/SplashHeading.astro"; -import SplashLinks from "@root/components/Splash/SplashLinks.astro"; -import SplashLink from "@root/components/Splash/SplashLink.astro"; -import RecentArticles from "@root/components/RecentArticles.astro"; +import SplashHeading from "@components/Splash/SplashHeading.astro"; +import SplashLinks from "@components/Splash/SplashLinks.astro"; +import SplashLink from "@components/Splash/SplashLink.astro"; +import RecentArticles from "@components/RecentArticles.astro"; +import UIString from "@components/UIString.astro"; const articles = (await getCollection("blog", (e) => !e.data.draft)).sort( (a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf() @@ -16,17 +17,16 @@ const articles = (await getCollection("blog", (e) => !e.data.draft)).sort(
-

Hello, I'am Sergey

+

Fullstack web-developer & freelancer

-

- Я занимаюсь разработкой веб-сайтов и веб-приложений разной сложности, а также публикую - статьи и туториалы на разные IT темы. -

+

- обо мне - написать мне + + + +
diff --git a/src/types/main.d.ts b/src/types/main.d.ts index 948fbe6..e2bcad5 100644 --- a/src/types/main.d.ts +++ b/src/types/main.d.ts @@ -1,4 +1,5 @@ import languages from "@i18n/languages"; +import uiKeys from "@i18n/ru/ui"; export {}; @@ -31,5 +32,6 @@ declare global { telegram?: string; github?: string; }; + nav: Array<{ key: UIDictionaryKeys; url: string }>; }; }