1. Where to include your code
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.So you have to create a folder in your theme’s root folder. I decided to create a vc_elements folder in the theme’s root.
Inside vc-elements folder you can create a php file that will contain your new element. I created for example my-vc_custom_category_wc.php
The file you just created is still not in WP so we’re going to require it.
Add the following code in function.php in your theme. It’s called BEFORE the Visual Composer initialization:
@
// Before VC Init Add custom elements to VC
add_action( 'vc_before_init', 'vc_before_init_actions' );
function vc_before_init_actions() {
// Require new custom Element
require_once( get_template_directory().'/vc_elements/vc_custom_category_wc.php' );
}
@
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
Code for the Class structure:
@
/*
Element Description: VC Info Box
*/
// Element Class
class customProductCat extends WPBakeryShortCode {
// Element Init
function __construct() {
add_action( 'init', array( $this, 'custom_product_cat_mapping' ) );
add_shortcode( 'custom_product_category', array( $this, 'custom_product_cat_html' ) );
}
// Element Mapping
public function custom_product_cat_mapping() {
//.. the Code is in the next steps ..//
}
// Element HTML
public function custom_product_cat_html( $atts ) {
//.. the Code is in the next steps ..//
}
} // End Element Class
// Element Class Init
new customProductCat();
@
CODE EXPLANATION
-Extended the WPBakeryShortCode class with new element class vcInfoBox
-Added a __construct() function to initialize the functions in the class
-Added an action to initialize the element’s mapping function custom_product_cat_mapping()
Used add_shortcode() function to create the new shortcode for the element. In the first parameter I passed the slug for the shortcode custom_product_category and in the second parameter I passed an array to call the element’s HTML function custom_product_cat_html()
-custom_product_cat_mapping() function (explained in the next steps)
-custom_product_cat_html() function (explained in the next steps)
-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@
public function custom_product_cat_mapping( ) {
// Stop all if VC is not enabled
if ( !defined( 'WPB_VC_VERSION' ) ) {
return;
}
$args = array(
'type' => 'post',
'child_of' => 0,
'parent' => '',
'orderby' => 'id',
'order' => 'ASC',
'hide_empty' => false,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'product_cat',
'pad_counts' => false,
);
$order_by_values = array(
'',
__( 'Date', 'js_composer' ) => 'date',
__( 'ID', 'js_composer' ) => 'ID',
__( 'Author', 'js_composer' ) => 'author',
__( 'Title', 'js_composer' ) => 'title',
__( 'Modified', 'js_composer' ) => 'modified',
__( 'Random', 'js_composer' ) => 'rand',
__( 'Comment count', 'js_composer' ) => 'comment_count',
__( 'Menu order', 'js_composer' ) => 'menu_order',
);
$order_way_values = array(
'',
__( 'Descending', 'js_composer' ) => 'DESC',
__( 'Ascending', 'js_composer' ) => 'ASC',
);
// All this move to product
$categories = get_categories( $args );
$product_categories_dropdown = array();
$this->getCategoryChildsFull( 0, 0, $categories, 0, $product_categories_dropdown );
vc_map(
array(
'name' => __( 'Custom Product category', 'js_composer' ),
'base' => 'custom_product_category',
'icon' => 'icon-wpb-woocommerce',
'category' => __( 'WooCommerce', 'js_composer' ),
'description' => __( 'Show multiple products in a category', 'js_composer' ),
'params' => array(
array(
'type' => 'dropdown',
'heading' => __( 'Category', 'js_composer' ),
'value' => $product_categories_dropdown,
'param_name' => 'category',
'save_always' => true,
'description' => __( 'Product category list', 'js_composer' ),
),
),
)
);
}
@
CODE EXPLANATION
- If Visual Composer is not enabled the function stops, avoiding the Fatal Error.
- I called the function vc_map() passing an Array of options and params
- A human friendly name for the element. It will be displayed in the list of elements in VC.
- Base attribute this must be extactly the shortcode slug you defined in previous step.
- A human friendly description for the element. It will be displayed in the list of elements in VC.
- 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.
- The icon attribute allows to add a custom icon for the element.
- Params attribute is the heart of the Mapping. You can pass here an array of arrays adding unlimited params to your custom element.
- The field type. In our example it’s a simple dropdown..
- Name attribute human friendly title of your param. Will be visible in shortcode’s edit screen.
- “param_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.
- Value attribute hera are the options of the dropdown
- description of params attribute, human friendly description of your param. Will be visible in shortcode’s edit screen.
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 custom_product_cat_html() function:@
public function custom_product_cat_html( $atts ){
$atts = shortcode_atts( array(
'category' => '',
), $atts, 'product_categories' );
$category = get_term_by('slug', $atts['category'], 'product_cat');
$small_thumbnail_size = 'full';
$dimensions = wc_get_image_size( $small_thumbnail_size );
$thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true );
if ( $thumbnail_id ) {
$image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size );
$image = $image[0];
$image_srcset = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $thumbnail_id, $small_thumbnail_size ) : false;
$image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false;
} else {
$image = wc_placeholder_img_src();
$image_srcset = $image_sizes = false;
}
$html = '<style>
.pix-image-box a:before {
content: "";
display: block;
position: absolute;
top: 0;
z-index: 10;
bottom: 0;
left: 0;
right: 0;
background: rgba(15,85,122,0.5);
}
</style>';
$html .= '<div class="pix-image-box ">
<a href="' . esc_url( get_term_link( $category, 'product_cat' ) ) . '">';
if ( $image ) {
// Prevent esc_url from breaking spaces in urls for image embeds.
// Ref: https://core.trac.wordpress.org/ticket/23605.
$image = str_replace( ' ', '%20', $image );
// Add responsive image markup if available.
if ( $image_srcset && $image_sizes ) {
$html .= '<img src="' . esc_url( $image ) . '" alt="' . esc_attr( $category->name ) . '" srcset="' . esc_attr( $image_srcset ) . '" sizes="' . esc_attr( $image_sizes ) . '" class="attachment-full size-full" />';
} else {
$html .= '<img src="' . esc_url( $image ) . '" alt="' . esc_attr( $category->name ) . '" class="attachment-full size-full" />';
}
}
//$html .='<img width="450" height="255" src="http://dev-cruisehole.pantheonsite.io/wp-content/uploads/2017/10/ch_cruise_wear.jpg" class="attachment-full size-full" alt="">';
$html .= '<div class="image-box-entry-box" style="color:#ffffff;">
<div>
<div style="vertical-align:middle; text-align:center; text-transform: uppercase;">
<p style="margin: 0px; font-weight: 600;">' . esc_html( $category->name ) . '</p>
</div>
</div>
</div>
</a>
</div>';
return $html;
}
@
CODE EXPLANATION
-I start saying that we have to set a variable ($atts) in the function in order to contain our attribute values.
-This function is extracting all the values from the DB and is putting them in some variables.
-I extract the category param. It must be exactly the same name you used in the params mapping (previous step). 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 $category and the name is exactly the param name you passed.
-I get the category info to display it
-I fill a $html variable with the HTML code.
-I finally return the $html variable rendering my custom element in frontend.
No comments:
Post a Comment