This commit is contained in:
Sergey Yarkov 2023-02-18 23:39:27 +03:00
parent 60c6bb5505
commit 43950ae134
No known key found for this signature in database
GPG Key ID: E91CE1FABC619B6F
8 changed files with 67 additions and 36 deletions

View File

@ -206,6 +206,9 @@
& .languages-available {
margin: 25px 0;
font-size: var(--font-size-lg);
& a:not(:last-child)::after {
content: ",";
}
}
}

View File

@ -1,23 +1,19 @@
---
import type { CollectionEntry } from "astro:content";
import slugify from "@sindresorhus/slugify";
import { URL_BLOG_PREFIX } from "@root/pages/[...blog].astro";
import { DEFAULT_LANGUAGE } from "@root/constants";
import { getLanguageFromURL } from "@i18n/utils";
import { createDateFormatter } from "@root/utils";
import { createDateFormatter, createRelativeArticleUrl } from "@root/utils";
export interface Props {
entry: CollectionEntry<"blog">;
}
const pageLang = getLanguageFromURL(Astro.url.pathname);
const { entry } = Astro.props as Props;
const {
entry: {
id,
data: { title, pubDate },
},
} = Astro.props as Props;
const slug = slugify(title, { lowercase: true });
id,
data: { title, pubDate },
} = entry;
const articleLang = id.split("/")[0];
---
@ -27,11 +23,7 @@ const articleLang = id.split("/")[0];
itemtype="http://schema.org/BlogPosting"
class="article-item"
>
<a
href={articleLang === DEFAULT_LANGUAGE
? `/${URL_BLOG_PREFIX}/${pubDate.toISOString().split("T")[0]}/${slug}`
: `/${articleLang}/${URL_BLOG_PREFIX}/${pubDate.toISOString().split("T")[0]}/${slug}`}
>
<a href={`${createRelativeArticleUrl(entry, URL_BLOG_PREFIX)}`}>
<div class="flex">
<h3 itemprop="headline">{title}</h3>
{articleLang !== pageLang && <sup>{articleLang.toLocaleUpperCase()}</sup>}

View File

@ -16,14 +16,13 @@ const { heading, description } = Astro.props as Props;
<style lang="scss">
div {
margin-bottom: 2.5rem;
text-align: center;
& h1 {
font-size: var(--font-size-4xl);
text-align: center;
margin-bottom: 15px;
}
& p {
font-size: var(--font-size-lg);
text-align: center;
max-width: 650px;
margin: 0 auto;
}

View File

@ -3,7 +3,7 @@ import { defineCollection, z } from "astro:content";
const blog = defineCollection({
schema: z.object({
title: z.string(),
draft: z.boolean().optional(),
draft: z.boolean().nullable().optional(),
coverImage: z.string().nullable().optional(),
author: z.string(),
tags: z.string().array().optional(),

View File

@ -27,7 +27,7 @@ function transformExports<T>(modules: Record<string, { default: T }>) {
const translations: Record<string, T> = {};
for (const [path, module] of Object.entries(modules)) {
const [, lang] = path.split("/");
translations[lang as LanguageKeys] = module.default;
translations[lang] = module.default;
}
return translations;
}
@ -36,7 +36,7 @@ const translations = transformExports<Record<string, UIDictionaryKeys>>(
import.meta.glob("./*/ui.ts", { eager: true })
);
function translate(key: UIDictionaryKeys, lang: LanguageKeys): string {
export function translate(key: UIDictionaryKeys, lang: LanguageKeys): string {
const value = translations[lang]?.[key] || translations[DEFAULT_LANGUAGE][key];
if (value === undefined) console.log(`Cannot find any string for translation key "${key}".`);
return value;

View File

@ -1,8 +1,12 @@
---
import { CollectionEntry, getCollection } from "astro:content";
import ArticleLayout from "@root/layouts/article.astro";
import { DEFAULT_LANGUAGE } from "@root/constants";
import slugify from "@sindresorhus/slugify";
import { createRelativeArticleUrl, removeLanguageCodeFromPath } from "@root/utils";
import { getLanguageFromURL, useTranslation } from "@i18n/utils";
import languages from "@i18n/languages";
const t = useTranslation(Astro);
const pageLang = getLanguageFromURL(Astro.url.pathname);
export const URL_BLOG_PREFIX = "blog";
@ -14,23 +18,39 @@ export const URL_BLOG_PREFIX = "blog";
export async function getStaticPaths() {
const collection = await getCollection("blog", (e) => !e.data.draft);
return collection.map((article) => {
const [languageCode] = article.slug.split("/");
const slug = slugify(article.data.title, { lowercase: true });
const pubDate = article.data.pubDate.toISOString().split("T")[0];
const url =
DEFAULT_LANGUAGE !== languageCode
? `${languageCode}/${URL_BLOG_PREFIX}/${pubDate}/${slug}`
: `${URL_BLOG_PREFIX}/${pubDate}/${slug}`;
return { params: { blog: url }, props: { article } };
const url = createRelativeArticleUrl(article);
return {
params: { blog: url.slice(1) },
props: {
article,
availableOnLang: collection.filter((e) =>
e.id.includes(removeLanguageCodeFromPath(article.id))
),
},
};
});
}
type Props = { article: CollectionEntry<"blog"> };
type Props = { article: CollectionEntry<"blog">; availableOnLang: CollectionEntry<"blog">[] };
const { Content } = await Astro.props.article.render();
const { article, availableOnLang } = Astro.props;
---
<ArticleLayout article={Astro.props.article}>
<ArticleLayout lang={article.id.split("/")[0]} article={article}>
{
availableOnLang.length > 1 && (
<div class="languages-available">
{t("article.availableOn")}:{" "}
{availableOnLang
.filter((a) => !a.id.startsWith(`${pageLang}/`))
.map((a) => (
<a href={`${createRelativeArticleUrl(a, URL_BLOG_PREFIX)}`}>{`${
languages[a.id.split("/")[0] as LanguageKeys]
}`}</a>
))}
</div>
)
}
<Content />
</ArticleLayout>

View File

@ -2,15 +2,18 @@ import rss from "@astrojs/rss";
import { getCollection } from "astro:content";
import { SITE_METADATA } from "@root/constants";
import type { APIContext } from "astro";
import * as utils from "@i18n/utils";
// TODO: generate feed for RU, EN, ... languages
export async function get(context: APIContext) {
const posts = await getCollection("blog");
const posts = await getCollection("blog", (e) => !e.data.draft);
return rss({
title: SITE_METADATA.title,
description: "",
site: context.site,
description: utils.translate("site.description", "ru"),
site: "https://yarkov.tech",
items: posts.map((post) => ({
...post.data,
title: post.data.title,
pubDate: post.data.pubDate,
link: `/blog/${post.slug}/`,
})),
});

View File

@ -1,4 +1,6 @@
import type { CollectionEntry } from "astro:content";
import { DEFAULT_LANGUAGE } from "@root/constants";
import slugify from "@sindresorhus/slugify";
import { findDuplicates } from "./string";
import { removeLanguageCodeFromPath } from "./url";
@ -31,3 +33,15 @@ export function removeDuplicates(
return entries;
}
export function createRelativeArticleUrl(
article: CollectionEntry<"blog">,
prefix: string = "blog"
): string {
const articleLang = article.id.split("/")[0];
const date = article.data.pubDate.toISOString().split("T")[0];
return `${articleLang !== DEFAULT_LANGUAGE ? "/" + articleLang : ""}/${prefix}/${date}/${slugify(
article.data.title,
{ lowercase: true }
)}`;
}