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

Netlify CMS: frontmatter image & relative path #4753

Closed
eur2 opened this issue Mar 29, 2018 · 28 comments
Closed

Netlify CMS: frontmatter image & relative path #4753

eur2 opened this issue Mar 29, 2018 · 28 comments
Labels
type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@eur2
Copy link

eur2 commented Mar 29, 2018

I'm working on a website using gatsby and Netlify CMS. It's based on the gatsby-starter-netlify-cms official starter
In the starter, the images are located in the static folder. So they don't use any optimization from gatsby-remark-images.
To be compiled by gatsby-remark-images, the image in the frontmatter of a markdown needs to have a path like this:

---
image: './photo.jpg'
---

But with NetlifyCMS, the path generated looks like this and doesn't work with gatsby-remark-images (only work with an image in the static folder):

---
image: photo.jpg
---

Does anyone have been confronted with this problem?
Many thanks in advance!

@ghost
Copy link

ghost commented Mar 30, 2018

Hi there !

I found this blog post about implementing gatsby-image with markdown frontmatter : https://codebushi.com/gatsby-featured-images/

You call Sharp in the GraphQL query and then pass the image into a gatsby-image Img component. I haven't implemented it yet but it seems logical.

EDIT: Oops sorry. I tried myself and i's true that you can't do anything about it. They're trying to implement a relative path for the public folder in NetlifyCMS, but in the meantime I have no idea.

@eur2 eur2 changed the title Frontmatter, gatsby-remark-images & Netlify CMS Netlify CMS: frontmatter image & relative path Mar 31, 2018
@eur2
Copy link
Author

eur2 commented Mar 31, 2018

Thanks for the link!
But the problem is i can't get childImageSharp on the image. It doesn't exist in the GraphQL because the path of the image in the markdown isn't relative…

@rbrcsk
Copy link
Contributor

rbrcsk commented Apr 1, 2018

I had the same problem as you @grdp. It's a relatively easy fix.

My directory structure looks like this:

gatsby-site
- content
-- news
-- img

In your gatsby-node.js

exports.onCreateNode = ({ node, getNode, boundActionCreators }) => {
  const { createNodeField } = boundActionCreators;

  if (node.internal.type === `MarkdownRemark`) {
    fillNewsEntryData(node, createNodeField, getNode);
  }
};

In a separate file (but can be done inline too):

const path = require('path');

module.exports = (node, createNodeField, getNode) => {
    let banner = path.join("..", node.frontmatter.banner);
    createNodeField({node, name: `banner`, value: banner})

};

As the path in the frontmatter is something like /img/uploads/fb-poszt-hatter-diploma.png adding .. before it gets us the relative path from the markdown file.

The only difference this makes is that instead of node.frontmatter.banner you'll have to use node.fields.banner

Hope this helps!

@ghost
Copy link

ghost commented Apr 1, 2018

@randomchars Am I wrong to assume that this code breaks the preview in NetlifyCMS? Not when you just added the image because the image displayed is cached, but when you come back to edit the entry.
To me, it seems like to make it work completely, the only option is to put the images inside the static folder, and add the relative path to the images with your code.
That way, the image folder will be copied as is to work with NetlifyCMS, and gatsby-transformer-sharp will still detect the relative path to make it work with gatsby-image

@ghost
Copy link

ghost commented Apr 1, 2018

I have been working on a custom widget to overcome NetlifyCMS's shortcoming :

https://github.com/zecakeh/react-netlifycms-custompathimage

It should work as is. And the preview should work too since it loads the images directly from the backend repository.

@eur2
Copy link
Author

eur2 commented Apr 2, 2018

@zecakel great! thanks for this fix
It's working in develop mode but when i make a build, i get a webpack error:

error Building static HTML for pages failed

See our docs page on debugging HTML builds for help https://goo.gl/yL9lND

  27 |   message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.';
  28 | 
> 29 |   var error = new Error(message);
     | ^
  30 |   error.name = 'Invariant Violation';
  31 |   error.framesToPop = 1; // we don't care about reactProdInvariant's own frame
  32 | 


  WebpackError: Minified React error #130; visit http://facebook.github.io/react/docs/error-decoder.html?invarian  t=130&args[]=object&args[]= for the full message or use the non-minified dev environment for full errors and ad  ditional helpful warnings.
  
  - reactProdInvariant.js?3afb:29 reactProdInvariant
    ~/react-dom/lib/reactProdInvariant.js?3afb:29:1
  
  - instantiateReactComponent.js?852a:72 instantiateReactComponent
    ~/react-dom/lib/instantiateReactComponent.js?852a:72:1
  
  - ReactChildReconciler.js?dd13:42 instantiateChild
    ~/react-dom/lib/ReactChildReconciler.js?dd13:42:1
  
  - traverseAllChildren.js?8c0a:75 traverseAllChildrenImpl
    ~/react-dom/lib/traverseAllChildren.js?8c0a:75:1
  
  - traverseAllChildren.js?8c0a:170 traverseAllChildren
    ~/react-dom/lib/traverseAllChildren.js?8c0a:170:1
  
  - ReactChildReconciler.js?dd13:72 Object.instantiateChildren
    ~/react-dom/lib/ReactChildReconciler.js?dd13:72:1
  
  - ReactMultiChild.js?9682:189 ReactDOMComponent._reconcilerInstantiateChildren
    ~/react-dom/lib/ReactMultiChild.js?9682:189:1
  
  - ReactMultiChild.js?9682:222 ReactDOMComponent.mountChildren
    ~/react-dom/lib/ReactMultiChild.js?9682:222:1
  
  - ReactDOMComponent.js?ab8a:657 ReactDOMComponent._createContentMarkup
    ~/react-dom/lib/ReactDOMComponent.js?ab8a:657:1
  
  - ReactDOMComponent.js?ab8a:524 ReactDOMComponent.mountComponent
    ~/react-dom/lib/ReactDOMComponent.js?ab8a:524:1

@ghost
Copy link

ghost commented Apr 2, 2018

Are you sure it comes from my Widget ?
I don't have any issue when I gatsby build...
Don't you have any warnings in your console in dev mode ?

@eur2
Copy link
Author

eur2 commented Apr 2, 2018

Ok it's working now! i think there was a kind of conflict with other markdown template/pages.
Now just need to fix the preview image in the netlify cms admin panel (the rawMediaPath doesn't seem to work)
Many thanks for your help and this plugin!

@eur2
Copy link
Author

eur2 commented Apr 2, 2018

Or maybe i'll try to put the image folder into the static folder to solve the preview in the admin panel

@ghost
Copy link

ghost commented Apr 2, 2018

Really, the rawMediaPath isn't applied ? Have you checked the preview img src attribute ? Maybe it's a mistake in the path.

@eur2
Copy link
Author

eur2 commented Apr 3, 2018

rawMediaPath is working but the path with this structurehttps://raw.githubusercontent.com/user/repo/master/images/ doesn't link to an image.
Is it working the preview to you with this kind of path?

@ghost
Copy link

ghost commented Apr 3, 2018

Yes it is. If you want to have the proper path just go on github.com into your repository to an image in the correct folder, then copy the url of the image and remove the filename. That's your rawMediaPath.

@eur2
Copy link
Author

eur2 commented Apr 3, 2018

indeed it's working! i probably did a type-mistake in the path before.
thanks a lot!
do you have any idea how to make this image field rendering a empty string ' ' when the field is empty (not required) in the markdown? It's to avoid a Cannot read property 'childImageSharp' of null)

@ghost
Copy link

ghost commented Apr 3, 2018

No I haven't looked into that yet. That's an error in React, not GraphQL, right ?
Couldn't you avoid this error by checking if the image data exists in your code first? Like this:

const image = this.props.data.markdownRemark.frontmatter.image;
if (image) {
  // Do some stuff with image.childImageSharp
}

@eur2
Copy link
Author

eur2 commented Apr 3, 2018

Even with a conditional like that, i have a GraphQL error (Cannot read property 'childImageSharp' of null) because in some posts there's no image ("img": null).

img {
              childImageSharp {
                sizes(maxWidth: 800) {
                  src
                  srcSet
                }
              }
            }

@ghost
Copy link

ghost commented Apr 3, 2018

Oh that was a mistake on my part. I always intended for it to save an empty string. I fixed it in my repository so just replace your customPathImage.js with the new one.

@eur2
Copy link
Author

eur2 commented Apr 3, 2018

Thanks for the new fix but that doesn't change an empty string or a empty field. I have just tested it. Still GraphQL need a valid childImageSharp value. I have two img field (img1, img2), sometimes the second is not required and so empty. => Cannot read property 'childImageSharp' of null
I'll try to figure it out… but thanks a lot for the help!

            main {
              img1 {
                childImageSharp {
                  sizes(maxWidth: 800) {
                    src
                    srcSet
                  }
                }
              }
              img2 {
                childImageSharp {
                  sizes(maxWidth: 800) {
                    src
                    srcSet
                  }
                }
              }
            }

@pieh
Copy link
Contributor

pieh commented Apr 3, 2018

Does Cannot read property 'childImageSharp' of null break the build? If you have repo to reproduce this problem I will take a look.

@eur2
Copy link
Author

eur2 commented Apr 5, 2018

I'm wondering if it's not better to use the body field and add images there. I just don't like the <p> and <span> created around the image in the body field.
What do you think?

@johnclark456
Copy link

Thanks @zecakeh, your custom widget worked great! I actually replaced the default image widget with that one for my deployment so I could use it for inserting images in the body too which otherwise stops working once you modify the config.yml media_folder parameter to be outside the static folder.

@kakadiadarpan kakadiadarpan added the type: question or discussion Issue discussing or asking a question about Gatsby label Sep 21, 2018
@kakadiadarpan
Copy link
Contributor

@grdp were you able to fix this issue? If not could you provide us with a reproduction repo? That would make it much easier to diagnose this issue.

@kakadiadarpan kakadiadarpan added the status: awaiting author response Additional information has been requested from the author label Sep 21, 2018
@eur2
Copy link
Author

eur2 commented Sep 21, 2018

@kakadiadarpan I solved it with this solution for gatsby v2:
https://github.com/gatsbyjs/gatsby/issues/8195#issuecomment-421745303

gatsby-node.js

  const { createNodeField } = actions
  const { frontmatter } = node
  if (frontmatter) {
    const { image } = frontmatter
    if (image) {
      if (image.indexOf('/img') === 0) {
        frontmatter.image = path.relative(
          path.dirname(node.fileAbsolutePath),
          path.join(__dirname, '/static/', image)
        )
      }
    }
  }

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
} 

config.yml

media_folder: static/img
public_folder: /img

@kakadiadarpan kakadiadarpan removed the status: awaiting author response Additional information has been requested from the author label Sep 21, 2018
@kakadiadarpan
Copy link
Contributor

That's great! Thank you for the quick update. 🙂

@erquhart
Copy link
Contributor

Relative image path support is now in beta as of Netlify CMS 2.9.8-beta.2 - try it out:

npm update netlify-cms-app@beta

Then add media_folder_relative: true to your Netlify CMS config.

Docs here.

@eur2
Copy link
Author

eur2 commented Aug 25, 2019

Have been waiting so long for it. Can't wait to test it!
@erquhart Thanks so much

@eur2
Copy link
Author

eur2 commented Aug 31, 2019

@erquhart I have tried the new Nelify CMS beta but I'm getting the error: Field "image" must not have a selection since type "String" has no subfields
Here is my config.yml.
At the end of this file, I have a list widget (name: archive) with object (name: figure) and image widget in it. The error is coming from there in the GraphQL query.

backend:
  name: git-gateway
  branch: master

media_folder_relative: true 
media_folder: static/assets
public_folder: /assets

collections:
  - name: 'post'
    label: 'Post'
    folder: 'content/post'
    create: true
    slug: '{{slug}}'
    fields:
      - {
          label: 'Template Key',
          name: 'templateKey',
          widget: 'hidden',
          default: 'post',
        }
      - { label: 'Cat', name: 'cat', widget: 'hidden', default: 'total-reconstruction' }
      - { label: 'Title', name: 'title', widget: 'string' }
      - { label: 'Publish Date', name: 'date', widget: 'datetime' }
      - { label: 'Description', name: 'description', widget: 'text' }
      - { label: 'Image', name: 'image', widget: 'image' }
      - { label: 'Body', name: 'body', widget: 'markdown' }
      - { label: 'Tags', name: 'tags', widget: 'list' }
      - { 
          label: 'Notes', 
          name: 'notes', 
          widget: 'list',
          required: false,
          fields:
            [
              { label: Number, name: number, widget: string },
              { label: 'Note',
                name: 'note',
                widget: 'markdown'
              },
            ],
        }
      - { 
          label: Archive, 
          name: archive, 
          widget: list,
          types:
            [
              { label: Figure,
                name: figure,
                widget: object,
                fields:
                  [
                    { label: Number, name: number, widget: string, default: '1' },
                    { label: Image, name: image, widget: image },
                    { label: Caption, name: caption, widget: string },
                  ],
              },
            ],
        }

@Jan17392
Copy link

@erquhart The beta functionality kind of works, but it seems to also set relative paths on upload which messes everything up. Please check the ticket I opened in the netlify cms repo, whether this is really a bug: decaporg/decap-cms#2696

@erquhart
Copy link
Contributor

Replied on the Netlify CMS issue 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

7 participants