Divine the future!
Namaste!
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:
$module_id = $this->shortcode_atts['module_id'];
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()’.
$module_class = ET_Builder_Element::add_module_order_class( $module_class, $function_name );
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()’.
‘et_pb_generate_responsive_css’
if ( '' !== $max_width_tablet || '' !== $max_width_phone || '' !== $max_width ) { $max_width_values = array( 'desktop' => $max_width, 'tablet' => $max_width_tablet, 'phone' => $max_width_phone, ); et_pb_generate_responsive_css( $max_width_values, '%%order_class%%', 'max-width', $function_name ); }
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:
et_pb_generate_responsive_css( $padding_values, '%%order_class%% .et_pb_slide_description, .et_pb_slider_fullwidth_off%%order_class%% .et_pb_slide_description', 'padding-top', $function_name );
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.
$additional_css = 'center' === $text_orientation ? '; margin: 0 auto;' : '';
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.
‘set_style()’
if ( 'on' === $force_fullwidth ) { ET_Builder_Element::set_style( $function_name, array( 'selector' => '%%order_class%% img', 'declaration' => 'width: 100%;', ) ); }
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.
‘sprintf()’
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:
$output = sprintf( '<img src="%1$s" alt="%2$s"%3$s /> %4$s', esc_url( $src ), esc_attr( $alt ), ( '' !== $title_text ? sprintf( ' title="%1$s"', esc_attr( $title_text ) ) : '' ), 'on' === $is_overlay_applied ? $overlay_output : '' );
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.
Metta!