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

Copy external images to the media library when pasting content. #2515

Open
ellatrix opened this issue Aug 23, 2017 · 40 comments
Open

Copy external images to the media library when pasting content. #2515

ellatrix opened this issue Aug 23, 2017 · 40 comments
Assignees
Labels
[Feature] Media Anything that impacts the experience of managing media Needs Dev Ready for, and needs developer efforts [Type] Enhancement A suggestion for improvement.
Milestone

Comments

@ellatrix
Copy link
Member

ellatrix commented Aug 23, 2017

With upcoming paste improvements, there will be more types of sources that the image block should be able to handle.

  • data: (base64 encoded)
  • file: (local files) Not possible sorry. They are now deleted in c9e6e62, but a placeholder is kept. We could also inform the user that they need to re-add them.
  • External images. We should not hot link to e.g. a Google CDN. The image should be copied to the server.
@karmatosed karmatosed added the [Feature] Media Anything that impacts the experience of managing media label Aug 24, 2017
@jeffpaul
Copy link
Member

This ticket was mentioned in Slack in #core-editor by jeffpaul. View the logs.

@jeffpaul jeffpaul added this to the Future milestone Feb 15, 2018
@ellatrix
Copy link
Member Author

The only thing left here is to copy external images (at least from pasting) to the server.

@danielbachhuber danielbachhuber modified the milestones: Future, WordPress 5.0 Jun 4, 2018
@danielbachhuber danielbachhuber added the [Priority] Low Used to indicate that the issue at hand isn't a top priority to address and can be handled later label Jun 4, 2018
@antpb antpb removed this from the WordPress 5.0 milestone Oct 5, 2018
@mtias mtias added this to the Future: 5.1 Onwards milestone Oct 12, 2018
@youknowriad youknowriad modified the milestones: WordPress 5.x, Future Jan 9, 2019
@youknowriad youknowriad modified the milestones: Future, Future: Phase 2 Jan 21, 2019
@youknowriad youknowriad changed the title Image block needs to handle variety of sources Copy external images to the media library when pasting content. Apr 3, 2019
@mapk
Copy link
Contributor

mapk commented May 12, 2020

I just tried doing this by copying images over from Google Docs to a make blog post and the images did not copy over. Am I right in thinking this is still an issue?

@bph
Copy link
Contributor

bph commented May 26, 2020

During our publishing process (Google Docs collaboration, copy/paste) we noticed, that images are not imported into media library, like noticed here, so it still would be a great feature to add.

We also noticed that smaller images are included as "inline image". It seems that's because they are also inline in the Google doc with a right alignment and the text wrapping around it.

Full-size images covering the full width of the Google Doc show up as an image block.

I tried to think through a process on how to replace the Google images with a separate upload to the media library. My first attempt was to download the Google Doc as HTML to get the image into a directory on my hard drive. All images landed in an image folder and the file names were image1.png, image2.png, image3.png and so forth.

This would be not half bad if the images are numbered in the order they appear on the document. Unfortunately, they are in the order the writer uploaded them to the Google Doc. So, a replacement process is really hard.

Is there a way to increase priority for this issue to solve?

@mapk mapk removed the [Priority] Low Used to indicate that the issue at hand isn't a top priority to address and can be handled later label May 26, 2020
@ellatrix ellatrix self-assigned this Jun 17, 2020
@ellatrix
Copy link
Member Author

ellatrix commented Jul 1, 2020

@bph I'm sorry for the delay with this. Unfortunately, this issue is not straightforward to solve because we have to download and upload the images to the server and this process is asynchronous while paste is synchronous.

Firstly, we'll have to make a separate REST API endpoint to allow uploading images by URL instead of data. This process seems a bit fragile as it's not the same as fetching an image with the browser (cc @azaozz for more info). I'm not sure how quick we can pull an endpoint together.

Secondly, I'm not sure if we can immediately upload images on paste, because of the asynchronicity of these actions. We'll first have to find a way to allow optimistic changes, meaning insert the pasted content, and after the images are uploaded replace the URLs in a way that doesn't affect undo levels. The simplest way to work around that for now is to add a button to manually upload externally hosted images.

@bph
Copy link
Contributor

