WPBakery Page Builder (Visual composer) пример добавления шорткода

Платный плагин WPBakery Page Builder (ранее Visual Composer) для WordPress позволяет создавать страницы из блоков(шорткодов), добавляя их в строку разделенную на колонки. Таким образом на фронтенде можно добиться довольно таки интересного результата, но это при условии, что нет дизайна или дизайнер действительно рисовал макет под возможности плагина.

Но что делать, если есть дизайн и он никак не соответствует возможностям плагина? А это бывает очень часто, и пользователям плагина в большинстве случаев приходится обращаться к разработчикам, чтобы они создали новый шорткод под дизайн макета, которым можно будет так же легко управлять как и блоками(шорткодами) предлогаемыми плагином по умолчанию.

Ниже приведен пример кода без каких либо усложнений и описание параметров для его работы. Таким образом — это основа для создания уникальных блоков для Visual Composer из темы. Готовый код, так же можно оформить в виде мини плагина, все зависит от результата который необходим.

function.php

add_action( 'vc_before_init', 'theme_vc_shortcodes' );
function theme_vc_shortcodes() {
    $shortcode_file = get_template_directory_uri() . '/shortcodes/example.php';

    require_once $shortcode_file;
}

shortcodes/example.php

if ( ! defined( 'ABSPATH' ) ) {
	die( '-1' );
}

class WPBakeryShortCode_theme_test extends WPBakeryShortCode {
    protected function content( $atts, $content = null ) {
        $output = '';

        extract( shortcode_atts( array(
            'title' => '',
        ), $atts ) );

        $width_class = '';
        $css_class = apply_filters( VC_SHORTCODE_CUSTOM_CSS_FILTER_TAG, $width_class, $this->settings['base'], $atts );

        ob_start(); ?>

        <div class="content-holder">
            <?php if( $title ) : ?>
                <h2><?php echo $title ?></h2>
            <?php endif ?>
        </div>

        <?php $output = ob_get_contents();
        ob_end_clean();

        return $output;
    }
}

vc_map( array(
    'base' => 'theme_test',
    'name' => __( 'Test', 'text-domain' ),
    'class' => '',
    'category' => __( 'Theme Shortcodes' ),
    'icon' => 'icon-heart',
    'params' => array(
        array(
            'type' => 'textfield',
            'holder' => 'div',
            'class' => '',
            'heading' => __( 'Title', 'text-domain' ),
            'param_name' => 'title',
            'value' => '',
            'description' => __( 'Enter title.', 'text-domain' ),
        ),
    ),
) );

name(string) название шорткода, используется в админке

base(string) тег шорткода, из примера my_hello_world будет такой шорткод [my_hello_world], так же нужно указывать название тега в названии класса, пример WPBakeryShortCode_my_hello_world

description(string) краткое описание шорткода, будет видно в окне «Добавить элемент»

class(string) CSS класс, который будет добавлен в бэкэнд на обвертку шорткода

show_settings_on_create(boolean) если установить false, то при добавлении шорткода блок с настройками отображаться не будет

weight(integer) для сортировки отображения шорткодов в админке, шорткод с большим весом будут отображаться в начале сетки

category(string) название таба(категория), в котором будет отображен шорткод

group(string) группировка параметров в группы

admin_enqueue_js(string|array) URL-адрес для подключения javascript-файла(backbone.js) в админке

admin_enqueue_css(string|array) URL-адрес для подключения css-файла в админке

front_enqueue_js(string|array) URL-адрес для подключения javascript-файла(backbone.js) при редактировании шорткода на фронтенд

front_enqueue_css(string|array) URL-адрес для подключения css-файла при редактировании шорткода на фронтенд

icon(string) URL или CSS класс с иконкой

custom_markup(string) html-разметка для блока в редакторе

js_view(string) backbone.js view для шорктода

html_template(string) можно переназначить путь к файлу вывода html шорткода.

deprecated(string) если указать номер версии, то шорткод переместится во вкладку «Устаревшие»

content_element(boolean) если указать false, то шорткод будет скрыт, используется вместе с параметром ‘deprecated’

params(array) настройка вида отображения полей

Список параметров для params

type(string) тип поля

holder(string) HTML тег, обвертка где Visual Composer будет отображать значение атрибута, по умолчанию: hidden input

class(string) css класс, для holder.

heading(string) название для поля

param_name(string) параметр шорткода

value(string|array) value значение

description(string) описание для поля

dependency(array) установка видимости поля в зависимости от другого value поля.

group(string) использование групп, для разделения полей по табам

Доступные типы полей

textarea_html — WYSIWYG редактор ( разрешен только один html редактор для одного шорткода ).

array(
    'type' => 'textarea_html',
    'heading' => __( 'textarea_html example', 'text-domain' ),
    'param_name' => 'example1',
    'value' => '',
    'description' => __( 'Enter description.', 'text-domain' )
)

textfield — input поле

array(
    'type' => 'textfield',
    'heading' => __( 'textfield example', 'text-domain' ),
    'param_name' => 'example2',
    'value' => '',
    'description' => __( 'Enter description.', 'text-domain' )
)

textarea — textarea поле

array(
    'type' => 'textarea',
    'heading' => __( 'textarea example', 'text-domain' ),
    'param_name' => 'example3',
    'value' => '',
    'description' => __( 'Enter description.', 'text-domain' )
)

dropdown — select поле ( обычный массив, либо ассоциативный массив )

array(
    'type' => 'dropdown',
    'heading' => __( 'dropdown example',  'text-domain' ),
    'param_name' => 'example4',
    'value' => array(
        __( 'Option 1 Label',  'text-domain'  ) => 'option1value',
        __( 'Option 2 Label',  'text-domain'  ) => 'option2value',
        __( 'Option 3 Label',  'text-domain'  ) => 'option3value',
    ),
    'description' => __( 'Enter description.', 'text-domain' )
)

attach_image — картинка

array(
    'type' => 'attach_image',
    'heading' => __( 'attach_image example', 'text-domain' ),
    'param_name' => 'example5',
    'value' => '',
    'description' => __( 'Enter description.', 'text-domain' )
)

attach_images — картинки

array(
    'type' => 'attach_images',
    'heading' => __( 'attach_images example', 'text-domain' ),
    'param_name' => 'example6',
    'value' => '',
    'description' => __( 'Enter description.', 'text-domain' )
)

posttypes — чекбоксы с доступными пост тайпами

array(
    'type' => 'posttypes',
    'heading' => __( 'posttypes example', 'text-domain' ),
    'param_name' => 'example7',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

colorpicker — color picker

array(
    'type' => 'colorpicker',
    'heading' => __( 'colorpicker example', 'text-domain' ),
    'param_name' => 'example8',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

exploded_textarea — textarea поле ( каждая строка будет разделена запятой )

array(
    'type' => 'exploded_textarea',
    'heading' => __( 'exploded_textarea example', 'text-domain' ),
    'param_name' => 'example9',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

widgetised_sidebars — select поле с набором доступных сайдбаров

array(
    'type' => 'widgetised_sidebars',
    'heading' => __( 'widgetised_sidebars example', 'text-domain' ),
    'param_name' => 'example10',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

textarea_raw_html — textarea поле для хранения js, html ( содержимое будет закодировано в base64 )

array(
    'type' => 'textarea_raw_html',
    'heading' => __( 'textarea_raw_html example', 'text-domain' ),
    'param_name' => 'example11',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

vc_link — создание ссылки

array(
    'type' => 'vc_link',
    'heading' => __( 'vc_link exampleexample', 'text-domain' ),
    'param_name' => 'example12',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

checkbox — checkbox поле

array(
    'type' => 'checkbox',
    'heading' => __( 'checkbox example', 'text-domain' ),
    'param_name' => 'example13',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

loop — создание запроса

array(
    'type' => 'loop',
    'heading' => __( 'loop example', 'text-domain' ),
    'param_name' => 'example14',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

css — вкладка с CSS редактором

array(
    'type' => 'css',
    'heading' => __( 'css example', 'text-domain' ),
    'param_name' => 'example15',
    'value' => '', 
    'description' => __( 'Enter description.', 'text-domain' )
)

Доступные параметры для dependency

element(string) value указанное в param_name

value(array) список value при котором будет отображено поле

not_empty(boolean) поле будет отображено при условии, что поле заполнено

callback(string) название javascript функции ( будет вызываться при изменении значения связанного поля )

Вложенный шорткод

пример из документации

//Register "container" content element. It will hold all your inner (child) content elements
vc_map( array(
    "name" => __("Your Gallery", "my-text-domain"),
    "base" => "your_gallery",
    "as_parent" => array('only' => 'single_img'), // Use only|except attributes to limit child shortcodes (separate multiple values with comma)
    "content_element" => true,
    "show_settings_on_create" => false,
    "is_container" => true,
    "params" => array(
        // add params same as with any other content element
        array(
            "type" => "textfield",
            "heading" => __("Extra class name", "my-text-domain"),
            "param_name" => "el_class",
            "description" => __("If you wish to style particular content element differently, then use this field to add a class name and then refer to it in your css file.", "my-text-domain")
        )
    ),
    "js_view" => 'VcColumnView'
) );

vc_map( array(
    "name" => __("Gallery Image", "my-text-domain"),
    "base" => "single_img",
    "content_element" => true,
    "as_child" => array('only' => 'your_gallery'), // Use only|except attributes to limit parent (separate multiple values with comma)
    "params" => array(
        // add params same as with any other content element
        array(
            "type" => "textfield",
            "heading" => __("Extra class name", "my-text-domain"),
            "param_name" => "el_class",
            "description" => __("If you wish to style particular content element differently, then use this field to add a class name and then refer to it in your css file.", "my-text-domain")
        )
    )
) );

//Your "container" content element should extend WPBakeryShortCodesContainer class to inherit all required functionality
if ( class_exists( 'WPBakeryShortCodesContainer' ) ) {
    class WPBakeryShortCode_Your_Gallery extends WPBakeryShortCodesContainer {
    }
}
if ( class_exists( 'WPBakeryShortCode' ) ) {
    class WPBakeryShortCode_Single_Img extends WPBakeryShortCode {
    }
}