Post images optimized by <g-image> on Wordpress Source
See original GitHub issueSummary
Have the wordpress post images available on GraphQL layer so they can be passed to g-image component.
During build / develop command:
- Wordpress Post HTML content is parsed;
- Posts are split into fragments being either html or img fragments;
- All images are downloaded from the remote source and stored locally if they haven’t been before;
- Images are added to graphql
- You can now pass the images to g-image and have the magic happen (optimization, lazy-loading and progressive image)
Basic example
I’ve created this fork and successfully implemented a working version of this feature. Please note that I am new to nodejs, webpack, and javascript in general. Mostly I work with php and vue. Let me know if I should pursue this and submit a PR.
https://github.com/dominiquedutra/gridsome/commits/source-wordpress-get-post-images
Simply clone the branch and start a new clean WordPress starter. Modify your WordPressPost.vue file:
<template>
<Layout>
<h1 v-html="$page.wordPressPost.title"/>
<template v-if="$page.wordPressPost.postFragments" v-for="fragment in $page.wordPressPost.postFragments">
<!-- Fragment is a html block -->
<template v-if="fragment.type == 'html'">
<div v-html="fragment.fragmentData.html"></div>
</template>
<!-- Fragment is a image -->
<template v-if="fragment.type == 'img' && fragment.fragmentData.image">
<g-image :src="fragment.fragmentData.image" width="200" />
</template>
</template>
</Layout>
</template>
<page-query>
query Post ($path: String!) {
wordPressPost (path: $path) {
title
content
excerpt
link
postFragments {
type
fragmentData {
image
html
}
}
categories {
id
title
path
slug
}
}
}
</page-query>
<script>
export default {
metaInfo () {
return {
title: this.$page.wordPressPost.title
}
}
}
</script>
<style>
//Up to you
</style>
Set options for Wordpress Source on gridsome.config.js
:
plugins: [
{
use: '@gridsome/source-wordpress',
options: {
baseUrl: '', // required
typeName: 'WordPress', // GraphQL schema name (Optional)
perPage: 100, // How many posts to load from server per request (Optional)
concurrent: 10, // How many requests to run simultaneously (Optional)
splitPostsIntoFragments: true, //Split html posts into fragments representing html blocks or images
downloadRemoteImagesFromPosts: true, //Download remote images
postImagesLocalPath: '/Users/username/this/must/be/full/path/', //Full path with '/' in the end
routes: {
post: '/:slug', //adds route for "post" post type (Optional)
post_tag: '/tag/:slug' // adds route for "post_tag" post type (Optional)
}
}
}
]
Run gridsome build
and use http-server (yarn global add http-server) to serve dist folder (cd dist && http-server
)
Tested on a production WordPress instance with about 250 posts and 1200 images. It takes some time to download and process the images but not nearly as much as I thought it would.
Motivation
I am sure some people out there want to use Wordpress (and other headless cms) that behave like WordPress regarding post images. Not having post images optimized is bad. We could use this as boilerplate to modify any source plugins.
Todo (I can easily invest time on this if the idea is on track)
- ~Check why building to Zeit now won’t work~;
- ~Extract image alt and description and have those properties available on graphql~;
- Replicate WordPress folder structure locally
wp-content/uploads/{year}/{month}
- currently, all images are being stored on a single dir; - ~Download featured images as well~.
- [ISSUE] sometimes, when syncing a lot of images, some images get downloaded partially.
Please let me know what you think. Let me know if you need a staging WordPress endpoint to test this.
@hjvedvik my fork branch is really dirty. If you think this is an idea that should be pursued I can clean it up and prepare a PR. Also, we could move further and split postFragments in:
HTML fragments -> ends in v-html IMG fragments -> ends up in g-image HREF fragments -> ends up in g-link
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:17 (8 by maintainers)
@dominiquedutra Downloading and processing is indeed on our roadmap and would be great if you want to look into it 😃 I have been thinking about how it could be solved, but haven’t done any testing yet. One approach would be to just let the source plugins download all its images when you start the project. But that will download lots of unnecessary images in development.
Another approach could be to have a
download
argument forg-image
and image fields in the schema. Gridsome would then download the image and process it only when they were visited in development mode.In the build process, we could somehow try to skip the GraphQL resolvers for external images while executing all the queries and run them in another step later in the process. Because downloading all the images while executing queries will be very slow. When downloading the images, we generate the base64 string and add the image to the process queue. Then patch the results from the GraphQL query in the previous step before the data file is written to disk.
Images in HTML content like the Wordpress post body could also be downloaded and processed in the same way, but just needs more logic to extract them from the HTML etc. I’m working on a GraphQL API which could let plugins do it instead of having each source plugin doing it manually. For example, a plugin could add a
@downloadAssets
directive to the schema which would process anyString
field.Just a few ideas if they make any sense 😃
I’ve added it as a PR #568