bph commented Jul 1, 2020

Yes, I suspected it wouldn't be straight forward.

Didn't think of the new endpoint for the REST-API, though - (your step one) I like the asynchronous part of the Step Two. It can be communicated to the content creator, that it happens in the background. The process would need to keep track of the images and know which URL to replace ones the images are uploaded. That's what state is for, I guess...

The "simplest way": - An upload only button, would assume the content creators already has the image on their hard drive. In many cases, the person compiling the Google Doc with the image is not the person copy/pasting to the content into WordPress. One would need more buttons, one for download and one for upload?

I appreciated, you're walking me through this. Thank you!

@azaozz
Copy link
Contributor

azaozz commented Jul 2, 2020

we'll have to make a separate REST API endpoint to allow uploading images by URL

Right, the end point should use (or do something similar to) media_sideload_image() . A server downloading image from another server is typically quite fast, but post-processing the downloaded image may take some time, so generally the whole process would be pretty slow, can even be 5-10 seconds.

There are other possible problems. Most servers would let anybody download images but some have restrictions in place and may disallow other servers from downloading. Guessing in these cases the editor can show an error asking the user to manually download the image and upload it to the media library, and replace it in the post.

This process seems a bit fragile as it's not the same as fetching an image with the browser.

Yes, the browsers would not allow access to the actual image file (blob) unless it is a CORS request, see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-crossorigin. A more detailed guide on saving the image file without the user right-clicking on the image and selecting "Save Image As..." https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image. Note that the third party server has to be configured to send Access-Control-Allow-Origin "*" headers for images which seems usually not the case.

@paaljoachim
Copy link
Contributor

Hey Birgit @bph
I am wondering if we should close this issue (it feels like it is finished),
and have you open a new issue in relation to the WordPress Importer.
What do you think?

@bph
Copy link
Contributor

bph commented Nov 25, 2020

@paaljoachim 👋 I am all for it, except I don't know if that's a Gutenberg issue or an Importer issue, when images are not coming over in the first place...

@paaljoachim
Copy link
Contributor

Hey Birigit @bph
Ahhh yes, it sounds like in a WordPress trac ticket would be the correct place to have it.

@ellatrix
Copy link
Member Author

The issue here is only partly fixed. Currently, we allow uploading images with the image block only if it can be done in JS (the image host has to allow it, like Google Docs does right now). A more complete solution would be to upload the externally linked image through the server.

@paaljoachim
Copy link
Contributor

Hey Ella. @ellatrix
Do you have a suggestion for a solution that a developer might have the time to pick up and create into a PR?

@ellatrix
Copy link
Member Author

Yes, like I said, it would have to be uploaded through the server. So: send the image URL to the server, which then fetches the image and uploads it to the server, create an attachment in the database etc, then send the new attachment data back to Gutenberg.

@paaljoachim paaljoachim added the Needs Dev Ready for, and needs developer efforts label Dec 15, 2020
@jonoalderson
Copy link

jonoalderson commented Mar 8, 2021

Hi, folks! Arriving late to this conversation, but I'm keen to revisit and see if we can move this forward. Apologies if I'm re-treading old ground, and/or if this is all already in hand and I'm just not seeing the relevant thread(s).

That said:

  • I'm conscious that a lot of sites/users just paste images into their content, and those images don't benefit from the kinds of modern image markup that hosted images do (srcset, sizes and loading attributes, just to name a few). That causes some pretty severe front-end performance issues, and does so at a rather scary scale.

  • I'm also nervous that every day which passes without us addressing this increases the likelihood that those existing images are permanently suboptimal, as it's unlikely that users will revisit and 'upgrade' images in existing content.*

    • *Separately, it'd be nice to explore opportunities to apply these upgrades automatically, retroactively, etc.
  • Given that the 'upload external image' button/function exists, is there anything preventing us from making that the default behaviour when you paste an image in, assuming that;

    • As part of the process, we'd need to account for the image block needing to expect the image asset asynchronously
    • Images which fail (due to permissions or otherwise) present some kind of graceful failure notification, and use the existing approach.
  • How can we push this as a matter of urgency? The marketing, carbon and performance costs here are hurting us and our users.

