Nested Shortcodes (container)

⌘K
  1. Home
  2. Docs
  3. Developers “How To&...
  4. Nested Shortcodes (container)

Nested Shortcodes (container)

SINCE 3.7

If you have a complex shortcode which consists of nested shortcodes as shown below, you can easily “map” them to the WPBakery Page Builder element list.

[your_gallery param="foo"]
 [single_img]
 [single_img]
 [single_img]
[/your_gallery]

So in this example [your_gallery] will be a container which can accept only [single_img] elements. Below is code snippet to get you started:

add_action( 'vc_before_init', function() {
    // Register "container" content element. It will hold all your inner (child) content elements.
    vc_map(
        [
            'name'                     => __( 'Your Gallery', 'my-text-domain' ),
            'base'                     => 'your_gallery',

            // Use only|except attributes to limit child shortcodes.
            // Don't use 'as_parent' to let all possible elements.
            'as_parent'               => [
                'only' => 'single_img',
            ],

            'content_element'         => true,
            'show_settings_on_create' => false,
            'is_container'            => true,

            'params'                  => [
                [
                    'type'       => 'colorpicker',
                    'heading'    => __( 'Background Color', 'my-text-domain' ),
                    'param_name' => 'bg_color',
                    'value'      => '#BED74247',
                ],
            ],

            'js_view'                 => 'VcColumnView',
        ]
    );

    // Register inner element.
    vc_map(
        [
            'name'            => __( 'Gallery Image', 'my-text-domain' ),
            'base'            => 'single_img',
            'content_element' => true,

            // Use only|except attributes to limit parent (separate multiple values with comma)
            'as_child'        => [
                'only' => 'your_gallery',
            ],

            'params'          => [
                [
                    'type'        => 'attach_image',
                    'heading'     => __( 'Image', 'my-text-domain' ),
                    'param_name'  => 'image_id',
                    'description' => __( 'Select image from media library.', 'my-text-domain' ),
                ],
            ],
        ]
    );
} );

if ( class_exists( 'WPBakeryShortCodesContainer' ) ) {
    /**
     * Custom WPBakery custom element class.
     *
     * @note You should extend your custom class with WPBakeryShortCodesContainer for the container element;
     * otherwise, the element won't have all controls in the editor.
     *
     * @note Class name always should start with WPBakeryShortCode_ prefix.
     * Another part of name should be the same as the base name of the element specified in vc_map with UPPER_SNAKE_CASE.
     */
    class WPBakeryShortCode_Your_Gallery extends WPBakeryShortCodesContainer {
        /**
         * Shortcode output.
         *
         * @param array  $atts    Shortcode attributes.
         * @param string $content Shortcode content.
         * @return string
         */
        public function content( $atts, $content = '' ) {
            $atts = shortcode_atts(
                [
                    'bg_color' => '#BED74247',
                ],
                $atts,
                'your_gallery'
            );

            $style  = 'background-color:' . esc_attr( $atts['bg_color'] ) . ';';
            $style .= 'padding: 30px; border-radius: 10px; margin-bottom: 20px;';

            $output  = '<div class="vc-dev-example-container" style="' . esc_attr( $style ) . '">';
            $output .= do_shortcode( $content );
            $output .= '</div>';

            return $output;
        }
    }
}

if ( class_exists( 'WPBakeryShortCode' ) ) {
    class WPBakeryShortCode_Single_Img extends WPBakeryShortCode {
        /**
         * Shortcode output.
         *
         * @param array  $atts    Shortcode attributes.
         * @param string $content Shortcode content.
         * @return string
         */
        public function content( $atts, $content = '' ) {
            $atts = shortcode_atts(
                [
                    'image_id' => '',
                ],
                $atts,
                'single_img'
            );

            if ( empty( $atts['image_id'] ) ) {
                return ''; // No image selected.
            }

            // Get image HTML.
            $image_html = wp_get_attachment_image(
                $atts['image_id'],
                'full',
                false,
                [
                    'class' => 'vc-dev-example-image',
                    'style' => 'max-width: 100%; height: auto; margin-bottom: 10px;',
                ]
            );

            return '<div class="vc-dev-example-image-wrapper">' . $image_html . '</div>';
        }
    }
}
Was this article helpful to you? No Yes

How can we help?