Edit this on

guides

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.

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 React from 'react'
import withPosts, { inCategory } from 'nextein/posts'
import { Content } from 'nextein/post' 

export default withPosts(({ posts }) => {
  const blog = posts.filter(inCategory('blog'))

  return (
    <main>
    {
      blog.map((post, idx) => <Content key={`post-${idx}`} {...post} excerpt />)
    }
    </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.

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'))

withPostsFilterBy

You can use the withPostsFilterBy which returns an HOC with a pre-configured filter. This avoid to process all posts and filtering them in your render method.

Our blog example can be then re-written as:

import React from 'react'
import { withPostsFilterBy, inCategory } from 'nextein/posts'
import { Content } from 'nextein/post' 

const fromBlog = withPostsFilterBy(inCategory('blog', { includeSubCategories: true }))

export default fromBlog(({ posts }) => (
    <main>
    {
      posts.map((post, idx) => <Content key={`post-${idx}`} {...post} excerpt />)
    }
    </main>
  )
)