Add a Custom Icon Set to Divi

|

Divi comes with a built-in set of icons, which are available in the icon picker found in many modules such as the blurb module and icon module. However, it doesn't include an option to upload your own icons. If you have an existing icon set you'd like to add to Divi's module icon picker, here's how to:

Add a Custom Icon Set using WP and Divi Icons Pro

If you've generated your icon set in Fontello or Icomoon (or are able to upload it to one of these services), then you can add it to Divi using WP and Divi Icons Pro. To do so, upload the font zip file generated with Fontello and/or Icomoon into the plugin and your new icons will then appear alongside the preinstalled ones. Note that the custom icon upload feature is not available in the free version.

Add a Custom Icon Set using Divi Booster

Divi Booster includes the option to upload individual images (svg, png, etc) to Divi for use as icons in the module settings icon picker. you can use this to upload an icon set like so:

1) If you haven't already, convert your icon set to individual image files, one per icon. Online tools such as Iconly may help with the conversion.

2) Install and activate Divi Booster, if you haven't already

3) Navigate to the Divi Booster settings page at: WP Dashboard > Divi > Divi Booster

4) Navigate to the "Site-wide Settings > Icons > Add custom icons for use in modules" option

5) Upload your icons one at a time in the option:

6) Save the Divi Booster settings.

Now, you should see your icons in the icon selection box within your modules, like so:

Add a Custom Icon Set using PHP Code

If you want to upload an icon set to Divi without a plugin, or in a form that you can package up and share, you can do it with some PHP code, as follows:

1) Upload your icon font set to a web accessible location such as a folder within your WordPress installation, using SFTP or your web host's file manager functionality. In this example, I'll use this Christmas icon set from FlatIcon and install its .ttf, .woff and .eot files into a folder I've created at:

/wp-content/icons/myiconset/

2) The next thing we need to do is add a filter to Divi that will let us add our icons to Divi's predefined icon list. Unfortunately, Divi doesn't provide such a filter and so we need to use a bit of a hacky method – overriding the relevant function in Divi. Here's the PHP code to do this: 

// === Add filter to Divi's icon list ===
// - The function isn't filterable, so need to replace it
// - Using the same filter name as Divi Booster does for compatibility

if (!function_exists('et_pb_get_extended_font_icon_symbols')) {
    // Override the built-in Divi function to support filtering
    // Changes: 
    // * Added filter
    // * Changed $full_icons_list_path
    // * Added function exist checks
    function et_pb_get_extended_font_icon_symbols() {
        $cache_key = 'et_pb_get_extended_font_icon_symbols';
        if (!et_core_cache_has($cache_key)) {
            $full_icons_list_path = dbc_divi_font_icons_path();
            if (file_exists($full_icons_list_path)) {
                // phpcs:disable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Can't use wp_remote_get() for local file
                $icons_data = json_decode(file_get_contents($full_icons_list_path), true);
                // phpcs:enable
                if (JSON_ERROR_NONE === json_last_error()) {
                    $icons_data = apply_filters('dbdb_get_extended_font_icon_symbols', $icons_data);
                    et_core_cache_set($cache_key, $icons_data);
                    return $icons_data;
                }
            }
            et_wrong('Problem with loading the icon data on this path: ' . $full_icons_list_path);
        } else {
            return et_core_cache_get($cache_key);
        }
    }
}

function dbc_divi_font_icons_path() {
    $plugin_active = (defined('ET_BUILDER_PLUGIN_ACTIVE') && ET_BUILDER_PLUGIN_ACTIVE);
    if ($plugin_active) {
        if (defined('WP_PLUGIN_DIR')) {
            return WP_PLUGIN_DIR . '/divi-builder/includes/builder/feature/icon-manager/full_icons_list.json';
        }
    } else {
        if (function_exists('get_template_directory')) {
            return get_template_directory() . '/includes/builder/feature/icon-manager/full_icons_list.json';
        }
    }
    return false;
}

You shouldn't need to change any of this. This works (for now at least), but the downside is that it may require updated if Divi changes this function in the future. Hopefully a suitable filter will be added in the future which will allow us to avoid overriding existing Divi functions.

3) Now, using this filter, we can use the PHP code below to loop through our individual icons adding them to Divi's icon list:

// === Register the new icons ===

add_filter('dbdb_get_extended_font_icon_symbols', 'dbc_add_to_extended_fonts', 10, 1);

function dbc_add_to_extended_fonts($icons) {

    if (!is_array($icons)) {
        return $icons;
    }

    $new_icons = apply_filters('myiconset_icon_details', array());
    foreach ($new_icons as $key => $new_icon) {
        $new_icons[$key]['styles'] = array('line', 'myiconset');
        $new_icons[$key]['is_divi_icon'] = true;
        $new_icons[$key]['font_weight'] = 400;
        $new_icons[$key]['unicode'] = '&#x' . str_replace('\\', '', $new_icon['unicode']) . ';';
        $new_icons[$key]['search_terms'] .= 'myiconset ' . $new_icon['search_terms'];
    }
    $icons = array_merge($icons, $new_icons);
    return $icons;
}

Rather than define all our icons in this function, we add a second filter called "myiconset_icon_details" which we'll use to add our icons shortly. The code above also adds some default values for the icons. Most of this you can ignore, but you may want to change the value in the "search_terms" key – currently it is set up so that if the user searches for "myiconset" in the icon picker search box then all the icons in our icon set will be returned. 

