## Element Definitions

Elements are registered with this function:

function cs_register_element( $type,$options )
• $type must be a unique element name. Please use a prefix to avoid naming collisions. e.g. my-plugin-my-element • $options provides all the details for our definition. It should be an array with the keys notated in Base Options below.

### Builder Options

These are all optional, but you'll want to provide some combination or the Inspector will be empty. Any of these keys can be added top level, but we recommend returning an array including them from the builder callback function. It is most likely that your builder callback will return the result of the cs_compose_controls function which provides an array in the shape described below. See Composing Controls

#### Sample Control Nav

xxxxxxxxxxarray(  'main_group' => __( 'Group', 'your-text-domain' ),  'main_group:setup' => __( 'Setup', 'your-text-domain' ),  'main_group:design' => __( 'Design', 'your-text-domain' ))

### Inline Editing

Here's an example of how to configure inline editing taken from the Tabs element.

xxxxxxxxxx'inline' => array(  'tab_label_content' => array(    'selector' => '.x-tabs-list button span'  ),  'tab_content' => array(    'selector' => '.x-tabs-panel'  ))

The selector indicates the double click target. When the user starts editing, it will update the value with the associated key (tab_label_content). You can set the selector to root to make the base element the double click target.

xxxxxxxxxxfunction cs_unregister_element( $name ) Can be used to unregister an element originally registered under $name.

xxxxxxxxxxfunction cs_get_element( $name ) Retrieve the instance of an element's definition originally registered under $name

## Defining Values

Every element needs values. These store data that will be customized later in the Element's controls.

### Single values.

xxxxxxxxxxfunction cs_value( $default = null,$designation = 'all', $protected = false ) Each value has a $default which is the initial value used when an element is created.

The $designation determines how the system will render this value. • markup - When this value changes it makes a HTTP request to the server with the updated attributes and fetches new markup for the builder preview. This is the most expensive in terms of performance, but most versatile as it invokes your custom PHP code. • attr - When this value changes it updates the value in the DOM immediately. • style - We'll cover this later on, but our builders allow you to provide a style template to output generated CSS. When a value with this designation changes, it causes the generated CSS to recalculate. • all - When this value changes it cause the element to fetch new markup from the server and renders the generated CSS again. When $protected is set to true it flags the variable as "content". This means it will not be overridden by default when pasting element styles or applying a preset.

Example

