Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rendering one type of data file in different ways #605

Closed
ejulen opened this issue Dec 12, 2016 · 3 comments
Closed

Rendering one type of data file in different ways #605

ejulen opened this issue Dec 12, 2016 · 3 comments

Comments

@ejulen
Copy link

ejulen commented Dec 12, 2016

Say I have two types of content, blog posts and articles, that both are written using JSON. They live in separate parts of the directory structure and need to be rendered completely differently. How would you do this in Gatsby?

Might just be that I'm misunderstanding something here, but it looks to me like, due to the wrapper concept, that I'll have to differentiate between blog posts and articles in the JSON wrapper by analysing the current route, since I don't want to wrap them in exactly the same way. Am I wrong?

@briancappello
Copy link
Contributor

Took me a while to figure out how to do this too, and perhaps @KyleAMathews can chime in if there's a better way, but this has worked for me:

Directory structure:

your-project/pages/blog/_template.js
your-project/pages/blog/index.json
your-project/pages/blog/post{1..N}.json

your-project/pages/articles/_template.js
your-project/pages/articles/index.json
your-project/pages/articles/article{1..N}.json
// a starting point for your _template.js files
// no need for wrappers/json.js (just delete it or return null from render)
import React, { Component } from 'react'

export default class Template extends Component {
    render() {
        const { location, route, routes } = this.props
        
        // your json data
        const { data } = routes[routes.length - 1].page

        if (location.pathname == route.path) {
            return this.renderIndex(data)
        }

        return (
            {/* some JSX based off your page data */}
        )
    }

    renderIndex(data) {
        // you can build a menu and/or post previews from data in this array
        const { childRoutes } = this.props.route

        return (
            {/* some JSX based off your index data */}
        )
    }
}
@KyleAMathews
Copy link
Contributor

@briancappello that totally works! Hadn't thought of doing things like that before actually :-)

Another option is to do exactly what you're proposing @ejulen and analyze the json data and choose different layouts based on that. You could look at the location or you could create a convention for your json files to designate their type e.g. type: 'article.

However you do it, I'd create different components for the blog posts & articles and then call to them e.g.

render () {
  if (data.type === 'blog') {
    <BlogComponent {...data} />
  } else {
    <ArticleComponent {...data} />
  }
}
@ejulen
Copy link
Author

ejulen commented Dec 13, 2016

@KyleAMathews that's exactly how I ended up doing it! I'm gonna go ahead and close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants