WordPress Directories

In the previous post, I spoke briefly about WordPress directories. Specifically, I talked about placing files in an inc directory whenever building a theme. This lead to a comment by Richard that I thought was worth covering here:

In the theme folder, sometimes I see people use “lib” to include theme assets and other times I see them use “inc”, as you’ve done here. Is there a reason for one vs the other?

I gave a short response in the comments, but thought that this warranted a longer form explanation to share my perspective, and to hear what you guys have to say, as well.

WordPress Directories

Using inc and lib aren’t something that I say belong in just themes or belong in just plugins. Instead, they are directories that I’ve used in both themes and plugins.

The inc Directory

As my general rule, I use the inc directory primary to place collections of functions that are related to core functionality but aren’t necessarily meant to clutter up the primary core of the theme or plugin.

For Themes

For example, if I’m working on a theme and I have a collection of functions for said theme that I use as helper functions, I’d much rather create inc/helpers.php than to drop them in functions.php. Over time, more helpers are added, the file gets longer, maintenance becomes a pain, and so on.

But in more specific cases, I also use the inc directory as a way to store core theme files such as theme-customizer.php or custom-header.php. This way, these files are focused solely on a single purpose and are easier to maintain over time. Plus, they are self-descriptive.

This keeps functions.php lean, and it keeps procedural programming files slightly more organized than having one giant “god-file” by the time of delivery.

For Plugins

In the case of plugins, I generally use object-oriented programming so the inc directory is normally used to hold additional classes that I write that are used as part of the core plugin file, but are dependencies.

This means that if I have the core plugin that depends on, say, a custom CSV parser or a serialization / de-serialization class, then these files would reside in inc.

The lib Directory

In short, the lib directory is used for third-party libraries. That is, these are used to make sure that I place code written by another author or team of developers in a place that I can easily retrieve (and attribute – don’t forget! :)) in my project.

The thing about third-party libraries is that they aren’t always PHP-based. Instead, they may be JavaScript based, CSS based, or a combination of all three. In that case, I have to take it case-by-case.

If it’s a third-party JavaScript library such as, say, FitVids, then I’ll have a directory js/lib/jquery.fitvid.js’. Similarly, if there’s a CSS libraries that I’m using, like Foundation, then I’ll drop those files in css/lib/foundation.css.

Finally, if there is a library that is composed of JavaScript and CSS and/or PHP, then I normally drop them in the lib directory in the root of the theme or plugin because most of those files will have dependencies on one another and it’s significantly more painful to try to go through and update all of the relative path references especially when you have to repeat the process when there’s an update.

Also, I know that an alternative to this is using a vendors directory. Though I’ve seen the convention and think it’s just as good, I’ve personally just stuck with lib.

What About You?

As I mentioned, these are primarily my rules of thumb for organizing my code; however, I know that others have different preferences many of which are likely more efficient or more organized than this.

If that’s the case, I’m all ears as I’m always looking for ways to streamline the development workflow. So if you got one, share it!

Category:
Articles
Tags:

Join the conversation! 11 Comments

  1. Based on what you wrote, doesn’t it make more sense to just have a lib folder and then go from there (js/, css/ and keep php on the top level or by /function)?

    If using js/lib is not a universal solution why use it? If down the line the need for lib in the root comes up, everything will have to be refactored.

    Cheers

    • I wasn’t trying to imply I was giving a universal solution, but I do like keeping my JavaScript libraries in a JavaScript directory, same for CSS, and so on.

      It helps me to think: So if I’m working with X-JavaScript library, then it’ll be located in `js/lib`. Same with CSS and so on.

      Generally, the only time to keep libraries in the top-level `lib` directory is if it’s a PHP-based library.

      That said, I’m totally open to the ideas you guys bring to the table on this. I have strong opinions, weakly held :).

  2. Good to see the discussions rage on over inc v lib folders… http:///functions-php-vs-plugin-who-wins/

    I keep looking at it, considering new approaches and I can only see it as a win to keep functions.php as simple as possible when developing themes.

    Personally, WordPress functionality (adding theme support for example) is added to functions.php while any custom template tags or functionality goes into the includes folder.

    External functionality, such as Advanced Custom Fields gets put into the lib folder. I find it makes maintaining & updating each project quicker.

    Might be the right way or the wrong way of doing things, regardless it’s just personal preference & I’m happy with it :)

  3. For me, the presence of inc/ or helpers is a bug that must be fixed immediately. All code is included somewhere, and all code is helpful in some way. If it isn’t, remove it completely.

    These names are not useful, they don’t tell me what to expect where.

    A directory reserved for PHP files should be named php, one for JavaScript files js and so on. A file with a class starts with class and one with plain functions with functions (if you still use that).

    The best rule for file and directory names is: be specific. Make it easy to understand the structure and the code. Unfortunately, WordPress is full of negative examples for that. We can and we should do better in our code.

    • For me, the presence of `inc/` or `helpers` is a bug that must be fixed immediately. All code is included somewhere, and all code is helpful in some way. If it isn’t, remove it completely.

      This is arguing semantics, so know I’m not trying to do that, but rather than it being it bug, it sounds like you think it’s more of a bogus convention.

      I’ve adopted it since it’s usually the one that people follow; however, I mentioned this in a another comment, but I’m always looking for better ways to organize theme and plugin files.

      A directory reserved for PHP files should be named php, one for JavaScript files js and so on. A file with a class starts with class and one with plain functions with functions (if you still use that).

      I try to stick with `js` and `js/lib`, `css`, `css/lib` and so on.

      `functions.php` is the only “functions” that I use. When it comes to breaking our procedural code I usually still use an `inc` directory, but using a `functions` directory isn’t a bad idea – the only thing is that it busts what appears to be an accepted convention.

      I will say, though, I’m a big fan of being as clear as possible – this is something I may start pushing myself.

      Thanks for the thoughts, Thomas.

      • In themes, I separate procedural functions into several files, so I don’t waste time compiling unused functions: functions.front.php (loaded when ! is_admin() only), functions.comments.php (loaded for posts with comments) and so on. They don’t have to live in their own directory.

        This is arguing semantics, so know I’m not trying to do that, but rather than it being it bug, it sounds like you think it’s more of a bogus convention.

        Yes, that’s what I think. :) It is misleading, and there are better names, so it should be avoided.

  4. Where would you place the views folder? Would it be a subdirectory of the plugin folder or would it be `imc/views`?

    • This is more of personal preference, but I think of views as being “first class” so I typically keep `views` in the root of the plugin directory, but if you were to follow what I’ve shared above, then they could also live in the `inc` directory.

  5. Interesting discussion. Personally I tend to think of and use /inc as “PHP includes”, /js as “JS includes”, /css as “CSS includes”. Then I place any 3rd party packages directly in /lib. ie. /lib/acf, /lib/fitvid/, etc.

    I don’t mind when people use /inc/js and /inc/css, however I do get annoyed when I see people put their own code in /lib (as opposed to /inc).

    I’m a bit confused by you’re use of /js/lib and /css/lib. Is that for all 3rd party libraries or only when they’re the dependency of something in your /js or /css directory?

    I’m not say it’s “right/wrong” it just conflicts with the mental model I use which is to keep packages whole and under a single directory.

    So if you were including bootstrap would it be:
    /css/lib/foundation
    /js/lib/foundation
    /img/lib/foundation
    or
    /lib/foundation/css
    /lib/foundation/js
    /lib/foundation/img ?

    The later is what I use so I’d have:
    /lib/acf
    /lib/fitvid.js
    /lib/foundation/…

    I’m not understand when you’d ever want a library inside /inc, /js or /css for a theme or plugin?

  6. I tend to prefer the use of ‘includes’ instead of ‘inc’. There’s no real disadvantage to being explicit and using one less abbreviation. It also them follows the platform standard (i.e. wp-includes and wp-admin/includes) so there’s a consistency there.

    Organising by type (js/lib/foobar, css/lib/foobar) or by package (lib/foobar/js, lib/foobar/js) is less about mental models (they can be changed), but what you might do with those files other than reference them. For instance, with a set of grunt tasks that might check for code standards or syntax, having all .js files in under one ancestor directory might be cleaner (js//*.js)than having to refer to is via lib//js/**/*.js etc.

Leave a Reply

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