At this point in the series, we've covered a lot of material - not only have we covered the basics of object-oriented programming, but we've also begun to build a fully functional plugin.
But the challenge that comes with the work that we've done this far is that it doesn't include any documentation about how the plugin actually works. If you recall from the previous article, we made a conscious development decision to postpone this feature.
Starting in this article, we're going to be taking a two-part look at how to document WordPress plugins, and how we can do so given our current plugin.
Before proceeding with the remainder of this article, I highly urge you to catch up with the content that we've covered thus far. As mentioned in every past article, each article builds upon the previous article in the series.
- An Introduction
- Control Structures: Conditional Statements
- Control Structures: Loops
- Functions and Attributes
- Building the Plugin I
- Building the Plugin II
With that said, it's time to turn our attention to documenting our plugin, but before we go ahead and do that, we need to make sure that we fully understand the standards that are in place for us to document our work.
So before providing the comments that are relevant to our plugin, we're going to take a look at what all we need to include. After that, we'll look at doing exactly that for our plugin in the next article.
The WordPress PHP Documentation Standards
For starters, the WordPress Codex includes a handbook specifically for the PHP Documentation Standards. You can read the standards in their entirety; however, we're going to be highlighting the most important features of what we're going to be implementing in the next article.
The primary things that we're concerned with documenting are the following:
- File Headers
- Class and Function definitions
- Variable or class properties
This will obviously be a much slower paced set of articles than the previous two, but given the amount of work that we've covered thus far, it should be a welcome change of pace for some readers.
So with that said, let's get started.
File headers are unique in the fact that they are something that should be placed in each file of the files that make up a plugin (or a theme, but that's not the focus of this series), but they aren't always.
According to the Codex:
The PHPDoc file header block is used to give an overview of what is contained in the file.
The general template that we'll be using starting in the next article looks like this:
/** * Short Description (no period for file headers) * * Long Description. * * @link URL * @since x.x.x (if available) * * @package WordPress * @subpackage Component */
Note that in the file headers, we do not include a period and there are two components of the description:
- A short description
- A long description
Whenever I write these out for my specific projects, I try to imagine that my short description if something that may fit in the top of of
README file, that may a be a single, short elevator pitch for the file, or that may even be contained in something as short as a tweet.
The longer description, of course, can be as easily more detailed as we like. In this case, there is a specific format that we should use for long description, but that's beyond the scope of this particular article as we'll see a particular, practical example of this in the next article in the series.
Occasionally, we have the need to document code that's included in a function or a class. These are different than function definitions or class variable definitions.
Instead, think of these as inline comments for when you need to include or require a certain dependency. This will generally be a separate PHP script over anything else.
/** * Short description. (use period) */ require_once( ABSPATH . '/filename.php' );
However, note that according to the Codex that this is not just limited to function calls such as
Files required or included should be documented with a short description PHPDoc block. Optionally, this may apply to inline get_template_part() calls as needed for clarity.
Since our plugin is making calls directly to external scripts, we will be using a practical example of this in the next article. The reason that I share it here is not only to prepare us for what's coming, but also to show the proper format for how to leverage this in any current that we may be doing.
Class and Function Definitions
Though I think that all documentation is important, and I'm not claiming that these two aspects are the most important part of documenting a plugin; however, given the fact that our plugin is object-oriented in nature, it's key that we understand how to properly document both our classes and our functions.
Class definitions are code comments that appear between the file headers (that we discussed above), and the name of the class.
The format that's used to document a class is as follows:
/** * Short description. (use period) * * Long description. * * @since x.x.x * * @see Function/method/class relied on * @link URL */
If you happen to look at the WordPress Codex for this article, you'll notice that it provides a little more information that I've included in the documentation above. This is because they've included content both class and function definitions.
Instead, we're breaking each of them out into separate areas for future reference, and so that we can see why we'll be documenting certain things in certain ways in the next article in the series.
Similar to class definitions, that you can expect to see the following:
/** * Short description. (use period) * * Long description. * * @since x.x.x * @access (for functions: only use if private) * * @see Function/method/class relied on * @link URL * @global type $varname Short description. * * @param type $var Description. * @param type $var Optional. Description. * @return type Description. */
Notice in the code comment above, there's very little difference to what we saw with class documentation.
In addition to what's above, we see information for:
- global variables
- return types
Obviously, this is material isn't typically used within the context of a class; however, it is used within the context of a function.
To that end, here's how you can think of each of the above:
globalvariables refer to those variables that are used within the context of the function that are global to the WordPress environment. This includes things such as
$authordata, and others listed here.
@paramtag refers to the variables that a function accepts. Obviously, this includes the type of variable that it accepts and a description as to what the variable represents.
@returntag discusses the type of variable that a function returns and a short description as to the type of data that's being returned.
Rather than give a concrete example of this here, we'll be doing this in the follow-up post with the code we wrote in the previous post.
Variable or Class Properties
Finally, variable properties - or more commonly known as class properties (which are sometimes called attributes), represent the data that is held within the class.
Remember from earlier in our series, we mentioned that attributes are like the adjectives that describe the noun that the class represents.
As you can see from the previous article, class properties are defined just after the name of the class and before the constructor (regardless of if its
To document these attributes, we follow the following template:
/** * Short description. (use period) * * @since x.x.x * @access (private, protected, or public) * @var type $var Description. */
Easy enough to understand.
Some may argue that the use of
@access is frivolous since the access modifier of the function directly following the comment explains the type of function it is.
But this is where the differences in the WordPress documentation standards differ from some of the PHP standards (both in place and those that are in process of being standardized).
A Word About PSR Standards
In short, PSR refers to the PHP standard recommendations as proposed by the PHP Framework Interop Group.
You can read about each of these standards here:
- PSR-0: The Autoloading Standard
- PSR-1: The Basic Coding Standard
- PSR-2: The Coding Style Guide
- PSR-3: The Logging Interface
- PSR-4: Autoloader
Which PSR-5 being discussed right now. These are important to follow for all PHP developers regardless of the platform or foundation they are using, but I also think it's worth noting that the differences (and similarities) existing between PSR and the WordPress standards as there are differences.
Which Do We Choose?
This is a point of disagreement, so what I'm about to say is purely subjective; however, I'm of the mindset that when you're working within WordPress, you should follow the conventions as proposed by WordPress.
This is not to say that we shouldn't make an effort to more closely align ourselves with what the larger PHP community is doing; however, if we're writing WordPress code for other WordPress developers, then this is something on which we should primarily be focused.
Coming Up Next
In the next article, we're going to take a look at applying the above principles within the context of our plugin.
This should help us to not only build a plugin that conforms highly to the WordPress coding standards, but also to the documentation standards such that we, our users, and our future contributors will be able to easily follow the flow of control through out the project.
In the meantime, feel free to leave any questions and/or comments in the feed below!