gutenberg-1-wolfactive-949x475
12/06/2021

[Gutenberg ] Tạo Block Gutenberg đầu tiên

Chào mọi người đến với Series lập trình block Gutenberg trong WordPress. Series này giành cho những bạn thích Wordpess nhưng muốn tìm cảm giác làm theme, giao diện WordPress theo hướng mới mẻ không bị nhàm chán, thích làm giao diện trong CMS và trang web với React.

Với bài lần trước mình đã giới thiệu cách cấu hình React vào plugin hỗ trợ viết block Gutenberg. Thì bài viết này sẽ hướng dẫn các bạn tạo Block Gutenberg đầu tiên

Khởi tạo class Gutenberg và register block Gutenberg

Do mình có thói quen dùng class trong lúc lập trình theme(plugin) WordPress. Nên bài này sẽ hướng dẫn các bạn sử dụng luôn hihi 😊.

Mình tạo file Gutenberg.php sau đó include vào wa-gutenberg.php và gọi class để sử dụng.

<?php
class Gutenberg {
    function __construct() {
         add_action('init',array($this,'register_block'));
         add_filter( 'block_categories', array($this,'register_block_category_type'), 10, 2 );
 }
    public function register_block(){}
    }
    public function register_block_category_type($categories, $post){}

Và trong file wa-gutenberg.php mình sẽ gọi class Gutenberg để sử dụng.

<?php
/* Định nghĩa các biến để sử dụng*/
define ('PLUGIN_DIR',plugin_dir_path(__FILE__));
define ('PLUGIN_URL',plugins_url('wa-gutenberg'));
/* Gọi class để thực thi*/
new Gutenberg();

Tuy nhiên gọi class ra xong thì chưa đủ vì mình chưa khởi tạo một block nào cả 😂😂😂. Mình viết thêm các hàm để bổ trợ cho việc tạo block.

Tạo hàm để đăng ký category block trong trình soạn thảo

<?php
public function register_block_category_type($categories, $post) {
    if ( $post->post_type !== 'page' ) {
        return $categories;
    }
    return array_merge(
        $categories,
            [
                $this->create_category('WA Page', 'page', [
                    'icon' => PLUGIN_URL.'/dist/images/logo-1.png'
                ])
                /*Tạo thêm các category khác trong array này */
            ]
     );
}

Hàm register_block_category_type giúp chúng ta đăng ký khởi tạo category trong block để là icon bên mình đã chuẩn bị trước các bạn có thể thay thế bằng icon của các bạn hoặc sử dụng dashboard icon của wordpress hay svg để thay thế.

Có thể thêm nhiều category trong vào array được đánh dấu bởi comment của mình.Trong hàm trên mình sẽ chỉ thêm category này trong page của WordPress và các post type khác sẽ không hiện category này.

Tiếp đến mình tạo hàm để tạo create_category để bổ trợ cho hàm register_block_category_type

<?php
protected function create_category($title, $slug, array $options = []){
        return array_merge(
            array(
                'slug'  => $slug.'-wolfactive',
                'title' => $title.' Wolfactive',
            ),$options
        );
    }

Với hàm create_category mình có thể tạo thêm prefix cho title và slug của catgory đồng thời đó các bạn có thể thêm option như icon ở hàm register_block_category_type hoặc có thể option khác có thể tham khảo thêm ở trang https://developer.wordpress.org/block-editor/

Và đây là kết quả

Gutenberg-dau-tien-voi-component-rich-text

Tạo hàm để đăng ký block trong trình soạn thảo

<?php
public function register_block(){
        wp_register_script(
            'wa-gutenbergs-editor',
            PLUGIN_URL.'/dist/js/editor.js',
            array('wp-blocks','wp-i18n','wp-element','wp-editor','wp-components')
        );
        wp_register_script(
            'wa-gutenbergs-frontend',
            PLUGIN_URL.'/dist/js/root.js',
            array()
        );
        wp_register_style(
            'wa-gutenbergs-editor',
            PLUGIN_URL.'/dist/css/editor.css'
        );
        wp_register_style(
            'wa-gutenbergs-frontend',
            PLUGIN_URL.'/dist/css/main.css'
        );
        $this->create_block('wa-page');
    }

Hàm register_block giúp chúng ta register script và style với WordPres ta dùng cho các block chúng ta tạo. Và ở bài trước mình có cấu hình cho các package có sẵn của WordPress sẽ không được complie chung với file JavaScript. Thì hàm này mình sẽ khai báo để WordPress biết mình sử dụng các package trên và xếp file JavaScript của mình nằm dưới các packages đó.

Tiếp theo mình tạo hàm create_block bổ trợ cho hàm register_block

<?php
protected function create_block($name, array $args = array()) {
        register_block_type(
            'themewa/'.$name,
            array_merge(
                array(
                    'editor_script' => 'wa-gutenbergs-editor',
                    'editor_style' => 'wa-gutenbergs-editor',
                    'script' => 'wa-gutenbergs-frontend',
                    'style' => 'wa-gutenbergs-frontend'
                ),
                $args
            )
        );
    }

Cũng như hàm create_category mình tạo các prefix và cấu hình mặc định cho các block mình tạo ra. Tuy nhiên do mình xài chung file JavaScript cho các block nên ở hàm register_block mình chỉ gọi ra đúng một lần. Sau này khi tạo các block mới mình chỉ tạo trong file jsx. Và tất nhiên là không có kết quả để chụp cho các bạn vì mình chưa tạo block trong file jsx. Giờ chúng ta sang phần tiếp theo để tạo nhé.

Khởi tạo Block đầu tiên trong file jsx

Các bạn tham khảo cấu trúc thư mục trước khi qua phần này.

Gutenberg-dau-tien-voi-component-rich-text

Mình vào folder blocks tạo folder heading và file index.jsx trong folder.

import { registerBlockType } from '@wordpress/blocks'
import { Component } from '@wordpress/element'
import { __ } from '@wordpress/i18n'
/* Import các package càn thiết để sử dụng*/

class Heading extends Component {
    constructor(props) {
        super(props)
    }

    init() {}
}
export default Heading

Thay vì chúng ta phài class Heading extends React.Component thì trong package đã có sẵn chúng ta không cần khai báo như vậy. Sau đó vào file editor.jsx mình gọi class mới tạo ra.

import Heading from './blocks/heading'

//Register Class Block
let HeadingRegister = new Heading()

// Init Blocks
HeadingRegister.init()

Chúng ta tiếp tục khai báo block heading trong file heading/index.jsx mình tạo nơi để chứa các thông tin cần khai báo cho block tại constructor của class

class Heading extends Component {
    constructor(props) {
        super(props)
        this.data = {
            slug: 'themewa/heading',
            title: __('Heading', 'wa-gutenberg'),
            description: __('Heading create by Wolfactive', 'wa-gutenberg'),
            category: 'page-wolfactive',
            icon: (
                <svg width="1em" height="1em" viewBox="0 0 512 512">
                    <path
                        d="M448 96v320h32a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H320a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32V288H160v128h32a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H32a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h32V96H32a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h160a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16h-32v128h192V96h-32a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h160a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16z"
                        fill="currentColor"
                    />
                </svg>
            ),
            keywords: [
                __('Heading', 'wa-gutenberg'),
                __('Wolf Active', 'wa-gutenberg'),
            ],
        }
    }

    init() {}
}
export default Heading

Ở constructor mình khai báo tilte của block và category của block heading là Wa Page, description – mô tả ngắn về block để người dùng có thể sử dụng. Icon cho block heading. Cuối cùng là keyword, phần này giúp người dùng có thể tìm kiếm block heading thông qua các từ khóa chúng ta khai báo. Sau đó mình sẽ đăng ký block vào hàm init

import { registerBlockType } from '@wordpress/blocks'
import { Component } from '@wordpress/element'
import { __ } from '@wordpress/i18n'
/* Import các package càn thiết để sử dụng*/

class Heading extends Component {
    constructor(props) {
        super(props)
        /*.......*/
    }

    init() {
    let { slug, title, description, category, icon, keywords } = this.data
        return registerBlockType(slug, {
            title: title,
            description: description,
            category: category,
            icon: icon,
            keywords: keywords,
            edit: this.edit(),
            save: this.save()
        })
    }
}
export default Heading

Tạo hàm save và edit cho block

import { registerBlockType } from '@wordpress/blocks'
import { Component } from '@wordpress/element'
import { __ } from '@wordpress/i18n'
/* Import các package càn thiết để sử dụng*/

class Heading extends Component {
    constructor(props) {
        super(props)
        /*......*/
    }

    save(){
        return save: () =>{
            return(
                <h1> Wolfactive <h1>
            )
        }
    }

    edit() {
        return edit: () => {
            return(
                <h1> Wolfactive <h1>
            )
        }
    }

    init() {
    /*......*/
    }
}
export default Heading

Và đây là kết quả
Gutenberg-dau-tien-voi-component-rich-text

Tổng kết

Với bài này mình đã hướng dẫn các bạn cách khai báo và tạo block Gutenberg đầu tiên. Tuy nhiên block này chưa đúng với title đặt ra là Heading. Với bài sau mình sẽ đi sâu hơn và block như: để user tự nhập nội dung, Điều chỉnh cỡ chữ, màu chữ, canh lề chữ,…
Các bạn có thể tham khảo tổng quan về series tại đây
Cảm ơn các bạn đã đón đọc. Các bạn có thắc mắc hay có vấn đề cần giải đáp thì hay inbox vào fanpage Wolfactive nhé.

Vui lòng chọn size trước khi đặt hàng (*)