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

How to configure sharp plugin for single images? #1749

Closed
foggy1 opened this issue Aug 9, 2017 · 13 comments
Closed

How to configure sharp plugin for single images? #1749

foggy1 opened this issue Aug 9, 2017 · 13 comments

Comments

@foggy1
Copy link
Contributor

foggy1 commented Aug 9, 2017

The following call makes sense to me

    allImageSharp {
      edges {
        node {
          ... on ImageSharp {
            resize(width: 125, height: 125, rotate: 180) {
              src
            }
          }
        }
      }

As do similar calls in the image processing example: I've got sharp looking at parts of my filesystem that I pre-ordained in gatsby-config and it's processing all of them into static assets. This dumps all the refs to those images out with a src attr, resized, and flipped. I also understand the individual images in the index files where we regex effectively from this same collection based on the original image's name.

But how does this work when we're in the child? The only examples I can find seem to do this thing where they nest an object called children: { or something like childImageSharp: { in a graphql query but I can't get any of these kinds of examples to work. When I try to pluck out imageSharp data nested in refs to image locations from frontmatter, I get complaints about data types. If I'm in a blog post template, how do I get an image affiliated with that blog post? What my point of reference?

Also, what if I want to be able to dynamically select/cross-reference specific images (as in not hard-coded) and affiliate them in an index view? This same issue applies. I just feel like I'm missing something here as I'm understanding everything up to unearthing, specifically, a single image that I want as that image corresponds with something in particular.

Example:

indexImage: childImageSharp {
          responsiveResolution(width: 50, height: 50) {
            src
          }
        }

I have a field from the frontmatter in my markdown with a key of indexImage and a value of the path to the image 'images/test.jpg', say. But if I write something like this, I can't get data out of props anymore, it makes graphql throw up.

@mattdean1
Copy link

If I'm in a blog post template, how do I get an image affiliated with that blog post?

I think I just implemented something similar: I render a hero image at the top of each blog post like on Medium.

Here's my query:

query BlogPostByPath($path: String!, $heroImageFilePath: String!) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")
        path
        tags
        title
      }
    }
    heroImage: imageSharp(id: { regex: $heroImageFilePath }) {
      responsiveSizes {
        aspectRatio
        base64
        src
        srcSet
        sizes
      }
    }
  }

If you put the image in the same folder as the .md, you can get the image file path by doing something like this in your gatsby-node.js

const imageFilePath = markdownPost.fileAbsolutePath.replace('index.md', 'imageName/')

The imageSharp id field contains the path, which is why the regex matches :)

@foggy1
Copy link
Contributor Author

foggy1 commented Aug 9, 2017

Aha, @mattdean1 I started messing around with gatsby-node last night to do something similar, thanks! I'll let you know how this turns out.

@foggy1
Copy link
Contributor Author

foggy1 commented Aug 11, 2017

I think that solution works but it feels hacky to me and I'm still confused. If you look at #950 there's yet another reference to this childImageSharp business. I have the latest versions of the sharp plugins and can still successfully query allImageSharp. But if I do the most basic query in which childImageSharp is nested like

query IndexQuery {
  site {
    siteMetadata {
      title
    }
  }
  allMarkdownRemark {
    edges {
      node {
        fields {
          slug
        }
        frontmatter {
          title,
          date,
          description,
          category,
          indexImage {
            childImageSharp{
              responsiveSizes (maxWidth: 200) {
                src
              }
            }
          }
        }
      }
    }
  }
}

where indexImage is in my markdown and looks like indexImage: "images/pancakes.jpeg"

Then I get the following error every time.

"message": "Field \"indexImage\" must not have a selection since type \"String\" has no subfields.",

@foggy1
Copy link
Contributor Author

foggy1 commented Aug 12, 2017

Well, I upgraded to the latest version of sharp, I changed all my markdown indexImage references to the file name only (e.g. "pancakes.jpeg"), and I think the big difference was that I didn't have a couple of the photos locally located, which now that I've struggled with this, makes sense. They were in allImageSharp, but they weren't children, (as in, they weren't in particular pages folders, I had them elsewhere) so indexImage still thought it was a string. The minute I moved everything and they all had children, indexImage started throwing up and actually needed children.

@mattdean1 in the process I did actually get something working similar to what you suggested, but I leveraged allImageSharp: since you can get the originalName attribute off of imageSharp children of certain types, I just cross-referenced that with the image names from allMarkdownRemark frontmatter and plucked the src off that way. Thanks a bunch for your suggestion, it helped me wrap my head around all these other issues and extant code examples.

@foggy1 foggy1 closed this as completed Aug 12, 2017
@mattdean1
Copy link

