---
description: https://wolfactive.dev/huong-dan-tao-custom-widget-cho-plugin-wpbakery/
---

# Hướng dẫn tạo custom widget cho plugin WPBakery

## Hướng dẫn tạo custom widget cho plugin WPBakery

Chào các bạn, ở bài này **WolfActive** tụi mình sẽ cho ra một bài viết liên quan đến **WPBakery.** Chắc hẳn đối với các bạn sử dụng WP dạng kéo thả, thì cũng không xa lạ gì nhiều với **WPBakery** nhỉ? Tuy nhiên hẳn sẽ có những Widgets mà bạn không ưng ý hoặc bạn không tìm thấy widgets mình cần. Thì bây giờ tụi mình sẽ chỉ cho các bạn qua bài [Hướng dẫn tạo plugin widgets extend WPBakery](https://wolfactive.dev/theme_products/huong-dan-tao-tao-plugin-widgets-extend-wpbakery/).

### 1/ Tạo Plugin

Đầu tiên các bạn cần phải tạo một plugin của chính bạn để có thể extend widgets của WPBakery. Như ở hình dưới, mình tạo một folder Plugin tên **wa-add-on-wp-bakery**. Trong folder này mình có tạo một file tên **plugin.php.**&#x20;

![](https://wolfactive.dev/wp-content/uploads/Capture-101.png)

Trong file **plugin.php** các bạn ghi những dòng sau vào comment.

```
/**
 * Plugin Name:       Wa Add on WpBakery
 * Plugin URI:        wolfactive.dev
 * Description:       director by wa
 * Version:           1.10.3
 * Author:            director by wa
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       wa-add-on-wp-bakery
 * Domain Path:       /languages
 */
```

Các dòng **comment** trên là các thông tin cần thiết để đặt tên và thông tin của plugin các bạn. Bây giờ kế tiếp các bạn cần tạo một **class** để tạo plugin

```
class Wa_Add_On_WpBakery{
    function __construct(){
        add_action( 'admin_notices', array($this,'check_condition'));
        add_action('init', array($this,'init'));
    }
    public function init(){
        $this->include_widgets();        
    }
    public function check_condition(){
        if(!is_plugin_active('js_composer/js_composer.php') || !defined('WPB_VC_VERSION')){
            $class = 'notice notice-error';
            $message = __( 'Cài WPBakery', 'wa-add-on-wp-bakery' );
            printf( '%2$s', esc_attr( $class ), esc_html( $message ) );
            return;
        }
    }
    private function include_widgets(){
        $dir= __DIR__;
        include_once($dir.'/widgets/text-box-widget.php');
        
    }
}
new Wa_Add_On_WpBakery();
```

Ở đây mình đặt một class tên **Wa\_Add\_On\_WpBakery.** Chắc hẳn các bạn cũng biết đến **OOP** nhỉ?! Bên trong class mình sẽ tạo một **function construct**. Tức đây là hàm khởi tạo khi plugin được hoạt đông.Bên cạnh đó mình có tạo hai function, Một là **check\_condition(),** đây là function dùng để check xem các bạn có **cài** và **active plugin** **WPBakery** hay chưa (ở đây trong **js\_composer.php** chính là **WPBakery** đó) bên cạnh đó xem có **Visual Composer** hay không? Nếu cả một trong hai không thỏa điều kiện, thì sẽ báo lỗi như ở trong function.Hai là function **include\_widgets(),** trong function này mình có tạo một biến **$dir=\_\_DIR\_\_** là đường dẫn thư mục ngay tại file đang viết, các bạn có thể đọc thêm [ở đây](https://www.php.net/manual/en/language.constants.predefined.php)![](https://wolfactive.dev/wp-content/uploads/Capture0-1.png)

### 2/ Tạo widgets và render

Trong folder widgets, mình có tạo một file **text-box-widget.php.**&#x1EDE; file này mình tạo một class **WaTextBoxWidgets** và kế thừa class **WPBakeryShortCode** của **WPBakery.** Sau đó mình tạo **function construct,** và một **function create shortcode.**&#x54;rong function **create shortcode**, mình sẽ kiểm tra xem có **Visual Composer (WPB\_VC\_VERSION)** hay không. Sau đó mình sử dụng một hàm **vc\_map()** để tạo field cho widgets (các bạn có thể xem thêm các field của nó [tại đây](https://www.sodawebmedia.com/blog/wpbakery-page-builder-formerly-visual-composer-vc_map-field-examples/)). Ở đây mình tạo ba field: **Text field, link, image.**&#x53;au đó mình bắt đầu **render** nó ra ngoài html, bằng cách tạo một **function render\_shortcode().** Tại đây mình tạo một **array** lấy thông tin, nội dung từ các **param\_name** mà mình tạo trước đó để truyền vào một biến **$atts.** Rồi mình **gán** từng giá trị, nội dung, thông tin vào các biến như trên.Sau khi gán xong, mình bắt đầu việc lưu content lại bằng hàm **ob\_start** và kết thúc nó bằng **ob\_end\_clean** và lưu nội dung bằng **ob\_get\_contents.** Các bạn có thể thấy trong lúc mình lưu **content** lại mình có **include** một file là **text-box-template.php** để dễ dàng **render html** ra hơn.

```
class WaTextBoxWidgets extends WPBakeryShortCode {
        //Initialize Component
        function __construct() {
            add_action( 'init', array( $this, 'create_shortcode' ), 999 );            
            add_shortcode( 'wa_text_box', array( $this, 'render_shortcode' ) );
        }        
        //Map Component
        public function create_shortcode() {
        
            //Code in the next steps
            if ( !defined( 'WPB_VC_VERSION' ) ) {
                return;
            }
            
            vc_map( array(
                'name'          => __('Wa TextBox ', 'wa-add-on-wp-bakery'), //Tên Widgets,tên Plugin
                'base'          => 'wa_text_box', // tên shortcode mà bạn sẽ gọi ở add_shortcode trong construct()
                'description'   => __( 'Text Box wa', 'wa-add-on-wp-bakery' ),
                'category'      => __( 'wa module', 'wa-add-on-wp-bakery'),                
                'params' => array(
                    array(
                        "type" => "textfield",
                        "class" => "",
                        "heading" => __( "Heading", "wa-add-on-wp-bakery" ), //Label của textfield
                        "param_name" => "wa_textbox_heading", //tên param
                        "value" => __( "", "wa-add-on-wp-bakery" ),
                        "description" => __( "Enter description.", "wa-add-on-wp-bakery" )
                    ),
                    array(
                        "type" => "vc_link",
                        "class" => "",
                        "heading" => __( "Links", 'wa-add-on-wp-bakery' ),
                        "param_name" => "wa_link",
                        "description" => __( "Add Your Url", 'wa-add-on-wp-bakery' ),                                                
                    ),
                    array(
                        "type" => "attach_image",
                        "class" => "",
                        "heading" => __( "Image", "wa-add-on-wp-bakery" ),
                        "param_name" => "wa_img",
                        "value" => '',
                        "description" => __( "Enter description.", "wa-add-on-wp-bakery" )
                      )    
                ),
            ));
        }
        //Render Component
        public function render_shortcode( $atts, $content, $tag ) {
            //Code in the next steps
            extract((shortcode_atts(
                //tạo array gọi các param_name ở trên để lấy nội dung
                array(
                'wa_textbox_heading'   => '',
                'wa_link' => '',
                'wa_img'=>'',
            ), $atts)));
            //Heading
            $heading = wpb_js_remove_wpautop($content, true); //Dùng để loại bỏ các thẻ breakline như br mỗi khi các bạn xuống dòng. Cái này các bạn dùng trong textarea là được.
            $textbox_heading = esc_html($atts['wa_textbox_heading']); // display content nhập vào từ field
            //Links
            $wa_source  = vc_build_link( $atts['wa_link'] ); //Chuyển post/page mình chọn về dạng link (ở đây có 2 loại phân dạng: title và url)
            $wa_url     = esc_url( $wa_source['url'] ); // display url của post/page
            //img 
            $wa_image_url     = wp_get_attachment_image_src($atts['wa_img']); //lấy thông tin img mình chọn
            
            ob_start(); // bắt đầu quá trình lưu thông tin code
            $directory = plugin_dir_path( __FILE__ ); // lấy path của plugin
            
            include_once( $directory.'template/text-box-template.php' );
            $output=ob_get_contents(); // lưu nội dung vào một biến
            ob_end_clean(); //điểm dừng của thông tin được lưu
            return $output;
        }
    }
    new WaTextBoxWidgets();
```

Và đây là file **text-box-template.php** của mình

```
<div class="wa-widgets-extend-wpbakery">
   <div class="wa-heading">
    <h1><?php echo $textbox_heading;?></h1>
   </div>
   <div class="wa-img">
     <a href="<?php echo $wa_url?>">
      <img src="<?php echo $wa_image_url[0]?>" alt="img">
     </a>
   </div>
</div>
```

Và đây là thành phẩm:

![](https://wolfactive.dev/wp-content/uploads/Capture0-2.png)

### 3/ Khai báo file css, js vào plugin

Bên cạnh đó mình sẽ hướng dẫn thêm các bạn về cách include file **js** và **css** vào plugin. Các bạn có thể add nó vào sau **ob\_start()**

```
wp_register_style( 'wa_src',  plugins_url('/wa-add-on-wp-bakery/src/css/main.css'),__FILE__ );
            wp_enqueue_style('wa_src');
            wp_register_script( 'wa_src', plugins_url('/wa-add-on-wp-bakery/src/js/root.js'),__FILE__);
            wp_enqueue_script('wa_src');
```

### 4/ Tổng kết

Như vậy là mình đã hướng dẫn các bạn xong việc tạo plugin tạo **Widgets** từ extend **WPBakery** rồi. Chúc các bạn thành công nhé, mọi thông tin thắc mắc các bạn cứ liên hệ fb tụi mình nhé.
