Software Engineering in WordPress and Musings on the Deep Life

Symbolic Links with WordPress: Working With Nested Directories in Repositories

I – along with a number of other contributors – have been working hard to close out issues and prepare the next version of the WordPress Plugin Boilerplate.

Sure, I’m excited, but while working on this particular plugin, I realized that for anyone who does work with a WordPress plugins either via git or Subversion, that you may be working with a mess of directories while trying to develop the thing.

It’s nothing that a symbolic link can’t fix, but first, let me explain the problem.

Symbolic Links with WordPress

The concept of symbolic links is nothing new, especially for those who have been using *nix based systems; however, if you’re new to the WordPress plugin development process and/or you’re looking for a way to easily maintain nested directories from a source code repository without having to shift files around, using symbolic links with WordPress can be really useful.

Using GitHub

This technically applies to anyone using a git-based system. It just so happens that I’m using GitHub for this particular project.

So when I checkout the latest branch of the Boilerplate and I stick it in my `wp-content/plugins` directory, I’m left with a directory structure that looks like this:

The WordPress Plugin Boilerplate Directory Structure

The problem is that the core plugin actually resides in the `plugin-name` directory, and because WordPress specifically looks for the headers in one of the plugin files, it won’t actually display the plugin in the WordPress Dashboard.

So now you’re left with having to figure out a way to work with your repository, all the while shifting code around so that it shows up in WordPress, and so that you can commit your changes to git.

Using Subversion

Similarly, if you work directory with the WordPress Plugin Repository, then you’re used to using Subversion such that your repository looks like this:

Single Post Message in Subversion

Specifically, if you pull down the entire repository, then you have:

  • `assets`
  • `branches`
  • `tags`
  • `trunk`

Where `trunk` is the current working version of the plugin. And sure, you can easily only check out the `trunk` and if that’s what you opt to do, then the following point is moot; however, if you’re one that pulls down the entire repository, then you’re left with the process of having to shift code around so you can work on it, and keep it maintained in source control.

Setup Those Symbolic Links

If you’re someone who has nested directories – such as in the case of git – or pulls down the entire repository – such as in the case of Subversion – then there’s an easy way to make sure that you can still work out of the proper directory or the `trunk` and have your code display in the WordPress Dashboard.

In short, you need to create a symbolic link to the nested directory – such as the `trunk` – in `wp-content/plugins`. You can do this using the following gist:

And from that point onward, your plugin should not only show up in the WordPress dashboard, but also allow you to make changes directly in the nested directory of your plugin from the IDE.


  1. Josh Eaton

    Great tip Tom. Thanks for writing about this kind of stuff, as it’s rarely covered elsewhere.

    I have my repos set up like this:


    Where all the git repos are in the wp-plugins directory, and SVN checkouts of plugins in the SVN folder.

    Plugins are symlinked from the git repos to whichever dev site I need them on, and I push the changes from git to SVN using these scripts from Scribu and Mark Jaquith. Just started using that script recently and it’s nice not having to remember how to do things in SVN (except when I screw up).

  2. David Smith

    Dayum! I’ve beat my face against this problem before even to the point of it turning me off of Git a bit. Looking forward to giving this a go.

  3. niels

    I manage my code in the same way but could not figure out how to handle path issues in wordpress. Functions like ‘plugins_url’ need to be replaced by static expression.

  4. Shea Bunge

    Windows users can use the `mklink` command:

    mklink /J plugin-name WordPress-Plugin-Boilerplate\plugin-name
    mklink /J Your-Plugin-Name Your-Plugin-Name/trunk/

    Note that the order of arguments are switched, and backward slashes are used instead of forward slashes.

  5. Gabi Udrescu

    I’ve reached this post while researching if it’s a good idea to create one directory wp-content/themes and wp-content/plugins and cerate symlinks for multiple domains hosted on the same server to the “master” folder.

    this way I would expect to make the maintenance process a bit easier, by having all plugins and themes in one places.

    from what I can see, it will work and there are no problems. right? can you share your experience with this solution, now, 6 months after this post? I would be very grateful

    • Tom

      Hey Gabi,

      6 months later, this particular solution still works fine for me! I don’t have much to add to the content that was originally written; however, I will say that the latest version of WordPress supports symbolic linking so it makes it really easy.

      I will throw this out: If you’re looking at running multiple domains and what not off of WordPress, then you may be suited better for WordPress Multisite rather than a symlinked single install (if I’m understanding your comment correctly!)

  6. Graham

    Thanks for handy post. I tried your second example

    ln -s Your-Plugin-Name/trunk/ Your-Plugin-Name

    but it fails to create the symlink and throws an error “File exists”, which makes sense as the folder already exists in that location.

    • Tom

      When drafting the post, the folder didn’t exist in that location so if something has changed or the directory is created, then that’d definitely throw that message ;).

      Either way, as long as you create a symbolic link in the root of the plugins directory to the trunk of the development directory, you should be good to go.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2023 Tom McFarlin

Theme by Anders NorenUp ↑