question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Post images optimized by <g-image> on Wordpress Source

See original GitHub issue

Summary

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:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:17 (8 by maintainers)

github_iconTop GitHub Comments

5reactions
hjvedvikcommented, Jun 20, 2019

@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 for g-image and image fields in the schema. Gridsome would then download the image and process it only when they were visited in development mode.

<g-image src="https://example.com/image.png" download />
query Post {
  image(download: true)
}

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 any String field.

type WordPressPost implements Node {
  title: String!
  content: String! @downloadAssets
}

Just a few ideas if they make any sense 😃

2reactions
u12206050commented, Jul 20, 2019

I’ve added it as a PR #568

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Easily Optimize Images for Web (without Losing Quality)
Image optimization is a process of saving and delivering images in the smallest possible file size without reducing the overall image quality.
Read more >
How To Optimize Images in WordPress - A Step-by-Step Guide
We recommend sizing your images to the desired dimensions using an image editor before uploading to WordPress. You can also optimize and compress...
Read more >
Image Optimization In WordPress - Smashing Magazine
In this article, Adelina Țucă explains how you can easily optimize all the images on your website (manually or on autopilot) in order...
Read more >
Image Optimization - Learn WordPress
Image Optimization helps you improve website performance. ... WordPress lets you upload images in several formats. Most commonly images are saved as JPG, ......
Read more >
How to Optimize Images for WordPress: Best Practices + Tips
What Is the Best Image Size for WordPress? ; Blog post images: 1200 x 630 px ; Headers: 1048 x 250 px ;...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found