Element API Reference
This is a deeply technical summary of what is offered by our Element API.
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.
Base Options
title | ✔ | string | Localized title to display in the library and when inspecting the element |
values | ✔ | array | See Defining Values below. |
builder | function | Function update the definition when the builder loads. This offers better performance with large control lists because they don't need to be populated on the front end. | |
style | function | Function that returns a string style template. | |
decorator | function | Function that updates the data before the render function is run. Useful to inject additional attributes. | |
render | ✔ | function | Function that accepts a single argument containing all the element data. Should return a string with the element markup |
options | array | See Element Definition Options below. | |
icon | string | Inline SVG as a string. | |
active | bool | Set to false if the element will not be able to render correctly. For example, if the element requires WooCommerce you can pass class_exists( 'WC_API' ) . | |
Key | Required | Type | Description |
---|
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
control_nav | array | Associative array where keys describe the control nav item, and the value is a localized title to display in the Inspector navigation |
controls | array | An array of top level controls. Each of these should be associated with the control navigation using a group parameter. See Controls below. |
controls_std_content | array | Top level controls to show under the Content navigation menu item when Advanced Mode is turned off. |
controls_std_design_setup | array | Top level controls to show under the Design navigation menu item when Advanced Mode is turned off. |
controls_std_design_colors | array | Top level controls to show under the Colors navigation menu item when Advanced Mode is turned off. |
Key | Type | Description |
---|
Sample Control Nav
array(
'main_group' => __( 'Group', 'your-text-domain' ),
'main_group:setup' => __( 'Setup', 'your-text-domain' ),
'main_group:design' => __( 'Design', 'your-text-domain' )
)
Element Definition Options
alt_breadcrumb | string | Provide an alternate localized string to show in the Inspector navigation breadcrumbs. Useful for elements with longer names. |
label_key | string | Set to the key of one of your element's values. It will use that value as the label shown in the observer, and when double clicking to rename the element. |
child | bool | Set to true to indicate this element will be rendered as a child of another element. |
library | bool|array | Set to false to prevent this element from appearing in the Element Library. Set to array( 'content' ) and the element will only show in the Content builder and Global Blocks builder (not Pro Headers or Footers). |
valid_children | array | An array of strings containing the names of elements that can be placed as a direct child of this element. Set as array( '*' ) to accept any child similar to a Column. This does not enable drag/drop. |
index_labels | bool | Set to true to make the labels have numeric indexes when they are created. e.g. "Section 1", "Section 2" |
empty_placeholder | bool | Set to false to disable the placeholder style when this element doesn't have any content. |
default_children | array | Provide an array of elements that should automatically be created as children when this element is created. |
add_new_element | array | Provide the data of an element that will be created when you click "Add New" in this element's sortable control. |
inline | array | Pass an associative array to enable inline editing. See Inline Editing below |
fallback_content | string | If the element does not have any children, this content will be used instead for the front end. Most notably used to prevent empty Columns from collapsing. |
empty_preview_min_height | int | If an element has zero height, it will show as an empty placeholder. You can set this to a larger number to invoke the placeholder even if your element has height. This is useful for elements with base markup that is a few pixels tall, but still empty. |
is_draggable | bool | Set to false to prevent users from lifting this element in the preview. |
cache | bool | Set to false to prevent the render system from caching markup. Useful for elements that integrate with 3rd party APIs |
render_children | bool | Set to true to instruct the rendering system to render this element's children with the parent markup. This has lower performance but is useful for cases like the Map where Markers depend on the parent element. |
Key | Type | Description |
---|
Inline Editing
Here's an example of how to configure inline editing taken from the Tabs element.
'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.
Additional Definition Functions
function cs_unregister_element( $name )
Can be used to unregister an element originally registered under $name
.
function 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.
function 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
'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
function 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
cs_define_values( 'my-feature', array(
'my_feature_enabled' => cs_value( false ), // uses 'all' designation
'my_feature_margin' => cs_value( '0em', 'style' ),
) );
Composing Values
function 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
'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
function 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.
The $key_prefix
argument is used to prefix every value in the list. The example below shows how you can retrieve the values of the native text element and prefix it for your element. The native card element is a good example of composing multiple values (controls as well).
Example
cs_values( 'text-headline', 'my_element_text' )
Individual Controls
In this section we'll cover all the different control types, the available options, and the helper functions you can use to work with them.
Control Parameters
A control is an array that contains the following keys
key | ✔ | string | The name of a value that will be mapped to this control. Not required if you use keys instead. |
keys | ✔ | array | Some control types allow mapping multiple values. |
type | ✔ | string | Type of control. Use the Control Reference below. |
group | string | Required for top level controls. Set the control navigation group under which this control should appear. | |
label | string | Localized string to describe this control. Allows templating. e.g. "{{prefix}} Margin" will populate prefix from what is passed into label_vars . | |
label_vars | array | Key value pairs to populate template strings in the Label. This technique is useful when amending controls for standard mode or when creating your own partials. | |
label_prefix | string | Shorthand to set label_prefix in label_vars | |
condition | array | A single condition to determine if this control should be visible. | |
conditions | array | Multiple conditions to determine if this control should be visible. Will supersede condition . | |
options | array | Array of options that correspond with the control type. | |
Key | Required | Type | Description |
---|
Control Reference
- Controls without keys only output a single value
- Keys with
|value
indicate which one is used when passing a singular key - Keys with
?
are optional. - Angle brackets indicate you must use one of the enclosed strings. e.g. for
<row|column>
you must providerow
orcolumn
. - Each line in Options is an individual option that can be mapped for this control. If an option references another control, it means that you can pass an array of the options for the named control.
Align | align | ✔ | ✔ | icon_direction : string <row|column> axis : string <main|cross> | |
Aspect Ratio | aspect-ratio | ✔ | width height | placeholder : str "16:9" | |
Atts | atts | id class style | |||
Border | border | width style color alt_color? | always_linked : bool width : [unit-slider options] color : [color options] | ||
Border Radius | border-radius | [see dimensions] | |||
Box Shadow | box-shadow | dimensions color? alt_color? | x_offset : [slider] y_offset : [slider] blur : [slider] spread : [unit-input] color : [color] | ||
Checkbox List | checkbox-list | ✔ | ✔ | Variable1 | list : [{ key : str, label : str, full : bool }] |
Choose (Multi) | choose-multi | ✔ | ✔ | choices : [{ value : str, label : str, icon : str }] delimiter : str | |
Choose (Single) | choose-single | ✔ | ✔ | choices : [{ value : str, label : str, icon : str }] off_value : str | |
Code Editor | code-editor | ✔ | ✔ | placeholder : str mode : <css|js> button_label : str header_label : str disable_input_preview : bool | |
Color | color | ✔ | ✔ | value alt? | output_format : str label : str alt_label : str dynamic : bool |
Date / Time | date-time | ✔ | ✔ | ||
Dimensions | dimensions | labels : { top : str, right : str, bottom : str, left : str } top : [slider] right : [slider] bottom : [slider] left : [slider] | |||
Flex | flex | ✔ | |||
Flex Layout | flexbox | layout justify align wrap? | allow_reverse : bool | ||
Font Family | font-family | ✔ | |||
Font Style | font-style | ✔ | |||
Font Weight | font-weight | ✔ | value font_family 2 | ||
Icon Picker | icon | ✔ | ✔ | value alt? | label : str alt_label : str |
Group | group | ✔ | None3 | ||
Image | image | ✔ | img_source|value height? width? 4is_retina? 5has_link? has_info? alt_text? | alt_text_placeholder : str | |
Image Source | image-source | ✔ | |||
Link | link | url link_text? has_info? new_tab? nofollow? | |||
Margin | margin | see dimensions | |||
Menu | menu | ||||
Number | number | ✔ | ✔ | placeholder : str monospace : bool | |
Padding | padding | see dimensions | |||
Ratio | ratio | ✔ | placeholder : str | ||
Select | select | ✔ | choices : [{ value : str, label : str }] | ||
Sortable | sortable | No keys6 | element: element-name add_label: str capacity : int floor : int | ||
Text | text | ✔ | ✔ | placeholder : str monospace : bool | |
Text Align | text-align | ✔ | |||
Text Decoration | text-decoration | ✔ | |||
Text Editor | text-editor | ✔ | |||
Text Format | text-format | font_family font_weight font_size letter_spacing line_height | |||
Text Shadow | text-shadow | dimensions|value color? alt_color? | |||
Text Style | text-style | font_style? text_align? text_decoration? text_transform? text_color? alt_color? | color : [color] | ||
Text Transform | text-transform | ✔ | |||
Textarea | textarea | ✔ | placeholder : str monospace : bool | ||
Unit | unit | ✔ | ✔ | unit_mode : str <distance|angle> available_units : [ values... ] valid_keywords : [ values... ] disabled : bool fallback_value : str | |
Unit Slider | unit-slider | ✔ | unit_mode : str <distance|angle> available_units : [ values... ] valid_keywords : [ values... ] disabled : bool fallback_value : str ranges : { px : { min : 0, max : 100, step : 1 } min : number max : number step : number | ||
Widget Area | widget-area | ✔ | |||
List | list | ✔ | ✔ | initial : object header_label : str | |
Name | Identifier | 2nd Level | 3rd Level | Keys | Options |
---|
Notes:
- Checkbox List - These keys are variable and depend on the items you map.
- Font Weight - This needs a reference to
font_family
but it doesn't directly modify the value. - Group - The group control doesn't accept
keys
oroptions
. A top levelcontrols
property will let you pass a list of controls to display inside the group. - Image -
width
andheight
are optional but you must declare both or neither - Image -
is_retina
can only be used ifwidth
andheight
are mapped. - Sortable - See sortable section below. Keys are not used
- List -
@since CS 7.4.0
Example Groups
You can add a group
as child control of a group
to create a third level. These controls don't support labels and you're even more restricted at the types of controls that can be mapped.
Group Example (2nd Level)
array(
'type' => 'group',
'label' => __( 'Feature Controls', 'text-domain' ),
'controls' => array(
array(
'key' => 'element_content',
'type' => 'text',
'label' => __( 'Content', 'text-domain' )
),
array(
'key' => 'element_color',
'type' => 'color',
'label' => __( 'Color', 'text-domain' )
)
)
)
Group Example (3rd Level)
array(
'type' => 'group',
'label' => __( 'Feature Controls', 'text-domain' ),
'controls' => array(
array(
'type' => 'group',
'label' => __( 'Before / After', 'text-domain' ),
'controls' => array(
array(
'key' => 'element_content_before',
'type' => 'text',
),
array(
'key' => 'element_content_after',
'type' => 'text',
),
)
),
array(
'key' => 'element_color',
'type' => 'color',
'label' => __( 'Color', 'text-domain' )
)
)
)
Example Checkbox List
Here's an example of the checkbox list control. The full
option tells the checkbox to span the full width of the control area instead of being half size.
array(
'keys' => array(
'checkbox_a' => 'some_element_value',
'checkbox_b' => 'another_element_value',
'checkbox_c' => 'one_more_element_value',
),
'type' => 'checkbox-list',
'options' => array(
'list' => array(
array( 'key' => 'checkbox_a', 'label' => __( 'Enable A', '__x__' ) ),
array( 'key' => 'checkbox_b', 'label' => __( 'Enable B', '__x__' ) ),
array( 'key' => 'checkbox_c', 'label' => __( 'Enable C', '__x__' ), 'full' => true ),
),
),
)
Composing Controls
function cs_compose_controls() // unlimited arguments
Call cs_compose_controls
with unlimited arguments. Each argument must be a string associated with a registered partial, or an array that adheres to the Builder Options parameters above. The function will combine multiple sets of controls into a single output used in the builder. This allows for leveraging partials and organizing the standard controls that should only appear when Advanced Mode is turned off.
Registering a Control Partial
function cs_register_control_partial( $name, $function )
To create your own control partials, call cs_register_control_partial
with $name
set to the key you will eventually reference in calls to cs_compose_controls
or cs_partial_controls
. Set $function
to a function that will return valid Builder Options.
Example
function my_plugin_control_partial( $settings = array() ) {
$group = = isset( $settings['group'] ) ? $settings['group'] : "feature"
$group_title = isset( $settings['group_title'] ) ? $settings['group_title'] : __( 'Feature', 'my-plugin' );
$group_setup = "$group:setup";
$group_design = "$group:setup";
return array(
'control_nav' => array(
$group => $group_title,
$group_setup => __( 'Setup', 'my-plugin' ),
$group_design => __( 'Design', 'my-plugin' ),
),
'controls' => array( /* */),
);
}
cs_register_control_partial( 'my-plugin-control-partial', 'my_plugin_control_partial' );
Using Control Partials
function 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
cs_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
function 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.
margin | Margin | {key_prefix}_margin | None |
padding | Padding | {key_prefix}_padding | None |
border-radius | Border Radius | {key_prefix}_border_radius | None |
border | Border | {key_prefix}_border_width {key_prefix}_border_style {key_prefix}_box_shadow_color {key_prefix}_box_shadow_alt_color | alt_color - Set to true to map the alt color key and make the control appear. |
box-shadow | Box Shadow | {key_prefix}_box_shadow_dimensions {key_prefix}_box_shadow_color {key_prefix}_box_shadow_alt_color | alt_color - Set to true to map the alt color key and make the control appear. |
flexbox | Flexbox | {key_prefix}_{layout_pre}_flex_direction {key_prefix}_{layout_pre}_flex_wrap {key_prefix}_{layout_pre}_flex_justify {key_prefix}_{layout_pre}_flex_align {key_prefix}_flex | no_self - Set to true to exclude the Self Flex control and key.layout_pre - An additional key prefix used on layout flex properties. If omitted the $key_prefix will be used. |
text-shadow | Text Shadow | {key_prefix}_text_shadow_dimensions {key_prefix}_text_shadow_color {key_prefix}_text_shadow_alt_color | alt_color - Set to true to map the alt color key and make the control appear. |
text-format | Text Format | {key_prefix}_font_family {key_prefix}_font_weight {key_prefix}_font_size {key_prefix}_line_height {key_prefix}_letter_spacing {key_prefix}_font_style {key_prefix}_text_align {key_prefix}_text_decoration {key_prefix}_text_transform {key_prefix}_text_color {key_prefix}_text_alt_color | alt_color - Set to true to map the alt color key and make the control appear.no_font_family , no_font_weight , no_font_size , no_line_height , no_letter_spacing , no_font_style , no_text_align , no_text_decoration , no_text_transform , no_text_color - Set any of these to false to prevent the respective key and control from being mapped. |
$type | Name | Mapped Keys | Settings |
---|
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
function 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
$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
function 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
cs_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
function 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
// in your list of controls
array(
'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 observingop
- The type of operator we are using for this comparison. See operator table belowvalue
- The value to check our condition against.or
- Set totrue
to enable OR logic for this condition. See Using OR Logic below.
== | Checks if what is currently held under key is equal to our condition's value . | any | |
=! | Checks if what is currently held under key is not equal to our condition's value . | ||
IN | Checks if what is currently held under key is present in the array of values set as our condition's value | ||
NOT IN | Checks if what is currently held under key is not present in the array of values set as our condition's value | ||
EMPTY | Checks if the what is currently held under key is considered an empty property1 for the purposes of CSS output. | ||
NOT EMPTY | Checks if the what is currently held under key is not considered an empty property1 for the purposes of CSS output. | ||
Operator | Description | Value Type | Description |
---|
- 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.
array( '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
[
'conditions' => [
[ 'feature_enabled' => true ].
[ 'key' => 'some_value', 'op' => 'IN', 'value' => [ 'one', 'two' ] 'or' => true ],
[ '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.
Basics
You can use variables in your selectors and property values. Variables can not be used as part of a property name. The available variables correspond to values that you have registered with designations style
or all
. An additional variable to reference the current element's class name is available as &
. The following example shows styling a few properties. Each of the property value variables is expected to mapped as one of your element values.
Example
& {
margin: $my_element_base_margin;
padding: get(my_element_base_padding); //Will also grab current breakpoint value
}
& .thing {
margin: $my_element_thing_margin;
padding: $my_element_thing_padding;
}
Conditions
Often you'll want to exclude styles unless a criteria is met. This is possible with @if
. When using @if
the contained styles will appear if the expression evaluates to true
.
& {
@if $feature_enabled == 'on' {
margin: $my_element_feature_margin;
padding: $my_element_feature_padding;
@if not empty($feature_min_width) {
min-width: $feature_min_width;
}
}
}
Learn more about Themeco Stylesheets here.
PHP in a style template
If you're browsing our partial templates, you'll notice that they are PHP functions that use object buffering. Remember that this PHP does not actually have any element data. We're constructing a template that contains rules applied to elements later. Using PHP is helpful to setup things like key prefixes and make calls to cs_get_partial_style
.
Partials
function cs_get_partial_style( $name, $settings = array() )
This function is used to get the string of a predefined style template partial registered under $name
. The $settings
parameter is used to instruct the partial on various adjustments that can be made.
Creating a Style Partial
This is accomplished via the cs_get_partial_style_$name
hook.
Example
function 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
function 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
function 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
function 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
.
function 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
cs_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
function cs_without( $data, $keys )
This function simply returns $data
after omitting key/value pairs found in the $keys
array.
Example
// Remove some data specific to the top level element.
$cleaned = cs_without( $data, array( 'mod_id', 'id', 'class', 'style' ) )
Deferred View Partials
function 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
function 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
function my_view_partial( $data = array() ) {
return '';
}
add_filter( 'cs_get_partial_view_my_view_partial', 'my_view_partial' );
Helpers
Attributes
function 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
$atts = cs_atts(
'id' => 'my-id',
'style' => 'color: white;'
);
$html = "<div $atts>Content</div";
Class Output
function 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
$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
function 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 [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 Footercontent
- 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?
$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.
Summary
We've taken an in-depth look at all the Element API has to offer, and covered specific options and covered the majority of functionality used in the native elements. When building your own elements, feel free to copy and paste sections of code from the native elements. For more of a step-by-step walkthrough of the Element API, see the API Primer.
See something inaccurate? Let us know