JS Scripting

Syntax and Formatting

Code should comply with the WordPress standards as it is aimed towards readability and consistency between PHP and JS files in the WordPress codebase.

The complete WP JavaScript standards are available at this link but here are some things to keep in mind:

  • Indentation with tabs.
  • No whitespace at the end of line or on blank lines.
  • Lines should usually be no longer than 80 characters, and should not exceed 100 (counting tabs as 4 spaces). This is a “soft” rule, but long lines generally indicate unreadable or disorganized code.
  • if/else/for/while/try blocks should always use braces, and always go on multiple lines.
  • Unary special-character operators (e.g., ++, –) must not have space next to their operand.
  • Any , and ; must not have preceding space.
  • Any ; used as a statement terminator must be at the end of the line.
  • Any : after a property name in an object definition must not have preceding space.
  • The ? and : in a ternary conditional must have space on both sides.
  • No filler spaces in empty constructs (e.g., {}, [], fn()).
  • There should be a new line at the end of each file.
  • Any ! negation operator should have a following space.*
  • All function bodies are indented by one tab, even if the entire file is wrapped in a closure.*
  • Spaces may align code within documentation blocks or within a line, but only tabs should be used at the start of a line.*

Files Structure

We use Gulp to run tasks for concatenating JavaScript into one single file main.js while keeping the source code modularized and third-party files separated

We want to limit the scope for the final JavaScript code but also want a set o globally available variables and functions.

|-- admin // standalone scripts to be used in the WP dashboard
|-- main // used to define general scope and variables
    |-- functions.js
    |-- main.js // App logic to say so
    |-- wrapper-start.js
    |-- wrapper-end.js
    |-- variables.js
|-- modules
    |-- dummy.js
    |-- jquery.dummy.js
    |-- ...
|-- vendor
    |-- ...

The module folder will contain two js files called dummy.js and jquery.dummy.js to give you a head start in writing desired the functionality to comply with our guidelines.

Basic jQuery Plugin Prototype

// the semi-colon before the function invocation is a safety
// net against concatenated scripts and/or other plugins
// that are not closed properly.
;(function ($, window, document, undefined) {

    function PluginName(element, options) {
        this.element = element;

        // jQuery has an extend method that merges the
        // contents of two or more objects, storing the
        // result in the first object. The first object
        // is generally empty because we don't want to alter
        // the default options for future instances of the plugin
        this.options = $.extend({}, $.fn.pluginName.defaults, options);
    }

    PluginName.prototype = {
        constructor: PluginName,
        _myMethod: function() {
            ...
        }
    }

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn.pluginName = function ( options ) {
        return this.each(function () {
            if ( ! $.data(this, "plugin_" + PluginName) ) {
                $.data(this, "plugin_" + PluginName, new PluginName( this, options ));
            }
        });
    }

    // This object should contain as many options as possible
    // Users should be able to overwrite any option in their Custom JavaScript textarea like so:
    // $.fn.pluginName.defaults.option = myNewDefaultValue;
    $.fn.pluginName.defaults = {
    };

})( jQuery, window, document );

// usage
;(function ($) {
    $('[data-pluginName]').pluginName({
        someOptionName: 'someValue'
    });
})(jQuery);

Revealing Module Pattern

var myRevealingModule = (function () {

    var privateVar = "Ben Cherry",
        publicVar = "Hey there!";

    function privateFunction() {
        console.log( "Name:" + privateVar );
    }

    function publicSetName( strName ) {
        privateVar = strName;
    }

    function publicGetName() {
        privateFunction();
    }


    // Reveal public pointers to
    // private functions and properties

    return {
        setName: publicSetName,
        greeting: publicVar,
        getName: publicGetName
    };

})();

myRevealingModule.setName( "Paul Kinlan" );

References: