Simplifying Code in WordPress: Option Arrays

Let’s say that you’re working on a plugin that has its own plugin settings page, and on that page there are options to determine what type of posts will support part of the functionality of the plugin.

For example, let’s say this plugin will be introducing a meta box for each post type that extends the type of information that the user can add to a post. The settings page allows you to control which post types will offer this information.

To give a concrete example, take a look at the following screenshot:

Simplifying Code: Options Arrays

Granted, it’s a small example but it makes the point: We have a plugin settings page that displays all of the post types that are in the current theme installation. If selected, we’ll save the values to an options array.

When it comes time to read the values, there are a couple of ways to go about doing it, but one that’s arguably simpler than all of the rest.

Simplifying Code

Before actually looking at any code, here’s how you can imagine all of this playing out:

  • The plugin settings page exposes all of the post types that exist in the theme
  • The user has the ability to select which post types should display a post meta box
  • If selected, the respective post types will support the meta box

For example purposes, we’ll say that all of the checkboxes are storing their values in an array called acme-supported-post-types so the way we’d retrieve the selected options would be get_option( 'acme-supported-post-types' );.

With that said, let’s say we end up on a post (or page or other custom post type) edit screen and we need to check if the given post type supports the addition of a meta box.

One way to go about doing it is like this:

This is long-winded, cumbersome, and leaves a bit to be desired, right? Not mention, there are somethings that some developers would argue is a code smell, but I digress.

To that end, this code can be simplified into a single line:

This returns the same boolean value with significantly less code.

Why Share This?

The reason that I think it’s important to look at example of code like this is two fold:

  1. Looking at how other people refactor and/or consolidate their code helps us to think more critically about the code we’re writing.
  2. If the code that we’re writing can be simplified by leveraging built-in libraries and functions in the native programming language, we should consider doing that.

To be absolutely clear: This is not a praise at my ability to write code. That’s arrogant and it’s not my style. I have just as much to learn as the rest of everyone.

Even more so, look through any of my past code snippets, gists, etc., and you’ll see that there’s room for improvement; however, all of this is coming from reading other books, articles, etc., that have helped me to think more critically about what I’m doing, and I’m sharing what I’ve put into action.

As with anything, there are other ways to go about doing this but all of them are dependent on how you end up saving the data. Since I opted to use the Options API, this ended up being the best way to go about doing that.

Of course, there are other examples and ways to go about doing the same thing, this just ended up being the way that I found to be the most readable given the constraints of the project.

17 Comments

A lot of usefull.
Love 1 line solutions :D

    I agree to a point – 1 line solutions are great; however, they can be more complicated than the one above.

    I always try to use them with care such that if they become too difficult to read, then things should be broken out into a few more lines.

Since PHP 5.4, you should be able to do something like this:

function post_type_is_supported() {
return isset( get_option( ‘acme-supported-post-types’ ) [get_post_type( get_the_ID() )] );
}

I think it’s a cleaner solution, since you don’t have to compare anything – you just ask if the value that you’re looking for actually exists. Though I’m not sure if this would be a recommended practice if you plan to publish that code, unless you warn the potential users about technical requirements. In fact, I recently had to modify a similar function in a plugin that I’m selling because some users were still in 5.3 and 5.2.

    This is a really nice solution; however, I can’t guarantee that the host running WordPress has 5.4. available.

    Then again, you already hit the nail on the head: I have to use features that I know are guaranteed to be applicable across all hosted.

I may be old fashioned in saying this, but I prefer the first approach. One liners look nice, but not when it’s 11 pm, and the deadline was 3 days ago!

    hahah, true, but that is here to let you use the next time :D

    That’s true!

    If one line takes a person longer to parse than not (and a lot of it has to do with familiarity with not only the WordPress API but the PHP API, as well) then going a slightly more verbose route is okay.

One thing I’ve been taught through WordPress is that it is better to write code that is easy for a developer to read than to write clever code that may condense your logic down to a single line like this.

Some developers spend a lot of time trying to write clever code instead of writing in a way that makes it readable by other humans. Depending on the reasons (performance improvements, whether the code is used just by me or other contributors, etc.) I prefer brevity over verbosity but also prefer to write code that is easy to follow.

    Indeed – the Codex even says this much, but the point, at least in this case, isn’t meant to be clever, it’s just much to be a bit more consolidated.

    For example, my rule of thumb is that I generally – not always – but generally create variables if I am going to need the data more than once. In this case, I don’t need the information more than once and the is_arrayis easy enough to understand to so that it’s relatively clear as to what’s happening.

    I realize this is predicated on the fact that people are aware with is_array, but this is also something that I think can be done on a case-by-case basis, not as a prescriptive idea for all code.

I’m definitely a fan of one liners. Just not in one line. When something like is_array() has two arguments, I prefer putting each argument on its own line. That makes it much easier readable. Even when it’s already 3pm.

Nice.

I can’t help but say… the next step would be to add arguments to the function like:

post_type_is_supported($post_id,$option_var)

so it is totally “dumb” and therefore re-usable.

I know this isn’t your point, but one could use array_key_exists() instead of in_array() to avoid array_keys(), which would result in something like this:

return array_key_exists( get_post_type (), get_option( ‘acme-supported-post-types’ ) );

    Indeed – this is a good tip and I’m happy you’ve shared it, Kaspars!

    Nice solution. I think it runs quicker than in_array() version since it doesn’t have to get array keys.

      That’d make for an interesting test – whenever I have some time, it might be fun to run some timers on that, but I suspect that we wouldn’t see much of a chance until there’s a large data set, you know?

      Even still – good thoughts, Anh!

Leave a Reply

Name and email address are required. Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>