Informations

47936 views
Medium

Ingredients

  • WordPress v4.5+required
  • Visual Composer Plugin v4.xx+required
  • Directly related tutorialadvised
  • Basic PHP/WP knowledge

STEPS

If you’ve used Visual Composer in developing of themes probably you’ve thought at least one time to create your custom block.
Well, this tutorial will explain how to do it, but before to start I strongly suggest you read the basic tutorial to integrate Visual Composer in your themeadvised

1. Where to include your code

As I wrote in other similar tutorials, the code position is a personal choice. Most tutorials on the net recommend to place any function in the functions.php file in the theme folder. I believe instead that it’s better to create a separate file for the Visual Composer setup in which to place all features.
In this tutorial I’ll share my way to include an element on Visual Composer. I think it’s a really clean way.

So you have to create a folder in your theme’s root folder. I decided to create a vc-elements folder in my theme’s root.
Inside vc-elements folder you can create a php file that will contain your new element. I created for example my-first-custom-element.php

The file you just created is still not in WP so we’re going to require it.
If you followed the related tutorial that I reported on the heading you’ll know how to add actions to the hook vc_before_init, but let me show you the code once again.

Add the following code in function.php in your theme. It’s called BEFORE the Visual Composer initialization:
// Before VC Init
add_action( 'vc_before_init', 'vc_before_init_actions' );

function vc_before_init_actions() {
	
	//.. Code from other Tutorials ..//

	// Require new custom Element
	require_once( get_template_directory().'/vc-elements/my-first-custom-element.php' ); 
	
}

Code explanation

  • row 02: I added an action to the vc_before_init VC hook, so my function will be called before VC init
  • row 09: I required the file we just created my-first-custom-element.php and to find its absolute path I used get_template_directory()
Now we can finally start to add code in our new file!
Note: if you want to edit or customize a Visual Composer default block please follow the tutorial How-To: customize default elements in Visual Composer advised

2. Initialize your new Element

Before to show you the element code I have to say that there are many ways to build it, I will show you my way. I commonly create a php Class to extend the WPBakeryShortCode Class so I can include all the code in the same place and it allows to do a clean work.
My Class consists of 3 parts:
  1. Shortcode Init
  2. Shortcode Map (parameters)
  3. Shortcode HTML
But now it’s time to paste the code for the Class structure:
/*
Element Description: VC Info Box
*/

// Element Class 
class vcInfoBox extends WPBakeryShortCode {
    
	// Element Init
	function __construct() {
        add_action( 'init', array( $this, 'vc_infobox_mapping' ) );
        add_shortcode( 'vc_infobox', array( $this, 'vc_infobox_html' ) );
    }
 	
	// Element Mapping
    public function vc_infobox_mapping() {
        
		//.. the Code is in the next steps ..//				  			  
	   
    } 
	
	
	// Element HTML
	public function vc_infobox_html( $atts ) {
		
		//.. the Code is in the next steps ..//
		
	} 
	
} // End Element Class

// Element Class Init
new vcInfoBox();	

Code explanation

  • row 02: I advise to put a description about the element you are developing
  • row 06: I extended the WPBakeryShortCode class with new element class vcInfoBox
  • row 09: I added a __construct() function to initialize the functions in the class
  • row 10: I added an action to initialize the element’s mapping function vc_infobox_mapping() (row: 15)
  • row 11: I used add_shortcode() function to create the new shortcode for the element. In the first parameter I passed the slug for the shortcode vc_infobox and in the second parameter I passed an array to call the element’s HTML function vc_infobox_html() (row: 23)
  • row 15: vc_infobox_mapping() function (explained in the next steps)
  • row 23: vc_infobox_html() function (explained in the next steps)
  • row 32: After the end of the Class,so outside the class, you have to initialize it so Visual Composer will be able to include your element in the list

3. Mapping the Element

It’s time to use the famous vc_map() function, that allows to add new elements inside Visual Composer and to assign them custom params/attributes.

