Automatic Updates For Private And Commercial Themes
Update 2017-06-20: This library has been deprecated. Please use PUC instead. It’s more current and it supports both themes and plugins.
This is a PHP library that lets you add automatic update notifications and single-click updates to any WordPress theme. It’s purpose is to be easy to integrate for developers and to provide a familiar experience to theme users. From the users’ point of view, update notifications generated by this library will look and function just like those displayed by WP itself.
Download
- Client library (requires WP 3.2 or later, tested up to 4.0-alpha)
- Example theme
- Example metadata file
License
This library is licensed under the GPL and is distributed free of charge. If you find it useful, consider making a donation. Commercial licensing (e.g. for projects that can’t use an open-source license) is available upon request.
Quick-Start Guide
There are two things you will need to do:
- Create a publicly accessible “metadata file” that describes the latest version of your theme.
- Add the update checker to your theme and tell it where to find that file.
First, the metadata file. Open your favourite text editor and copy the following JSON code into a new file:
{ "version" : "2.0", "details_url" : "http://example.com/example-theme/details.html", "download_url" : "http://examle.com/example-theme/example-theme.zip" }
Replace the placeholder values with your own data. As you can probably guess, version
is the version number of your theme. details_url
specifies the page that the user will see if they click the “View version 1.2.3 details” link in an update notification. Set this field to your “What’s New In Version 1.2.3” page or the theme homepage (tip: if you notice that your page looks strange when viewed from the WP dashboard, see this comment).
Finally, download_url
is the URL where the latest version of the theme can be downloaded. This field is optional. If you leave it out, the user will still get an update notification when a new version comes out, but there will be no “update automatically” link. They’ll have to download and install the update manually.
Upload the metadata file to your website. You can use any directory and file name you like; just remember that the file URL should be accessible from wherever someone might install your theme.
Next, lets add the update checker library to you theme. Copy the “theme-updates” directory from the client library to your theme. Then add the following to your functions.php
:
//Initialize the update checker. require 'theme-updates/theme-update-checker.php'; $example_update_checker = new ThemeUpdateChecker( 'example-theme', 'http://example.com/example-theme/info.json' );
Again, replace the placeholders with your own settings. The first argument should be the name of your theme’s directory. For example, if your theme lives in /wp-content/themes/my-theme/, use “my-theme” here. The second argument should be the URL of the metadata file you just created.
Congratulations, your theme now supports automatic updates 🙂 The update checker will automatically query the metadata file every 12 hours, checking to see if a new version is available. If it finds one, it will display a standard theme update notification on the Dashboard. Your users will be able to install the new version with a single click.
The ThemeUpdateChecker class
Class constructor
The library is configured by passing a number of arguments to the ThemeUpdateChecker constructor. They are, in order :
$theme
– The theme directory name, sometimes called the “slug”.$metadataUrl
– The URL of the theme metadata file.$enableAutomaticChecking
– Enable/disable automatic update checking. If set to FALSE, you’ll need to explicitly call the checkForUpdates method to, err, check for updates. Defaults to TRUE.
checkForUpdates()
Manually trigger an update check. This is useful if you want to do update checks on your own schedule. checkForUpdates has no parameters and does not return anything. If you want to actually retrieve the latest update, use requestUpdate instead.
requestUpdate()
Retrieve update information from the configured metadata URL. Returns either an instance of ThemeUpdate, or NULL if there is no newer version available or if there’s an error.
deleteStoredData()
The update checker stores various update-related bookkeeping data in a DB option. Call this method to delete that data. This is can be useful is your theme provides some kind of “uninstall” feature.
addQueryArgFilter($callback)
Register a callback for filtering query arguments. Whenever the update checker needs to retrieve the metadata file, it will first run each filter callback and attach the query arguments that they return to the metadata URL. This lets you pass arbitrary data to the server hosting the metadata. For example, commercial themes could use it to implement some kind of authorization scheme where only paying users get automatic updates.
The callback function will be passed an associative array of query arguments and should return a modified array. By default, the update checker will append the following query arguments to the URL:
- installed_version – the currently installed version of the theme.
This method takes one parameter – the callback function.
addHttpRequestArgFilter($callback)
Register a callback for filtering arguments passed to wp_remote_get. The callback function should take one argument – an associative array of arguments – and return a modified array or arguments. See the WP documentation for details about what arguments are available and how they work. This method takes one parameter – the callback function.
addResultFilter($callback)
Register a callback for filtering theme info retrieved from the metadata URL. The callback function should take two arguments. If a theme update was retrieved successfully, the first argument will be an instance of ThemeUpdate. Otherwise, it will be NULL. The second argument will be the corresponding return value of wp_remote_get (see WP docs for details). The callback function should return an instance of ThemeUpdate, or NULL. This method takes one parameter – the callback function.
Bummer, on that. Thanks for the tutorial, it works great.
The iFrame for changelog notes is blank whatever URL i write.
I did even test:
“details_url” : “http://w-shadow.com/files/example-theme-updates/details.html”,
Are there any errors in the browser console? In particular, any network errors or security-related stuff? Maybe some security policy prevents iFrames from working on that site.
Works For Me™ 🙂
description of this was exactly what I was looking for. thank u!!
Hi,
it seems like the update script is broken since WP 4.5.5 because I do not see any requests since users update to a WP version higher than 4.5.4 on the log-file.
I’m actually not able to give my theme an update on a page with WP 4.6 for example, because there’s no update message any more.
Could you please give me a reply? Thanks a lot!
As far as I can tell, it still works on my WP 4.6 and WP 4.7-alpha test sites. However, I don’t have any themes “in the wild”, so there might be some compatibility issue that I’ve missed.
Have you tried activating the example theme (see the download link in the post) on a WP 4.6 site? Does it show the update notification?
Hi Jānis Elsts,
thanks for your quick respond! I found the reason for my issue.
There seems to be a problem with my ssl certificate on my update server so that the script can’t get a connection since the last renewal of the certificate.
With a simple http request it works fine.
Thanks again!
I got this to work once. I was able to update my example theme from v1.0 to v2.0.
However, after this I updated my info.json to v3.0, but no updates show up in wordpress.
I noticed this: “The update checker will automatically query the metadata file every 12 hours, checking to see if a new version is available.”
I also noticed: “checkForUpdates() Manually trigger an update check.”
So I added “$example_update_checker->checkForUpdates();” in my functions.php, but nothing is happening. Neither does “$example_update_checker->requestUpdate();” do anything.
I’m very new to this, so could somebody please tell me what I’m doing wrong?
Thank you
Try printing the return value of requestUpdate() with something like print_r() or var_dump(). Does it show the correct info for your theme? Also, are there any recent errors in your PHP error log?
[…] まずはライブラリをAutomatic Updates For Private And Commercial Themesからダウンロードします。 […]
Any idea as to why when the theme is updated, the directory name changes? When I update a theme the directory changes from `sample-theme` to something like `sample-theme-keD4kq`I can’t figure out why WordPress is appending the random characters at the end of the updates theme. Any ideas?
That usually means that the directory structure of the ZIP file is incorrect. The theme files must be inside a directory, not at the root (i.e. top) of the archive.
Are you on OS X by any chance? Multiple people have reported that the default ZIP software on that OS makes ZIP archives look like the files are in a directory when they’re actually not.
I am on OSX. I am zipping the theme using the ZipArchive class. The structure is simple-theme > theme files.
Are you sure? How did you verify the structure?
I stand corrected. I did not have a root directory! Thank you so much for the help!
I have this running on one site with one issue: on the updates dashboard it doesn’t print the current version. It prints:
“You have version installed. Update to 1.0.1.”
Where is should have “You have version 1.0 installed.”
I will keep digging and hopefully figure it out.
Second issue: It looks like it won’t work on multi-site installs?
I’d love to get these things worked out if I knew where to start looking.
Does the style.css have a valid “Version” header? Does the version number show up correctly on the “Themes” page?
It will only work on Multisite if the theme is active on the main site. The update checker code must be running for it to display an update, and, as far as I know, WordPress will only load your theme (and thus the custom update checker) in the network admin if the theme is active on the main site.
Thanks for the reply.
Yes, the theme version shows correctly on the themes page, and the headers are fine.
Funny thing: The multi site themes are being added to my MainWP email notifications and the updates are showing as available in the MainWP dashboard but again without the current version number.
I have to take a closer look. Perhaps a conflict with custom admin styles or something else I have hacked.
Thanks for your time and the awesome code!
Hi, Jānis. I use your wp-update-server for plugin auto update. Can I apply it for theme update checker? Thanks.
Yes. wp-update-server also supports themes.