@aristath
Copy link
Member

aristath commented Mar 8, 2021

Just spitballing some ideas here...
The editor already saves drafts periodically using a rest hook. So we could hook into that, get the content, scan for external images and upload them on the server at that time. This way it happens async, and by the time the author hits the publish button most (if not all) images will already live on the server.
If there are 1-2 images that were not caught by the auto-draft action because they were added after the last autosave, then a 2nd hook ok save would take care of them. It's certainly possible.... 🤔

@ianstewart
Copy link
Contributor

With the pattern directory on the horizon and (perhaps) more opportunity for hotlinked images added to the Editor via paste or insertion from another site via an API it may be another reason to add more weight to the remaining Todo on this issue.

@zdenys
Copy link

zdenys commented Jun 25, 2021

The possibility to copy external images to the media library when pasting content instead of hotlinking them would be such a helpful feature! 😍

@zdenys
Copy link

zdenys commented Jun 25, 2021

I can see it's now possible to upload images when copied and pasted from a Google Document: https://wordpress.org/support/article/image-block/#external-image-upload

But if I copy all of the content from one post on a given site into another site, the images are hotlinked. It would be helpful to address this scenario.

@adamziel
Copy link
Contributor

I imagine this could work just like uploading an image, the hotlinked version would be just a greyed-out preview with a spinner on top of it to indicate that the actual image is being downloaded/processed. The technical side could be even similar: Gutenberg would issue an API request with the URL in question and then we would just need an endpoint that would do the work.

@adamziel
Copy link
Contributor

Given that the 'upload external image' button/function exists, is there anything preventing us from making that the default behaviour when you paste an image in, assuming that;

It looks like that button only uploads inline blobs and can't handle external URLs at the moment:

{ externalBlob && (
<ToolbarButton
onClick={ uploadExternal }
icon={ upload }
label={ __( 'Upload external image' ) }
/>
) }

@nerra0pos
Copy link

Is there any update to this? We switched from another software to Wordpress. That software used a markdown editor and pasting external images into posts were instantly uploaded. Amazing that is not the case in Gutenberg, yet.

@ellatrix
Copy link
Member Author

We could upload external images after paste automatically. The problem is that paste is synchronous while uploading is async, so it's probably best to insert the block immediately and handle upload after that (so the action is not blocking the user). Without a solution to #8119 though, it will add a new undo level for each uploaded image.

@TimothyBramlett
Copy link

Any more updates on this? I don't want to have to click upload on every image.

  • Could there be a button to do it all at once for an article?
  • Perhaps even better, could there be a setting to auto-upload external images when the post is published?

@hellosubscription
Copy link

"So, If you copy and paste an image from a resource like Google Docs, a button will appear on the toolbar to upload it to the media library. Click that, and it will stay in the post, but also upload to your media library."

Why does this button not appear for any external images and only the ones wrapped on gdocs (or similar)? Are there ANY workarounds? It's super appalling this is still not dealt with.

This has been four years of knowing this need exists and it still does not?

