TryGhost / gatsby-source-ghost

Source plugin for pulling data into Gatsby.js from the Ghost Public API.
https://ghost.org
MIT License
175 stars 45 forks source link

Add gatsby-transformer-sharp support #5

Open gil-- opened 6 years ago

gil-- commented 6 years ago

I'll try to look into adding this via a PR but would be nice to add gatsby-transformer-sharp so we can do responsive images and use gatsby-image for lazyload, etc.

See https://github.com/angeloashmore/gatsby-source-shopify

aileen commented 5 years ago

Thanks for the idea! ❤️

We'll probably not focus on that for now, but as always: contributions are very welcome!

riencoertjens commented 5 years ago

hi, I'll probably need this in a project this or early next week, I'll make a pr with the changes... @DSchau do you know any comparable plugins that are already doing this in a good way to use as an example, the gatsby-source-filesystem docs about createRemoteFileNode doesn't really say in which gatsby node api this is done best 🤔

nocash commented 5 years ago

My coworker and I had this working in a fork a while ago. I'm not sure if or how outdated it might be today but it might be useful to use as a reference. The changes are in a PR here: https://github.com/substantial/gatsby-source-ghost/pull/2

It's been a while since I worked on that, but I think the relevant sections to look at are downloadImageAndCreateFileNode, mapImagesToMedia, createLocalFileFromMedia functions in ghost-nodes.js.

amcc commented 4 years ago

I'm interested in this too - using ChildImageSharp seems a pretty fundamental thing in a source plugin for Gatsby. I needed to add this manually for a site using gatsby-source-apiserver and did it in the gatsby-node.js file as below. As you can see there's some extra stuff in there you wont need for Ghost.

I'll try and get this working for Ghost now - ideally this shouldn't be in the gatsby-node.js file and should be handled by the source plugin - but that's a bit beyond my knowledge. I'll post my efforts at getting this to work though.

// get all imageNodes
exports.sourceNodes = ({
  actions,
  cache,
  createNodeId,
  getNodesByType,
  store,
  reporter,
}) => {
  const { createNode } = actions
  const imageDownloads = []
  const submissions = getNodesByType("submissions")
  submissions.forEach(node => {
    node.works &&
      node.works.forEach(({ mediaItems }) => {
        mediaItems &&
          mediaItems.forEach(mediaSource => {
            if (
              mediaSource.mime !== "image/jpeg" &&
              mediaSource.mime !== "image/png" &&
              mediaSource.mime !== "image/gif" &&
              mediaSource.mime !== "image/svg"
            ) {
              // return reporter.warn(
              //   `The mime type is not an image, its ${mediaSource.mime}`
              // )
              return false
            }
            let fileType = mediaSource.mime.split("/")[1]
            if (fileType === "jpeg") {
              fileType = "jpg"
            }
            const imageUrl = `https://example.com/media/${
              mediaSource.filename.split(".")[0]
            }-resize-1920-2560.${fileType}`
            imageDownloads.push(
              createRemoteFileNode({
                url: imageUrl,
                store,
                cache,
                createNode,
                createNodeId,
                reporter,
              })
                .then(result => {
                  if (!result) {
                    return reporter.warn(`Could not download ${imageUrl}`)
                  }
                  mediaSource.imageFile___NODE = result.id
                })
                .catch(err => {
                  reporter.warn(err)
                }),
            )
          })
      })
  })
  return Promise.all(imageDownloads)
}
amcc commented 4 years ago

This works for the demo site and will get all the feature_image images from Posts and create local optimised versions allowing childImageSharp fixed and fluid images to be used etc with Gatsby Image:

add this to gatsby-node.js

suggestions on the best way to do this very welcome

// use gatsby-source-filesystem to create the nodes
const { createRemoteFileNode } = require("gatsby-source-filesystem");

// get all imageNodes
exports.sourceNodes = ({
    actions,
    cache,
    createNodeId,
    getNodesByType,
    store,
    reporter,
}) => {
    const { createNode } = actions;
    const imageDownloads = [];
    const GhostPost = getNodesByType("GhostPost");
    GhostPost.forEach((node) => {
        const imageUrl = node.feature_image;
        imageDownloads.push(
            createRemoteFileNode({
                url: imageUrl,
                store,
                cache,
                createNode,
                createNodeId,
                reporter,
            })
                .then((result) => {
                    if (!result) {
                        return reporter.warn(`Could not download ${imageUrl}`);
                    }
                    node.feature_image_sharp___NODE = result.id;
                })
                .catch((err) => {
                    reporter.warn(err);
                })
        );
    });
    return Promise.all(imageDownloads);
};
raae commented 2 years ago

For those looking for a solution gatsby-plugin-remote-images might get you there.