Divine the future!


Note: There has been updates to the Divi theme that make some changes to the code. This tutorial was written about pre-Divi 3.0.45, but having said that, ET was careful to update in such a way that old code still maps nicely. That means that these tutorials are still germane (at least as of May 13, 2017), but we will see what future updates bring! I will be writing new tutorials to introduces the new features of Divi soon!

This is the fifth in a series of tutorials looking at the main-modules.php file of the Divi theme from Elegant Themes. This file codes for all of the modules used for this page builder. This series of tutorials lays the groundwork for producing custom modules to extend this powerful page builder. In this tut we will begin to explore the final method of each module class, the ‘shortcode_callback()’ function.

To review, each module class is broken down into three main methods. The first, ‘init()’, initializes any default values and outlines what values the module will collect from the user. The second, ‘get_fields()’, defines the look of each field being collected from the user – essentially, it is a big php-powered form generator. The third method, ‘shortcode_callback()’, defines what is done with the collected data when the browser displays the particular module. This method takes all of the content that has been added by the builder on the backend and processes it into HTML output.

The name of the ‘shortcode_callback()’ method tells us a lot about how Divi works. If you have a site running the Divi theme and change to another theme, you will find that the pages left behind look like someone with a fetish for brackets wrote your content.

This is because the Divi builder stores all of your page information as a series of shortcodes that get decoded during page load. Some are structural and added by Divi automatically as you add in sections, columns, and rows. Others are specific to each module. The ‘shortcode_callback()” method is called when WordPress is interpreting the shortcode for a particular module. 

This method starts with retrieval of all the stored data into variables to be used in the method. This is done using the WordPress ‘shortcode_atts’ function to access the array that is stored with the property name that is being passed in. So the first line:

will assign the contents of the ‘module_id’ field to the variable ‘$module_id’. When writing your own module you will need to add in an assignment like this for every custom field you have added. 

Following this assignment, the method makes a call to another Divi function, ‘add_module_order_class()’.

It does so using the ‘::’ operator, which allows the current function to access a function defined in the parent class. Basically, this allows for the builder to begin adding all of the class names to the element.  

The remainder of this method can generally be split into two parts. First, any styling to be applied to the content is generated. Second, all the actual content is placed into HTML markup through a series of ‘sprintf()’ statements. Most of the content is straight-forward php programming and would take more than a short tutorial to cover in-depth. However, I will delve briefly into some Divi-specific features of this section and ‘sprintf()’. 


This function call is used to set up the media queries that Divi uses for each module. As a first argument, it takes an array of key=>value pairs taken from the builder page. The keys it expects are ‘desktop’, ‘tablet’, and ‘phone’.  In this case, the values are maximum width values for each device, but it could be different padding amounts for each device, or any other value you want to change based on device. The next argument is the css selectors that need to be used to target the element. In this example it is a simple dynamic variable, ‘%%order_class%%’, that contains the base class selectors for this particular module. However, this can also contain a more complex list of selectors, for example:

 The next argument is the actual CSS property that is being set, ‘max-width’ in the first example, ‘padding-top’ in the second. The final argument being passed in each example is essentially the name of the module. This function can actually take one additional optional argument which is any additional CSS that should be applied. This can be used to add centering for example.

The syntax is a little tricky. The above code says that if the $text_orientation property value is equal to ‘center’ then set the value of $additional_css to ‘; margin: 0 auto;’. Note the semi-colon at the beginning.


Another mechanism for changing the stylesheet for an element is the ‘set_style()’ method. This method takes two arguments. The first is essentially passing in what module is calling the method to set up various base CSS selectors. The second is an array of two key:value pairs. The first has a key of ‘selector’ and is the combination of tags, class names, and ids that will be used in the style sheet to specify what is being styled. The second has a key of ‘declaration’ and is the actual CSS being applied.


The sprintf() function is part of php, but because it is so core to the last bit of this method, I’ll briefly explain what it does. After the majority of styling is set using the above two function calls, the rest of the method is generally devoted to building the $output variable, which is what is returned to WordPress when it makes the shortcode call. Typically, this is done through a series of logic tests to determine if fields have content or if certain checkboxes have been ticked in the builder. Taking an example from the Image module:

So, sprintf() is basically a way to build dynamic HTML. The first argument it takes is the HTML element with numbered variables in areas that need to change. Following the number is a ‘$’ and character that defines what type of variable it is, typically either a string ‘s’ or digit ‘d’. All of the rest of the comma-separated arguments are the variables to be slotted, in order, into the first argument. In the above example, $output is being assigned an img tag with the src, alt, and title dynamically assigned, plus additional elements if the user selected to have an overlay. So, ‘%1$s’ is getting assigned the output of ‘esc_url( $src )’ – which is a sanitized version of the data stared in the $src variable. ‘$2$s’ is getting the output of ‘esc_url( $alt )’. For ‘%3$s’ there is a nested sprintf() with some conditional logic. It will be assigned ” if there is no value for the $title_text variable or ‘ title=”the title”‘ if there is a title. Note the spacing and quotes – this is directly what will be output. So, if the space before title wasn’t there it would run into the variable before it. To better illustrate this, let’s assign the variables.

  • $src = http:www.example.com/image1.jpg
  • $alt = an example image
  • $title = first example image
  • $overlay_output = off

So $output would equal, <img src=”http:www.example.com/image1.jpg” alt=”an example image” />. 

Each subsequent section of this method will add to the $output variable using values retrieved from the database to create the final HTML markup. 

I hope this helps out with your understanding of the Divi module php. This final method really needs a decent understanding of basic php and some time digging around in the code, so get your hands dirty! Next up, we will begin to write our own custom module. As usual, if you have any questions, comments, or corrections leave them below or shoot me an email.



Saving Private Divi


One complaint that I have heard a lot in the Divi world is that it isn’t easy to find/access the save button on the front-end builder. Wouldn’t it be great if it was right in the admin bar at the top of your screen? In this tutorial, I’ll show you how to modify the functions.php file of your child theme (you are using a child theme, right?) and add in some javascript to accomplish this. Best of all, you can give you new button some color so that your clients can find it!

All of this code is posted on github for you to fork and make your own. First, we will start by adding the button. Open up your child theme functions.php file. Do NOT edit the main Divi theme functions.php file. Even if you don’t brick your site, you risk losing your custom php during the next upgrade! In order to add this button we will use the ‘add_node()’ method. 

Okay, let’s walk through it. First, we call our function a unique name – ‘shd_add_divi_fb_save_button’. Okay, okay, I’m being a little crazy with the name. I posted my code on a github and the wonderful Jonathan Bossenger, who runs Divi Hackers United, gave me an important reminder. When you introduce a new function into a WordPress environment through the functions.php or through a plugin, it is competing with every other public function – if it doesn’t have a unique name you will get a conflict. Here is a great article about it. At any point, I’m prefixing with my group’s initials and using adding a meaningful function name. I’m also passing in the class that WordPress uses to generate the toolbar, ‘$wp_admin_bar’. This allows us to make changes to the toolbar within out function.

Next, I’m setting up an array of arguments that describe our new button. The ‘id’ is used on the backend and is not the ‘ID’ we would assign when programming in HTML. The ‘title’ is the label that will be added to our button – we could pass in HTML tags if we wanted. The final argument we are defining is ‘meta’, which accepts an array of parameters. In this case, I’m only setting the class of the button. Here is a link to the WordPress codex describing the parameters that can be passed to add_node(). Finally, I add the $args array to the toolbar by using the object operator (‘->’) to use the add_node method on the $wp_admin_bar.

We finish this section off by telling WordPress that we want to run this function whenever it loads in the ‘admin_bar_menu’ hook. Additionally, I have given this action a priority of 1500. This number determines when the function is run compared to all of the other functions being run when WordPress gets to the ‘admin_bar_menu’ hook. In this case, I set the priority higher than the ‘Exit Visual Builder’ button, so it will display after that button, or to the right of it.

Next up, I’m going to hide the button when we are on an admin page using a little CSS. Note-I will also be modifying my child theme styling sheet to hide the button when we aren’t using the front-end builder

, but this won’t impact the look of the button on the dashboard, because our theme styling isn’t loaded there. 

All I’m doing with this function is saying that when WordPress loads the head of the admin pages, I want to inject the following styling. The ‘admin_head’ hook is useful for hooking up any style sheets for modifying the look of your dashboard.

The final thing that I’m adding to my functions.php file is a directive to enqueue my javascript that I’ll be writing next.

Not too much to comment on here.

Moving on to the javascript side of things. Overall, what we need to do is:

  1. Make the button appear when we are in the visual builder only.
  2. Set up our new save button to act like the existing buttons.

First, a thank you to Bruno Bouyajdad of indikator-design.de and Jonathan again for suggestions on improving this code. Now, let’s walk through to understand what is going on. To start, the whole of the script is being run as an anonymous self-executing function with jQuery being passed in so that we can use ‘$’ instead of having to type out jQuery each time. Remember, WordPress runs in noConflict mode by default.

To solve for list item one – only revealing the button when the visual builder is active – We use a function named  ‘getQueryVariable’. The Divi builder passes a variable in the URL when you activate the visual builder. That is the portion after the ‘?’. We retrieve this portion of the URL  using ‘window.location.search.substring(1)’. That substring is then split and parsed to look at the name and value of each variable. If this function finds the variable we passed in when we called it, it will return the value of the variable. On almost all browsers (I’m looking at you Microsoft), there is an easier way to do this using the Web API’s URLSearchParams() constructor, but I wanted to make sure this worked for everyone..Once we identify that the visual builder has been activated 

Once we identify that the visual builder has been activated we start a timer. This timer calls the ‘iconCheck()’ function every 600ms, waiting for all of the page elements to load in. Both the ‘$(window).load()’ and ‘$(document).ready()’ methods fire too early for our purposes. In this case, I am surveying the DOM for the presence of the round purple button with a class of ‘et-fb-icon–move’ that appears at the bottom of the viewport once the visual builder loads in. The line of code ‘ if( $(‘.et-fb-icon–move)[0]) {‘ could be re-written as, ‘if ( $(‘.et-fb-icon–move).length > 0) {‘. So basically, I’m just checking if the element exists. If the element is found, the timer is turned off using ‘clearInterval()’ and a call is made to a new function, ‘catchClicks()’.

The ‘catchClicks()’ function first causes the save button to be revealed by changing the ‘display’ value to ‘list-item’. It then sets-up two click listeners. The class of the save button depends on if the particular page has been previously published or is brand-new. So, the first two ‘if’ statements test which particular button exists and then set a click listener on our newly revealed save button to trigger that particular Divi save button. The last ‘if’ statement turns the visibility of the new save button off when the user clicks on the exit visual builder button.

And that is it! Sometime in the future, I will release this as a free plugin. I’m debating whether I make a go at refactoring this in OOP first or not. As always, if you have any questions or corrections, feel free to shoot me an e-mail or make a comment. Hope this helps someone!


Caress the Divine Detail! (Part Two)


Note: There has been updates to the Divi theme that make some changes to the code. This tutorial was written about pre-Divi 3.0.45, but having said that, ET was careful to update in such a way that old code still maps nicely. That means that these tutorials are still germane (at least as of May 13, 2017), but we will see what future updates bring! I will be writing new tutorials to introduces the new features of Divi soon!

This is the fourth post in a series looking at the php code underlying the Divi theme modules. So far, we looked at the overall structure of each class that makes up a module and examined the ‘init()’ method that initializes all of the fields and variables that the class uses. In our last tut, we began looking at the second major method of the Divi module classes, the ‘get_fields()’ function. This method delineates how each of the fields should be presented in the backend. We covered the basic properties that each field typically has defined. One interesting one is the ‘type’ property. To recap, 

To recap, there are (at least) 12 different possible values for the ‘type’ property, ranging from the simple ‘text’, which creates a text input field, to the ‘multiple_checkboxes’, which unsurprisingly creates multiple checkboxes that the user can tick for different options. The subjects of today’s tut are four of the ‘type’ values: ‘yes_no_button’, ‘select’, ‘multiple_checkboxes’, and ‘range’.


This value is used to generate a switch. While it is called a ‘yes_no_button’, it delivers back a binary choice that can be anything you want. One common use of this is to determine if the Lightbox is used to display an image. In this case, the choices are ‘On’ and ‘Off’. Let’s look at the code for this.

Walking through the code, we see several properties that should be familiar from the last tut. We are defining a ‘label’ that is showing up to the left of the switch, setting an ‘option_category’, and giving the ‘description’ a value that shows up below the switch. Now we come to a new property, ‘options’. This property holds an array as a value. This array in turn holds two property:value pairs. 

The first property taken by the ‘yes_no_button’ type is ‘off’. This provides a translatable lable for the off position using the WP ‘esc_html__()’ function. The second property, unsurprisingly is ‘on’, and it is a translatable label for the other position of the switch. These labels can be anything – for example, a choice between the ‘light’ and ‘dark’ text layouts we see in some modules. Note, the button is called a ‘yes_no_button’, but it takes ‘off’ and ‘on’ as properties – makes sense, right? 🙂

The second new property is a little more complex. The ‘affects’ property takes an array as a value. Each of the strings stored in the array is comma-separated. They are each the names of other fields that can be presented to the user in the backend. So in the Image module, the ‘url’, ‘url_new_window’, and ‘use_overlay’ options will change how they are displayed when the user changes the position of the ‘show_in_lightbox’ ‘yes_no_button’. What determines whether they are shown by default and hidden on switch, or vice-versa? The answer is another property that is included in the field to either be shown or hidden.

The property ‘depends_show_if’ determines whether the field is shown. As we can see from the picture at the top of this section, the field to put in a link URL for our image (defined by the ‘url’ field) is displayed by default. Looking at the ‘url’ fields it has the following:

So, if we set the value to ‘off’ it will show until we flip the switch. In contrast, the ‘use_overlay’ field is only displayed after the button is clicked, as shown in the picture just above. The initial value of the ‘depends_show_if’ for the ‘use_overlay’ field is ‘on’. 

This can get a little complicated once we start nesting ‘yes_no_button’ types. In the Image module, once the ‘Open In Lightbox’ switch is turned to ‘Yes’, this displays an additional ‘yes_no_button’ field to add an ‘Image Overlay’. Clicking that brings up additional fields that all have their ‘depends_show_if’ set to ‘on’. One property that I’m not sure about is ‘depends_default’. I’ve tried changing this to false without impact. I’m still digging through the code!!

To summarize – if you have a ‘yes_no_button’ type set for a field you need to also provide a ‘options’ property that supplies the labels for each choice. You also have to supply an ‘affects’ property with an array containing the names fields to either be shown or hidden on click. Each of the ‘affects’ fields needs to have a ‘depends_show_if’ property set to ‘off’ or ‘on’ to be shown or not shown, respectively.


The ‘select’ type provides a drop down list of options for the user to select from. Like the ‘yes_no_button’ it requires an ‘option’ property, in this case an array of property:value pairs that defines each of the choices in the drop down list. Let’s look at the code for the ‘Image Alignment’ choice in the Image module:

Our friends ‘label’, ‘type’, ‘option_category’, and ‘description’ are all there! Looking at the ‘options’ property, there are three choices, ‘left’, ‘center’, and ‘right’. The actual properties will become important later – they are what is passed to the next function that actually builds the page. Following these properties are values that contain the translatable label for each choice. The actual property does not have to match the label. In fact, when translated, they won’t. So even though a German Divi user might select, ‘Links’, the backend function gets passed ‘left’.


Continuing our pattern from the other two types, the ‘multiple_checkboxes’ has all of the basic field properties, with the addition of an ‘options’ property. An example of this is the ‘Disable on:’ field found in most of the modules. The format of the options field is identical to that of the ‘select’ type. The only difference is that all the choices are displayed and more than one can be selected. 

As a side note, there is an addition property that is associated with the ‘disabled_on’ field that generates the selection of devices that get disabled. The key:value ‘additional_att’ =>’disable_on’ is added in this block and is processed by the builder to generate changes in the stylesheet, adding ‘display: none;’ to media queries corresponding to each device.  


The ‘range’ type accepts a different property from the other advanced types. The property ‘range_settings’ accepts an array with three properties.

The ‘min’ property is the minimum you want you slider to be able to select. This value a decimal or whole number, and it can be less than zero – for example if you want the user to be able to set a negative margin. The ‘max’ property, unsurprisingly, establishes what you want the maximum amount selectable to be. The final property, ‘step’, is how much you want the value to change as you move the slider. This can be a fractional number like ‘0.02’. One other property that can be set here, rather than in the ‘init()’ method, is ‘default’. This will be the value that your slider starts at and also sets the type of value. In this case ‘px’, but it could be ’em’ or ‘%’ depending on where you are using the slider.

Well, that is it for this method! As you look through the main-modules.php code on your own, you will see that there are other properties I haven’t covered, like the mysterious, ‘mobile_options’ => ‘true’! I also have skipped over a bit of how you add in some of the fields on the ‘Advanced Design Settings’ and ‘Custom CSS’ tabs. Divi “automates” some of this since they are re-used so often. In a later tut I will likely revisit the ‘Custom CSS’ tab. 

As always, I hope this helps someone. If you have any questions or corrections, please reach out to me in the comments or by email. Happy coding!! 


Caress the Divine Detail! (Part One)


Note: There has been updates to the Divi theme that make some changes to the code. This tutorial was written about pre-Divi 3.0.45, but having said that, ET was careful to update in such a way that old code still maps nicely. That means that these tutorials are still germane (at least as of May 13, 2017), but we will see what future updates bring! I will be writing new tutorials to introduces the new features of Divi soon!

This is the third tut in this series, meant for Divi users that want to begin creating and customizing the builder modules. There is a lot of details that need to be covered, so these tutorials are a little dense. Take it slow (maybe several sittings) and feel free to ask questions!

In our last tut, we examined the first method (remember, in a class object, a function is called a method) that initialized the class – adding our slug, outlining what fields would be used, and adding some defaults and options. In this tut, we are going to begin digging into the second method, ‘get_fields()’. This method delineates what each field presented in the module will look like – what type it is, what labels are added, what tab of the builder it is located in, and whether it impacts other fields in the builder. There is a lot to cover, but let’s get started.

In this case, I will be using the Post Slider Module because it has a relatively simple ‘get_fields()’ method. As we will cover in future tuts, some of the modules are split in their design. A good example of this is the Contact Form module where you have a number of additional fields for email, message, etc… that can be added. Each of these are treated as an item that is added to the main ‘get_field()’ method. The Image module that we used in the last tut has some code for animation options at the beginning of its method, so I’ll start with a simple one.

In essence, this method is simply creating an array of comma-separated arrays. Each field is one element in the array. The first field in the Post Slider module sets the number of posts that should be shown. That option is defined by the first array in the ‘get_fields()’ method.

The first line is saying, “set the key ‘posts_number’ equal to the following array”. Remember, in PHP the equal sign followed by a greater-than sign is used to set “key”=>”value” pairs. Essentially setting the key property equal to a certain value. So in the above code, we are setting a total oof four “key”, “value” pairs. Looking at the ‘init()’ method proceeding it, we can see that ‘posts_number’ is one of the whitelisted_fields. The other thing that I will point out is that we don’t have to define our fields in the same order as they are listed in the whitelisted_fields. When designing from scratch, I like to put them in the same order so that I make sure I white_list everything for which I define a field and vice-versa. 

Almost every field is going to then have four properties defined within its array. First is the ‘label’ – this is what appears to the left of the input area in the picture above. The esc_html__() function in WordPress does two jobs. If you are using a different language, it retrieves the translation of the string from the provided domain, in this case, ‘et_builder’. Second, it escapes any HTML in the translation file making the output safe. 

Second is the ‘type’ – in this case we are asking the Divi builder to put a simple text input field to accept user input. Defined types (exhaustive, I think):

  1. ‘text’  Provides a simple input field – short input like a name or number
  2. ‘textarea’  Provides a simple input field – long input like a message
  3. ‘select’    Provides a drop down list of values for the user to select from
  4. ‘yes_no_button’  Provides a switch that can toggle between two values (doesn’t have to be yes and no)
  5. ‘color’  Provides a color picker without the option for opacity (rgb)
  6. ‘color-alpha’  Provides a color picker with opacity option (rgba)
  7. ‘upload’  Provides a link to the media library to select a file
  8.  ‘multiple_checkboxes’  Provides multiple checkboxes to allow for selection of more than one option (Used for display on phone/tablet/desktop)
  9. ‘range’  Provides a slider for the input of a number
  10. ‘hidden’  Provides an empty field that isn’t shown to the user
  11. ‘skip’ Provides an empty field like a ‘text’ type that is used for custom padding and margins
  12. ‘tiny_mce’  Provides a WYSIWYG editor for input – like in the Code module

I will go through the options for each of the different types in my next tutorial (might take several depending on detail!).

Third, is the ‘option_category’. This field typically has one of four different values that I have to admit I don’t fully understand the differences:

  1. ‘basic-option’  Seems to be used for fields that change the content of the output (like adding an image or author name)
  2. ‘configuration’  Seems to be used for that change how the content is displayed
  3. ‘layout’ Similiar to ‘configuration’, not sure of the difference
  4. ‘color_option’  Used in conjuction with the ‘select’ type, not with the ‘color-alpha’ or ‘color’ types

Note – as far as I can tell, the ‘color’ and ‘color-alpha’ types do not have an ‘option-category’ value.

Fourth is the ‘description’ property. This property provides a string that is displayed to the user below the input field to inform the user what type of input is expected (light gray in the picture above). Once again, this value is put through the ‘esc_html__()’ function to ensure that it is translated and safe to display.

So, those are the basic properties that are set for almost every field. Another basic property is the ‘tab_slug’. If undefined, our field will be presented on the first ‘General Settings’ tab. If it is set equal to ‘advanced’ it will be shown on the ‘Advanced Design Settings’ tab (the second tab). Finally, a value of ‘custom_css’ will cause display of the field on the third tab, ‘Custom CSS’.

So, I know this tut had a lot of information, but still leaves a lot out! In the next few tuts I will go through the additional properties that need to be set-up to give choices for the ‘select’, ‘multiple_checkboxes’, and ‘yes_no_button’ types.

As always, feel free to ask questions or point out errors in the comments or by email. I hope this series is proving useful. Only a few more informative tuts and we will begin the design of our first custom module!




Divine Initiation


Note: There has been updates to the Divi theme that make some changes to the code. This tutorial was written about pre-Divi 3.0.45, but having said that, ET was careful to update in such a way that old code still maps nicely. That means that these tutorials are still germane (at least as of May 13, 2017), but we will see what future updates bring! I will be writing new tutorials to introduces the new features of Divi soon!

This tutorial is the second in a series deconstructing the code that goes into the Divi theme with the goal of being able to write our own module at the end. The first in the series was an overview of the main parts of each module. This article will look specifically at the first method of each class, the ‘init()’ function. Fair warning to those of you who know a bit of php, this tutorial goes over a lot of basic items and maybe a bit slow and wordy! For those not familiar with php, we will be getting into the thick of it and this might require a re-reading later to get all the concepts. TL;DR, the ‘function init()’ method of the module sets up and partially pre-populates all of the field variables that will be needed for the other methods in the class.

First, a couple of notes on terminology. In php, a class is an object that holds both variables and functions. Using correct terminology, variables within the class are called ‘properties’ of the object and functions are called ‘methods’ of the object. I’m going to try to use the correct terms going forward, but wanted to introduce these terms without getting all nerdy in the first article and scaring people off! 

Once again, we will be walking through the standard width ‘Image’ module code, which is the first class in the Divi 3.0 main-modules.php file. This file is located in builder folder of the theme folder, Divi>>includes>>builder. Open it up to follow along (I switch between Atom, Brackets, and Sublime Text depending on whims and needs)! 

So starting off, prior to the ‘init()’ function we open up the class with the line: 

This says we want to instantiate a new class called ‘ET_Builder_Module_Image’. If we were making a custom module we could change this to anything we want. However, it can’t conflict with any existing class name, so it is good to prefix our class name. For example, I always prefix with SHD (Spring Hill Design) and then usually something plugin specific. So as a name for a custom image module for Divi I might use, ‘SHD_Divi_Module_Image_Extended’. Our name is followed up by ‘extends’ and ‘ET_Builder_Module;. This is a way that the core Divi builder class, ‘ET_Builder_Module’ can share properties (variables) and methods (functions()) with the individual modules and is called ‘inheritance’. Basically, this new ‘child’ class inherits everything within its ‘parent’ class. You don’t need to worry too much about this, just know that all of the Divi modules need to start this way.

Okay, next up in the code is the creation of the init() method.

As with all functions, you have the keyword ‘function’  followed by the name of the function and a set of parentheses. If data is being passed into the function, the variable name would be between those parentheses. Finally, all of the code of the function is sandwiched between open ‘{‘ and close ‘}’ braces.

Moving into the method we see a lot of use of ‘$this’. What is this? It can be a little confusing, but it is a reference to the current object. Remember, classes are objects, so $this here means the ‘ET_Builder_Module_Image’ class. So, you have to keep track of where you are in the code to know exactly what ‘$this’ means. Following each ‘$this’ is a dash and greater-than sign. In php this is called the “object operator”. It allows us to do a number of things, but in this case, it is allowing access to the properties (variables) of our new class. This operator is followed by the name of the property we want to access. So, the first line says we want to access the ‘name’ property of the ‘ET_Builder_Module_Image’ class and set it equal to esc_html__( ‘Image’, ‘et_builder’ ). I’m not going to cover the esc_html__() – it is a WordPress function that cleans up the text it is passed for storage and allows for translation into different languages. However, in this case, if we were building our own custom module we would change ‘Image’ out for the name we wanted to give our module, like ‘Best Module Ever’. Next down is the slug. Again, this is a WordPress term, but basically, gives a method for the Divi builder to retrieve these modules. Importantly, it must be prefixed with’et_pb_’, contain only lowercase alphanumeric characters, underscores, not have 2 or more dashes in a row, and not end in a hyphen. I keep mine short and simple, like ‘et_pb_image_custom’. Finally, in this module, there is a fb_support variable. This refers to whether this module can be modified on the front end by the visual builder. Until I learn a lot more react.js, this will remain at false on my custom modules! There are several other variables that can appear in other modules, but those are the basic three.

Shifting to the next section of code, we have an array property called whitelisted_fields. This variable gets assigned all of the various fields that will be presented to the user. In the next method, all of these fields will be retrieved and assigned values.  If we were making a custom module we would simply add the names of the new fields here. The field names cannot have spaces, but I haven’t experimented to determined if other characters are disallowed, but I would follow the same rules as for a slug. So for example, we could add ‘pop_up_image’ to hold the URL of an image we want to be displayed on click. Note, all of the variables being stored in the array have a comma separating them, even the last one. This is not needed, but perfectly valid.

Only two more sections to the init() method! This next section sets the ‘fields_defaults’ property equal to an array of the values we want initially set for the white_listed fields. Not all of the fields need to have values set. Basically, we set up an array where the key value is the name of the field, like ‘show_in_lightbox’ followed by the value that we want it to have stored as an array. In one of the next articles, we will go through the valid values for each type of field. Note, we are not using an equal sign to set the value of the field. We are using an equal sign followed by a greater-than sign. Don’t worry about why unless you are curious, just remember to assign values to keys within arrays using this operator. Like our simple array in the previous section, all of our items are separated by a comma and a non-needed trailing comma is added. 

The final section in the Image module init() method is assigning values to the ‘advanced_options’ variable. There is a number of potential key:value pairs to add in here that are dependent on the type of module and what fields it contains. Most of the properties that get set here are ones that get manipulate by the Divi builder behind the scenes. In the image module, there are two ‘advanced_options’ being set. The first is ‘border’. This allows the user to determine if a border is added to the image displayed on the browser. It originally starts as a yes/no box set to no. If the designer clicks it to ‘yes’ a whole host of additional possibilities slide-down. In a future article, we will go into how we toggle and collect those extra values for our own fields. However, if we look through the code of our class, we don’t see any mention in the white_listed fields for ‘border’. We have to depend on Divi to handle this and all we can do here is zero out the variable. In the case of the ‘custom_margin_padding’, there are some custom values already being added in as array values. First, ‘use_padding’ is set to false – this tells Divi not to add on any padding (duh!), but will get changed behind the scenes to ‘true’ as soon as a something is entered into one of the input boxes. Second, the property ‘css’ has an array assigned to it. This is a property that can be used to restyle elements that are being added and again, depends on what type of field/module is being used. In this case, the ‘css’ array is receiving the beloved ‘important’ key with a value of ‘all’. This means that all of the padding numbers being added in will receive an ‘!important’ modifier in the style sheet. We will delve into other key:value pairs in another article, but as another example: 

This chunk of code from the ‘Text’ module will grab the main class of the module that was defined earlier and add a line height to all of the <p> with that class and then set the color of the text with the main class pluss the ‘et_pb_text’ class (remember, classes get prepended with a period in CSS. The ‘advanced_options’ property is a little trial-and-error, I usually search through the other modules to see if there is something that looks like I need and copy it. Another major one is ‘fonts’, that brings up all of the customization of font size, color, line height…

Although we are at the end of the Image module ‘init()’ method. I want to touch briefly on two other key:value pairs that you run across in some of the other modules. In many modules you will see, as alluded to above, an assignment  to ‘main_css_element’. If defined it should use at least ‘%%order_class%%’ which the builder switches out for the main class of the correct selector that can be set in the next method of the class. Additional selectors can be tagged on such as the ‘.et_pb_text’ above. Another is ‘custom_css_options’. This is used when there are non-Divi handled CSS values to be set. A good example of this is located in the ‘Gallery’ module that you can seek out.

This is by no means a complete list of all the key:value pairs that are set in the various modules, but it should get you started in understanding the code a bit better. If you find examples you don’t understand, feel free to bring them up in the comments or drop me an email. As always any other questions or corrections are welcome!


You are Divine!


Note: There has been updates to the Divi theme that make some changes to the code. This tutorial was written about pre-Divi 3.0.45, but having said that, ET was careful to update in such a way that old code still maps nicely. That means that these tutorials are still germane (at least as of May 13, 2017), but we will see what future updates bring! I will be writing new tutorials to introduces the new features of Divi soon!

This is meant to be a quick intro to the structure of Divi Modules and mostly a discussion of the back-end builder (not the visual builder on the front-end). I intend for it to be the first in a series of articles discussing the programming behind the Divi theme. I need to start with the warning that all of this information is simply based on me deconstructing the fine work that the people at Elegant Themes (ET)(not an affiliate link) did in putting together the Divi theme. So, I could be completely and utterly wrong like eating gum and nuts at the same time.

The first step to modifying modules from ET to extend their functionality is simply understanding the module structure. All of the modules that are loaded into your builder screen for easy selection are located in Divi >> includes >> builder >> main-modules.php. Within this magic file, is a mix of php and HTML (actually technically still as php in sprintf(), but…) broken down into individual classes representing each different module with each class containing several repetitive functions.

So, if we open up the main-modules.php file as of early Divi 3.0, the first class we see is ‘ET_Builder_Module_Image’. Not surprisingly, this is the standard width Image module. The code for the fullwidth image module is located near the end of this file. All of the classes in this file begin with ‘ET_Builder_Module’, so you can usually find the module you are looking for by prepending this to the module name.   

The structure of each of these classes is fairly simple. The first set of functions register the module and are focused on setting up what data is collected and written into your WP SQL database during the building of the page. The last function is typically focused on actually retrieving the data and building the page that the user sees. 

Mostly, this is meant to be a big-picture overview of the modules, so I won’t break each function down completely, just introduce them. First up is the ‘init()’ function. This gives a name to this particular module and a way for the information about it to be retrieved. One note that we will come back to in the future when we start hacking these modules – your slug needs to have ‘et_pb_’ prepended for recognition by the page builder. Once the class is registered with Divi, the init function then registers all of the different fields it intends to collect from the user and store. These are listed in an array of ‘whitelisted_fields’. This can be expanded for your custom data. Next, if any of the fields have a default value, those values are entered into the array. Lastly, any advanced options are turned on, like fonts or background colors.

The next function that is typically called is ‘get_fields()’. This function defines how each of the white-listed fields is presented in the back-end. Basically, it sets up an array of stored values for each field that other functions within the Divi theme can interpret and present to the person building on the back-end.  This includes at least a label, a type of field, and a description. In a future article, we will go through the types of fields and where they are defined. In addition to these base fields, there can be some conditional logic to only show the field if there a checkbox is ticked and an option to show the field only on one of the tabs besides the main tab.

The final function, called ‘shortcode_callback()’ handles the presentation in the browser. Basically, when the server retrieves a shortcode that has a call to this particular class (‘ET_Builder_Module_Image’) it uses this section to output the correct HTML. At the beginning of this function, all of the stored values from the database are assigned to variables. Following this, there is a series of conditional logic tests to determine if a value is set and if so, to modify the styling. Finally, there is a whole set of ‘sprintf()‘ functions used to construct the actual HTML of the page. Basically, a sprintf() function is a way to easily add variables into some HTML output. We will explore this a little more in a future article when we dive deeper into looking at the shortcode_ callback function.

So TL;DR, the first portion of each module is typically the back-end the last part is the browser view (I wanted to say front-end, but that has other meanings!). I hope this helps to start people down the road to further customization of their own Divi theme! As usual, make a comment or drop me an e-mail with any questions or if you notice an error you want to be rectified.


Splitting the difference


***UPDATE: I didn’t realize earlier, but enqueueing the multiScroll.js library on non-split screens will break the scrolling capability of the page. I have updated how we enqueue the library to get around this.

This tut will look at how to use the multiScroll.js library in Divi. This library is used to create divided multi-scrolling pages where half of the screen will scroll one direction, and the other half the other. If this explanation is clear as mud, take a look at this demo I set up. Warning, I haven’t set up multiScroll to work with mobile (not sure it can), so this is desktop/tablet only for now.

In this tut we will briefly cover enqueuing the scripts, how to set up your Divi page, a few of the options that multiScroll employs, and finally, a little about data-anchors. I will not be exploring styling of your multiScroll pages. As you can see in my demo, I’m using a clunky menu at the top to hide the small parts of extra sections at the top. This kludge fails at narrower widths and a little bit of the other section shows through – the purple in the above screenshot. Each site is going to need a different amount of fiddling. Okay, enough with the caveats and onto the actual tut!

First up, head over to the multiScroll.js site and download the library. Inside the zip archive you will find a number of files. We will be utilizing three of them for this tutorial – jquery.multiscroll.min.js, jquery.multiscroll.css, and within the “vendors” folder, jquery.easings.min.js. I’m a big proponent of using child themes and as few “crutches” as possible, so I’m going to use these files in a Divi-independent manner. So, I’m going to upload these three files to my hosting account by FTP. Within my child theme folder I made two folders – one for the javascript and one for the styling. Next, open up your functions.php file with your favorite editor.

Next, open up your functions.php file with your favorite editor. We will add in a new function that loads up our library, plus an additional file we will create next. ****UPDATE to code

Let’s walk through this. On the first line, we set up the name of the function, ‘addMultiscroll’. All of the code in this function will then be wrapped inside a conditional statement. This is because (as I learned the hard way) if you load the multiscroll onto a page, it will prevent normal scrolling. To only load multiscroll on a specific WordPress page we are using the ‘is_page()’ WordPress function. In this case, I’m passing it the page slug, which is the portion of the URL at the very end of the page location. You might have to publish your page in order to determine your slug.
Next, we use a WordPress function called ‘wp_enqueue_script()’. This tells WordPress that when a page gets loaded, this script should also be loaded. Within this function call, we first give the particular script a unique name – in the case of the first one, ‘multiscroll-library’. It is important that these are unique! Next, we identify what we want to load, in this case, we first get the location of our child theme stylesheet using the ‘get_stylesheet_directory_uri()’ function. This will return the path to where we uploaded the files by FTP. We then use the ‘.’ to concatenate the rest of the pathway and the file name. Remember we stored the main library in the ‘js’ folder, so we add ‘/js/jquery.multiscroll.min.js’. The next item passed to this function is dependencies – in this case, we can’t use the multiScroll library without jQuery being loaded. Following that, we turn off any versioning using ‘null’. This is actually optional and we could leave it off in this case. Finally, we can elect to have WordPress load this script in the header or the footer. I’m electing to load these scripts into the header, so I’m passing a value of ‘false’.  

Next, we use a WordPress function called ‘wp_enqueue_script()’. This tells WordPress that when a page gets loaded, this script should also be loaded. Within this function call, we first give the particular script a unique name – in the case of the first one, ‘multiscroll-library’. It is important that these are unique! Next, we identify what we want to load, in this case, we first get the location of our child theme stylesheet using the ‘get_stylesheet_directory_uri()’ function. This will return the path to where we uploaded the files by FTP. We then use the ‘.’ to concatenate the rest of the pathway and the file name. Remember we stored the main library in the ‘js’ folder, so we add ‘/js/jquery.multiscroll.min.js’. The next item passed to this function is dependencies – in this case, we can’t use the multiScroll library without jQuery being loaded. Following that, we turn off any versioning using ‘null’. This is actually optional and we could leave it off in this case. Finally, we can elect to have WordPress load this script in the header or the footer. I’m electing to load these scripts into the header, so I’m passing a value of ‘false’.  

We use this same function to load the other javascript files we need (including a file named ‘SHD-multiscroll.js’, which we will create later in the tutorial. To enqueue the stylesheet we use a similar function called ‘wp_enqueue_style()’. This should be pretty self-explanatory. Lastly, we fire the whole function using ‘add_action()’. Here we are giving the action ‘wp_enqueue_scripts’ – notice it is plural, not singular like within our function. 

Moving on, we will look at the stucture of the Divi page. We will set up three sections that alternate text and pictures. This is replicating the structure they have in the multiScroll.js documentation. There is an outer wrapper with the ID ‘multiscroll’. This is then followed by two <div> containing the left and right panels, with classes ‘ms-left’ and ‘ms-right’, respectively. Finally, each of the panels have a class of ‘ms-section’. When we initiate the multiScroll function we can pass in other classes and IDs, but we will stick with these for now.

On my Divi page I added a standard section and two full-width rows. To each of these rows I added three modules. So the first module of each row will take up half the screen and be placed across from one another by multiscroll. I elected to start with a text module on the left and an image module on the right. Then I alternated for each of the next sets. To replicate the HTML above, first open the section settings (three lines on the left side of the large blue box) and navigate to the ‘Custom CSS’ tab. Add ‘multiscroll’ (without the quotes) to the ‘CSS ID’ box at the top. Save and exit, the open up the row settings of the top row (three lines on the left of the teal-colored boxes). Navigate to the ‘Custom CSS’ tab once again and add ‘ms-left’ to the ‘Column CSS Class’. In the same manner, add ‘ms-right’ to the bottom row. Finally, for each of the modules, navigate to the ‘Custom CSS’ tab and add ‘ms-section’ (no quotes) to the ‘CSS Class:’ box. Great, now we have replicated the HTML structure we need. Last thing to do on the Divi page to replicate the demo is add in our sections menu.

I have elected to do this with a code module. Put in a fullwidth section and add in a code module. Into that code module you can put the markup for your menu.

So, our menu is a simple unordered list<ul> with the ID of ‘splitMenu’. We will need this ID for initiating scrollMagic. There is a list item <li> for each of the three sections with a link targeting their eventual ID that can be used for bookmarking, as well as another attribute called ‘data-menuanchor’. The data attribute was introduced in HTML5. This allows for the storage of little snippets of data associated with a particular DOM element. In this case, we are using it to store the location that menu item is supposed to scroll to on the page. This can be used for complex page operations where unique IDs can’t neccessarily be addded to each element. I’m not going to go through all of the styling here except to say that I gave it a solid background color and height to mask the tops of each section where they don’t align. If I have time I might go back and find a different way of doing this!

As the last step, we need to write a function to actually initiate scrollMagic on our page. Again, we are doing this by creating a stand-alone file that we upload into the js folder we made in our theme folder. My file is named ‘SHD-multiscroll.js’, but you can name it whatever you want, just make sure to use the correct name in your functions.php file. 

Walking through the code. First up we tell jQuery not to run the function until the widow (images, text, other scripts) is fully loaded. This is important because we want to make sure that the elements we are targeting exists. Next we add the multiscroll() function to the outer wrapper of our HTML that has an ID of ‘multiscroll’ – the ID we gave the section on our Divi Page earlier. Remember, with jQuery we target IDs by adding a ‘#’ in front of them. Everything following this is a list of scrollMagic options and I’ll point out a few. The option ‘menu:’ allows use to link the scrolling to the menu we made earlier. We target it be providing its ID, ‘#splitMenu’. Along with that option, we need to pass in a list of the data-menu anchors. In order to make styling easy, I passed in different background colors for each of the sections using the ‘sectionsColor’ option. Dropping down to the bottom I am passing in the names of the left and right panels wrappers, ‘ms-left’ and ‘ms-right’, plus the name of each panel, ‘ms-section’. Rememeber that we added these to our divi page as classes and jQuery targets a class by pre-pending a period, so ‘.class-name’. And we are done! You should have a split scroller that you can add content to in order to make it your own. Adding new sections is as simple as adding another list item to the menu markup and adding in pairs of panels.

Good Luck!! Feel free to ask questions in the comments or by e-mail. I can give some help if you have trouble with getting the styling just right or explaining some of the other multiScroll.js options.


Starry, Starry Night


This tutorial is somewhat specialized. Over on Facebook, someone asked how to implement a specific Codepen in Divi. The overall tutorial is pretty specific to this Codepen, but is useful if you want to learn a little jQuery and more about the power of keyframes, so let’s get started!  

So, here is a link to the original Codepen. Basically, it displays stars scrolling up the page in the background. Here is a link to what we will be building in Divi. Starting with the Codepen page, we have two different panels to replicate. The first is the HTML for displaying everything. Looks a little strange, doesn’t it?!? None of the usual <div> or <span>. That is because we are in a notational form of HTML called Haml – notice at the top next to HTML? In this case, ‘#stars’ is shorthand for, ‘<div id=”stars”></div>’, pretty neat! Okay, to move this over to Divi we need to translate part of it. We won’t be taking

Okay, to move this over to Divi we need to translate part of it. We won’t be taking the title, so it is just the first three <div> that we need, so I think we will just re-type it in Divi (plus I want to change it). If you are translating another Codepen with more substantial HTML written in Haml, click the down caret to the right of the HTML header and then select ‘View compiled HTML’ from the dropdown menu. You can then copy and paste over to Divi.

So moving over to Divi, we will make a new post or page and add a standard width code module. Opening it up we will add in the following:

So, we are recreating those three divs from the Codepen, but giving them class names rather than IDs. This is because in certain circumstances we need to re-use this code and it isn’t a good idea to re-use IDs.

Okay, now moving on to the CSS. This part is a little more daunting.  Once again, things might not look like you expect for your normal CSS. In this case, it is because two powerful, pre-processors are being used. The first is called Sass, and the second is Compass, which is a Sass framework add-on. As with the HTML, we can click the down caret to the right and view the compiled CSS, but what is this actually saying. On line 5 we are defining a function called ‘multiple-box-shadow’  that accepts one variable, ‘$n’. This function then generates a random X, Y pixel location ranging from 1-2000 in a loop that is essentially re-iterated $n times (actually $n-1 since it starts at 2) and assigns it a color of ‘#FFF’ (white). After this function, three additional variables are defined: ‘$shadows-small’, ‘$shadows-medium’, and ‘$shadows-big’. In each case, the function is called but a different number is passed in for ‘$n’. In the case of ‘$shadows-small’, a value of 700 is passed in. This tells our function to generate 700 locations in a grid that is 2000px by 2000px. For  ‘$shadows-medium’, only 200, and 100 for ‘$shadows-big’.  Okay, what is now done with those variables. Let’s drop down and look at the CSS for the first ID, ‘#stars’.

We can see that the variable is being used in two places. In the CSS for the main <div> and in the CSS for the :after pseudo-element. In both cases they are being attached to the box-shadow style. This means that once comiled, the list of 700 different pixel locations will be used to generate 700 box-shadows with just a few lines of CSS! One other important bit of CSS to look at here, and that is the ‘animation:’. If you went through some of my previous tutorials, you know that this states that we want to alter the contents of the #stars <div> by the keyframes named ‘animstar’. Further, we want those frames of animation to happen over 50 seconds, we want them to occur in a linear fashion, and to loop forever. There is more CSS to pull apart here, but I’ll leave that for another time. Let’s get implementing this in Divi!

As I said above, we will be using classes instead of IDs for each of the star fields, so go through the uncompiled CSS and change the ‘#’ into a period – there should be three instances. Clicking on the ‘View Compiled CSS’ drop-down item generates a huuuge list of CSS.  Copy it all. We will be editing out the styling for the title, but we need the keyframes at the end. This CSS should now be pasted into your child style sheet. This is a large amount of CSS – it could be put into a code block, or into a number of other areas of the Divi theme, but I can’t really recommend this. For testing purposes I put it into a code block and it REALLY slowed loading time.

Go into the CSS and comment out the HTML portion, we will have to edit this after we get the page ID. Scroll down to the bottom and delete the ‘#title’ and ‘#title span’ sections. Back on your Divi page, add in whatever element you want on the page. In my case, I added in a fullwidth header and a set of blurb boxes. At this point if you preview your page you will see a white background without stars. We need to get rid of the background on the page. In order to accomplish this, we will need to use a bit of jQuery. Add in another code module at the very top of your page and enter in the following code: 

What does this do? On the second line it tells jQuery to wait until the DOM has loaded before firing our instruction – plus it adds in support for using a ‘$’ instead of typing out jQuery. On the next line we tell jQuery to select the ‘article’ element of the DOM. This is basically everything on the page within the ‘#main-content’ <div>. Then the styling of the background of the section is set to ‘#000’ (black) using the css() function. Remember, all of our ‘stars’ are white pixels, so they need a black background to show up. At this point, if we preview the page we might see some areas of stars and some that are still white. This is because Divi “loves” to set section background colors to white. To address this we will use a little more CSS.

To make sure we are only impacting this page, we will publish the page and then use our inspect tool to get the article ID. This ID is located on the page just after the ‘#main-content’ <div> within the ‘#page-container’ (highlighted in blue). In this case it is ‘post-1068’. In our CSS we will not target all of the sections on this page and give them a background-color of transparent. 

So we are using the ‘#post-1068’ to target just this page, then all <div> with the class ‘et_pb_section’ that are children of the <div> with the class ‘entry-content’. Basically, ‘entry-content’ is the top <div> on the page, so any section added to the page will be targeted by this selector.

Almost done. We have to add just a touch more styling. Again, we will use the article ID to make it specific for the page.

The first styling prevents the star fields from extending beyond the bottom of the page. The second is more specific to my page – if I don’t add this I can see the stars though my footer. You will likely have to play with this styling, as well as the styling of your header to make everything look good. You will also have to add in styling to remove certian margind and padding throughout as appropriate. Unfortunately, this depends on how your pages are set-up and it isn’t generic.

Finally, I mentioned above that I changed the star fields from using IDs to using classes. This is because if you have a long page you will need to add an extra code block (or two) with the divs further down your page as the star fields run out after 4000 pixels. Add in as many as you need throughout your page.

That is it! A lot of steps, but a neat effect. If you need more styling help, reach out by comment, e-mail or Facebook. I’ll likely need a link to the page to help. Hope this hels people to implement not only this Codepen, but the multitude of other cool ones that are out there!