4) Now we'll add some PHP code to enqueue our icon set:

// === Add our icon font as a fallback font for Divi's icons ===

add_action('wp_head', 'dbc_add_custom_icon_css');

function dbc_add_custom_icon_css() {
	
    $font_path = site_url('wp-content/icons/myiconset/Flaticon'); // Path and icon file name without extension

?>
    <style>
        @font-face {
            font-family: "myiconset";
            src: url("<?php esc_html_e($font_path); ?>.eot");
            src: url("<?php esc_html_e($font_path); ?>.eot?#iefix") format("embedded-opentype"),
                url("<?php esc_html_e($font_path); ?>.woff") format("woff"),
                url("<?php esc_html_e($font_path); ?>.ttf") format("truetype");
            font-weight: normal;
            font-style: normal;
            unicode-range: U+F101-F132;
        }

        .et-pb-icon,
        body .et_pb_module .et-pb-icon,
        body .et_pb_module .et_pb_icon_wrap .et-pb-icon,
        body #page-container .et_pb_section a.et_pb_button:after,
        body #page-container .et_pb_section a.et_pb_button:before,
        .et_pb_module span.et_overlay:before,
        .et-db #et-boc .et-l #et-fb-icon_picker.et-fb-font-icon-list li[data-icon-type="divi"]:after,
        .et-db #et-boc .et-l #et-fb-exp_icon_picker.et-fb-font-icon-list li[data-icon-type="divi"]:after {
            font-family: <?php echo apply_filters('divibooster_etmodules', "'ETModules', 'myiconset'"); ?> !important;
        }
    </style>
<?php
}

What's happening here is that we're loading our new icon set and calling it "myiconset" using the @font-face declaration. Then we're applying it as a fallback font to Divi's own icon font "ETModules", wherever necessary. To make this work, we need to ensure that our icon font set spans a unicode range that isn't assigned by Divi's own icon font. Fortunately, the icon set I'm using from FlatIcon uses unicode characters in the range \f101 to \f132, which isn't used by Divi. That means when the browser tries to render an icon in this range it will first try the Divi icon set and not find a suitable icon, so it will then try our icon and find and display an assigned icon. To make this work, you'll need to add the correct unicode range for your icons in the CSS above. I haven't encountered a situation where the range I've tried to use conflicts with Divi's own icon range, but if you find that happening to you let me know and I'll look into it.

5) Now let's declare the details of each individual icon:

// === Declare the individual icons ===

add_filter('myiconset_icon_details', 'dbc_add_icon_details');

function dbc_add_icon_details($icons) {

    if (!is_array($icons)) {
        return $icons;
    }

    $new_icons = array(
        array(
            "search_terms" => "bell bow",
            "unicode" => '\f101',
            "name" => "Bell with Bow"
        ),
        array(
            "search_terms" => "candle",
            "unicode" => '\f102',
            "name" => "Candle"
        ),
        array(
            "search_terms" => "candy",
            "unicode" => '\f103',
            "name" => "Candy"
        ),

        // ... entries removed for brevity ...

        array(
            "search_terms" => "wine glasses",
            "unicode" => '\f131',
            "name" => "Wine Glasses"
        ),
        array(
            "search_terms" => "angel",
            "unicode" => '\f132',
            "name" => "Angel"
        ),
    );
    return array_merge($icons, $new_icons);
}

Here, as you can see, we add an entry for each icon, specifying its name, Unicode value and search terms that can be used to find it in the icon picker. Note that in the return statement we're returning the original icons then the new icons. This means our new icons will appear at the end of the icon list. You can reverse this if you'd prefer the new icons to appear first in the icon picker list.

6) At this point, if everything is working, your icons should now show in the icon picker within Divi modules. Since our icons are at the end of the list, the easiest way to find them is to enter the default search term we included above "myiconset". Like so: 

7) You can stop at this point if you like. But one thing I like to add is an entry for the new icons in the "+Filter" dropdown in the icon picker bar. To do this, add the following PHP code:

// === Add filter to the icon picker ===

add_filter('et_fb_backend_helpers', __NAMESPACE__ . '\\add_to_et_fb_backend_helpers', 10, 1);

function add_to_et_fb_backend_helpers($helpers) {
    if (!array($helpers)) {
        return $helpers;
    }
    if (!isset($helpers['searchFilterIconItems'])) {
        $helpers['searchFilterIconItems'] = array();
    }
    if (!isset($helpers['searchFilterIconItems']['show_only'])) {
        $helpers['searchFilterIconItems']['show_only'] = array();
    }
    $helpers['searchFilterIconItems']['show_only']['myiconset'] = 'My Icons';

    return $helpers;
}

This adds an entry in the filter menu called 'My Icon Set' which shows any icon registered as having one of its styles set to "myiconset" (which we did when we set the icon defaults earlier). This lets you filter on just those icons in your set. Here's the result:

This post may contain referral links which may earn a commission for this site

Divi Booster

Hundreds of new features for Divi
in one easy-to-use plugin

0 Comments

Submit a Comment

Comments are manually moderated and approved at the time they are answered. A preview is shown while pending but may disappear if your are cookies cleared - don't worry though, the comment is still in the queue.

Your email address will not be published. Required fields are marked *.