Agile Programming for WordPress Plugins: The Joy of Output Buffering
A standard practice of Agile programming, and good programming in general, is to separate your display code from your application logic. Bob Martin:
The ideal is for a source ﬁle to contain one, and only one, language. Realistically, we will probably have to use more than one. But we should take pains to minimize both the number and extent of extra languages in our source ﬁles.
Separating display code is central to the MVC pattern, which underlies almost all PHP frameworks (and frameworks in many other languages as well). WordPress is a blogging platform and arguably a CMS, but for plugin authors, it does not provide the typical tools of a development framework. If you want to separate out your display layer, you’re on your own.
As a result, very few plugin developers do. A common style for WordPress plugins is a single file, sometime running thousands of lines, that consists of cryptically named functions (often in no discernible order), which have the display code scattered around within the core application logic. This style might be acceptable for something small and simple. But once the functionality becomes complex, this style makes the code very difficult to understand for anyone other than the author (and the author is likely to find it hard to understand six months after finishing work on it). It also makes extending the functionality difficult. For example, adding support for a mobile UI would entail a major rewrite.
For a WordPress plugin, you can use output buffering to solve this problem. You can see an example in my ShashinMenuDisplayerAlbum class. The run() method triggers the display of the menu, and its HTML is in a separate file:
ob_start(); // start the output buffer require_once($this->relativePathToTemplate); // get the HTML template $toolsMenu = ob_get_contents(); // store it in a variable ob_end_clean(); // empty the buffer and turn it off
require_once call would include the file, evaluate any PHP code, and immediately output the HTML. Including the file with output buffering turned on allows you to instead store all the output in a variable. You can then control when it is displayed. With this approach you do not have to write all your HTML inline with your application logic.
The template file being included in my example does have PHP as well as HTML in it, so I am not meeting the ideal of complete separation. But as Bob Martin points out, such total separation isn’t always possible. In this case, the PHP code used in the template is the minimum necessary for the purpose of rendering the page (for example, it contains a foreach loop to display rows of data in a table).