v1.x Code Style - Getbeans/Beans GitHub Wiki

Beans 1.x is based upon PHP 5.2.

We are working to upgrade the codebase to be WordPress Coding Standards (WPCS) compliant. We follow the WordPress Handbook, except for noted below.

Need Help?

Reach out on Slack in the #contribute group. We are here to help you contribute to Beans! And don't worry. ALL QUESTIONS should be asked. If you're wondering, someone else is too.

Quick Links

Here are some quick links to jump to the section you are most interested in:

Code Construction

Let's talk about code construction, you know, the actual act of designing and building your code.

Code Quality

Code quality is a core principle in Beans. We will think about and then implement the SOLID principles of:

  • DRY - Don't Repeat Yourself
  • Single Responsibility - One reason to exist in the code
  • Separation of Concerns - HTML in a view file not in the PHP logic. JavaScript in a script file.
  • KISS - Keep it Simple
  • and more

If these concepts are new to you, don't worry about it. Stick with these simple ideas.

Make it:

  1. Readable - code itself (without comments) is readable and makes sense
  2. Reusable - it's flexible enough to be reused in multiple places
  3. Maintainable - fixing one thing doesn't break 2 other things

Where Stuff Goes

Use these guidelines to help you figure out where code should go:

  • If it's a class, then one class per file and nothing else in that file.
  • Group like functionality together in a file and folder.
  • A function should have one expected behavior when you call it. Keep your functions skinny (less lines of code).

For tests, all tests will be in the tm-beans/tests/ folder. There are 2 types of types: unit tests and integration tests. Unit tests are required, whereas integration tests are optional but preferred for some types of functionality or features. See the Testing Documentation for more information.

Naming Conventions

Quick Naming Guide

Element Type Name by
Functions & methods action phrase (verb) Tell what it will do when it runs, i.e. its expected behavior.
Variables mixed Tell what value it represents.
Class noun Tell what thing it is, such as Post, User, Comment, View, Testimonial, Payment_Processor
File noun Tell what group of functionality within it. Why does it exist?

File

A file should be named for why it exists.

Follow WordPress' standard where a file is named:

  • in lowercase
  • words are separated by a - (hyphen)

If a file contains a class, it should:

  • contain only one class and nothing else.
  • be named as class-classname.php
  • omit the Beans prefix from the filename.

For example, the file holding a class named Beans_Action would be named: class-action.php.

Class

A class is a noun, as it's the blueprint for building an object.

Naming:

  • Capitalized first letters
  • Separate the words with an underscore
  • Prefix with Beans_
  • In most cases, it's a singular noun (not plural). Plural would be for a Pool of Objects.

For example, Beans_Compiler_Option, Beans_Compiler, Beans_Action, etc.

Functions and Methods

Follow WordPress' naming standards, meaning:

  1. lowercase letters
  2. underscores render_view() and run()

The exposed functions, i.e. those the child theme and plugins will use, will be prefixed and not namespaced. Naming follows this convention:

beans_verb_description()

Functions do work, such as render, run, check, do, process, etc. Work means they are action-based, i.e. verbs.

The description tells you what the expected behavior is when you call this function. It's clear and expressive. Remember the intent: tells you the expected behavior.

The benefit to that naming convention is: you can read the function's name and know what will happen when you call it.

Variables

Variables should be named to tell you what value(s) it represents (holds). Be verbose and descriptive.

Don't name variables $x $i $pre, etc. Instead, use variables like $key, $user_name, $event_name, etc.

This naming strategy applies to PHP and JavaScript (minus the $).

File DocBlock Header

Files should have a DocBlock header at the opening of the file. It will follow this format:

<?php
/**
 * An overview description of what this file is and why it exists.
 *
 * More details or even information about not removing....
 *
 * @package Beans\BeansFramework\...
 *
 * @since   Version Number
 */

The @package name follows a namespace format. Though we are not using PHP namespacing in v1.x, the package naming will follow that format.

Namespace format is:

VendorName\PackageName\ModuleOrComponentName\SubModuleOrSubComponentName

It follows the folder names with the lib main folder. For example, the api folder has multiple components. For the api/utilities the @package name is:

@package Beans\BeansFramework\API\Utilities

For example:

<?php
/**
 * The Beans Utilities is a set of tools to ease building applications.
 *
 * Since these functions are used throughout the Beans framework and are therefore required, they are
 * loaded automatically when the Beans framework is included.
 *
 * @package Beans\BeansFramework\API\Utilities
 *
 * @since   1.5.0
 */

Function and Method DocBlock

Of course we want to document our code. Functions and methods should be included in a DocBlock in this format:

/**
 * Tell us what the expected behavior is of this function/method when it runs. Start with a verb such as:
 * Checks to see if .... or Filters ..... or Gets the value from xxx when .... etc.
 *
 * Use this area if more explanation is needed.
 *
 * @since versionNumberGoesHere
 *
 * @global $global_variable_name <- if there's a global in the function, list it here.
 *
 * @param dataType $param1_name Tell us what value this parameter represents (will hold).
 * @param dataType $param2_name (Optional) Tell us what value this parameter represents (will hold).
 *
 * @return dataType A quick description of what's being returned.
 * @throws ExceptionName <- if this function has a new ExceptionName, list it here.
 */
function beans_some_function( $param1_name, $param2_name = '' ) {

for example:

/**
 * Convert internal path to a url.
 *
 * This function must only be used with internal paths.
 *
 * @since 1.5.0
 *
 * @param string $path          Path to be converted. Accepts absolute and relative internal paths.
 * @param bool   $force_rebuild (Optional) Forces the rebuild of the root url and path.
 *
 * @return string Url.
 */
function beans_path_to_url( $path, $force_rebuild = false ) {

Tests

A test file will hold one Test Case class. Name the file the same as the class. An exception is when you want the tests to run in a specific order. Then you can prefix with A_ for the first test, B_ for the 2nd, and so on.

A Test Case should be named for the tests it will do.

Testing a ____ Naming Convention
Class ClassnameTest - name it the same as the class it's testing + a suffix of Test
Function FunctionNameTest - name it the same as the function it's testing + a suffix of Test
Group of Functions ApiUtilitiesTest - name it either by the file it's testing or some name to tell us about the group. Add Test as a suffix.

Testing

Everything in Beans will be fully tested. Period.

Why? Tests prove that the functionality is performing as expected and designed. Then when we make a change, the tests run again and confirm that the change did not break anything. If it did, we know where to go looking for the problem.

Yup, tests are important. When submitting PR, make sure you include fully functioning and passing tests with the code.

Not sure how? Ask. We're here to help get you started.

Refer to the Testing Documentation for more information.