Filtering Posts
Each post defines a set of metadata using frontmatter format. There are a few properties that are generated by default by Nextein: category
, page
and date
. You can override any property using the frontmatter section.
These properties are available through the post.data
object. You can define your own properties like tags
, author
, etc.
Using Categories
The category
property follows the directory structure by default. If you have a post located at posts/nodejs/start/hello-world.md
then nodejs/start
is assigned as its category.
The most common case is to filter posts by category
. Nextein exposes a filter function to help: inCategory(category, options)
. This method uses the post.data
to filter posts by a given category
:
import { getPosts } from 'nextein/fetcher'
import Content from 'nextein/content'
import { inCategory } from 'nextein/filters'
export async function getStaticProps () {
return { props: { posts: await getPosts() } }
}
export default function Index ({ posts }) {
const blog = posts.filter(inCategory('blog'))
return (
<main>
{
blog.map(post => (
<article key={post.__id}>
<h1>{post.data.title}</h1>
<Content {...post} excerpt />
</article>
))
}
</main>
)
}
In this example we are listing only the posts with category: 'blog'
and showing only the first paragraph by using the excerpt
property in the <Content />
tag.
SubCategories
If you have sub categories such as blog
, blog/react
and blog/nodejs
the example above will only list those posts with category: 'blog'
. To include the posts in the sub categories you need to pass the includeSubCategories: true
in the options object.
const blog = posts.filter(inCategory('blog', { includeSubCategories: true }))
Custom Filtering
In case you want to use your own filter, the posts property is an Array
and can be filtered out by the usual means. For instance, if we want to also filter out our blog posts by author
we could write a filter function like this:
const byAuthor = (author) => (post) => {
return post.data.author === author
}
//...
const maxBlog = posts
.filter(inCategory('blog', { includeSubCategories: true }))
.filter(byAuthor('max'))
Using getPostFilterBy
You can use the getPostFilterBy
to avoid to process all posts and filtering them in your render method.
Our previous example can be simplified by doing:
import { getPostsFilterBy } from 'nextein/fetcher'
import Content from 'nextein/content'
import { inCategory } from 'nextein/filters'
export async function getStaticProps () {
return { props: { bllog: await getPostsFilterBy(inCategory('blog')) } }
}
export default function Index ({ blog }) {
return (
<main>
{
blog.map(post => (
<article key={post.__id}>
<h1>{post.data.title}</h1>
<Content {...post} excerpt />
</article>
))
}
</main>
)
}
This is the preferred way in case you have a large amount of posts and you display just a small set.
Note
Filtering posts using the getPostsFilterBy
method will help performance since we are not adding unnecessary posts into the global cache, reducing the size of the final HTML file.