In this article, I’ll show you a great way to share a single instance of a plugin or theme with multiple installations of WordPress – symlinks.
What Is a Symlink
A symlink – or symbolic link – is a special file that is actually a reference to another file or folder. If you’re a Windows user you probably already use Desktop shortcuts which are a kind of symlink since they point to a file somewhere else on your system.
The key to us is that they can point to folders as well. Since WordPress 3.9 symlinks have been allowed for plugins and themes which allows us to store them elsewhere and hook them up to our installs.
Symlink Common Use Cases
Let’s assume that you have a localhost setup with a root directory. Each directory within is a separate WordPress installation. Normally you would install your new plugin in all of them. An error found in one would need to be changed everywhere, making the process long and error-prone.
With symlinks you can keep your plugins and themes in a separate folder and – using symlinks – you can point it into each installation you have. Each installation uses the same files which makes modifications and maintenance a breeze.
If you have multiple domains on the same server you can pull off the same trick. As long as the files for your websites occupy the same file system and your environment allows for symlinks (most do), you can use this method.
My favorite use for this method is handling themes and plugins from Github repositories. I prefer using git as my version control system and my projects have a structure which puts the actual theme/plugin in a sub-directory.
This means that I can’t use the folder as-is in the wp-content folder. Normally I would have to manually copy-paste the changes into the repo or change the repo’s structure. With symlinks I can just symlink the folder I need.
Creating a Symlink
The process of creating a symlink is the same on Windows and Linux based systems (like OSX), but the syntax is a little different. When creating them you’ll need to specify the location of the symlink and the target.
In our case, the location of the symlink will be a folder in the themes or plugins directory. The target will refer to the directory that contains the actual plugin/theme files.
Let’s look at an example where we would use a symlink to link to a plugin in a separate folder. In the example, the root of our project contains multiple WordPress installations and a projects directory which contains plugins and themes.
Symlinks on Windows
Let’s assume that the root directory for our web projects is in C:/websites. You’ll need to open the command prompt and navigate to a WordPress install’s plugin folder and within that folder issue the following command:
mklink C:\websites\projects\my-plugin-github\my-plugin\trunk my-plugin
This command will create a my-plugin
folder in your plugins folder which will lead to the folder at C:\websites\projects\my-plugin-github\my-plugin\trunk
. When loading the plugin list and processing code WordPress will follow this symlink, making it seem like you have a regular plugin.
Symlinks on OSX and Linux
Let’s assume that the root directory for our web projects is in /Users/danielpataki/websites. You’ll need to open the terminal and navigate to a WordPress install’s plugin folder and within that folder issue the following command:
ln -s /Users/danielpataki/websites/projects/my-plugin-github/my-plugin/trunk my-plugin
This command will create a my-plugin
folder in your plugins folder which will lead to the folder at /Users/danielpataki/websites/projects/my-plugin-github/my-plugin/trunk
. When loading the plugin list and processing code WordPress will follow this symlink, making it seem like you have a regular plugin.
Summary
You can repeat the process as needed for all your WordPress projects on the same system. At the end of the day, all your installations will use the same files so you can fix a bug once and see it disappear from all WordPress installs.
I use this method a lot in my day-to-day programming. If you do too and you have some tricks up your sleeve, or you have a better way of doing things, let us know in the comments below!
This is a really interesting article and it got me thinking.
We run a web design studio and offer hosting within the package. Let’s just say for arguments sake that you have 100 clients. Using this technique could you set those clients up on hosting and have 1 central location for all the plugins and themes on those client sites?
Because if so then that would save a ton of work in terms of maintaining an updating all those sites.
Something I’m missing or would it be that simple?
Thanks!
I just tried this and it’s awesome, however the WordPress updates don’t seem to work with it – I tried to update a plugin that I had symlinked and WordPress moved the plugin folder out of the source folder and into its normal wp-content/plugins folder, which destroyed the symlink. Is there any way to make WordPress updates obey the symlink and copy to the source directory instead?
This symlink strategy is only for plugin development workflow.
I think you should not use this to manage third-party plugins installations. For this, a tool like wp-cli maybe more appropriate.
– https://developer.wordpress.org/cli/commands/plugin/update/
Thanks for this article. I am looking for a way to speed up my site by easing the plugin loads on my main server. In that case, have the plugins file load in another server. Then I stumbled on this your article. But going through the comments and your response, it happens not to be favorable for third party plugins.
Do you have a better solution to install plugins on a different server, and use it in another server, while the server it is installed on handles the load?
Due to a temporary situation i needed to have a symlink and in some cases you may get permission denied if the owner of the symlink and the owner of the folder don’t match (this improves security somewhat by preventing a second user from linking to the files of the first user). In your httpd.conf or .htaccess file this option is called SymLinksIfOwnerMatch . It may not be obvious at a glance, but is a standard setting in some hosts.
More info https://webmasters.stackexchange.com/questions/98822/what-is-symlinksifownermatch
Just in case anyone else using Windows runs across this article: The parameters in the Windows example above are in the wrong order. With mklink, the order is and then .
Also, the `/D` parameter is needed to symlink directories.
Here’s an example that works:
mklink /D example-plugin C:\github\website\example-plugin
I have been using symlinked directories for a long time. They work well most of the time. Unfortunately, there is a huge flaw when using them in Windows.
Ideally, you want the symbolically linked folder to be recognized by its location (where it’s linked), not by the path to the actual folder.
It seems to work as expected on Local by Flywheel, but on IIS 10 in Windows, it doesn’t. Or let me rephrase that: it works for most cases, not all.
On IIS10, the PHP function:
dirname( __FILE__ ), and
pathinfo( __FILE__, PATHINFO_DIRNAME )
return the actual path to the file/folder, not the expected path.
For example:
actual path: c:\users\me\onedrive\plugins\my_plugin\…
symbolically linked as:
c:\inetpub\myTestWebsite\wp-content\plugins\my_plugin
Calling dirname( __FILE__ ) when inside the plugin returns:
c:\users\me\onedrive\plugins\my_plugin
NOT
c:\inetpub\myTestWebsite\wp-content\plugins\my_plugin
In other words, Windows doesn’t treat the symbolically linked directory as part of the folder tree where it’s linked. This kind of defeats the purpose of having a symbolically linked directory in Windows.
I’ve tried both:
MKLINK /D my-plugin c:\users\me\onedrive\plugins\my-plugin
MKLINK /J my-plugin c:\users\me\onedrive\plugins\my-plugin
Neither work as expected.