Open dtcblyth opened 1 year ago
Reporter
Scope(s) :: One Sentence To Describe The Issue
VB :: Floating Toolbar :: Jumps To Top Of Page
Developer
Peer Review
Quality Assurance
Design Review
Dev Review
Bonus Request:
The current implementation of et_pb_all_fields_unprocessed_{$slug}
requires us to manually loop through all possible parent and child module slugs, setting up a filter for each. Although this is kind of laborious, it is at least possible to do for built-in modules because we know what they are. However, for third-party modules we have no way to know which third-party modules a customer will use.
Currently, we get around this by providing the user with an admin option (ie. textarea field) which allows them to manually enter slugs for additional third-party modules they wish to register with our extension.
It would be great if the D5 implementation could automatically process all registered and internal and third-party modules.
@dtcblyth did you find any solution?
No... as far as I know this has not yet been implemented in Divi 5.
Please find below a minimal code example of how I use the et_builder_get_parent_modules()
, et_builder_get_child_modules()
, et_pb_all_fields_unprocessed_{$slug}()
, and et_module_shortcode_output()
filter in my extensions. I am using this structure in four of my D4 extensions, and without this functionality these extensions cannot be replicated in D5.
Note: This code was originally partly based on this D4 code example: https://github.com/elegantthemes/create-divi-extension/issues/462
Note: It may be possible to replicate the et_module_shortcode_output()
filter functionality using the Wordpress render_block()
filter.
<?php
class My_Class {
/**
* Module slugs.
*
* @var array
*/
private static $included_modules = array();
/**
* Module toggle flags.
*
* @var boolean
*/
private static $parent_toggles_added = false;
private static $child_toggles_added = false;
/**
* Constructor.
*
* @return void
*/
public function __construct() {
// Prepare module slugs.
self::prepare_included_modules();
// Add toggles to modules.
add_filter('et_builder_get_parent_modules', array(__CLASS__, 'add_parent_module_toggle'));
add_filter('et_builder_get_child_modules', array(__CLASS__, 'add_child_module_toggle'));
// Add fields to modules.
foreach (self::$included_modules as $slug) {
add_filter("et_pb_all_fields_unprocessed_{$slug}", array(__CLASS__, 'add_module_fields'));
}
// Filter shortcode output.
add_filter('et_module_shortcode_output', array(__CLASS__, 'shortcode_output'), 10, 3);
}
/**
* Prepares an array of included module slugs.
*
* @return void
*/
private static function prepare_included_modules() {
// Parent modules.
$slugs = 'et_pb_section, et_pb_row, et_pb_row_inner, et_pb_accordion, et_pb_audio, et_pb_counters, et_pb_blog, et_pb_blurb, et_pb_button, et_pb_circle_counter, et_pb_code, et_pb_comments, et_pb_contact_form, et_pb_countdown_timer, et_pb_cta, et_pb_divider, et_pb_filterable_portfolio, et_pb_fullwidth_code, et_pb_fullwidth_header, et_pb_fullwidth_image, et_pb_fullwidth_map, et_pb_fullwidth_menu, et_pb_fullwidth_portfolio, et_pb_fullwidth_post_content, et_pb_fullwidth_post_slider, et_pb_fullwidth_post_title, et_pb_fullwidth_slider, et_pb_gallery, et_pb_icon, et_pb_image, et_pb_login, et_pb_map, et_pb_menu, et_pb_number_counter, et_pb_portfolio, et_pb_post_content, et_pb_post_slider, et_pb_post_title, et_pb_post_nav, et_pb_pricing_tables, et_pb_search, et_pb_sidebar, et_pb_signup, et_pb_slider, et_pb_social_media_follow, et_pb_tabs, et_pb_team_member, et_pb_testimonial, et_pb_text, et_pb_toggle, et_pb_video, et_pb_video_slider,';
// Child modules.
$slugs .= 'et_pb_column, et_pb_column_inner, et_pb_accordion_item, et_pb_counter, et_pb_contact_field, et_pb_signup_custom_field, et_pb_map_pin, et_pb_pricing_table, et_pb_slide, et_pb_social_media_follow_network, et_pb_tab, et_pb_video_slider_item,';
// Woocommerce modules.
$slugs .= 'et_pb_wc_additional_info, et_pb_wc_add_to_cart, et_pb_wc_breadcrumb, et_pb_wc_cart_notice, et_pb_wc_cart_products, et_pb_wc_cart_totals, et_pb_wc_checkout_additional_info, et_pb_wc_checkout_billing, et_pb_wc_checkout_order_details, et_pb_wc_checkout_payment_info, et_pb_wc_checkout_shipping, et_pb_wc_cross_sells, et_pb_wc_description, et_pb_wc_gallery, et_pb_wc_images, et_pb_wc_meta, et_pb_wc_price, et_pb_wc_rating, et_pb_wc_related_products, et_pb_wc_reviews, et_pb_shop, et_pb_wc_stock, et_pb_wc_tabs, et_pb_wc_title, et_pb_wc_upsells,';
// Return.
self::$included_modules = $slugs;
}
/**
* Adds toggle to parent-modules.
*
* @param array $modules All parent modules.
*
* @return array
*/
public static function add_parent_module_toggle($modules) {
if (self::$parent_toggles_added) return $modules;
if (empty($modules)) return $modules;
self::$parent_toggles_added = true;
return self::add_module_settings($modules);
}
/**
* Adds toggle to child-modules.
*
* @param array $modules All child modules.
*
* @return array
*/
public static function add_child_module_toggle($modules) {
if (self::$child_toggles_added) return $modules;
if (empty($modules)) return $modules;
self::$child_toggles_added = true;
return self::add_module_settings($modules);
}
/**
* Adds toggle to parent-modules and child-modules.
* See: https://github.com/elegantthemes/create-divi-extension/issues/462
*
* @param array $modules All parent or child modules.
*
* @return array
*/
private static function add_module_settings($modules) {
// Each module.
foreach ($modules as $slug => $module) {
// Bail.
if (!in_array($slug, self::$included_modules)) continue;
if (!isset($module->settings_modal_toggles)) continue;
// Add toggle.
$toggles = $module->settings_modal_toggles;
if (isset($toggles['custom_css']) && !empty($toggles['custom_css']['toggles'])) {
// Content tab.
$toggles['custom_css']['toggles']['my_toggle'] = array(
'title' => 'My Toggle',
'priority' => 95,
);
// Add toggle.
$module->settings_modal_toggles = $toggles;
}
}
// Return.
return $modules;
}
/**
* Adds fields to each module.
*
* @param array $unprocessed_fields The current module’s fields.
*
* @return array
*/
public static function add_module_fields($unprocessed_fields) {
// Field.
$fields['my_field'] = array(
'label' => esc_html__('My Field', 'my-extension'),
'description' => esc_html__('My description.', 'my-extension'),
'option_category' => 'configuration',
'tab_slug' => 'custom_css',
'toggle_slug' => 'my_toggle',
'type' => 'yes_no_button',
'default' => 'off',
'options' => array(
'on' => esc_html__('On', 'my-extension'),
'off' => esc_html__('Off', 'my-extension'),
),
);
// More fields here...
// Return.
return array_merge($unprocessed_fields, $fields);
}
/**
* Filters shortcode output.
*
* @param string $output The current module’s html output.
* @param string $render_slug The current module’s unique slug.
* @param object $module The current module’s class instance.
*
* @return string
*/
public static function shortcode_output($output, $render_slug, $module) {
if (in_array($render_slug, self::$included_modules)) {
// Do something...
}
// Return.
return $output;
}
}
Description: I have two D4 extensions which use the
et_builder_get_parent_modules()
,et_builder_get_child_modules()
, andet_pb_all_fields_unprocessed_{$slug}()
filters to add custom Toggles and Fields to built-in and third-party Divi modules. These additional field settings are then processed using theet_module_shortcode_output()
filter to modify module output on the front-end.Request: In order for me to continue supporting my products it will be important for me to be able to replicate this functionality in D5. I imagine that there are other third-party extensions which rely on these features also. It may be too early to ask, but any documentation or assistance that ET can provide for replicating this functionality in D5 would be greatly appreciated.
Conclusion: I’m more than happy to provide sample code and/or access to my extensions upon request. Thanks!