forked from danielcgilibert/blog-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request danielcgilibert#44 from medevs/fix/case-sensitivit…
…y-issue-with-tags Fix case sensitivity issue with tags
- Loading branch information
Showing
3 changed files
with
118 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
--- | ||
export interface Props { | ||
tag: string | ||
} | ||
const { tag } = Astro.props | ||
--- | ||
|
||
<a href={`/tags/${tag}`} aria-label={tag}> | ||
<span | ||
class='bg-indigo-600 font-semibold text-white dark:bg-indigo-900 dark:text-white shadow text-sm w-fit px-2 py-1 md:px-5 md:py-2 rounded-full' | ||
> | ||
{tag ?? 'Blog Tag'} | ||
</span> | ||
</a> | ||
--- | ||
export interface Props { | ||
tag: string | ||
} | ||
const { tag } = Astro.props | ||
--- | ||
|
||
<a href={`/tags/${tag.toLowerCase()}`} aria-label={tag}> | ||
<span | ||
class='bg-indigo-600 font-semibold text-white dark:bg-indigo-900 dark:text-white shadow text-sm w-fit px-2 py-1 md:px-5 md:py-2 rounded-full' | ||
> | ||
{tag ?? 'Blog Tag'} | ||
</span> | ||
</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,65 @@ | ||
--- | ||
import { type CollectionEntry, getCollection } from 'astro:content' | ||
import BlogPost from '@/layouts/BlogPost' | ||
import Code from '@/components/mdx/Code' | ||
import ListRelatedPosts from '@/components/ListRelatedPosts' | ||
import Share from '@/components/Share' | ||
import TableOfContents from '@/components/TableOfContents' | ||
import { getPosts } from '@/utils' | ||
import SButton from '@/components/mdx/SButton' | ||
const posts = await getCollection('blog') | ||
export async function getStaticPaths() { | ||
const posts = await getPosts() | ||
return posts.map((post) => ({ | ||
params: { slug: post.slug }, | ||
props: post | ||
})) | ||
} | ||
type Props = CollectionEntry<'blog'> | ||
const post = Astro.props | ||
const MAX_POSTS = 3 | ||
const getRelatedPosts = (post: Props) => { | ||
const relatedPosts = posts.filter( | ||
(p) => p.slug !== post.slug && p.data.tags.some((t) => post.data.tags.includes(t)) | ||
) | ||
return relatedPosts.slice(0, MAX_POSTS) | ||
} | ||
const relatedPosts = getRelatedPosts(post) | ||
const { Content, headings, remarkPluginFrontmatter } = await post.render() | ||
--- | ||
|
||
<BlogPost | ||
id={post.id} | ||
data={post.data} | ||
headings={headings} | ||
readTime={remarkPluginFrontmatter.minutesRead} | ||
> | ||
<div class='grid grid-cols-1 md:grid-cols-[20%_auto] gap-10 mt-8'> | ||
<!-- aside --> | ||
<aside class='md:flex flex-col gap-8 hidden'> | ||
<Share /> | ||
<div class='sticky top-24 self-start hidden md:block transition-all duration-200'> | ||
{headings && headings.length > 0 && <TableOfContents {headings} />} | ||
</div> | ||
</aside> | ||
|
||
<!-- post --> | ||
<article class='max-w-full w-full'> | ||
<div class='prose prose-lg md:prose-xl dark:prose-invert mb-12 min-w-full'> | ||
<Content components={{ pre: Code, SButton }} /> | ||
</div> | ||
|
||
<!-- related posts --> | ||
<footer> | ||
<h2 class='font-bold text-lg dark:text-white mb-6'>Related Posts</h2> | ||
<ListRelatedPosts posts={relatedPosts} /> | ||
</footer> | ||
</article> | ||
</div> | ||
</BlogPost> | ||
--- | ||
import { type CollectionEntry, getCollection } from 'astro:content' | ||
import BlogPost from '@/layouts/BlogPost' | ||
import Code from '@/components/mdx/Code' | ||
import ListRelatedPosts from '@/components/ListRelatedPosts' | ||
import Share from '@/components/Share' | ||
import TableOfContents from '@/components/TableOfContents' | ||
import { getPosts } from '@/utils' | ||
import SButton from '@/components/mdx/SButton' | ||
const posts = await getCollection('blog') | ||
export async function getStaticPaths() { | ||
const posts = await getPosts() | ||
return posts.map((post) => ({ | ||
params: { slug: post.slug }, | ||
props: post | ||
})) | ||
} | ||
type Props = CollectionEntry<'blog'> | ||
const post = Astro.props | ||
const MAX_POSTS = 3 | ||
const getRelatedPosts = (post: Props) => { | ||
const lowercaseTags = post.data.tags.map((tag) => tag.toLowerCase()) | ||
const relatedPosts = posts.filter( | ||
(p) => p.slug !== post.slug && p.data.tags.some((t) => lowercaseTags.includes(t.toLowerCase())) | ||
) | ||
return relatedPosts.slice(0, MAX_POSTS) | ||
} | ||
const relatedPosts = getRelatedPosts(post) | ||
const { Content, headings, remarkPluginFrontmatter } = await post.render() | ||
--- | ||
|
||
<BlogPost | ||
id={post.id} | ||
data={post.data} | ||
headings={headings} | ||
readTime={remarkPluginFrontmatter.minutesRead} | ||
> | ||
<div class='grid grid-cols-1 md:grid-cols-[20%_auto] gap-10 mt-8'> | ||
<!-- aside --> | ||
<aside class='md:flex flex-col gap-8 hidden'> | ||
<Share /> | ||
<div class='sticky top-24 self-start hidden md:block transition-all duration-200'> | ||
{headings && headings.length > 0 && <TableOfContents {headings} />} | ||
</div> | ||
</aside> | ||
|
||
<!-- post --> | ||
<article class='max-w-full w-full'> | ||
<div class='prose prose-lg md:prose-xl dark:prose-invert mb-12 min-w-full'> | ||
<Content components={{ pre: Code, SButton }} /> | ||
</div> | ||
|
||
<!-- related posts --> | ||
<footer> | ||
<h2 class='font-bold text-lg dark:text-white mb-6'>Related Posts</h2> | ||
<ListRelatedPosts posts={relatedPosts} /> | ||
</footer> | ||
</article> | ||
</div> | ||
</BlogPost> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,39 @@ | ||
import { getCollection } from 'astro:content' | ||
|
||
export const getCategories = async () => { | ||
const posts = await getCollection('blog') | ||
const categories = new Set(posts.map((post) => post.data.category)) | ||
return Array.from(categories) | ||
} | ||
|
||
export const getPosts = async (max?: number) => { | ||
return (await getCollection('blog')) | ||
.filter((post) => !post.data.draft) | ||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()) | ||
.slice(0, max) | ||
} | ||
|
||
export const getTags = async () => { | ||
const posts = await getCollection('blog') | ||
const tags = new Set(posts.map((post) => post.data.tags).flat()) | ||
return Array.from(tags) | ||
} | ||
|
||
export const getPostByTag = async (tag: string) => { | ||
const posts = await getPosts() | ||
return posts.filter((post) => post.data.tags.includes(tag)) | ||
} | ||
|
||
export const filterPostsByCategory = async (category: string) => { | ||
const posts = await getPosts() | ||
return posts.filter((post) => post.data.category.toLowerCase() === category) | ||
} | ||
import { getCollection } from 'astro:content' | ||
|
||
export const getCategories = async () => { | ||
const posts = await getCollection('blog') | ||
const categories = new Set(posts.map((post) => post.data.category)) | ||
return Array.from(categories) | ||
} | ||
|
||
export const getPosts = async (max?: number) => { | ||
return (await getCollection('blog')) | ||
.filter((post) => !post.data.draft) | ||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()) | ||
.slice(0, max) | ||
} | ||
|
||
export const getTags = async () => { | ||
const posts = await getCollection('blog') | ||
const tags = new Set() | ||
posts.forEach((post) => { | ||
post.data.tags.forEach((tag) => { | ||
tags.add(tag.toLowerCase()) | ||
}) | ||
}) | ||
|
||
return Array.from(tags) | ||
} | ||
|
||
export const getPostByTag = async (tag: string) => { | ||
const posts = await getPosts() | ||
const lowercaseTag = tag.toLowerCase() | ||
return posts.filter((post) => { | ||
return post.data.tags.some((postTag) => postTag.toLowerCase() === lowercaseTag) | ||
}) | ||
} | ||
|
||
export const filterPostsByCategory = async (category: string) => { | ||
const posts = await getPosts() | ||
return posts.filter((post) => post.data.category.toLowerCase() === category) | ||
} |