An Attempt to Improve JavaScript in WordPress

One of the things that’s always been somewhat of a point of pain in both theme and plugin development is how to handle JavaScript in WordPress.

By this, I’m not talking about third-party dependencies such as jQuery, FitVids, or whatever libraries Bootstrap, Foundation, or what’s contained within the frontend framework you opt to use when building your theme – instead, I’m talking specifically about code that we write in order to get things done within the context of our work.

When it comes to procedural programming in WordPress – think working in functions.php – it’s expected that we’re going to be naming our functions with a unique prefix in order to prevent conflicts with other functions that may exist within plugins, third-party libraries, or even in WordPress itself.

For anyone who is just getting started in working in WordPress, this can be a hard lesson learned depending on if you’re one of the “read-the-documentation-first” type of people or not, but the thing is that the global nature of PHP mixed with the wide array of functions included in WordPress, PHP, and third-party code can lead to naming collisions that will either break the overall application or cause erratic behavior.

Most likely the former, but whatever.

But look at that: I spent the entire first part of this article talking specifically about naming PHP functions – but this is exactly the point I’m trying to make: We spend a lot of time talking about doing this in PHP, but not a lot of time talking about doing it in JavaScript.

The State Of JavaScript in WordPress

To be clear, part of what I’m saying is simply this: We need to be more careful with how we name our JavaScript functions so that we don’t accidentally end up with a naming collision just like we might in PHP.

After all, there are a quite a few similarities between JavaScript and PHP one of the biggest being the global namespace. For example,  let’s say that you’re using a plugin that includes some JavaScript with a function called truncate_post_title.  The idea behind the plugin’s JavaScript code is to shorten to the post title so that it, say, only takes up one line (this is arbitrary and a weak example, but bear with me :).

Then, let’s say that you come and write your own function in JavaScript that’s intended to truncate the post title on the single post page and is going to perform some type of manipulation of the title element’s text (again, a weird, contrived example, but hang in) and you opt to name your function truncate_post_title.

What happens?

And that’s exactly my point. Regardless of which function fires first, only one of them is going to be “seen” by the JavaScript interpreter and it’s going to be the one doing the work.

Clearly, this can have unintended consequences.

A Potential Solution to an Anti-Pattern

One easy solution is to take all of the functions in your JavaScript source and give them a unique prefix just like you may do whenever you’re working in PHP.

Another alternative would be to wrap all of the functions within an anonymous function that you can invoke when the script is loaded, or define your functionality within a closure.

The problem that I see with the above – and this is coming from both writing code like this myself as well as working with code from others – is that if the code has too much functionality (a weird thought, I know), then it can become really difficult to trace and to debug.

That’s exactly what we should want to avoid.

So the more that I’ve been experiencing this, and the more that I’ve begun to realize (read: feel the pain) of this – again in my own code just as much as anyone else’s – the more I’ve begun to think that perhaps there needs to be a type of system or pattern that’s used when working with JavaScript in WordPress.

To keep the remainder of the article short, I’ll talk specifically about doing something like this in a plugin, but the idea can still be implemented within theme’s, as well.

Get Out of the Mud

For those who have been writing plugins for sometime and who are comfortable with jQuery, it’s not at all unlikely that your source code normally starts off with the ready function, contains a ton of functionality wrapped within it.

Perhaps you then define some functions in the file that are called from within the anonymous function when the script begins its execution, but generally speaking, this is a format that’s popular.

The problem with this is that it can lead to a massive amount of code within the $( document ).ready function, and/or it may result in a giant JavaScript file that contains the $( document ).ready function as well as a number of different functions defined throughout the file that are invoked at different times.

JavaScript in WordPress - The Big Ball of Mud
This is us. WordPress Developers. we are writing JavaScript. it is our big ball of mud.

Whatever the case, it can quickly start to feel like a big ball of mud. Ew.

A Potential Pattern

As such, one of the things that I’ve been toying with in a recent project is how to organize the JavaScript so that the code that’s initially executed is easy to read, small, and easy to trace. In order to achieve that, though, it requires additional JavaScript files that help break up the functionality into more cohesive functions.

But this still leaves one problem: How do you organize the code to prevent naming collisions? The way that I’ve been doing this – at least for now – is to use objects within their own namespace (which, in JavaScript, is basically an object within an object or an object that has another object as a property).

I’ll show some example code in a minute, but all of this has got me thinking about creating a definitive pattern that can be reused whenever we’re working on WordPress plugins (or themes). That is, there’s a bit of structure that can be reused and followed in order to prevent anti-patterns, to prevent spaghetti code, to prevent confusion when working with the code, and to prevent naming conventions.

Here’s how I’ve been thinking about it in its very simplest form:

  1. The Bootstrap File. Each JavaScript component – be it for the dashboard or for the public-facing side of a site – includes a bootstrap file (I normally name these admin.js and public.js that’s responsible for, say, defining the ready function, instantiating the rest of the variables that we need an setting things in motion.
  2. A Namespace. Again, in JavaScript, this is practically a wrapper object that’s used to container another object. The namespace should be unique in order to prevent collisions (that is, don’t go with the wp namespace. Instead, go with Acme or whatever the name of your company or plugin is).
  3. A Unique Object Name. Within the context of writing plugins, let’s say that you’re working on a widget – then perhaps the unique object name would be the name of the widget and it would be defined within the namespace.

I’ll share some example code momentarily, but the overall point (for those who are getting tired of reading) that I’m trying to make is this: I think that breaking up our JavaScript files into a bootstrap, a namespace, and uniquely named objects can go a long way in writing much more maintainable JavaScript.

The Implementation of the Pattern

So, practically, what would this look like?

Yesterday, I shared that I’ve been working on a really simple plugin. In the codebase or this plugin, I decided to put the aforementioned approach to work and ended up with something like this.

Obviously, I’ve truncated the code for ease of readability but the point remains. I’ll show the implementation of this particular pattern in reverse, because I think it makes more sense to read it that way:

First, the unique object. Note that this is contained within an outer object, one that serves as a namespace:

Secondly, the namespace:

And finally, the bootstrap file:

I assume this is easy enough to follow. I know that it leaves a lot of core functionality out, but the point of this isn’t to show how to do anything with an image widget. Instead, it’s about how to implement a potential pattern for writing cleaner, more maintainable JavaScript.

Is This Enough?

If not, I’m all for discussion as this is something that I’d love to improve if for no other reason than personally get better at what I’m doing. To that end, I’m open to whatever comments you have to offer about the above approach.

I’ve found it to be much easier to deal with than one giant JavaScript file, but I still think that there’s room to improvement this even further.

Right now, though, this is what I’ve got.

4 Replies to “An Attempt to Improve JavaScript in WordPress”

  1. Great post, Tom. It’s easy to get wrapped up in jQuery and forget that while JavaScript isn’t a true OOP language on its own, it does have some nice features that make it easy to namespace and encapsulate your code. Not only does doing so keep the global namespace clean and free of conflicts, but it also makes larger applications much easier to manage. I’ve inherited a few projects in the past that didn’t follow that pattern and were a nightmare to debug because as you mentioned, the ready call was a hodgepodge of functions and unorganized logic.

    There are a number of ways to achieve the same result, but at the end of the day, what matters is that there is a method to the madness. Without some level of code organization, you’re left with a jumbled mess of logic that’s hard to follow.

    1. …while JavaScript isn’t a true OOP language on its own, it does have some nice features that make it easy to namespace and encapsulate your code.

      For sure, and though its not OOP in terms of how our modern languages work in terms of classes and what not, it does use prototypes and prototypal inheritance and everything – well, almost everything ;) – is an object.

      I’ve inherited a few projects in the past that didn’t follow that pattern and were a nightmare to debug because as you mentioned, the ready call was a hodgepodge of functions and unorganized logic.

      Amen, and I see this becoming much more commonplace as WordPress is adopted as a foundation for applications and we begin to do more and more with JavaScript. Thus, I want to see different strategies adopted.

      Without some level of code organization, you’re left with a jumbled mess of logic that’s hard to follow.

      Amen. I’d rather not be the kind of person who lives that lying around.

  2. I like this pattern. It’s roughly what I have adopted in our more recent work, except that I haven’t been splitting it all up into separate Javascript files, for the sake of avoiding too many HTTP requests. How do you see yourself working around that? Do you build a minified version that bundles everything into the same minified JS file?

    Also, I note the use of Pressware as your namespace. Is this with the idea of it being something you’ll use across different plugins/themes? If so, would it make more sense to first check for the existence of the namespace and only create it if it doesn’t exist already?

    Cheers,
    Eric

    1. How do you see yourself working around that? Do you build a minified version that bundles everything into the same minified JS file?

      Yep – I combine and minify everything as much as possible so there are as few requests as possible.

      Also, I note the use of Pressware as your namespace. Is this with the idea of it being something you’ll use across different plugins/themes?

      That’s the general idea; however, if I were to take this a step further, I’d probably add objects on to the Pressware prototype. The problem with that is that it assumes you’re aware of the properties of the object (which, I mean, I would but a consumer may not) and it makes it more difficult to implement private functionality.

      I’ve mixed feelings on private functions in JavaScript, though. They can be done, sure, and I think as part of good design and encapsulation, they should be, but at the same time, JavaScript, by its nature, is open source so if someone wants some type of access to the method or functionality of a private class, there’s nothing stopping them from taking the code out of the source file and placing it into their own work or just making a public property on the existing object for their own implementation.

Leave a Reply

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