태그를 기반으로 관련 기사를 가져오는 아스트로
17803 단어 astro
이들은 가장 근접하게 일치하는 태그를 기반으로 하며, 이 기사에서는 Astro에서 이를 재생성하는 방법을 설명합니다.
관련 기사 검색
가장 먼저 할 일은 간단한 사용 사례를 만드는 것입니다. 최신 기사 두 개를 보여드리고자 합니다.
구성 요소 디렉터리에
RelatedArticles.astro
라는 구성 요소를 만듭니다.Frontmatter 섹션에서는 먼저 모든 게시물을 로드합니다.
fetchContent
는 무한 루프를 일으키기 때문에 여기에서 작동하지 않는다는 점에 유의하는 것이 중요합니다.---
const fetchedPosts = await import.meta.glob("../pages/posts/*.md");
const allPosts = await Promise.all(
Object.keys(fetchedPosts).map((key) => {
const post = fetchedPosts[key];
const url = key.replace("../pages/", "/").replace(".md", "/");
return post().then((p) => {
return { ...p.frontmatter, url };
});
});
);
---
그런 다음 현재 기사를 표시하지 않도록 하고 날짜를 기준으로 정렬합니다.
// Retrieve the props from the component
const { tags, currentPathname } = Astro.props;
const mappedTags = allPosts
.filter(({ url }) => url !== currentPathname)
.filter((a) => new Date(a.date) <= new Date())
.sort((a, b) => new Date(b.date) - new Date(a.date));
그런 다음 HTML 섹션에서 두 가지를 반환할 수 있습니다.
<div class="container md:mx-auto">
<div class="mx-0 md:-mx-4 grid grid-cols-1 md:grid-cols-2">
<article article="{mappedTags[0]}" />
<article article="{mappedTags[1]}" />
</div>
</div>
참고: 저는 제가 만든 기존
Article
구성 요소를 사용하고 있습니다. 귀하의 구성 요소는 다르게 보일 수 있습니다.이제 관련 기사를 게시물 템플릿에 추가할 수 있습니다.
<RelatedArticles tags={content.tags} currentPathname={canonicalURL.pathname} />
현재 게시물의 태그와 사용자가 있는 페이지의 현재 경로 이름을 전달합니다.
내 것을 복사 관련 기사 순위
스크립트가 준비되었으므로 마지막 두 기사가 표시되지만 주로 서로 관련이 없을 수도 있습니다.
몇 가지 규칙을 생각해 냈고 다음과 같은 순서가 되어야 합니다.
이 모든 것은 이미 날짜를 기반으로 하므로 최신 기사와 일치시킵니다.
내 태그는 다음과 같이 보일 수 있는 내 마크다운의 주요 섹션입니다.
---
layout: ../../layouts/Post.astro
...
tags:
- developer
- javascript
- css
---
물론 기사에 이러한 태그가 모두 있으면 완벽하게 일치하므로 먼저 표시해야 합니다.
이 시점에서 나는 이것이 설정하기 꽤 힘든 일이라는 것을 깨달았고 실제 예제가 있었지만 약간 보기 흉했습니다.
그래서 친구에게 조언을 구하기로 했습니다.
그는 완벽하게 작동하는 것으로 판명 된 미친 솔루션을 생각해 냈습니다!
가장 먼저 할 일은 각 기사의 모든 태그를 일치시키는 것입니다.
필터 및 정렬 설정이 이미 있으므로 여기에 축소를 추가할 수 있습니다.
const mappedTags = allPosts
.filter(({ url }) => url !== currentPathname)
.filter((a) => new Date(a.date) <= new Date())
.sort((a, b) => new Date(b.date) - new Date(a.date))
.reduce(
(filtered, article) => {
// TODO
},
{ all: [], some: [], one: [], none: [] }
);
무슨 일이 일어나고 있는지 눈치채셨을 것입니다. 아시다시피, 누산기와 현재 값이 있습니다.
기본값으로 계산하려는 유형이 있는 객체에 값을 설정합니다.
가장 먼저 해야 할 일은 축소된 기사의 태그가 페이지의 태그와 일치하는지 계산하는 것입니다.
우리가 구현한 이 기능을 통해 게시물 태그에 액세스할 수 있음을 기억하십시오.
const { tags, currentPathname } = Astro.props;
const mappedTags = allPosts
.filter(({ url }) => url !== currentPathname)
.filter((a) => new Date(a.date) <= new Date())
.sort((a, b) => new Date(b.date) - new Date(a.date))
.reduce(
(filtered, article) => {
// nice use of type coercion: true => 1, false => 0, so we can add a boolean to number here
const foundTagsCount = tags.reduce(
(count, tag) => count + article.tags.includes(tag),
0
);
},
{ all: [], some: [], one: [], none: [] }
);
솔직히 말해서, 저는 이것이 Alex의 약간의 마술임을 발견했습니다. 우리는 또 다른 reduce를 사용하지만 여기에 일치하는 태그의 수를 합산합니다.
결국
reduce
는 원본 기사와 일치하는 태그의 수입니다.그런 다음 금액이 맞는 범주를 정의해야 하므로
foundTagsCount
, all
, some
또는 one
중 하나가 될 수 있습니다.const amount =
tags.length === foundTagsCount
? 'all'
: foundTagsCount > 1
? 'some'
: foundTagsCount
? 'one'
: 'none';
따라서 모든 태그와 일치하면
none
로 푸시합니다. 개수가 모두 일치하지 않고 둘 이상인 경우 all
등으로 푸시합니다.그런 다음 이를 기본 reduce 함수의 누산기 값으로 푸시해야 합니다.
filtered[amount].push(article);
return filtered;
우리는 각 카테고리의 모든 기사와 일치하는 깔끔한 배열을 얻었습니다.
그리고 우리는 그것들을 하나의 큰 배열로 분산시키고 당신이 보여주고 싶은 첫 x개의 양을 취할 수 있습니다.
const { all, some, one, none } = mappedTags;
const output = [...all, ...some, ...one, ...none];
some
변수는 제 경우에 처음 2개를 사용하기 위해 퍼진 순서대로 됩니다.<div class="container md:mx-auto">
<div class="mx-0 md:-mx-4 grid grid-cols-1 md:grid-cols-2">
<article article="{output[0]}" />
<article article="{output[1]}" />
</div>
</div>
꽤 도전적이지만 태그를 기반으로 몇 가지 멋진 권장 사항을 만들었습니다.
앞으로 여기에 필터링 옵션을 더 추가할 수도 있지만 현재로서는 원하는 것과 비슷해 보입니다.
산출 읽어주셔서 감사합니다. 연결해 보겠습니다!
제 블로그를 읽어주셔서 감사합니다. 내 이메일 뉴스레터를 구독하고 또는
Reference
이 문제에 관하여(태그를 기반으로 관련 기사를 가져오는 아스트로), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dailydevtips1/astro-getting-related-articles-based-on-tags-382l텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)