How to create custom Divi module?

How can I add a custom module for Divi WordPress theme?
http://www.elegantthemes.com/gallery/divi/

Original modules are created in main-modules.php

Read More

Example:

class ET_Builder_Module_Gallery extends ET_Builder_Module { .... }

But the ET_Builder_Module class is not accessible in my plugin, or in theme functions.php

Related posts

7 comments

  1. Most other solutions here are way too complex. The simplest way is to load your custom module in the divi specific action hook et_builder_ready, like this:

    add_action( 'et_builder_ready', 'evr_initialize_divi_modules' );
    
    function evr_initialize_divi_modules() {
        if ( ! class_exists( 'ET_Builder_Module' ) ) { return; }
    
        class EVR_Builder_Module_Testimonial extends ET_Builder_Module {
            function init() {
                $this->name       = esc_html__( 'Testimonial', 'evr' );
                $this->slug       = 'evr_pb_testimonial';
                $this->fb_support = true;
    
                // ...
    
            }
        }
    }
    

    You can find the full demo-code on github. Along with some instructions how to get it work in the all new Divi 3 frontend builder:

    https://github.com/stracker-phil/divi3-vb-custom-modules/

  2. Place below in your functions.php file. The include file (I called it custom-modules.php) will be a class that extends ET_Builder_Module (which is very similar to WP_Widget). Just open the file from Divi>>includes>>builder>>main-modules.php. Use any of the preexisting modules as an example or basis for your new one. Copy and paste into your custom-modules.php. New class names, make edits as needed, etc.

    function doCustomModules(){
     if(class_exists("ET_Builder_Module")){
        include("custom-modules.php");
     }
    }
    
    function prepareCustomModule(){
     global $pagenow;
    
     $is_admin = is_admin();
     $action_hook = $is_admin ? 'wp_loaded' : 'wp';
     $required_admin_pages = array( 'edit.php', 'post.php', 'post-new.php', 'admin.php', 'customize.php', 'edit-tags.php', 'admin-ajax.php', 'export.php' ); // list of admin pages where we need to load builder files
     $specific_filter_pages = array( 'edit.php', 'admin.php', 'edit-tags.php' ); // list of admin pages where we need more specific filtering
     $is_edit_library_page = 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && 'et_pb_layout' === $_GET['post_type'];
        $is_role_editor_page = 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'et_divi_role_editor' === $_GET['page'];
        $is_import_page = 'admin.php' === $pagenow && isset( $_GET['import'] ) && 'wordpress' === $_GET['import']; // Page Builder files should be loaded on import page as well to register the et_pb_layout post type properly
        $is_edit_layout_category_page = 'edit-tags.php' === $pagenow && isset( $_GET['taxonomy'] ) && 'layout_category' === $_GET['taxonomy'];
    
     if ( ! $is_admin || ( $is_admin && in_array( $pagenow, $required_admin_pages ) && ( ! in_array( $pagenow, $specific_filter_pages ) || $is_edit_library_page || $is_role_editor_page || $is_edit_layout_category_page || $is_import_page ) ) ) {
        add_action($action_hook, 'doCustomModules', 9789);
     }
    }
    $theme_data = wp_get_theme();
    $parent_data = $theme_data->parent();
    if(version_compare((string)$parent_data->Version, "2.5.9", ">")) {
        add_action('et_builder_ready', 'doCustomModules');
    } else {
        doCustomModule();
    }
    
  3. Important note: The slug for your custom module must contain the string et_pb_, or it will be filtered out by the function et_pb_allowed_modules_list().

    I was able to add a new Divi module using the following code (requires PHP 5.3+ for the anonymous function):

    add_action(is_admin() ? 'wp_loaded' : 'wp', function() {
      require __DIR__ . '/custom-divi-module.php';
    }, 20);
    

    Inside the included file, copy and paste a class from the wp-content/themes/Divi/includes/builder/main-modules.php file, then modify to suit your needs. See the example below (copy an actual class from the file mentioned to get the content of each method listed below… I like the ET_Builder_Module_Code class for simplicity’s sake):

    class YOUR_MODULE_NAME extends ET_Builder_Module {
      function init() {
        // Name, slug, and some other settings for the module go here
      }
    
      function get_fields() {
        // This method returns an array of fields that the module will
        // display as the module settings
      }
    
      function shortcode_callback($atts, $content = null, $function_name) {
        // This method returns the content the module will display
      }
    }
    new YOUR_MODULE_NAME;
    
  4. The code above didn’t work
    The function needs to be called as well.

    Here’s an example with working code from https://divi.space/blog/adding-custom-modules-to-divi/

    function DS_Custom_Modules(){
     if(class_exists("ET_Builder_Module")){
     include("ds-custom-modules.php");
     }
    }
    
    function Prep_DS_Custom_Modules(){
     global $pagenow;
    
    $is_admin = is_admin();
     $action_hook = $is_admin ? 'wp_loaded' : 'wp';
     $required_admin_pages = array( 'edit.php', 'post.php', 'post-new.php', 'admin.php', 'customize.php', 'edit-tags.php', 'admin-ajax.php', 'export.php' ); // list of admin pages where we need to load builder files
     $specific_filter_pages = array( 'edit.php', 'admin.php', 'edit-tags.php' );
     $is_edit_library_page = 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && 'et_pb_layout' === $_GET['post_type'];
     $is_role_editor_page = 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'et_divi_role_editor' === $_GET['page'];
     $is_import_page = 'admin.php' === $pagenow && isset( $_GET['import'] ) && 'wordpress' === $_GET['import']; 
     $is_edit_layout_category_page = 'edit-tags.php' === $pagenow && isset( $_GET['taxonomy'] ) && 'layout_category' === $_GET['taxonomy'];
    
    if ( ! $is_admin || ( $is_admin && in_array( $pagenow, $required_admin_pages ) && ( ! in_array( $pagenow, $specific_filter_pages ) || $is_edit_library_page || $is_role_editor_page || $is_edit_layout_category_page || $is_import_page ) ) ) {
     add_action($action_hook, 'DS_Custom_Modules', 9789);
     }
    }
    Prep_DS_Custom_Modules();
    
  5. I want to try settling the little debate here.
    class ET_Builder_Module_Custom_Module extends ET_Builder_Module {} actually works and main-modules.php can be modified freely IF a Child Theme is used.
    I recently ajaxified a Divi Theme and after update everything worked like a charm.

    Note: It’s always a good idea to check if there are updates on the files you use inside the child theme because sometimes you may need to update the child files also.

    I hope this helped all future readers of this post.

    HFGL with the new modules you are about to create 😉

  6. You can do it modifying the Divi theme files (which is bad)

    For example, you can modify main-modules.php to add a new module:

    class ET_Builder_Module_Custom_Module extends ET_Builder_Module {
        function init() {
            $this->name = __( 'My Module', 'et_builder' );
            $this->slug = 'et_pb_custom_module';
    

    After that you need to add the panel for the customizer in functions.php:

    /* Section: Custom Module */
    $wp_customize->add_section( 'et_pagebuilder_custom_module', array(
        'priority'       => 220,
        'capability'     => 'edit_theme_options',
        'title'          => __( 'My Module', 'Divi' ),
        // 'description'    => '',
    ) );
    

    If you do a search in functions.php you’ll find where to add it easily 😉

Comments are closed.