# Tạo Custom Widget Elementor

## Tạo Custom Widget Elementor

Chào các bạn đến với **Wolfactive** tụi mình, ở bài này tụi mình sẽ hướng dẫn các bạn Tạo **Custom Widget Elementor**. Đối với các bạn thường hay sử dụng **elementor** để xây dựng giao diện, thì chắc các bạn cũng không lạ lẫm gì về **Elementor** nữa nhỉ? Nhưng sẽ có những widget của elementor mà bạn không ưng ý, hoặc phải trả tiền bản pro mới xài được. Thì đến với bài này mình sẽ hướng dẫn các bạn tạo **Widget Elementor** như các bạn muốn.

### 1/ Tạo Plugin

Các bạn thư mục rồi tạo một file bất kì và đặt tên plugin như bên dưới nhé ( này mình đã nói qua phần này ở bài [tạo custom widget cho wpbakery](https://wolfactive.dev/huong-dan-tao-custom-widget-cho-plugin-wpbakery/) rồi nhé). Và đây là mình tạo một cây thư mục như sau:

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

Bên trong file **wolfactive-extend-elementor** mình sẽ ghi những thông tin cần thiết để tạo plugin.

```
/*
Plugin Name: Wolfactive Extend Elementor
Plugin URI: https://wolfactive.dev/
Description: Extendes Elementor and creates custom widgets.
Version: 1.0.0
Author: Wolfactive
Author URI: https://wolfactive.dev/
License: GPLv2 and later
Text Domain: wolfactive-extend-elementor
Domain Path: /languages/
*/
```

### 2/ Tạo Class khởi tạo plugin

Sau đó mình bắt đầu kiểm tra thoát file nếu truy cập trực tiếp vào file mà không nằm trong folder plugin WP

```
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly.
}
```

Kế tiếp mình bắt đầu tạo một **Class** bao gồm những nội dung sau: **version plugin, version elementor** thấp nhất để sử dụng, **version** **php.** Ngoài ra mình có chú thích **comments** thêm ở trong code, mọi người đọc để hiểu thêm nhé.

```
class Wolfactive_Extend_Elementor {
    /**
     * Plugin Version
     */
    const VERSION = '1.0.0';

    /**
     * Minimum Elementor Version
     */
    const MINIMUM_ELEMENTOR_VERSION = '2.9.7';

    /**
     * Minimum PHP Version
     */
    const MINIMUM_PHP_VERSION = '7.0';
    public static function instance() {
      if ( is_null( self::$_instance ) ) {
          self::$_instance = new self();
      }
      return self::$_instance;
    }
    /**
     * Constructor
     */
    public function __construct() {
        add_action( 'init', [ $this, 'i18n' ] );
        add_action( 'plugins_loaded', [ $this, 'init' ] );
    }

    /**
     * Load Textdomain
     */
    public function i18n() {
        load_plugin_textdomain( 'wolfactive-extend-elementor' );
    }

    /**
     * Initialize the plugin
     */
    public function init() {
        // Check if Elementor installed and activated
        if ( ! did_action( 'elementor/loaded' ) ) {
            add_action( 'admin_notices', [ $this, 'admin_notice_missing_main_plugin' ] );
            return;
        }

        // Check for required Elementor version
        if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) {
            add_action( 'admin_notices', [ $this, 'admin_notice_minimum_elementor_version' ] );
            return;
        }

        // Check for required PHP version
        if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) {
            add_action( 'admin_notices', [ $this, 'admin_notice_minimum_php_version' ] );
            return;
        }

        // 1. Add Plugin actions
        // here we will add actions to elementor widgets and controls
        add_action( 'elementor/widgets/widgets_registered', [ $this, 'init_widgets' ] );

        // 2. Register Widget Styles
        // here we will add action to enqueue styles

        // 3. Register custom categories
        //here we will add actions to create a custom category for our widgets
        add_action( 'elementor/elements/categories_registered', [ $this, 'WolfactiveElementor__widget_categories' ] );
        add_action( 'wp_enqueue_scripts', [ $this, 'init_style_script' ]);
    }

    /**
     * Admin notice
     * Warning when the site doesn't have Elementor installed or activated.
     */
    public function admin_notice_missing_main_plugin() {
        if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );
        $message = sprintf(
            /* translators: 1: Plugin name 2: Elementor */
            esc_html__( '"%1$s" requires "%2$s" to be installed and activated.', 'wolfactive-extend-elementor' ),
            '' . esc_html__( 'Wolfactive Extend Elementor', 'wolfactive-extend-elementor' ) . '',
            '' . esc_html__( 'Elementor', 'wolfactive-extend-elementor' ) . ''
        );
        printf( '%1$s', $message );
    }
    /**
     * Admin notice
     * Warning when the site doesn't have a minimum required Elementor version.
     */
    public function admin_notice_minimum_elementor_version() {
        if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );
        $message = sprintf(
            /* translators: 1: Plugin name 2: Elementor 3: Required Elementor version */
            esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'wolfactive-extend-elementor' ),
            '' . esc_html__( 'Tartist Elementor Extension', 'wolfactive-extend-elementor' ) . '',
            '' . esc_html__( 'Elementor', 'wolfactive-extend-elementor' ) . '',
                self::MINIMUM_ELEMENTOR_VERSION
        );
        printf( '%1$s', $message );
    }
    /**
     * Admin notice
     * Warning when the site doesn't have a minimum required PHP version.
     */
    public function admin_notice_minimum_php_version() {
        if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );
        $message = sprintf(
            /* translators: 1: Plugin name 2: PHP 3: Required PHP version */
            esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'wolfactive-extend-elementor' ),
            '' . esc_html__( 'Wolfactive Extend Elementor', 'wolfactive-extend-elementor' ) . '',
            '' . esc_html__( 'PHP', 'wolfactive-extend-elementor' ) . '',
                self::MINIMUM_PHP_VERSION
        );
        printf( '%1$s', $message );
    }
    /**
     * Adding custom widget category
     */
    public function WolfactiveElementor__widget_categories( $elements_manager ) {
        $elements_manager->add_category(
            'wolfactive-widgets',
            [
                'title' => __( 'Wolfactive Add On', 'wolfactive-extend-elementor' ),
                'icon' => 'fas fa-plug',
            ]
        );
    }
    /**
     * Include widgets files and register them
     */
    public function init_widgets() {
        /**
         * Posts Widget
         */
         //Include Widget File 
        require_once( __DIR__ . '/widgets/wolfactive-image-widget.php' );
        // Register widget
        \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \Wolfactive_Elementor_Image() );
    }

    //add style, script vào plugin
    public function init_style_script() {
        /**
         * Style Script 
         */
        $plugin_url = plugin_dir_url( __FILE__ );
        wp_enqueue_style( 'wolfactive-css', $plugin_url . 'dist/css/main.css' );
        wp_enqueue_script( 'wolfactive-js', $plugin_url . 'dist/js/root.js', array ( 'jquery' ), 1.1, true);
    }
}
}
Wolfactive_Extend_Elementor::instance();
```

### 3/ Tạo Widget Wolfactive\_Elementor\_Image.

Ở đây mình sẽ tạo tên class trùng với tên mà mình đã khai báo ở **register\_widget\_type()** và kế thừa class của **Elementor**

```
class Wolfactive_Elementor_Image extends \Elementor\Widget_Base{

        /*get_name(): method is a simple one, you just need to return a widget name that will be used in the code.*/
        public function get_name(){
            return 'wolfactive_image';
        }

        /*get_title(): method, which again, is a very simple one, you need to return the widget title that will be displayed as the widget label.*/
        public function get_title(){
            return __('Wolfactive image','wolfactive-extend-elementor');
        }

        /*get_icon(): method, is an optional but recommended method, it lets you set the widget icon. you can use any of the eicon or font-awesome icons, simply return the class name as a string.*/
        public function get_icon() {
            return 'eicon-image';
        }

        /*get_categories(): method, lets you set the category of the widget, return the category name as a string.*/
        public function get_categories() {
            return [ 'wolfactive-widgets' ];
        }

        /*register_controls(): method lets you define which controls (setting fields) your widget will have.*/
        protected function _register_controls() {
            $this->start_controls_section(
                'content_section',
                [
                    'label' => __( 'Setting', 'wolfactive-extend-elementor' ),
                    'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
                ]
            );
            $this->add_control(
                'image_title', [
                    'label' => __( 'Title', 'wolfactive-extend-elementor' ),
                    'type' => \Elementor\Controls_Manager::TEXT,
                    'default' => __( '#ELLA ON INSTAGRAM' , 'wolfactive-extend-elementor' ),
                    'label_block' => true,
                ]
            );
            $this->add_control(
                'gallery',
                [
                    'label' => __( 'Add Images', 'plugin-domain' ),
                    'type' => \Elementor\Controls_Manager::GALLERY,
                    'default' => [],
                ]
            );
            $this->add_control(
                'image_link', [
                    'label' => __( 'Link Button', 'wolfactive-extend-elementor' ),
                    'type' => \Elementor\Controls_Manager::TEXT,
                    'default' => __( 'javascript:void(0)' , 'wolfactive-extend-elementor' ),
                    'label_block' => true,
                ]
            );
            $this->end_controls_section();
        }

        /*render(): method, which is where you actually render the code and generate the final HTML on the frontend using PHP.*/
        protected function render() {
            $settings = $this->get_settings_for_display();
            include __DIR__ . '/sections/image-template.php';
        }
    }
```

### 4/ Render HTML

Ở Function **render()** ở mục 2, mình có include file **image-template.** Ở file này mình sẽ chứa html để bạn render ra ngoài website.

```
<h3 class="image-bg">
   <div class="mc-dp-flex">
      <p class="wa-icon-image"><i class="far fa-image"></i></p>
      <p class="mc-text-title-inst"><?php _e($settings['image_title'],'wa') ?></p>
   </div>
</h3>
<div class="description-image">
   <?php _e($settings['image_description'],'wa') ?>
</div>
<div class="<?php _e($class_preflix,'wa') ?>" >
   <?php foreach ( $settings['gallery'] as $image ): ?>
   <a href="<?php echo $image['url']; ?>" data-lightbox="roadtrip" class="<?php _e($class_preflix,'wa') ?>-image-image">
   <?php
   echo '<img src="' . $image['url'] . '">';
?>
</a>

<?php endforeach; ?>
</div>
```

### 5/ Tổng kết

Và đây là thành phẩm của chúng ta.

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

Như vậy mình đã giới thiệu cho các bạn về cách làm b trên WordPress rồi. Ngoài ra các bạn cũng có thể tìm hiểu và đọc thêm nhiều hơn nữa ở trang [Elementor](https://developers.elementor.com/creating-an-extension-for-elementor/). Mọi thông tin thắc mắc, các bạn hãy liên hệ Fb tụi mình trên facebook nhé.!