So we can edit our vc_infobox_mapping() function:
// Element Mapping
public function vc_infobox_mapping() {
        
	// Stop all if VC is not enabled
	if ( !defined( 'WPB_VC_VERSION' ) ) {
            return;
    }
		
	// Map the block with vc_map()
	vc_map( 
 
        array(
			'name' => __('VC Infobox', 'text-domain'),
			'base' => 'vc_infobox',
			'description' => __('Another simple VC box', 'text-domain'), 
			'category' => __('My Custom Elements', 'text-domain'),   
			'icon' => get_template_directory_uri().'/assets/img/vc-icon.png',            
			'params' => array(   
					 
				array(
					'type' => 'textfield',
					'holder' => 'h3',
					'class' => 'title-class',
					'heading' => __( 'Title', 'text-domain' ),
					'param_name' => 'title',
					'value' => __( 'Default value', 'text-domain' ),
					'description' => __( 'Box Title', 'text-domain' ),
					'admin_label' => false,
					'weight' => 0,
					'group' => 'Custom Group',
				),  
				 
				array(
					'type' => 'textarea',
					'holder' => 'div',
					'class' => 'text-class',
					'heading' => __( 'Text', 'text-domain' ),
					'param_name' => 'text',
					'value' => __( 'Default value', 'text-domain' ),
					'description' => __( 'Box Text', 'text-domain' ),
					'admin_label' => false,
					'weight' => 0,
					'group' => 'Custom Group',
				)                   
					
			)
		)
	);                   			  
	   
}

Code explanation

  • row 05-07: If Visual Composer is not enabled the function stops, avoiding the Fatal Error.
  • row 10: I called the function vc_map() passing an Array of options and params
  • row 10: A human friendly name for the element. It will be displayed in the list of elements in VC. how-to-create-a-custom-new-block-in-visual-composer-01
  • row 14: This must be extactly the shortcode slug you defined in previous step on the row 11.
  • row 15: A human friendly description for the element. It will be displayed in the list of elements in VC. how-to-create-a-custom-new-block-in-visual-composer-02
  • row 16: Using the category attribute is allowing you to create a custom tab for your personal elements in the VC list of elements. If you don’t add this attribute, your element will be placed in the “All” tab. how-to-create-a-custom-new-block-in-visual-composer-03
  • row 17: The icon attribute allows to add a custom icon for the element. I created and uploaded my icon in the img folder in my theme and I used get_template_directory_uri() function to reach it. how-to-create-a-custom-new-block-in-visual-composer-04
  • row 18: params attribute is the heart of the Mapping. You can pass here an array of arrays adding unlimited params to your custom element.
  • row 21: The field type. In our example it’s a simple textfield (input type text).
  • row 22: HTML tag name where Visual Composer will store attribute value in Visual Composer edit mode. Default: hidden input.
  • row 23: Class name that will be added to the “holder” HTML tag. Useful if you want to target some CSS rules to specific items in the backend edit interface.
  • row 24: Human friendly title of your param. Will be visible in shortcode’s edit screen.
  • row 25: Will be the “name” attribute for your field. Use only _ for multiple words and try to add unique names because it will be used to save the data.
  • row 26: Default value
  • row 27: Human friendly description of your param. Will be visible in shortcode’s edit screen.
  • row 28: Show/Hide value of param in Visual Composer editor.
  • row 29: Params with greater weight will be rendered first respect the other params.
  • row 30: Use it to divide your params within groups/tabs (the position of the tab is influenced by the previous option).
  • row 33-44: I added another param (a textarea to add some text). You can add any else arrays/params here.
Now our custom element has its params and can it appears in the VC list of elements but it can’t be displayed in frontend because it’s missing the HTML code to render it.

4. Element HTML

We are finally ready to work on the frontend layout, so let’s edit our vc_infobox_html() function:
// Element HTML
public function vc_infobox_html( $atts ) {
	
	// Params extraction
	extract(
		shortcode_atts(
			array(
				'title'   => '',
				'text' => '',
			), 
			$atts
		)
	);
	
	// Fill $html var with data
	$html = '
	<div class="vc-infobox-wrap">
	
		<h2 class="vc-infobox-title">' . $title . '</h2>
		
		<div class="vc-infobox-text">' . $text . '</div>
	
	</div>';		
	
	return $html;
	
}

Code explanation

  • row 02: I start saying that we have to set a variable ($atts) in the function in order to contain our attribute values.
  • row 05: This function is extracting all the values from the DB and is putting them in some variables.
  • row 08: I extract the title param. It must be exactly the same name you used in the params mapping (previous step, row 25). You can also pass a default value in case of empty value. I don’t need to add a default value so I leave it blank.
    Note: the function will create a var $title and the name is exactly the param name you passed.
  • row 09: I extract the text param. It must be exactly the same name you used in the params mapping (previous step, row 38). You can also pass a default value in case of empty value. I don’t need to add a default value so I leave it blank.
    Note: the function will create a var $text and the name is exactly the param name you passed.
  • row 11: I pass to the function the $atts variable where the data is saved (as described for the row 02)
  • row 16-23: I fill a $html variable with the HTML code adding also my 2 attributes $title and $text
  • row 25: I finally return the $html variable rendering my custom element in frontend.

5. Result and Complete Code

This is our backend result: how-to-create-a-custom-new-block-in-visual-composer-05
And this is our frontend result: how-to-create-a-custom-new-block-in-visual-composer-06
If you need the complete code paste in your function.php file this function:
// Before VC Init
add_action( 'vc_before_init', 'vc_before_init_actions' );

function vc_before_init_actions() {
	
	//.. Code from other Tutorials ..//

	// Require new custom Element
	require_once( get_template_directory().'/vc-elements/my-first-custom-element.php' ); 
	
}
And paste in your my-first-custom-element.php file this class:
/*
Element Description: VC Info Box
*/

// Element Class 
class vcInfoBox extends WPBakeryShortCode {
    
	// Element Init
	function __construct() {
        add_action( 'init', array( $this, 'vc_infobox_mapping' ) );
        add_shortcode( 'vc_infobox', array( $this, 'vc_infobox_html' ) );
    }
 	
	// Element Mapping
    public function vc_infobox_mapping() {
        
		// Stop all if VC is not enabled
		if ( !defined( 'WPB_VC_VERSION' ) ) {
            return;
        }
		
		// Map the block with vc_map()
		vc_map( 
			array(
				'name' => __('VC Infobox', 'text-domain'),
				'base' => 'vc_infobox',
				'description' => __('Another simple VC box', 'text-domain'), 
				'category' => __('My Custom Elements', 'text-domain'),	
				'icon' => get_template_directory_uri().'/assets/img/vc-icon.png',	 		
				'params' => array(	
						
					array(
						'type' => 'textfield',
						'holder' => 'h3',
						'class' => 'title-class',
						'heading' => __( 'Title', 'text-domain' ),
						'param_name' => 'title',
						'value' => __( 'Default value', 'text-domain' ),
						'description' => __( 'Box Title', 'text-domain' ),
						'admin_label' => false,
						'weight' => 0,
						'group' => 'Custom Group',
					),  
					
					array(
						'type' => 'textarea',
						'holder' => 'div',
						'class' => 'text-class',
						'heading' => __( 'Text', 'text-domain' ),
						'param_name' => 'text',
						'value' => __( 'Default value', 'text-domain' ),
						'description' => __( 'Box Text', 'text-domain' ),
						'admin_label' => false,
						'weight' => 0,
						'group' => 'Custom Group',
					),  					
					   
				),
			)
		);					  			  
	   
    }
	
	
	// Element HTML
	public function vc_infobox_html( $atts ) {
		
		// Params extraction
		extract(
			shortcode_atts(
				array(
					'title'   => '',
					'text' => '',
				), 
				$atts
			)
		);
		
		// Fill $html var with data
		$html = '
		<div class="vc-infobox-wrap">
		
			<h2 class="vc-infobox-title">' . $title . '</h2>
			
			<div class="vc-infobox-text">' . $text . '</div>
		
		</div>';		
		
		return $html;
		
	}
	
} // End Element Class


// Element Class Init
new vcInfoBox();	
  • Aris Mistakidis

    To the point explanation and documentation. Well Played.

  • Sandip patel

    nothing work. i have same issue

Your Personal Notes