Use Ghost as content manager for multiple static sites (via generator)

Hello.

I am using Ghost as source for number of sites that built using Gatsbyjs + plugin gatsby-source-ghost. To distinguish what article belongs to what site using Gatsby build-time environment variable and internal tag in Ghost articles.

Example:

  • article1 has tags longread , level:average , #site:site1
  • article2 has tags tech , level:beginner
  • article3 has tags longread , level:average , #site:siteX

When building like SITE=site1 gatsby build articles 1 an 2 appears. If building like gatsby build - only second articles appear in all posts collection, featured and author’s posts.

I cannot do that using filter - it is easy to get posts with some string but unable to get other posts - without such tag at all.

Question: is it possible to inject filtering somewhere in information sourcing process to pre-filter posts based on tag?

Hi there @nosuchip :wave:. Indeed there is a filter option in the Ghost Content API:
https://ghost.org/docs/api/v2/javascript/filtering/

You can use this inside GraphQL queries too, there’s an example in our GraphQL docs https://ghost.org/docs/api/v2/gatsby/graphql-recipes-for-ghost/#filtering-posts-by-tag

Thank you for reply. I already checked out as filtering documentation as GraphQL filter statement.

It will not work to filter using GraphQL as logict too tricky to filter statement. And anyway I have to put this filtering login in each place where using allGhostPost (author page, featured posts selection and so on).

Also, due the fact I am using gatsby-source-ghost I cannot use filtering provided by Content API - plugin simply doesn’t exposed thish feature.

Sorry, maybe I’m missing something? gatsby-source-ghost does expose filter as an option. In this example I’m querying posts by their tags:

{
  allGhostPost(filter: {tags: {elemMatch: {slug: {in: ["longread", "level:average", "#site:site1"]}}}}) {
    edges {
      node {
        slug
        ...
      }
    }
  }
}

Due to the characters in the tags you may need to switch to using the name rather than the slug.

I hope this sheds a bit more light on how to use GraphQL with Ghost :slightly_smiling_face:

Hi. Yes, I already see and tried this feature. Here you (as me before) filtered posts with specific tag. But I have slightly more complex scenario described in initial post - I need not only posts with tag #site:site1 (actually it could also contains spaces after colon, so it can be filtered only by regexp, so it block in usage), but: posts with #site:site1 AND all posts that doesn’t contains #site:* tag (i.e. that doesn’t belongs to another blog).

And this case cannot be done via suggested GraphQL filter. I suppose it cannot be done in one request with Ghost filtering too.

I think I get what you mean, sorry I didn’t fully understand your original post. So to clarify you want to filter posts that DO HAVE #site:site1 AND posts that DON’T HAVE #site:*? If so then you could use the ne option which means “no equal”. There’s a brief example here in the Gatsby docs: GraphQL Query Options | Gatsby

I quickly tried this out by filtering out posts by a certain tag and it worked as expected :+1:

I take a look to docs one more time and tried to experiment but failed. My goal is TO HAVE posts with #site:site1 AND TO HAVE posts WITHOUT #site:*.

If I have not corresponding env.var (i.e. BUILD_SITE=, not BUILD_SITE=site) then I want NOT TO HAVE #site:* at all.

If corresponding env.var set to BUILD_SITE=site2 then I want TO HAVE #site:2 + post WITHOUT TAGS like #site:*. All other should be dropped.

See, here I anyway have AND join for 2 different selections.

Could this be simplified in some way? It seems like you’re using a fairly complex method of filtering posts for various sites, I mean this is probably why you should be using separate installs :sweat_smile:. Wouldn’t applying a single tag of “site-1” to all the posts you want in “site 1” be sufficient?