WDS PHP Coding Standards

Plugin Folder Naming

The plugin folder name should begin with the client prefix followed by the plugin name. Words should be separated by dashes.


Folder Structure

Inside the plugin, WDS uses the following general structure:

  • / – Main plugin file
  • /assets – Folder containing all plugin assets
  • /assets/images – Folder containing images
  • /assets/js – Folder containing compiled javascript (and minified) files
  • /assets/js/src – Folder containing javascript src files and partials
  • /assets/js/vendor – Folder containing any third party scripts
  • /assets/css – Folder containing compiled CSS (and minified) files
  • /assets/css/sass – Folder containing SASS source files. Often will include a partials directory
  • /includes – Folder containing project files
  • /includes/libraries – Folder containing external libraries
  • /includes/templates – Folder containing andy view templates

You can see it in action in the WDS-Grunt-WP-Plugin.

File Naming

Files containing classes should be named the same as the class with all letters lowercase and hyphens (-) instead of underscores (_) and with class- prepended. The WDS and Client Prefix should be included.


Follow the one class per file convention.


While should ideally be self-documenting due to clear naming conventions and small non-complex code blocks at WDS we strive to create high quality in all we do and that includes commenting code. Comments should include the ‘why’ and ‘what’ the code does in human readable form. Example uses of functions and methods can also be helpful. As a general rule of thumb; a manager or client should be able to grok your code by simply reading the docblock and inline comments. Keep in mind that WDS may not be the only company looking at your code in the future.

The WordPress handbook contains a section on general code documentation tips https://make.wordpress.org/core/handbook/inline-documentation-standards/php-documentation-standards/

Docblock tags along with example usage can be found on the phpDocumentor site http://www.phpdoc.org/docs/latest/index.html

Class Naming

Class names should have capitalized words separated by an underscore (_). All classes should be prefixed. In general, the main plugin class file will look like ‘WDS_CLIENTPREFIX’. The internal classes of the plugin can use a shortened version of the main plugin class prefix which helps remove a bit of ambiguity and makes the purpose of that class clearer. An example would be ‘WDSCP_Settings_Page’, ‘WDSCP’ being a shortened version of  ‘WDS_CLIENTPREFIX’.

If developing a plugin to be released publicly, replace ‘CLIENTPREFIX’ with ‘Plugin_Name’. ‘WDS_CE_Document_Management’ would just be ‘WDS_Document_Management’.

Although not currently a requirement it is polite to comment the end of classes for other developers.

class WDS_CE_Document_Management {
} // end class

An internal class…

class WDSCEDM_Settings_Page {
} // end class

Class Methods

Class methods follow the standard WordPress convention of all lowercase with underscores (_) separating words. When creating a new method it should be prefixed with proper access level of public, private, or protected. Remember it is always easier to make a method less protected than more protected in the future. Methods called via WordPress hooks must be public.

Private methods should be small and to the point. Usually helpers for that class. Choose your access level carefully.

Be sure to provide good docblock documentation for all methods.

class WDS_CE_Document_Management {
     * Adds a new document to the document management system.
     * New document will be visible to all subsites on the multisite containing
     * that subsites’ slug.
     * @param string $path File system path to new document
     * @return WP_Post or false
    public function add_new_document( $path ) {
} // end class

Class Properties (Variables)

All class properties should declared at the top of the class. Creating new class variables on the fly in methods is discouraged. Class properties should be prefixed with the proper access level of public, private, or protected. When creating class properties that you want to provide read-only access to, the __get() magic method can be quite useful.

class WDS_CE_Document_Management {
  * Contains a list of documents pertaining to the current subsite.
  * Array of WP_Post items.
  * @var array
 private $document_list;
  * Magic getter for retrieving white-listed object properties.
  * @param string $field
  * @throws Exception Throws an exception if the field is invalid.
  * @return mixed
 public function __get( $field ) {
     switch ( $field ) {
         case 'document_list':
             return $this->{$field};
             throw new Exception( 'Invalid '. __CLASS__ .' property: ' . $field );
} // end class

Function naming

Functions should be all lower case with spaces between words separated with an underscore (_). All functions should be prefixed ‘WDS_CLIENTPREFIX’. Functions should be documented with proper docblocks.

* Finds the permissions the specified user has on the given document.
* @param integer $user_id User to check
* @param integer $document_id Document to check
* @return array
function wds_ce_get_user_document_permissions( $user_id, $document_id ) {
    // ...

Require the plugin!

Any and all plugins we create or use on a client site that are necessary for the site to operate properly (This does not include MigrateDB Pro necessarily) should be added to the required plugins list. The list lives in the mu-plugins directory.

Here is an example:

require_once( WPMU_PLUGIN_DIR . '/wds-required-plugins/wds-required-plugins.php' );
 * Add required plugins to WDS_Required_Plugins
 * @param  array $required Array of required plugins in `plugin_dir/plugin_file.php` form
 * @return array           Modified array of required plugins
function wds_uber_required_plugins_add( $required ) { 
    $required = array_merge( $required, array(
    ) );
    return $required;
add_filter( 'wds_required_plugins', 'wds_uber_required_plugins_add' );

If the required plugins library has not been setup on the project yet you can find it at https://github.com/WebDevStudios/WDS-Required-Plugins