With an external storage adapters Ghost no longer creates resized images for use with srcsets. Is there a way to implement this with the storage adapters?
I poked around in the source and it looked like the lack of a .saveRaw() method caused it to skip resizing so I’ve added an appropriate .saveRaw() but didn’t have any luck.
Any other tips?
Update: Does it only generate the images when the Ghost engine itself receives an image request with a size? Seems that way.
Update2: This is tough. It also seems like the generated path has a hardcoded ‘/content/images’ from url tools.
As staticImageUrlPrefix: 'content/images'
It took me a long time to find that.
Now I have a Google Load Balancer with a content/images/* prefix directed to the bucket from the domain to force Ghost to prove srcsets correctly (it is specifically coded to only provide them for “internal” images).
The goal is to be able to use the google storage adapter with srcsets.
Step 1 was to get Ghost to generate the srcsets at all (it is coded not to if the adapter is external, but the only way that it checks is by host and path). It generates the srcsets now.
That’s the goal. When using the Google Storage Adapter to take advantage of a GCP Bucket Ghost will never even see the image requests (as intended) - but it looks like it generates the resized images only on request. The adapter has to generate them. Then you have to trick Ghost into producing srcsets for the image tags because it’s logic locked to not produce them for external hosts.
The first work-around is the load balancer work-around mentioned. A google load balancer remaps content/images/* → bucket. This tricks Ghost into providing the srcsets correctly in the frontend helpers because it thinks https://MYSITE/content/images/* is being served by Ghost (but it isn’t).
An assetPath config item was added to the ghost-google-cloud-storage-new adapter to make it easier to tweak the path.
This is the fork of the ghost-google-cloud-storage-new adapter I’m working in
Maybe a toggle for the srcset helpers in the templates to force them on? Once forced on, maybe the Ghost admin upload could get the sizes from the theme and use the adapter.save() on its own? I’m not sure what would be best.
Small side note: I am not the greatest node developer… ;)
Uploaded images go through the Ghost image processor/Sharp and are sent to the bucket with all of the sizes specified in the package.json of the current theme. All images are served directly from the bucket. Images appear in the theme with the appropriate srcsets.
I have this really nasty chunk of synchronous code to sort out later:
But for now it does exactly what I want. I can use the Ghost API freely, the Ghost UI with responsive images, and all the responsive images (with the API) in a separate front end.
hey @elijahsgh and @Hannah how you got this custom storage adapter to set srcset for all different sizes ?
I followed your code and become able to generate images of all different sizes
but can not make any use of it since srcset has not changes yet
Hello Nitish.
Unfortunately I haven’t tried this custom storage adapter with the newer versions of ghost. It may have changed.
In previous versions there is specifically a chunk of code that is “hardcoded” to guess if media is coming from ghost. If ghost believes the media is external it will not provide the srcsets. If it believes it is serving the media then it will.
For newly created/updated posts you should see it using srcsetif the storage adapter presents images as being local (url matches SITE_URL/content/images) and has the saveRaw method.
If you’re referring to old/existing posts then nothing will change automatically, the html for a post is generated on save and is static. To update older posts to have srcsets you’d need to make a change to the post’s content and save, or force a re-render through the API (there’s an example API script to force-render all posts here).
@Kevin
then what is the solution?
how I can achieve my goal (using s3 as storage and also getting responsive images )
like if can work with any other external store ,using any plugins like cloudinary.
You’re on the right track. See Kevin’s post for a better explanation for what I meant by “hardcoded chunk of code” where “ghost thinks it is serving the images”.
Kevin specifically mentioned {SITE_URL}/content/images which is what I did with GCP. Basically you need a url matcher that matches that path and serves from the bucket. When Ghost generates a template it will think that it is serving the images. If your external storage does not match the {SITE_URL}/content/images pattern ghost will never generate srcsets.
I haven’t tried any of this with version 4 but if Kevin says that’s how it works it probably still works that way.