Software Engineering in WordPress and Musings on the Deep Life

What Constitutes Clean Code in WordPress?

When it comes to writing code specifically for WordPress, I try my best to follow a combination of the WordPress coding standards, tips and advice from various books I’ve read (which I hope to cover in a future post), tips from others in the community, and certain habits that I’ve developed along way the way.

The thing that I’ve always struggled with determining is what constitutes clean code. There is code that follows standards, then there’s clean code, and I think that the definition is almost somewhat subjective.

With the open source nature of WordPress, the desire to improve education around the platform, the desire to improve the plugins repository, and the existence of things such as Theme Review team, Theme Unit Test, and tools specifically for helping us write code, there’s an innate desire for programmers to write clean code – I just think that we could do a better job defining it.

To be clear, I don’t believe that clean code is synonymous with quality code, nor do I believe that clean code is synonymous with good code. They’re absolutely all related, but they aren’t the same thing.

With said, what does constitute clean code specifically in the context of WordPress development?

1. It Follows Standards

I want to be clear that I do not think that writing clean code in the context of WordPress constitutes breaking away from the standards. In fact, I think that for any framework or library – be it .NET, Rails, jQuery, etc. – that you play by the rules first, write clean code second.

So I think that the first pre-requisite for writing clean code in WordPress is that you have to follow the standards. We all need a foundation off of which to build and standards provide just that.

The problem is that I think we often view standards like laws – they’re there, but we still, say, speed, right? If we can’t follow the rules, then is it really possible to write clean code in the context in which you’re working?

I think you could make a case for it, but only if the standards are weak. That isn’t something that can be said about WordPress.

Start with the standards and move up.

2. English Readability

If it was something that everyone could do (or wanted to do), then it wouldn’t be called code, right? The funny thing about writing code is that the longer than you do it, the more difficult it becomes to “unsee” it.

It’s like reading or riding a bicycle: Once you’ve done it, it’s hard to remember what it’s like to not do it.

To that end, I don’t believe that code is ever going to get to a point where it reads with a natural flow. There are technical reasons for this, but I digress. This doesn’t mean that we can’t make an effort to improve it, right?

Take a look at the native WordPress function in this conditional:

if( is_user_logged_in() ) {
    // Do work for users who are logged in
} else {
    // Do work for everyone else
} // end if/else

If you read that aloud, it literally reads like English (or whatever your native language is – I’m not here to discriminate :). “If the user is logged in, then … otherwise, …” That’s the type of stuff I believe that we should aim for.

Here’s an example from a project on which I’ve been working:

function gm_get_total_goals_for( $user_id ) {

	$query = new WP_Query(
		array(
			'post_type'		=>	'goal',
			'author'		=>	$user_id
		)
	);

	echo $query->found_posts;

} // end gm_get_total_goals_for

Now when this particular function is called, the line of code may read like this:

gm_get_total_goals_for( wp_get_current_user()->ID );

I think the function could be improved by even taking in the user’s name rather than the ID, but you get the point.

When you read the function aloud, it has a more natural flow to it.

3. Function Size

In Clean CodeBob Martin says the following:

The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that. Functions should not be 100 lines long. Functions should hardly ever be 20 lines long.

This is one of those suggestions that I love, but have a hard time implementing usually because it requires a significant bit of refactoring.

For me, this is what happens:

  • Write a function definition and write comments out for what the code should do
  • For each comment, write the code necessary to make it happen (testing along the way)
  • Move on to the next task

But for each single line of code, you could be looking at 5 – 15 lines of code, right? Those should be single functions which would ultimately contribute back to the whole point of readability.

Rather than “Move on to the next task,” I should be taking time to refactor and improve the code. This will help not only myself, but future developers.

To be clear, I’m getting better at doing this – but I’m not yet where I want to be. It’s what I’m aiming for.

Rather than writing functions that consist of multiple blocks of code, have each function represent a block of code.

But that’s not all…

There are so many things that can contribute to writing clean code that I can’t outline them all here. Besides, if it’s a truly subjective matter than that means that are probably going to be things on which we agree and on which we disagree.

But I’m hoping for this to be more of a discussion than some op-ed on my personal attitude about the topic. I’ve shared three thoughts of my own, but I’m genuinely interested in what you guys have to say.

So, for you, what constitues clean code in WordPress?

16 Comments

  1. Pippin

    After standards, readability is a huge one. I would also go on to say organization is highly important. For example, functions that are related by subject (users) should be grouped together.

    • Tom McFarlin

      Definitely agree here. Readability is key especially when you’re going to have other developers working with you. Anyone that’s worked as part of a larger team of developers feels the pain of when this is not done.

      And for function relationships in llarger projects, I actually do a “table of contents” so that I can easily find related functions (via CMD+F / CTRL+F).

      For example, I often start off with general WordPress functionality (like hooks for general functionality), then the stylesheet and JavaScript dependencies, custom functionality, then helper functions.

    • Chris

      On the note of readability:
      At WordCamp SF 2012, Nikolay Bachiyski made a great suggestion in his ‘Selected Pieces from “Elements of Style” Translated to Code’ presentation. The most important part of the ‘paragraph’ should come last. His case, returning false at the end of a function instead of returning the true or non-empty case.

      It’s much easier and quicker to debug when I can look at the last line of a function to know what the positive case should return and move on.

      If you didn’t get a chance to watch this one here’s the link:
      http://wordpress.tv/2012/08/25/nikolay-bachiyski-selected-pieces-from-elements-of-style-translated-to-code/

      • Tom McFarlin

        In short, I agree with Nikolay.

        What I’m about to share is something that a lot of people disagree with because it’s an older school of thought, but I only use a single return statement in my functions.

        Usually, I’ll define the variable to be returned at the beginning of the function. Then, as work is done throughout the function’s call, I’ll manipulate it. At the end of the function, I’ll return the variable.

        In my opinion, it makes the function a bit easier to debug.

  2. Andrew

    Seems almost silly, but thanks for adding an actual snippet from something you are working on. Too often you’ll see the if/else with no real context.

    • Tom McFarlin

      Sure … I’d like to add more, but I never know (a) how much code people actually want to read, (b) how much is too much (or too little), and (c) if I provide enough context for the stuff I’m working on.

      Nonetheless, I’m glad this one was helpful!

  3. Ryan McCue

    I don’t agree with all of this, but it’s a start. :)

    For example, gm_get_total_goals_for() is a silly name, and gm_get_total_goals() would make just as much sense. Imagine if you had a second parameter, suddenly the “for” would make much less sense. This (unfortunately) isn’t Obj-C where parameter names are part of the method and you can have things like getAllCommentsForPost:2 limit:10 displayAs:"HTML" so you have to deal with that. If you want to follow convention, see functions like get_comments(), get_tags(), etc. On the other hand, is_user_logged_in() does make sense, as the “is” makes it clear at a glance that it returns a boolean.

    Also, I disagree with keeping functions that small. Small function size is great to aim for, but never at the cost of readability or usability. Things should be put into functions where they make sense and you might want to reuse them, not simply because you want to reduce the size of other functions. Logical grouping, not size-related grouping.

    • Tom McFarlin

      gm_get_total_goals_for is part of an approach of domain-driven design where the function names mimic the language you use when talking about the problem domain. So when talking about this face-to-face, you’d maybe say:

      On this screen, we’d be getting the total number of goals for John Doe.

      So the code mimics just that.

      I totally get your point with just having gm_get_total_goals, but in this case, the analogy to get_comments and get_tags isn’t the same. By that, I mean the latter is defined as:

      Retrieve an array of objects for each term in post_tag taxonomy.

      And I don’t want an array of objects. I want a total count of goals for a single person – just a single value. It follows convention in that it uses the get prefix to denote that it will need to be echo’d back to the screen.

      I’d say it’s more closely related to something like get_user_by which accepts a field value to return.

      Finally, I didn’t mean to imply that I’m for breaking up functions at the cost of readability. I’m really all for the contrary. Having smaller functions can make it (a) much easier to test because each function represents a single logical unit and (b) it can make the function that was once so much longer easier to read.

      This is all contingent on getting the smaller functions right, though and I think that’s a skill that’s learned over time versus something that we just learn how to do. Still, like I said, this is one area where I’m still working to improve.

      Either way, clean code is a grey area but it’s one of those things that I [obviously] dig discussing.

      • Ryan McCue

        I’d say it’s more closely related to something like get_user_by which accepts a field value to return.

        I’d definitely disagree on that. get_user_by is called that because it’s a replacement for get_user_by_email etc. The difference is that the first parameter is usually constant, so it’s saving having separate functions. In your case, the first parameter isn’t going to be constant, so it doesn’t make sense.

        And I don’t want an array of objects. I want a total count of goals for a single person – just a single value.

        I misunderstood; in that case, the best name would be something like gm_get_total_goal_count() – it makes it clear that it’s a total and is obvious to me that it’s going to return an integer.

        the function names mimic the language you use when talking about the problem domain […] [so] the code mimics just that.

        In my opinion, that’s doing it wrong. Code is meant to be an abstraction, otherwise, what’s the point? There’s a reason we use $a = array('a', 2); and not let the variable denoted by the name "a" represent the list with elements of the string "a" and the integer 2.

        If I read $count = gm_get_total_goal_count($post_id), I know what that’s going to be without needing to express that out in full. And if I don’t understand what it’s doing, that’s what our editors and the documentation are for.

        • Tom McFarlin

          The difference is that the first parameter is usually constant, so it’s saving having separate functions. In your case, the first parameter isn’t going to be constant, so it doesn’t make sense.

          I’ll concede to this to a point – not everyone coming to WordPress knows that get_user_by is a replacement for get_user_by_email (or any of the other helpers), so knowing that it’s a constant is something that’s come from your experience.

          To someone coming in a bit later in the game, it reads a bit differently, though I do admit that knowing the underlying database schema gives the finite options that you have. For example, you know you can get a person by his email but not, say, some custom piece of user meta.

          In my opinion, that’s doing it wrong. Code is meant to be an abstraction, otherwise, what’s the point?

          And that’s all I’m saying in this post – it’s my opinion; however, though I definitely agree code is an abstraction (otherwise it wouldn’t be called code, right?), that doesn’t mean we can’t aim to make it as readable as possible.

          Now if this strictly violates the WordPress Coding Standards, I’d be willing to completely stop doing it. But I’m not sure it does, and when I’m reading code, reading: gm_get_total_count_for( $post_id ) reads as close to a sentence as you can get.

          And if I don’t understand what it’s doing, that’s what our editors and the documentation are for.

          Absolutely. I’m one of the ones that leaves a fair amount of comments and PHPDoc’s every function to the best of my ability, but but if I can save time by making the code just a little bit more readable, it’d save me the time from hunting in down in the documentation.

          Of course, this may be just debating over nothing at this point.

          That said, I don’t want to come off like I’m dismissing your points or that I even dislike them. These are exactly the kind of discussions I dig having and love hearing where other developers stand on things like this!

  4. Brian

    Great post, Tom.

    I work in an environment where at least three or four other people could potentially be in my code, so I’ve had to make conscious effort to have really readable code. I get made fun of for my lengthy function names sometimes, but hey – better lengthy than confusing!

    The other aspect of readable code to me is organizing code in a way that gives the person trying to figure something out only one or two places to go to have to find it. In other words, it’s good to document where code is (plugins, themes, functions files, includes, etc.) and also, once there, have a home-base that’s easy to read through and find the functions that apply.

    My biggest @to-do in my code is to comment more. I usually give a brief description of the code, but I don’t do near enough inline comments for explaining what each item in the code block is.

    Thanks for the post, loved it!

    • Tom McFarlin

      When I was working a 9-to-5, I was in a huge codebase. Usually, I only worked with about four other people per project, but all of it was built on top of a significantly larger whole. This is where you can really see how clean code impacts the ability to get stuff done.

      I think long function names are actually a pretty good idea because, like you said, it’s clear. I’m also one of those types that does hungarian notation though a lot of programmers hate it. In my mind, if you’re working in a dynamic language like JavaScript or PHP, I’d like to know what type of variable I’m working with; otherwise, I’m stuck having to cast it or I get stuck with the interpreter doing implicit casting and sometimes guessing wrong.

      And yeah, organizing code is key. I mentioned in another comment that I’ve actually begun placing a table of contents in my code in order to make it easier to find where certain related functions are. I do this not only in WordPress, but in my LESS files, and in my JavaScript as well. I hope to cover all of this stuff in a future blog post :).

      I’ve swung from rarely commenting to what some would consider commenting too much, but I’d much rather be verbose so I – or another developer – are aware of exactly what’s intended rather than having to guess. I’ve also begun to PHPDoc all of my functions. Eventually, I want to get to a place where I can easily ship a docs directory with each of my projects, but I’m not there just yet.

  5. Diana

    І’m really loving the theme/design of your site. Do you ever run into any web browser compatibility issues? A couple of my blog readers have complained about my blog not working correctly in Explorer but looks great in Safari. Do you have any suggestions to help fix this issue?

    • Tom McFarlin

      Without knowing your theme, I don’t – and even then, it can be really tough to diagnose a problem. I’d suggest contacting the theme developer.

      The theme I’m using is based on Standard.

  6. Justin Kopepasah

    To me, clean code is all about the ability to figure out what the code is doing, easily. Troubleshooting code that is not organized well is painful.

    • Tom

      I think that’s a really good definition of how to define clean code.

Leave a Reply

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

© 2023 Tom McFarlin

Theme by Anders NorenUp ↑