Wordpress: Cleanup and Optimization tips

Anh-Thi Dinh

Turn off auto-generating thumbnails for images

When you upload an image to the WP Media Library, all the "neccessary" thumbnails (of various sizes and scales) are automatically generated, depending on your WP site settings and the theme you are using.
I use reGenerate Thumbnails Advanced to regenerate all of the current images on my site and remove all of the thumbnails. To prevent the generation when you upload new images in the future, you can use the Stop Generating Unnecessary Thumbnails plugin.
When you upload an image to the WP Library, this image can be very large (in MB). It's recommended to resize and compress the image before uploading it to your site, but what about the images you have already uploaded?
I use imagemagick to shrink the images to a maximum width and height of 1280x1080 and skip images that are below this value.
Resize all the images in the current folder and put the new images in ./out/
1magick mogrify -path out -resize 1280x1080\> *
In order to compress the images, you can use iloveimg website.
If WP Amin > Settings > Media > "Organize my uploads into month- and year-based folders" is enabled (normally this option is enabled by default), every time you upload a new image, it will be placed in a subfolder like 2022/09/21/. So, if you want to find a featured image of a post to resize and compress it, you need to know which folder it belongs to.
Use the following Python script to move all images in subfolders to a new folder,
1# copy_source_images.py
2import shutil
3import sys
4import os
5import re
6
7def copy_source_images(path, path_copied):
8    """
9    Copy all images in folders/subfolders whose name not end with "???x???" to a new folder
10    """
11    for root, _, files in os.walk(path):
12        for name in files:
13            if not re.match('.*-[0-9]{1,4}x[0-9]{1,4}.*', name):
14                file_full_path = os.path.abspath(os.path.join(root, name))
15                rst = shutil.copy(file_full_path, path_copied)
16                if (rst):
17                    print(f'✅ Copied "{name}" to {path_copied}')
18
19if __name__ == "__main__":
20    copy_source_images(sys.argv[1], sys.argv[2])
How to use it?
1python copy_source_images.py /home/thi/Downloads/
Require: posts are already attached with an featured image name.
This is useful when doing the previous step (moving all featured images from subfolders to a new folder). Each post has the featured image's information attached (the name and the path of the image). If you change the path of this image (on disk), you must also change the path in the post's data. We can do this by the name of the image and the title of the post.
Uncheck "Origanize my uploads in month- and year-based folders" in WP Admin > Settings > Media.
Get the list of posts with their data: WP Admin > GraphiQL IDE,
1{
2  posts {
3    nodes {
4      databaseId
5      title
6      featuredImage {
7        node {
8          sourceUrl
9        }
10      }
11    }
12  }
13}
Note that WPGraphQL is limited to a maximum of 100 nodes by default (ref), follow this guide to increase that limit.
1// Add below code to functions.php
2add_filter( 'graphql_connection_max_query_amount', function( $amount, $source, $args, $context, $info  ) {
3    $amount = 1000; // increase post limit to 1000
4    return $amount;
5}, 10, 5 );
After retrieving the post data, you can save it in a posts.json file.
We need wp-cli to attach an image to a post and set it as the feature image for that post.
1wp media import --post_id=6804 --featured_image /Users/thi/Downloads/image.jpg
If you are using Local, the wp-cli is already there (you just need to go to the site folder on your terminal or using Local > "Open site shell"). Otherwise, install wp-cli.
The following script is an example. It automatically detects the name of the featured image attached to a post (in a list of posts posts.json) and attaches that image from the uploads_resize_path folder to that post with a new path.
1# assign_featured_images.py
2import sys
3import os
4import json
5
6json_path = '/Users/thi/Downloads/math2it/posts.json'
7uploads_resize_path = '/Users/thi/Downloads/math2it/uploads_resize'
8site_path = '/Users/thi/Local\ Sites/math2it/'
9
10def main(fromIndex, toIndex):
11    """
12    Auto upload images to wordpress + assign featured images to posts
13    """
14    f = open(json_path, 'r')
15    data = json.load(f)
16    f.close()
17    nodes = data['data']['posts']['nodes']
18    total_posts = len(nodes)
19    for idx, node in enumerate(nodes[int(fromIndex):int(toIndex)]):
20        image_name = node['featuredImage']['node']['sourceUrl'].split(
21            '/')[-1] if node['featuredImage'] else 'math.png'
22        post_id = node['databaseId']
23        post_title = node['title']
24        cmd = f'wp media import --post_id={post_id} --featured_image {uploads_resize_path}/{image_name}'
25        os.system(f'cd {site_path} && {cmd}')
26        print(
27            f'✅ [{idx + int(fromIndex)} / {total_posts}] Assigned featured image "{image_name}" to post "{post_title}"')
28
29if __name__ == "__main__":
30    main(sys.argv[1], sys.argv[2])
Use it?
1# Upload post from index 5 to 16-1
2python assign_featured_images.py 5 16