Working with CF7 Skins Add-ons

Last Updated on December 27, 2023 by Neil Murray

All Add-ons functions are available in addons.js and can be accessed at window.cf7svisual.addons.functionName().

Basically we follow the same approach as Gutenberg, using the WordPress apply_filters and add_filter functions.

Refer:

Add-on Hooks #

  • edit added in Form/Edit/index.js.
    Passed parameters:
    props object Edit props.
    styles object available styles found in index.css.
  • beforeToolbar added in Form/Items/InputItem/index.js.
    Passed parameters:
    node object current edited node.
    styles object available styles found in index.css.
  • itemToolbar added in Form/index.js.
    Passed parameters:
    props object all Form component props
  • menu added in Form/Items/InputItemMenu/index.js. Learn more about creating an Add-ons Menu.

More Add-on hooks might be added in the future as needed. Be sure to use the appropriate hook to display Add-on components.

Refer src/visual/util/cf7sItems.js for default node properties.

Add-on Functions #

All Add-on functions are available in addons.js:

  • register( hook, callback )
    hook string the hook name to register
    callback function/object callback function/object for rendering -supports JSX
  • get( hook )
    hook string the hook name to get

Registering Add-ons #

In this example, we add a component to the Edit dialog using the edit hook.

Edit Dialog

First we need to create our MyEditAddon component that contains the render function in JSX as below:

const MyEditAddon = (node, editOnChange , styles) => {
  const myValue = !! node.cf7sMyAddon ? node.cf7sMyAddon : ''
    
  return (
    <div className={styles.attribute} key="cf7sMyAddon">
      <div className={styles.label}>My Addon</div>       
      <div className={styles.value}>
        <input type="text" name="cf7sMyAddon" value={myValue} 
          onChange={editOnChange} />
      </div>
    </div>
  )
}

There are three passed parameter ( node, editOnChange , styles ) which can be used.

#We name our input as cf7sMyAddon which does not exist in the node property yet. Once we edit it, it will be available in the node object.

The editOnChange call back function will handle the changes to the input and update the node object.

Since we store our input type="text" as a single string, we don’t need to pass any arguments to it.

To store the input value as an array, we would need to pass:

onChange={ event => {
  onChange( event, 'myArrayName', event.target.value )
}}

Read more about editOnChange function for input type handling.

Unique Key #

We need to provide key="cf7sMyAddon"

<div className={styles.attribute} key="cf7sMyAddon">

because the Edit React Component iterates it and should have a unique ‘key’ prop.

const renderAddonEdits = get('edit').map((edit) => {
    return edit(node, this.props.editOnChange, styles)
})

See https://fb.me/react-warning-keys for more information.

Register the render function #

Finally we register the render function into the edit hook:

window.cf7svisual.addons.register( 'edit', MyEditAddon )

Now the Add-on component is ready to render in the Edit dialog.

Updated Edit component

After changes, the RST node will have the cf7sMyAddon property.

Updated node log

Enqueueing Add-ons File #

Addons should enqueue their files using wp_enqueue_script to CF7 admin page. It should be loaded right after the addons.js file, before main visual .js file or the addons will not be applied into Visual. For example,

add_action( 'admin_enqueue_scripts', 'my_enqueue_script', 10 );
 
function my_enqueue_script() {
  // Return if this is not CF7 editing page
  if ( ! CF7_Skins_Admin::edit_page() ) {
    return;
  }
 
  wp_enqueue_script( 'my-addon.js',
    $my_plugin_url . 'my-addon.js',
    array( 'visual-addons' ), $my_version, true );
}  

As the result, the addon file will be enqueued in between as seen below.

<script type='text/javascript' src='...init.js'></script>
<script type='text/javascript' src='...addons.js'></script>
<script type='text/javascript' src='...my-addon.js'></script>
<script type='text/javascript' src='...visual.js'></script>

Separating Add-on Files #

  • wp.org requires that a plugin does not include any disabled code
  • we have to ensure that no Add-on code is included in the free version of CF7 Skins
  • we can however provide a connection mechanism for CF7 Skins Visual Addons in the free version of CF7 Skins

Code Splitting #

We use webpack code splitting to ensure:

  • no Add-on code is included in the free version of CF7 Skins
  • all the JS code for each Add-on is created as a chunk which can be added as a standalone file in the Add-on plugin
  • Add-on JS is loaded dynamically as needed

Add-on Folders #

Each Add-on:

  • needs to export as module
  • folder needs to contain all the code for that Add-on
  • needs their own webpack chunk file

All the JS code for the Add-on is created as a webpack chunk which can be added as a standalone file in the Add-on plugin.

Further Reading


Notes

Add comments, questions & notes here.

Save all Images to Sync – use ..\ Sync\..\Development\Development Guidelines\CF7 Skins Code\CF7 Skins Visual Code\Working with CF7 Skins Add-ons\