Creating Styling options for modules

For this tutorial we're going to build off of the Custom Quotes modules, so if you have not already please read up the first part: Coding Builder Modules.


Before we begin, make sure to do these two steps:

Important Step 1: genearting the Styling options requires Node.js. Familiarity with Node.js is not required however, simply make sure to install this for your system.

Important Step 2: Enable "development mode" in Themify Settings page (this is located under Performance tab). This disables various types of caching the theme does, and ensures your code is updated as expected when you make changes to it.

Updating our module

The Themify Builder stores the Styling data for the modules in .JSON files, separate from the JavaScript that defines the interface for our module. So first step, we need to instruct Builder that we have a JSON file for our module that it needs to load. Open module-quotes.php file and add this method to the "TB_Quotes_Module" class:

    public static function get_json_file():array {
        return [
            'f' => plugin_dir_url( dirname( __FILE__ ) ) . 'json/style.json',
            'v' => '1.0'

The method is returning an array with two pieces of information: f is the URL to the JSON file, and v is for a version number, this can be useful if down the line we need to update our code and thus have to ensure new version loads on our user's system. Now if we load up the editor, we'll get a 404 error that "style.json" file is not found.

So now we have to build it.

Generating module style.json file

We could define the options and how they're laid out by manually typing them out in our style.json file, but there's a better option! This is where node.js comes in, we'll write the options we need in a little script file that Node will then compile and generate the JSON off of. So download this zip file and extract it inside your "builder-custom-quotes" plugin folder. We need to edit this script a little bit beforehand. Open "app.mjs" file, in it you see:

const modules = [	

Here we define a list of modules we want to make the styling options for. This is useful in case our plugin is registering multiple modules but our Custom Quotes plugin has just the one, so we need to put "quotes". Also open "config.mjs" file and find this bit:

const BUILDER_URL = "../../../../themes/themify-ultra";

This is where we need to put the address to where Builder is, so the script can load the proper files it needs. If you have followed everything exactly like the tutorial, the path is four folders up: module-styles > builder-custom-quotes > plugins > wp-content, then inside "wp-content" we look for the "themes/themify-ultra" theme. If you're using a different Themify theme you need to set the path accordingly here.
Inside "module-styles/src" we have "quotes.mjs" file, this is where we actually define the options we want. Currently it's filled with some general options (font / background / padding & margin, etc.) that apply on the ".module" element. We'll go into more details about how this work later, but for now let's generate! Open up the termnial in your operating system and navgate to that "module-styles" folder. In Windows, you can simply click the address bar and type "cmd" and enter.

When terminal opens, type "node app.mjs" and hit enter. Now if everything goes according to plan, you should see the command prompt again, this means there has been no errors and our JSON file has been compiled successfully. And if you navigate to the plugin's directory you should see the new "json" folder which contains our style.json file.

Now if you load Builder up and add a Quotes module, you should see the new Styling options showing up:

Structure of styles.mjs file

The get_styles() is where we define all of the Styling options we want. At the moment the function is just returning an array of options. A lot of modules have items that needs to be styled separately (for example in Post module you can style the post container, post title, post content, etc.) so to create a similar interface in get_styles() we can return an object that does that:

return {
    type : 'tabs',
    options : {
        "Tab 1 Options" : [],
        "Tab 2 Options" : []

Now under "options" we can add as many items as desired, where the key is the title of the displayed tab and the value is the array of options we want to display under that tab.
Here's an example snippet that generates the Styling options for fonts:

this.get_expand('f', [
        n: [
        h: [
            this.get_color_type( '', 'h' ),
            this.get_text_shadow( '', 't_sh' )

get_expand creates an accordion-like item that you can click to show extra stuff underneath. The first parameter "f" is the text that is displayed (in this case it will show "Font"), we'll describe how that works under the Localization section.
The get_tab creates a tabbed-interface, this is used to separate the options for normal / hover state. This is optional, but it gives the end user flexibility to customize our module. "n" is the options for the Normal state, while "h" lists the options for Hover state.

The other function calls simply generate the options, so "get_font_family()" will display options to change the font, "get_text_shadow()" will generate the options for adjusting "text-shadow" CSS property. All of them have to important parameters: the first parameter is the "CSS selector" we want these styles to apply to, empty value simply means the styles apply to ".module" element itself (the module wrapper). For example in link styles, the selector is set to ' a' so the end selector becomes: .module a and the styles apply to all a elements inside .module. This parameter can also be an array, so the option affects multiple CSS selectors at the same time.
Second parameter should be a unique ID to save the option values. In the current quotes.mjs file most of them are empty because the functions have a default ID and since we have just one we don't need to declare anything of our own, but if we add more options this has to be supplied.

You can download the finished module.