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

Allow for relative paths of media files #2394

Merged
merged 9 commits into from
Aug 24, 2019
Merged

Conversation

s0
Copy link
Contributor

@s0 s0 commented Jun 20, 2019

Summary

fixes #325

This is an initial attempt at fixing the long-standing issue of Netlify not supporting relative paths in the output in markdown, frontmatter, yaml etc...

I wasn't quite able to get it working the way I had hoped, which I'll go into in a little bit, but this at least should work for the majority of cases talked about on #325. (EDIT: I was able to get this working)

In short, I've introduced a new configuration option media_folder_relative which when set to true, is used in place of public_folder, and no slash is prepended to the path will calculate the relative path to media files from the relevant collection's folder, instead of using public_folder or media_folder. This work is based on the work @fk did in fk@2ebbed8

Original Idea (now implemented):

What I was originally thinking after reading the thread in #325 was that it would be great if we could instead use a boolean configuration flag to indicate if paths should be relative, and then if that's the case, resolve what that relative path would be using the path of the Entry that we're inserting the media into. This has the added benefit of not requiring all collections to be in the same location relative to the media folder. e.e, something like this:

content
├── posts
│    ├── hello_world.md
│    └── foo_bar.md
├── media
│    └── image.png
└── meta
     ├── tags
     │    └── tag_1.md
     └── categories
          └── category_1md

Would allow files in posts, tags and categories to all relatively refer to images in media. However I was unable to get this working as I wasn't sure how to obtain information of the current entry from within the context of the mediaLibrary actions and reducers, or from within the FileControl component (i figured out how to pass a path from FileControl to resolvePath though).

For example, media_folder would be content/media. And for content/posts/hello_world.md we'd resolve image.png to ../media/image.png. And from tag_1.md we'd resolve it to ../../media/image.png.

Other Ideas Considered:

Just use public_folder, and don't prepend a slash if it starts with ./ or ../.

@erquhart had suggested this (#325 (comment)). However this has the downside that it is a breaking change for people that have misconfigurations of public_folder, but also it prevents us being able to also use public_folder to display preview images in the CMS. I also felt that the name would be inconsistent with how we were treating that configuration variable (i.e. not as a public folder at all).

Further Potential Improvements:

  • Implement the original idea (DONE)
  • resolvePath seems to be used in a number of different contexts, and it's not clear that they're all the same. For example it's now used for converting a single filename to a path to enter in to the markdown. It's also used to convert that path into a path to use when displaying the image in the CMS. It probably makes sense to split it out into different functions for the different contexts so this is clearer. (EDIT: this is partially done in resolveMediaFilename now).
  • due to its use of resolvePath, the image preview in FileControl doesn't work in the case where the image:
    • has not been deployed to the public site yet
    • is not directly published to some static folder (e.g. when using resharper)
    • is referred to by some relative path (i.e. the use case here)
      It would probably make sense to have it use the same mechanism as loadMediaDisplayURL in the mediaLibrary action.

@netlify
Copy link

netlify bot commented Jun 20, 2019

Preview proposed changes to netlifycms.org in the link below:

Built with commit 80cf364

https://deploy-preview-2394--netlify-cms-www.netlify.com

@netlify
Copy link

netlify bot commented Jun 20, 2019

Preview proposed changes to the CMS demo site in the link below:

Built with commit 80cf364

https://deploy-preview-2394--cms-demo.netlify.com

s0 added 2 commits June 21, 2019 23:14
The required relative path is now calculated depending on the
location of the collection of the current entry having the
media inserted into. And the configuration option has now been
changed to a boolean flag.

This allows collections to not neccesarily all be in the same
location relative to the media folder, and simplifies config.
@s0
Copy link
Contributor Author

s0 commented Jun 22, 2019

While working on my other pull request #2397, I was able to work out how to get information about the current entity being edited from within mediaLibrary actions. So I came back to this PR and implemented the original idea. I'm now much happier with the way that this is implemented, which feels significantly more robust.

I also introduced a new function in path.js called resolveMediaFilename that is specifically used to calculate the path to insert into the frontmatter / markdown / collection entry, and has a more explicit API and docs.

The image previews in FileControl are still not working for now though.

@erquhart
Copy link
Contributor

Thanks for digging into this! The approach is dead on, resolving the relative path for individual files makes the mosts sense 👍

I know there's not a ton of existing coverage to add to (we're working on it), but we're requesting that new pull requests include adequate test coverage. Makes it much easier to ensure against regressions, cover the new code, and provide documentation-in-action of how new functionality is supposed to work.

@s0
Copy link
Contributor Author

s0 commented Jun 25, 2019

Sounds good. I'll add some tests for these changes.

s0 added 3 commits June 25, 2019 20:06
This moves more of the media path resolution logic into the action
which makes it easier to unit test
@s0
Copy link
Contributor Author

s0 commented Jun 26, 2019

I've added unit tests now, and reworked the action a little bit to make it easier to test too. To do this I also added redux-mock-store as a devDependency for netlify-cms-core to use in testing thunk action creators (which insertMedia is now).

@erquhart
Copy link
Contributor

Awesome, thanks for that! I think we can get this into beta and ask some Gatsby users to test it out.

@Benaiah you good with this being merged? I don't think it impacts what you're working on, but wanted to be sure.

@s0
Copy link
Contributor Author

s0 commented Jul 5, 2019

@Benaiah @erquhart any update on this? :)

@erquhart
Copy link
Contributor

Hey Sam - sorry, haven't forgotten about this, will get it merged and released soon.

@erquhart
Copy link
Contributor

Fixed merge conflict, merging and releasing to beta.

@erquhart erquhart merged commit a47a29f into decaporg:master Aug 24, 2019
@erquhart
Copy link
Contributor

Released in 2.9.8-beta.2 - so sorry for the wait!

@s0
Copy link
Contributor Author

s0 commented Aug 26, 2019

Awesome! =)

@dclayto1
Copy link

Thanks for doing this guys! I've been excited for this feature to get merged, but when I run an npm install with 2.9.8-beta.2, I'm getting the following dependency error

npm ERR! code ETARGET
npm ERR! notarget No matching version found for netlify-cms-backend-github@^2.5.0-beta.1
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget 
npm ERR! notarget It was specified as a dependency of 'netlify-cms-app'
npm ERR! notarget 

Did the dependencies of netlify-cms-app not get updated properly?

@erquhart
Copy link
Contributor

You're totally right! Thanks for reporting this, I'll update when it's published.

Sent with GitHawk

nathankitchen pushed a commit to nathankitchen/netlify-cms-backend-azure that referenced this pull request Feb 24, 2020
* Allow for relative paths of media files

fixes decaporg#325

* Switch to calculating the relative path based on collection

The required relative path is now calculated depending on the
location of the collection of the current entry having the
media inserted into. And the configuration option has now been
changed to a boolean flag.

This allows collections to not neccesarily all be in the same
location relative to the media folder, and simplifies config.

* Clean up code and fix linting

* Add unit tests to resolveMediaFilename()

* Rework insertMedia action to fetch own config

This moves more of the media path resolution logic into the action
which makes it easier to unit test

* Add unit tests for the mediaLibrary.insertMedia action

* yarn run format

* add dependabot config (decaporg#2580)
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

Successfully merging this pull request may close these issues.

'relative path' field for uploaded images
3 participants