Why is the behavior different for an image in a clipboard from a screenshot (pastes right in and actually uploads to media library, yes it's grayed out for some seconds, who cares) vs an image copied to clipboard by right click/copy image? I think the answer is really obvious - use whatever function that's being used to paste that in when pasting an image into a post. Make it a global setting if you want to choose between hotlinking or copying to the media library.

I just pasted the image below from the wordpress docs. Works fine. Obviously copies over. Github can do it, so can WP. Whatever handwringing is happening with that it may be slightly asynchronous completely and absolutely ignores user needs. This is literally insane.

image

@mcsf
Copy link
Contributor

mcsf commented Feb 3, 2022

Why is the behavior different for an image in a clipboard from a screenshot (pastes right in and actually uploads to media library, yes it's grayed out for some seconds, who cares) vs an image copied to clipboard by right click/copy image? I think the answer is really obvious - use whatever function that's being used to paste that in when pasting an image into a post. Make it a global setting if you want to choose between hotlinking or copying to the media library.

I just pasted the image below from the wordpress docs. Works fine. Obviously copies over. Github can do it, so can WP. Whatever handwringing is happening with that it may be slightly asynchronous completely and absolutely ignores user needs. This is literally insane.

First of all, everyone here puts the user first. Everyone comes with their own experience and weighs advantages and drawbacks differently. Calling collaboration "literally insane" is not helpful.

Now, it's been two years since the original comments about breaking undo levels, and some progress has been made since. The proof is that, in most circumstances, images can indeed be copied from elsewhere and pasted into Gutenberg to produce an Image block with a freshly uploaded local image.

But this can fail at times. There are two things at play here.

One of them is that cross-origin resource sharing (CORS) — a security feature wherein browsers honour websites' sharing policies — prevents Gutenberg from processing external images if the remote host forbids it. This is the case, for instance, with Google Photos, and it is the reason why the "Upload external image" button is disabled.

The other thing is the heuristics used by Gutenberg to determine what to do when content is pasted into it. Because of an annoying quirk in Microsoft Word, there was a workaround in Gutenberg that was causing images pasted in specific circumstances to be dismissed. I fixed this in #38459, and I hope this will make a noticeable difference in how Gutenberg does what the user would it expect it to.

@corentin-gautier
Copy link
Contributor

corentin-gautier commented Sep 22, 2022

Hi @ellatrix !

So here's the thing :

The following images is hosted on another wordpress instance, on another server. I just used the "copy all content" feature and pasted everything into a new post.

  • I have no way of knowing it's not a locally hosted image (ie: in the media library)
  • I have no way of making it a local file.

Screenshot 2022-09-22 at 15 56 06

To achieve this I would have to go to the old file, download it, upload it in the new site then replace the image in the new post. For every single images in the post ...

Having at least a button under "Current media url" in the "Replace" menu would help a lot !

@cbirdsong
Copy link

I've just run into this exact issue twice this week, once when moving content between a staging server and a production server and once when a publication republished content (with permission!) from another site. At the very least there should be an indication in the UI that the image is hosted externally that I can tell editors to look out for.

@ellatrix
Copy link
Member Author

Excited to announce that this will be improved in #46014.

  • Any external image can now be uploaded (no longer limited to images with CORS headers). This means also the images in the demo content can be uploaded.
  • Added a prepublish that shows you all external images with the option the batch upload them.

@priethor
Copy link
Contributor

@ellatrix I think this can be closed now that #46014 is merged unless we want images to auto-upload to the library by default.

@ellatrix
Copy link
Member Author

ellatrix commented Jul 1, 2023

I think it would still be good to auto upload, but that's blocked by better undo: #2515 (comment)

@jordesign jordesign added the [Type] Enhancement A suggestion for improvement. label Aug 1, 2023
@scruffian
Copy link
Contributor

I created a connected issue: #54185

@solaceten
Copy link

solaceten commented Sep 3, 2024

Wordpress Post Page when copying images and text over to a post I see the wonderful:

Suggestion: External media
Upload external images to the Media Library. Images from different domains may load slowly, display incorrectly, or be removed unexpectedly.

With thumbnails and a "Upload" button.

I love this feature, but unfortunately it's not working for me. I am copying content over from Mailchimp. Is it a CORS issue?
Is this a localised issues? I can reproduce this error in multiple browsers and different devices, so I think it's something in the code...

When I click the "Upload button" here is the dev console output

Uncaught (in promise) TypeError: Failed to fetch
    at editor.min.js?ver=8607251058f984a77c8f:7:172104
    at Array.map (<anonymous>)
    at onClick (editor.min.js?ver=8607251058f984a77c8f:7:172089)
    at n.<computed> (components.min.js?ver=36b97398bf090476214e:27:14952)
    at Object.De (react-dom.min.js?ver=18.3.1:2:16716)
    at Be (react-dom.min.js?ver=18.3.1:2:16870)
    at react-dom.min.js?ver=18.3.1:2:36731
    at Ir (react-dom.min.js?ver=18.3.1:2:36825)
    at Ur (react-dom.min.js?ver=18.3.1:2:37239)
    at react-dom.min.js?ver=18.3.1:2:42667

Is this related to : #24334

And also

#54185 (comment)

and

#46014 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Media Anything that impacts the experience of managing media Needs Dev Ready for, and needs developer efforts [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests