Skip to content

Latest commit

 

History

History
403 lines (326 loc) · 13.5 KB

File metadata and controls

403 lines (326 loc) · 13.5 KB

WPBakery PHP API Reference

Full developer API for registering, modifying, and extending WPBakery Page Builder elements.

Parameter Types

Every vc_map() param has a type that determines the UI control and how data is stored.

Type UI Control Stored Value Format
textfield Text input Plain string
textarea Textarea Plain string
textarea_html WYSIWYG. ONE per shortcode, param_name MUST be "content" Content between shortcode tags
textarea_raw_html Textarea for raw code Base64-encoded string
dropdown Select Selected option value string
checkbox Checkbox(es) Comma-separated checked values
colorpicker Color picker Hex color "#ff0000"
attach_image Media library (single) Attachment ID integer as string
attach_images Media library (multi) Comma-separated IDs
posttypes Post type checkboxes Comma-separated slugs
taxonomies Taxonomy checkboxes Comma-separated slugs
exploded_textarea Textarea (line = item) Comma-separated string
exploded_textarea_safe Same + encoding Encoded comma-separated
css_editor Visual CSS editor .vc_custom_TIMESTAMP{prop: val !important;}
vc_link Link dialog `url:...
loop Query builder `post_type:post
autocomplete Search input Comma-separated IDs/slugs
param_group Repeater field group URL-encoded base64 JSON
google_fonts Google Fonts selector `font_family:...
font_container Font settings `tag:h2
iconpicker Icon picker CSS class: "fas fa-adjust"
animation_style CSS animation picker Animation name: "fadeIn"
widgetised_sidebars Widget area dropdown Sidebar ID string
el_id Element ID input String
hidden Hidden field Any string
tab_id Tab identifier String ID

vc_map() — Full Specification

Register a new element. Hook: vc_before_init.

add_action('vc_before_init', function() {
    vc_map([
        // Required
        'name'        => __('My Element'),       // Display name
        'base'        => 'my_element',           // Shortcode tag

        // Optional metadata
        'description' => __('Description'),
        'category'    => __('Content'),           // "Content","Social","Structure", or custom
        'icon'        => 'dashicons-star-filled', // URL or CSS class
        'weight'      => 0,                       // Higher = appears first in panel
        'show_settings_on_create' => true,

        // Container settings
        'is_container'=> false,                   // true for parent containers
        'as_parent'   => ['only' => 'child_tag'], // Restrict which children allowed
        'as_child'    => ['only' => 'parent_tag'],// Restrict which parents allowed
        'js_view'     => 'VcColumnView',          // Required for containers
        'default_content' => '',                  // Initial child shortcodes

        // Visibility
        'content_element' => true,                // false to hide from add panel
        'deprecated'  => '',                      // Version string to mark deprecated

        // Asset enqueueing
        'admin_enqueue_js'  => [],
        'admin_enqueue_css' => [],
        'front_enqueue_js'  => [],
        'front_enqueue_css' => [],

        // Template
        'html_template'     => '',                // Path to custom template file
        'php_class_name'    => '',                // Custom PHP class

        // Parameters
        'params' => [
            [
                'type'       => 'textfield',       // See Parameter Types table
                'heading'    => __('Title'),
                'param_name' => 'title',           // Maps to shortcode attribute name
                'value'      => 'Default value',   // Default displayed value
                'std'        => '',                // Default selected/saved value
                'description'=> 'Help text',
                'admin_label'=> true,              // Show in backend preview
                'holder'     => 'div',             // HTML tag to show value in backend
                'group'      => 'General',         // Settings tab name
                'weight'     => 0,
                'save_always'=> false,             // Force save even if matches default
                'edit_field_class' => 'vc_col-sm-6', // Layout width in settings panel
                'dependency' => [                  // Show/hide based on another param
                    'element'   => 'other_param',
                    'value'     => ['val1', 'val2'],
                    'not_empty' => true,
                ],
            ],
        ],
    ]);
});

vc_lean_map() — Lazy Registration (Performance)

vc_lean_map('my_element', function() {
    return ['name' => 'My Element', 'base' => 'my_element', 'params' => [...]];
});
// Or with file:
vc_lean_map('my_element', null, get_template_directory() . '/vc/my-element.php');

Modifying Existing Elements

All hook on vc_after_init:

// Add parameter
vc_add_param('vc_row', [
    'type' => 'textfield', 'heading' => 'My Param', 'param_name' => 'my_param'
]);

// Add multiple parameters
vc_add_params('vc_row', [/* array of param arrays */]);

// Update element properties
vc_map_update('vc_message', ['name' => 'New Name', 'category' => 'New Category']);

// Update a single parameter
vc_update_shortcode_param('vc_single_image', [
    'type' => 'textfield', 'param_name' => 'img_size', 'value' => 'full'
]);

// Remove element entirely
vc_remove_element('vc_flickr');

// Remove parameter
vc_remove_param('vc_message', 'el_class');

// Remove ALL elements (clean slate)
vc_remove_all_elements();

// Get element's full mapping data
$settings = vc_get_shortcode('vc_row');

// Get all attributes with defaults
$atts = vc_map_get_attributes('my_element', $atts);

// Get only defaults
$defaults = vc_map_get_defaults('my_element');

Element Integration (Reuse Params)

// Pull another element's params with a prefix
$btn_params = vc_map_integrate_shortcode('vc_btn', 'btn_', 'Button', [
    'exclude' => ['css']
]);
// Merge into your element's params array

// In render callback, parse the integrated attributes
$btn_data = vc_map_integrate_parse_atts('my_element', 'vc_btn', $atts, 'btn_');
$btn_output = wpbakery()->getShortCode('vc_btn')->render(array_filter($btn_data));

Creating Custom Elements

Simple Element

// 1. Register shortcode handler
add_shortcode('my_box', function($atts, $content = '') {
    $atts = vc_map_get_attributes('my_box', $atts);
    $css_class = vc_shortcode_custom_css_class($atts['css'], ' ');
    return '<div class="my-box' . esc_attr($css_class) . '">'
         . '<h3>' . esc_html($atts['title']) . '</h3>'
         . '<div>' . wp_kses_post($content) . '</div></div>';
});

// 2. Map to WPBakery
add_action('vc_before_init', function() {
    vc_map([
        'name' => 'My Box', 'base' => 'my_box', 'category' => 'Content',
        'params' => [
            ['type'=>'textfield', 'heading'=>'Title', 'param_name'=>'title'],
            ['type'=>'textarea_html', 'heading'=>'Content', 'param_name'=>'content'],
            ['type'=>'css_editor', 'heading'=>'CSS', 'param_name'=>'css', 'group'=>'Design Options'],
        ],
    ]);
});

Container (Nested) Element

// Parent element
add_action('vc_before_init', function() {
    vc_map([
        'name' => 'My Tabs', 'base' => 'my_tabs',
        'is_container' => true,
        'show_settings_on_create' => false,
        'as_parent' => ['only' => 'my_tab'],
        'default_content' => '[my_tab title="Tab 1"][/my_tab][my_tab title="Tab 2"][/my_tab]',
        'js_view' => 'VcColumnView',
        'params' => [],
    ]);
});
// MUST extend WPBakeryShortCodesContainer
class WPBakeryShortCode_My_Tabs extends WPBakeryShortCodesContainer {}

// Child element
add_action('vc_before_init', function() {
    vc_map([
        'name' => 'Tab', 'base' => 'my_tab',
        'as_child' => ['only' => 'my_tabs'],
        'is_container' => true,
        'content_element' => true,
        'js_view' => 'VcColumnView',
        'params' => [
            ['type'=>'textfield', 'heading'=>'Title', 'param_name'=>'title', 'admin_label'=>true],
            ['type'=>'textarea_html', 'heading'=>'Content', 'param_name'=>'content'],
        ],
    ]);
});
class WPBakeryShortCode_My_Tab extends WPBakeryShortCodesContainer {}

Class naming convention: WPBakeryShortCode_ + base name with dashes as underscores.

  • WPBakeryShortCode — for leaf elements (no children)
  • WPBakeryShortCodesContainer — for container elements (can hold children)

Custom Parameter Types

vc_add_shortcode_param('my_type', 'my_type_callback', $optional_js_url);

function my_type_callback($settings, $value) {
    return '<input name="' . esc_attr($settings['param_name'])
         . '" class="wpb_vc_param_value wpb-textinput '
         . esc_attr($settings['param_name']) . ' '
         . esc_attr($settings['type']) . '_field"'
         . ' type="text" value="' . esc_attr($value) . '" />';
    // MUST include class "wpb_vc_param_value" for WPBakery to parse on save
}

Parsing Special Values in PHP

// Parse vc_link → array
$link = vc_build_link($atts['link']);
// Returns: ['url' => '...', 'title' => '...', 'target' => '...', 'rel' => '...']

// Parse css_editor → class name
$css_class = vc_shortcode_custom_css_class($atts['css'], ' ');
// Returns: " vc_custom_1664369671640"

// Parse param_group → array of items
$items = vc_param_group_parse_atts($atts['my_group']);
// Returns: [['field1' => 'val1', 'field2' => 'val2'], ...]

// Get all attributes with defaults (replaces shortcode_atts since v4.6)
$atts = vc_map_get_attributes('my_shortcode', $atts);

Filters Reference

Output Filters (fire in order)

// 1. BEFORE template rendering
add_filter('vc_shortcode_content_filter', function($output, $tag, $atts) {
    return $output;
}, 10, 3);

// 2. AFTER template rendering
add_filter('vc_shortcode_content_filter_after', function($output, $tag, $atts, $content) {
    return $output;
}, 10, 4);

// 3. FINAL output
add_filter('vc_shortcode_output', function($output, $shortcode_obj, $atts, $tag) {
    if ($tag === 'vc_separator') {
        $output = '<div class="wrap">' . $output . '</div>';
    }
    return $output;
}, 10, 4);

CSS Class Filter

add_filter('vc_shortcodes_css_class', function($class_string, $tag) {
    if ($tag === 'vc_row') {
        $class_string = str_replace('vc_row', 'my_row', $class_string);
    }
    if ($tag === 'vc_column') {
        $class_string = preg_replace('/vc_col-sm-(\d+)/', 'my_col-$1', $class_string);
    }
    return $class_string;
}, 10, 2);

Theme Integration

// Theme mode — hides Design Options and Custom CSS tabs
add_action('vc_before_init', function() { vc_set_as_theme(); });

// Disable frontend editor
vc_disable_frontend();

// Set post types for WPBakery
vc_set_default_editor_post_types(['page', 'post', 'my_cpt']);
vc_editor_set_post_types(['page', 'post']);

// Override template directory
vc_set_shortcodes_templates_dir(get_stylesheet_directory() . '/vc_templates');

Template Override

Copy element templates from: wp-content/plugins/js_composer/include/templates/shortcodes/{base}.php

To: wp-content/themes/your-theme/vc_templates/{base}.php

Templates must echo output, not return it. Custom directory via vc_set_shortcodes_templates_dir().

Default Templates

add_action('vc_load_default_templates_action', function() {
    vc_add_default_templates([
        'name'         => 'My Template',
        'weight'       => 0,
        'image_path'   => plugins_url('images/thumb.jpg', __FILE__),
        'custom_class' => 'my_template',
        'content'      => '[vc_row][vc_column][vc_column_text]Hello[/vc_column_text][/vc_column][/vc_row]',
    ]);
});

// Filter to modify/remove defaults
add_filter('vc_load_default_templates', function($data) {
    return array(); // removes all
});

Grid Builder

Grid Shortcodes

  • vc_basic_grid — Post grid (posts, pages, CPTs)
  • vc_media_grid — Media library grid
  • vc_masonry_grid — Masonry post grid
  • vc_masonry_media_grid — Masonry media grid

Custom Grid Elements

add_filter('vc_grid_item_shortcodes', function($shortcodes) {
    $shortcodes['my_grid_el'] = [
        'name' => 'My Grid Element',
        'base' => 'my_grid_el',
        'category' => 'Content',
        'post_type' => Vc_Grid_Item_Editor::postType(),
    ];
    return $shortcodes;
});
add_shortcode('my_grid_el', function($atts) {
    return '{{ post_data:post_title }}';
});

Grid Template Variables

  • {{ post_data:ID }} — Post ID
  • {{ post_data:post_title }} — Title
  • {{ featured_image:data }} — Featured image
  • Custom: register via vc_gitem_template_attribute_{name} filter

Grid Zones

  • Normal — Main display (3 rows, dividable into columns)
  • Hover — On hover (requires animation preset ≠ "Single block")
  • Additional — Around Normal/Hover, not animated

WooCommerce Element Removal

WooCommerce elements use different hooks than standard elements:

function remove_woo_elements() {
    if (is_plugin_active('woocommerce/woocommerce.php')) {
        vc_remove_element('woocommerce_cart');
        vc_remove_element('recent_products');
    }
}
add_action('vc_build_admin_page', 'remove_woo_elements', 11);
add_action('vc_load_shortcode', 'remove_woo_elements', 11);