Great stuff mate. Your solution using the pic name from frontmatter is definitely less hacky, but does mean you have the overhead of having to specify the pic name in frontmatter I guess.

Any chance you could post your working query for future reference?

@sgriffey
Copy link

@foggy1 yes, please if you could post your working query and frontmatter example, that'd be huge!

@foggy1
Copy link
Contributor Author

foggy1 commented Jan 29, 2018

@sgriffey I just realized I missed Matt's comment! I'll post a couple of things later today.

@sgriffey
Copy link

sgriffey commented Jan 29, 2018 via email

@foggy1
Copy link
Contributor Author

foggy1 commented Jan 30, 2018

Let's say I've got a pages/ folder full posts. It's important that gatsby-source-filesystem is looking here, like

{
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/src/pages`,
        name: "pages",
      },
    }

Let's say one of my folders in pages is 2017-some-date-whatever-time-is-arbitrary/ which contains index.md and a picture called red_sprite.jpg. In the frontmatter of index.md is the following value: indexImage: "red_sprite.jpg" For this next part, you should make sure you have gatsby-plugin-sharp and gatsby-transformer-sharp. The following is a query you could put in your index.js file (the one that renders your index page!) and when you go to pull out details about your posts, (2017-some-date-whatever-time-is-arbitrary in particular in this case), you'll get some responsive image props out of thechildImageSharp field.

query theNameOfThisQueryDoesntStopItFromWorking {
  allMarkdownRemark {
    edges {
      node {
        fields {
          slug
        }
        frontmatter {
          title,
          date,
          description,
          category,
          path,
          indexImage {
            childImageSharp {
              responsiveSizes(maxWidth: 670){
                base64
                aspectRatio
                src
                srcSet
                sizes
                originalImg
                originalName
                }
            }
          }
        }
      }
    }
  }
}

NOTE: this syntax is dated, this is an example from a project closer to the time that I raised this issue! responsiveSizes is now just sizes (you can also do resolutions) and if you look at the gatsby-image examples on the gatsby homepage, you'll see there's even fragments, things you can spread into this query to prevent you from having to figure out which props you need to feed into the gatsby-image helper component.

The important difference between what I posted here and my example above is literally just the name of the field where the indexImage lives.

To get a specific image, you can look at an example here from my personal website where I blur up my image in the navbar. The regex matcher you see (that Matt mentions above) is built into gatsby-transformer-sharp. Look through my config file: I had to add the place where my image lived to gatsby-source-filesystem.

Number 1 tip: Use graphiQL to test these queries! Don't use your site to test them, get comfortable with the structure of the query, do a quick and dirty graphQL CRUD project to get comfy with this stuff. It's 100% worth it.

I should just expand this into a blog post lol

@foggy1
Copy link
Contributor Author

foggy1 commented Jan 30, 2018

Whoops! Forgot to include what this looks like within a single Post template.

Again, not sure how dated any of this is, but this is the general idea. As long as your images that are associated with posts are co-located with those posts in the folders with the markdown, the childImageSharp query can nest on that field and pull out whatever you need while you harvest the frontmatter props for your template like normal!

query BlogPostByPath($slug: String!) {
    site {
      siteMetadata {
        title
        author
      }
    }
    markdownRemark(fields: { slug: { eq: $slug }}) {
      id
      html
      fields {
        slug
      }
      frontmatter {
        title
        date(formatString: "MMMM DD, YYYY"),
        indexImage {
          childImageSharp {
              resize(width: 500, height: 500){
                src
                }
          }
        },
        layout,
        itemTitle,
        itemAuthor,
        itemType,
        itemPublisher,
        description
      }
    }
  }

Again, graphiQL is your friend. Always start from a query that shipped with gatsby that you know works and then start trying stuff out.

@sgriffey
Copy link

sgriffey commented Feb 1, 2018

@foggy1 dang. Please let me know if you ever create that expanded blog post on this. I appreciate your help. Throwing in the towel for now.

Can't seem to get this right. Wish the gatsby docs were more explicit for this. Seems like a really common use-case.

@foggy1
Copy link
Contributor Author

foggy1 commented Feb 1, 2018

@sgriffey idk how much you can share about your project but feel free to either include stuff here or dm me on Twitter @austinlanari, it's usually like, one small thing that needs to change when this kind of thing doesn't work. mine was literally like two chars in a string lol

@sgriffey
Copy link

sgriffey commented Feb 2, 2018

@foggy1 appreciate that sir. thank you. might come knocking in future. for time being I cloned a starter that had this functionality working — then just spent a good amount of time removing all the other bloat.

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

No branches or pull requests

3 participants