mirror of
https://github.com/sergeyyarkov/yarkov.tech.git
synced 2026-10-11 02:19:08 +03:00
recent articles render
This commit is contained in:
parent
c311050b65
commit
a334a67b03
@ -5,14 +5,15 @@ import { createDateFormatter } from "@root/utils";
|
||||
import ArticleCover from "@components/ArticleCover.astro";
|
||||
import ArticleComments from "@components/ArticleComments.astro";
|
||||
// import TranslatedLink from "../TranslatedLink";
|
||||
// import { useTranslation } from "@i18n/utils";
|
||||
import { useTranslation, getLanguageFromURL } from "@i18n/utils";
|
||||
|
||||
export type Props = {
|
||||
article: CollectionEntry<"blog">;
|
||||
lang: string;
|
||||
};
|
||||
|
||||
const { article, lang } = Astro.props as Props;
|
||||
const { article } = Astro.props as Props;
|
||||
const pageLang = getLanguageFromURL(Astro.url.pathname);
|
||||
const canonicalUrl = new URL(Astro.url.pathname, Astro.site);
|
||||
const {
|
||||
data: { coverImage, title, author, description, tags, pubDate },
|
||||
@ -50,7 +51,7 @@ const {
|
||||
</div>
|
||||
<div class="published">
|
||||
<time itemprop="datePublished" datetime={pubDate.toString()}>
|
||||
{createDateFormatter(lang).format(pubDate)}
|
||||
{createDateFormatter(pageLang).format(pubDate)}
|
||||
</time>
|
||||
<span itemprop="author">{author}</span>
|
||||
</div>
|
||||
|
||||
@ -3,19 +3,20 @@ import { SITE_METADATA } from "@root/constants";
|
||||
import { Icon } from "astro-icon";
|
||||
import TranslatedLink from "./TranslatedLink.astro";
|
||||
import UIString from "./UIString.astro";
|
||||
const date = new Date();
|
||||
---
|
||||
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div>
|
||||
<i>
|
||||
Разработка: <TranslatedLink to="/contacts">{SITE_METADATA.author}</TranslatedLink>
|
||||
© {date.getFullYear()}
|
||||
<UIString key={"footer.developed"} />: <TranslatedLink to="/contacts">
|
||||
{SITE_METADATA.author}
|
||||
</TranslatedLink>
|
||||
© {new Date().getFullYear()}
|
||||
</i>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/rss.xml" target="_blank"><UIString key={"rss.feed"} /></a>
|
||||
<a href="/rss.xml" target="_blank"><UIString key={"footer.rssFeed"} /></a>
|
||||
<span>
|
||||
<Icon name="rss" width="20" height="20" />
|
||||
</span>
|
||||
@ -27,14 +28,18 @@ const date = new Date();
|
||||
footer {
|
||||
font-weight: 500;
|
||||
margin-top: 5rem;
|
||||
color: var(--color-gray-200);
|
||||
color: var(--color-gray-400);
|
||||
font-size: var(--font-size-sm);
|
||||
& .container {
|
||||
padding: 15px 0 15px 0;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 20px;
|
||||
row-gap: 5px;
|
||||
& div:last-child {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import siteconfig from "siteconfig.json";
|
||||
import { getLanguageFromURL } from "@i18n/utils";
|
||||
import * as utils from "@utils/index";
|
||||
import ArticleItem from "@components/ArticleItem.astro";
|
||||
import EmptyList from "@components/EmptyList.astro";
|
||||
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 pageLang = getLanguageFromURL(Astro.url.pathname);
|
||||
const filtered = utils.removeDuplicates(articles.slice(0, length), pageLang);
|
||||
const isEmpty = articles.length === 0;
|
||||
---
|
||||
|
||||
<section>
|
||||
<div>
|
||||
<h2><UIString key={"recentArticles.heading"} /></h2>
|
||||
<h2>
|
||||
<UIString key={"recentArticles.heading"} />
|
||||
</h2>
|
||||
<TranslatedLink to="/articles">
|
||||
<UIString key={"recentArticles.all"} />
|
||||
</TranslatedLink>
|
||||
</div>
|
||||
|
||||
<div itemscope itemtype="http://schema.org/Blog">
|
||||
{
|
||||
!isEmpty ? (
|
||||
articles.slice(0, length).map((article) => <ArticleItem entry={article} />)
|
||||
) : (
|
||||
<EmptyList />
|
||||
)
|
||||
}
|
||||
{!isEmpty ? filtered.map((article) => <ArticleItem entry={article} />) : <EmptyList />}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
coverImage: null
|
||||
draft: false
|
||||
author: Sergey Yarkov
|
||||
title: 74HC595 shift register control by microcontroller
|
||||
description: This tutorial shows how to control the shift register of the
|
||||
74HC595 in conjunction with the AVR microcontroller.
|
||||
tags:
|
||||
- AVR
|
||||
- Digital Electronics
|
||||
- Tutorial
|
||||
pubDate: 2023-02-14T19:23:55.622Z
|
||||
updatedDate: 2023-02-14T19:23:55.646Z
|
||||
---
|
||||
|
||||
...
|
||||
@ -53,6 +53,7 @@ export default {
|
||||
"form.contactError": "An error occurred while sending. Please try again later.",
|
||||
/* Error messages */
|
||||
"error.invalidEmail": "Fill in the field in the e-mail format.",
|
||||
/* Other */
|
||||
"rss.feed": "RSS Feed",
|
||||
/* Footer */
|
||||
"footer.rssFeed": "RSS Feed",
|
||||
"footer.developed": "Developed",
|
||||
};
|
||||
|
||||
@ -54,6 +54,7 @@ export default {
|
||||
"form.contactError": "При отправке произошла ошибка. Повторите запрос позже.",
|
||||
/* Error messages */
|
||||
"error.invalidEmail": "Заполните поле в формате e-mail.",
|
||||
/* Other */
|
||||
"rss.feed": "RSS Лента",
|
||||
/* Footer */
|
||||
"footer.rssFeed": "RSS Лента",
|
||||
"footer.developed": "Разработка",
|
||||
};
|
||||
|
||||
33
src/utils/article.ts
Normal file
33
src/utils/article.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import { findDuplicates } from "./string";
|
||||
import { removeLanguageCodeFromPath } from "./url";
|
||||
|
||||
/**
|
||||
* If there is a translation of an article in the current language of the page,
|
||||
* the remaining articles with other translations should be removed.
|
||||
*
|
||||
* @param entries Array of articles
|
||||
* @param pageLang Current language on page
|
||||
* @returns
|
||||
*/
|
||||
export function removeDuplicates(
|
||||
entries: CollectionEntry<"blog">[],
|
||||
pageLang: LanguageKeys
|
||||
): CollectionEntry<"blog">[] {
|
||||
const ids = entries.map((a) => a.id) as string[];
|
||||
const duplicates = findDuplicates(ids.map((id) => removeLanguageCodeFromPath(id)));
|
||||
|
||||
duplicates.forEach((id) => {
|
||||
const toDeleteIdxs: number[] = [];
|
||||
if (ids.indexOf(`${pageLang}/${id}`) !== -1) {
|
||||
entries.forEach((a, i) => {
|
||||
if (a.id !== `${pageLang}/${id}` && a.id.includes(id)) {
|
||||
toDeleteIdxs.push(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
toDeleteIdxs.forEach((i) => entries.splice(i, 1));
|
||||
});
|
||||
|
||||
return entries;
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
export * from "./date";
|
||||
export * from "./history";
|
||||
export * from "./url";
|
||||
export * from "./string";
|
||||
export * from "./article";
|
||||
|
||||
@ -7,7 +7,11 @@ export function isEmail(email: string): boolean {
|
||||
}
|
||||
|
||||
export function isURL(url: string): boolean {
|
||||
return new RegExp(/(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\\/~+#-]*[\w@?^=%&\\/~+#-])/).test(
|
||||
url
|
||||
);
|
||||
return new RegExp(
|
||||
/(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\\/~+#-]*[\w@?^=%&\\/~+#-])/
|
||||
).test(url);
|
||||
}
|
||||
|
||||
export function findDuplicates(array: string[]): string[] {
|
||||
return array.filter((item, i) => array.indexOf(item) !== i);
|
||||
}
|
||||
|
||||
@ -3,3 +3,7 @@ export const encode = (data: object) => {
|
||||
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
|
||||
.join("&");
|
||||
};
|
||||
|
||||
export function removeLanguageCodeFromPath(path: string) {
|
||||
return path.replace(/^[a-zA-Z-]+\/+/, "");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user