xxxxxxxxxx'values' => array(  'my_element_content' => cs_value( 'Initial Text', 'markup', true )  'my_element_attribute' => cs_value( false, 'attr' ),  'my_element_feature_enabled' => cs_value( false ), // uses 'all' designation  'my_element_margin' => cs_value( '0em', 'style' ))

### Defining Reusable Values

xxxxxxxxxxfunction cs_define_values( $key,$values )

This function is useful if you're creating a suite of elements that will share values. Call this before you register your elements to define values that can be reused later. The $key is a name to use when you want to recall your values with cs_values or cs_compose_values. Set $values to an associative array that assigns keys to the result of cs_value calls.

Example

xxxxxxxxxxcs_define_values( 'my-feature', array(  'my_feature_enabled' => cs_value( false ), // uses 'all' designation  'my_feature_margin' => cs_value( '0em', 'style' ),) );

### Composing Values

xxxxxxxxxxfunction cs_compose_values() // accepts unlimited arguments

The cs_compose_values function accepts unlimited arguments. Each can be a string or an array. If you pass a string, the function will retrieve the values stored via cs_define_values under the given key. If passed an array, it will merge those values into the list. This function will let you create elements that tap into predefined functionality.

Example

xxxxxxxxxx'values' => cs_compose_values(  'my_element_content' => cs_value( 'Initial Text', 'markup', true ),  'my-feature', // Defined in the previous example  'omega' // Defined natively to power the Customize controls)

### Prefixing Defined Values

xxxxxxxxxxfunction cs_values( $values,$key_prefix = '' )

By passing a string as the first argument, this function allows you to fetch values stored with cs_define_values. An array as the first argument assumes you are passing an associative array of values.

### Using Control Partials

xxxxxxxxxxfunction cs_partial_controls( $name,$settings = array() )

Call cs_partial_controls and pass the result as an argument of cs_compos_controls to add the partial registered as $name to your control list. The $settings array is passed to the partial to allow for customization of the resulting controls.

Example

xxxxxxxxxxcs_compose_controls(  cs_partial_controls( 'my-plugin-control-partial', array(    'group' => 'element-group',    'group_title' => __( 'Element', 'text-domain' )  ) ),  cs_partial_controls( 'omega' ))

### Leveraging Common Control Types

xxxxxxxxxxfunction cs_control( $type,$key_prefix = '', $control = array() ) The cs_control function returns an array describing various common control types. It automatically maps one or more keys for you, and honors $key_prefix in front of those keys. Use the table below to see what is allowed for the $type argument. You can set Control parameters like group, condition(s), and options by passing them through $control. Settings can also be passed into $control to adjust the output. All of these include {{prefix}} in their label, so you can pass label_prefix as a parameter of $control to further describe how the control should be used.

### Amending a Control used multiple times

xxxxxxxxxxfunction cs_amend_control( $control,$update )

Use cs_amend_control to make an adjustment to a control that you've defined once, but need to use somewhere an additional time (useful for standard controls) with a slight adjustment. The $control argument is the original, and $update is the changes to merge in. This is different from array_merge because it handles the additional layer of updating the control's options parameter.

Example

xxxxxxxxxx$base_control = array( /* ...other control parameters... */ 'label' => __( 'My Control', 'your-text-domain' ));​$updated_control = cs_amend_control( $base_control, array( 'label' => __( 'Different Label', 'your-text-domain' )) ); ### Remembering Commonly Used Options xxxxxxxxxxfunction cs_remember($key, $value ) This can only be used inside a builder callback, but it allows you to store commonly used bits of data. For example, if you have a list of localized options that you may need to add on multiple elements you could store it like this. Example xxxxxxxxxxcs_remember( 'my-element-choices', array( array( 'value' => 'one', 'label' => __( 'One', 'your-text-domain' ) ), array( 'value' => 'two', 'label' => __( 'Two', 'your-text-domain' ) ), array( 'value' => 'three', 'label' => __( 'Three', 'your-text-domain' ) ), array( 'value' => 'four', 'label' => __( 'Four', 'your-text-domain' ) ),) ); ### Recalling Commonly Used Options xxxxxxxxxxfunction cs_recall($key )

Building off the previous example, we can recall the stored options as well. Remember it can only be used inside of a builder callback.

Example

xxxxxxxxxx// in your list of controlsarray(  'key' => 'my_element_value',  'type' => 'select',  'label' => __( 'Select Something', 'your-text-domain'),  'options' => array(    'choices' => cs_recall( 'my-element-choices' )  ))

## Control Conditions

When mapping a control, you can set condition or conditions to determine when a control should be visible. This is primarily used to reveal additional controls after they are enabled. Each condition has the following properties:

• key - String identifier of the value we are observing
• op - The type of operator we are using for this comparison. See operator table below
• value - The value to check our condition against.
• or - Set to trueto enable OR logic for this condition. See Using OR Logic below.
1. Blank strings, CSS values that are zero with any unit, and the keyword none are considered empty.

### Shorthand

The equality operator is the most commonly used and therefore is offered as a shorthand. The following two conditions are identical.

xxxxxxxxxxarray( 'key' => 'my_value', 'value' => 'Should be this', 'op' => '==' )array( 'my_value' => 'Should be this' )

### Using OR Logic

By default multiple conditions are applied with AND logic. This means they must all be true for the control to be visible. You can override this on individual controls by setting the or parameter to true. When enabled, the condition will be automatically be considered true if condition immediately following it is true. The following example is considered true when feature_enabled is true AND either some_value is a value in the list (one, two) or another_value is ten.

Example

xxxxxxxxxx'conditions' => array(  array( 'feature_enabled' => true ),  array( 'key' => 'some_value', 'op' => 'IN', 'value' => array( 'one', 'two' ) 'or' => true ),  array( 'key' => 'another_value', 'op' => '!=', 'value' => 'ten' ),)

## Style Templates

When you set style to a function when registering your Element definition you will need to return a string style template. This uses a CSS like syntax to create dynamic styles based on the state of your element's values.

Example

xxxxxxxxxxfunction my_style_partial( $settings = array() ) { return ''; }​add_filter( 'cs_get_partial_style_my_style_partial', 'my_style_partial' ); ## Rendering The function you assign to the render parameter accepts $data which includes the element values and should return a string.

Example

xxxxxxxxxxfunction my_element_render( $data ) {​ extract($data );​  $atts = cs_atts( array( 'class' => cs_attr_class($mod_id, 'my-element' ),    'data-my-attribute' => $custom_attribute ) );​ ob_start(); ?>​ <div <?php echo$atts; ?>>    <?php echo $data['content']; ?> </div>​ <?php return ob_get_clean();} ### Rendering View Partials xxxxxxxxxxfunction cs_get_partial_view($name, $data = array() ) Within your render function, call cs_get_partial_view with the $name of a partial you wish to render and a string will be returned with that partial's markup. The $data array is used to pass through your element's data (the $data argument of the render function). The example below is the native Button element.

Example

xxxxxxxxxxfunction x_element_render_button( $data ) { return cs_get_partial_view( 'anchor',$data );}

### Preparing Partial Data

#### Extracting and Prefixing Data

Sometimes you'll need to modify the data passed into the partial. For example, if you want to use a partial multiple times, or need to rename some of the keys, you can do that with cs_extract.

xxxxxxxxxxfunction cs_extract( $data,$find = array() )

Pass in the $data from your render function (or manipulate it first with calls so cs_without and/or array_merge) and specific what values you want to extract in the $find array. Here's an example of using cs_extract to retrieve values prefixed with headline_one/headline_two and rename those keys to text for the purposes of rendering the partial. Notice how the cs_extract calls work in parallel with calls to cs_values .

Example

xxxxxxxxxxcs_register_element( array(    'values' => cs_compose_values(    array(      // other values    ),    cs_values( 'text-headline', 'headline_one' ),    cs_values( 'text-headline', 'headline_two' ),  ),    'builder' => 'my_element_builder', // not includes in this example​  'render' => 'my_element_render'  ) );​function my_element_render( $data ) {$headline_one_markup = cs_get_partial_view(    'text',    cs_extract( $data, array( 'headline_one' => 'text' ) ) );$headline_two_markup = cs_get_partial_view(    'text',    cs_extract( $data, array( 'headline_two' => 'text' ) ) ); // ...continue rendering. should return a string.}​ #### Omitting Data xxxxxxxxxxfunction cs_without($data, $keys ) This function simply returns $data after omitting key/value pairs found in the $keys array. Example xxxxxxxxxx// Remove some data specific to the top level element.$cleaned = cs_without( $data, array( 'mod_id', 'id', 'class', 'style' ) ) ### Deferred View Partials xxxxxxxxxxfunction cs_defer_partial($name, $data = array(),$priority = 100 )

Sometimes you want to output partial markup at the end of the site markup instead of inline. This is useful for modal and off-canvas elements. You can call cs_defer_partial with the $name of your registered partial and it will internally utilize a function called x_set_view which caches HTML and outputs it at a specific hook. In this case, it will be output at the x_before_site_end hook. This is a few levels above the closing </body> tag, and where X and Pro output all deferred markup. When using Cornerstone with other themes this will be equivalent to the wp_footer hook. The $data argument is identical the cs_get_partial_view function. You can adjust the $priority used when attaching to the x_before_site_end hook. The following example is from the Content Area Modal element with some comments added. Example xxxxxxxxxxfunction x_element_render_content_area_modal($data ) {​  // Add some ARIA attributes (See ARIA Attributes section later in this article)  $data = array_merge($data,    cs_make_aria_atts( 'toggle_anchor', array(      'controls' => 'modal',      'haspopup' => 'true',      'expanded' => 'false',      'label'    => __( 'Toggle Modal Content', '__x__' ),    ), $data['id'],$data['mod_id'] )  );​  // Defer output of the modal to the site footer.  cs_defer_partial( 'modal', cs_extract( $data, array( 'modal' => '' ) ) );​ // Output the toggle inline using an anchor partial return cs_get_partial_view( 'anchor', cs_extract($data, array( 'toggle_anchor' => 'anchor', 'toggle' => '' ) ) );​}

### Creating a View Partial

This is accomplished via the cs_get_partial_view_$name hook. Example xxxxxxxxxxfunction my_view_partial($data = array() ) {  return ''; }​add_filter( 'cs_get_partial_view_my_view_partial', 'my_view_partial' );

### Helpers

#### Attributes

xxxxxxxxxxfunction cs_atts( $atts,$echo = false )

Takes an associative array ($atts) and combines them into single escaped string that can be output in an HTML tag. Example xxxxxxxxxx$atts = cs_atts(  'id' => 'my-id',  'style' => 'color: white;');​$html = "<div$atts>Content</div";

#### Class Output

xxxxxxxxxxfunction cs_attr_class() // unlimited string arguments

Combines multiple strings into a single CSS class name. Pass as many arguments as you like. They can be strings or arrays of strings. It will automatically remove any values that are empty.

Example

xxxxxxxxxx$feature_a = '';$feature_b = array( '', 'feature-b' );$classes = cs_attr_class($mod_id, 'my-element', $feature_a,$feature_b );// $classes === "e123-1 my-element feature-b" #### ARIA Attributes Some of the native view partials look for additional data to populate the aria attributes. We can attach this data with the cs_make_aria_atts function. Example xxxxxxxxxxfunction my_element_with_toggle_render($data ) {​  $data = array_merge($data,    cs_make_aria_atts( 'toggle_anchor', array(      'controls' => 'dropdown',      'haspopup' => 'true',      'expanded' => 'false',      'label'    => __( 'Toggle Dropdown Content', '__x__' ),    ), $data['id'],$data['mod_id'] )  );    // continue rendering element}

The best way to understand how this function is used would be to look at the code for the Content Area Dropdown, Content Area Modal, and Content Area Off Canvas elements.

## FAQ

### How can I make an element like [some native element]?

Feel free to copy and paste from our native elements liberally! The native partials are not a documented part of the public API, but you're welcome to re-use anything you find in our elements.

### What is the _region value?

This is used internally to track which "region" the element resides in. Here are the regions and what they mean

• top, left, right, bottom - Element is a bar or descendant of one in the respective region of a Pro Header.
• footer - Element is a bar or descendant of one in a Pro Footer
• content - Element is in the main area of content created in the Content Builder of Global Blocks

Referencing this value can be useful if you want to slightly alter the element behavior based on the output location.

### How can I make my render function behave differently in the preview area?

xxxxxxxxxx\$is_preview = did_action( 'cs_element_rendering' );`

This is useful in render functions if you want to slightly adjust the behavior for the preview versus the front end.

### How can I turn my element into a drag/drop container?

Because this requires additional client side (React Components) code, we do not currently offer a way to define an element as a drag and drop container.