elegantthemes / create-divi-extension

MIT License
185 stars 58 forks source link

Set the default items of child in the parent module #233

Open mrkenng opened 5 years ago

mrkenng commented 5 years ago

Problem Description

How can i set a few child items on the parent module as default? for example like to contact form or the slider module.

Steps To Reproduce

I've tried using predefined_child_modules() by using the contact form module as an example.

function predefined_child_modules() {
        $output = sprintf(
            '[et_pb_contact_field field_title="%1$s" field_type="input" field_id="Name" required_mark="on" fullwidth_field="off" /][et_pb_contact_field field_title="%2$s" field_type="email" field_id="Email" required_mark="on" fullwidth_field="off" /][et_pb_contact_field field_title="%3$s" field_type="text" field_id="Message" required_mark="on" fullwidth_field="on" /]',
            esc_attr__( 'Name', 'et_builder' ),
            esc_attr__( 'Email Address', 'et_builder' ),
            esc_attr__( 'Message', 'et_builder' )
        );

        return $output;
    }

Changed et_pb_contact_field to my child slug. then output using:

do_shortcode( $this->predefined_child_modules() ); on the parent module. It is showing up on the frontend but it's not showing up on the module.

Screenshot and/or gif

screenshot 2019-02-16 at 6 28 36 pm
mrkenng commented 5 years ago

Found out that this will only work on the old classic builder. Any idea why this is not working on the visual builder?

jcdotnet commented 5 years ago

I'm trying to achieve this as well.

I mean, when the user adds the module, a default child module should be added too if the "Add placeholder content to new modules" builder option is ON.

I have added default placeholders for the item fields but I don't know how to add a default item. As a result, the item content is not displayed in the VB because no items have been added.

Hope someone helps here!

jcdotnet commented 5 years ago

Well, I have added the module item defaults to window.ETBuilderBackend.defaults and this is working.

The second task is adding default items to the module so the default content set above is placed in the Visual Builder.

How can I add 1-2 default items? I’m really struggling with this and I have tried almost everything: have a look at the Divi code (trying to spot the code that are related to this), JS handlers, etc. I know this can be done easily but we have no documentation and we only can get support from you (ET).

How the Tab/Slider module does that? I would appreciate very much if you gave me the solution.

There is a similar issue: #132 but adding the predefined_child_modules function is not what we need here.

To sum up: I have set the defaults to the item fields but I can’t set a default item to the parent module. I have some approachs that I don’t want to implement, I want to do this in the Divi way if possible :)

No matter how expertise in PHP and JavaScript you have if you don’t know how Divi Works :(

@mrkeng Did you manage to make default items work in the VB? If so message me please.

PD. The builder.js code checks the app preferences (dummy content, etc) and adds 2 items for the tabs: case"et_pb_tabs":t.content=[a("et_pb_tab"),a("et_pb_tab",1)]. This is minify and uglify JS but might help someone if ET don't give us support here.

Adding a default module item in the Visual Builder is something important for many third-party developers.

(This is part of ET chat box message and I am leaving it here as they suggested me: Hope someone from the devs can respond to the issue, feel free to leave your comment there as well)

mrkenng commented 5 years ago

@jcdotnet I didn't get the VB to work. Have it and move on until ET steps in. Hopefully someone will direct us.

jcdotnet commented 5 years ago

I think I'm almost there:

@mrkenng use et_fb_process_shortcode instead of do_shortcode:

This is what I have done:

function process_item_shortcode() {
    $processed_shortcode =  et_fb_process_shortcode('[child_module_slug /]');
    wp_die(json_encode( $processed_shortcode ) );
}

Called this function from the parent component via ajax if this.props.content === ''(we have no items):

const _this = this;
$.ajax({
         ..... 
         data : {
              action : 'process_item_shortcode'
              ...,
          },
          success : function( response ) {
              let itemProps = JSON.parse(response)[0]; 
              itemProps.matching = {slug: 'child_module_slug'};
              itemProps.methods = []; 
              const itemElement = React.createElement(ChildModuleComponent, itemProps)
              itemElement.key = 'child_module_slug-' + _this.props.moduleInfo.address+'-'+ itemProps._order; 
             //itemElement.type = 'et_pb_signatures_item'; // created automatically
             itemElement._owner = _this._reactInternalFiber; 
          }
      }); 

The itemComponent is added to this.props.content correctly but it isn't rendered (I guess it's not accepted as a valid component). Also, when a new child module is added manually, the itemComponent is replaced by the new one.

What am I missing?

lots0logs commented 5 years ago

Sorry for the delayed response. Its actually not currently possible to make this work in a custom module. We'll have to add access in the API for manually updating a module's content in order for this to work. We're currently planning another round of improvements and bug fixes for the API. Work on that should begin soon. I'll keep you posted.

jcdotnet commented 5 years ago

I see... Looking forward to the builder API :)

In the meanwhile, what if we use the ETBuilderInjectedComponent? It seems like this component allows updating the module's content, doesn't it?

lots0logs commented 5 years ago

No that's the component the builder wraps all custom modules with.

kelleymuro commented 4 years ago

Bumping this. Has an update to the API allowed for this to be possible?