當前位置:首頁>WordPress建站>WordPress開發(fā)>WordPress編輯器Gutenberg創(chuàng)建自定義Block模塊

WordPress編輯器Gutenberg創(chuàng)建自定義Block模塊

注:本文寫于2018年3月24日,內容有些表述和現狀可能不太相符,請見諒。原文出自: http://panda.panda-studio.cn/how-to-creat-custom-block-type-in-gutenberg

在寫這篇文章前,本來還在考慮寫一個TinyMCE的教程,來自定義一個在后臺編輯就可以所見即所得的模塊功能。然而突然想到WordPress的新編輯器Gutenberg本身不就是以這樣的目的來開發(fā)的嗎?雖然Gutenberg現在還在測試階段,但在今年晚些時候就將和WordPress5.0正式版一起上線。因此,就放棄了寫TinyMCE教程的想法,直接上“如何創(chuàng)建Guntenberg自定義Block”的教程吧!

什么是Gutenberg

當你看到這篇文章時,無論WordPress是否已經更新到5.0,Gutenberg終將成為WordPress未來的編輯器。它是一個以JavaScript(React)為驅動的編輯器,以“Block 模塊”的形式,讓用戶在寫文章時能更方便的自定義文章排版。

  • 截止文章發(fā)布時,WP5.0尚未發(fā)布,Gutenberg以插件的形式向舊版本提供測試和開發(fā)
  • 詳見:WordPress官方介紹

要實現的功能

在開始這個教程前,先介紹最終要實現的效果:我想要實現的是一個Tips功能,將有4種類型的Tip,分辨是四種顏色。用戶插入模塊后,可以編輯自己輸入的文字內容。在鼠標選定此模塊時,將出現4個Tip類型選擇器,分別是藍色(info)、綠色(success)、橙色(worning)、紅色(error)。點擊相應的色彩按鈕后,用戶輸入的文字內容背景將變成對應的色彩。

實現此功能的原理:通過點擊對應的色彩選擇器,來修改class,從而改變tip的類型。如:class為“.tip.info”就顯示藍色、class為“.tip.success”就顯示綠色。代碼如下:

<div class="tips info">
    <p>藍色效果示例</p>
</div>
 
<div class="tips success">
    <p>綠色效果示例</p>
</div>

效果示例:

開始創(chuàng)建

PHP部分

首先在主題的function.php中用注冊需要的腳本、樣式:

function register_pandastudio_tips() {
    wp_register_script(
        'pandastudio-tips',
        get_stylesheet_directory_uri().'/blocks/tips.js',
        array( 'wp-blocks', 'wp-element' )
    );
 
    wp_register_style(
        'pandastudio-tips',
        get_stylesheet_directory_uri().'/blocks/tips.css',
        array( 'wp-edit-blocks' )
    );
 
    register_block_type( 'pandastudio/tips', array(
        'editor_script' => 'pandastudio-tips',
        'editor_style'  => 'pandastudio-tips',
    ) );
}
if (function_exists('register_block_type')) {
    add_action( 'init', 'register_pandastudio_tips' );
}

在上面的代碼中,將主題目錄下的 tips.jstips.css 引入到了Gutenberg編輯器中,由于WordPress5.0以前的版本在未安裝Gutenberg插件的狀態(tài)沒有注冊block的方法(register_block_type),因此需要在添加action的時候先判斷一下是否存在這個方法,否則在老版本的WordPress中會報錯。

CSS部分

接下來是CSS樣式,這里僅作示例,可以寫任何你喜歡的樣式:

.tip {
    background: #eef6fd;
    padding: 8px 20px !important;
    border-left-width: 3px !important;
    border-left-style: solid;
    border-left-color: #38a3fd;
    border-radius: 0 5px 5px 0 !important;
    margin: 0 0 10px 0 !important;
    box-shadow: none !important;
}
 
.tip p {
    margin: 5px 0 !important;
}
 
.tip:before {
    background: #38a3fd;
    border-radius: 50%;
    color: #fff;
    content: "i";
    font-family: "Dosis", "Source Sans Pro", "Helvetica Neue", Arial, sans-serif;
    font-size: 16px;
    height: 21px;
    line-height: 21px;
    margin-left: -32px;
    margin-top: 5px;
    position: absolute;
    text-align: center;
    width: 21px;
}
 
.tip ol {
    margin: 0;
}
 
.tip.success {
    border-left-color: #86cc00;
    background: #f0f8e5;
}
 
.tip.success:before {
    background: #86cc00;
    content: "√";
}
 
.tip.worning {
    border-left-color: #ff7800;
    background: #fcf2e9;
}
 
.tip.worning:before {
    background: #ff7800;
    content: "!";
}
 
.tip.error {
    border-left-color: #ed0000;
    background: #fcf1f1;
}
 
.tip.error:before {
    background: #ed0000;
    content: "×";
}
 
.tip.inlineBlock {
    display: inline-block;
}
 
.tip.error p {
    padding: 0 !important;
}

JavaScript(ES5)部分

接下來重點來了,由于Gutenberg是用JS驅動的,因此,最重要的是tip.js才對。先上代碼,再做講解:

var el = wp.element.createElement,
    registerBlockType = wp.blocks.registerBlockType,
    RichText = wp.blocks.RichText;
 
var el = wp.element.createElement,
    registerBlockType = wp.blocks.registerBlockType,
    RichText = wp.blocks.RichText;
 
registerBlockType('pandastudio/tips', {
    title: '提示框',
    icon: 'info',
    category: 'layout',
    attributes: {
        content: {
            type: 'array',
            source: 'children',
            selector: 'p',
        },
        typeClass: {
            source: 'attribute',
            selector: '.tip',
            attribute: 'class',
        }
    },
    edit: function(props) {
        var content = props.attributes.content,
            typeClass = props.attributes.typeClass || 'tip info',
            isSelected = props.isSelected;
 
        function onChangeContent(newContent) {
            props.setAttributes({ content: newContent });
        }
 
        function changeType(event) {
            var type = event.target.className;
            props.setAttributes({ typeClass: 'tip ' + type });
        }
 
        var richText = el(
            RichText, {
                tagName: 'p',
                onChange: onChangeContent,
                value: content,
                isSelected: props.isSelected,
                placeholder: '請輸入...'
            });
 
        var outerHtml = el('div', { className: typeClass }, richText);
 
        var selector = el('div', { className: 'panda tipSelector' }, [
            el('button', { className: 'info', onClick: changeType }, '藍色'),
            el('button', { className: 'success', onClick: changeType }, '綠色'),
            el('button', { className: 'worning', onClick: changeType }, '橙色'),
            el('button', { className: 'error', onClick: changeType }, '紅色'),
        ])
 
        return el('div', {}, [outerHtml, isSelected && selector]);
 
    },
 
    save: function(props) {
        var content = props.attributes.content,
            typeClass = props.attributes.typeClass || 'tip info';
 
        var outerHtml = el('div', { className: typeClass }, el('p', {}, content));
 
        return el('div', {}, outerHtml);
    },
});

wp.element.createElement 是一個創(chuàng)建dom元素的方法,由于Gutenberg是基于React的,所以這實質上就是React的方法。由于我們寫的是ES5的寫法,所以才用得到。如果用JSX來寫,然后再編譯的話,就不需要了。

registerBlockType 是WordPress在Gutenberg中提供的創(chuàng)建塊的方法,直接用就好。到本文發(fā)布為止,官方還沒有關于此方法的詳細文檔(正式發(fā)布之后應該就有了)。

RichText 官方的說法是提供一個供用戶編輯的輸入框。類似于React的Controlled Components。

registerBlockType的icon參數:圖標可以任意從WordPress的Dashicons里面選擇。

attributes 用于定義從保存的內容中提取Block屬性值的策略。提供了一種從保存的標記映射到Block的JS表示形式的方法

可以看到,edit和save是兩個最復雜的參數,前者提供了在WordPress后臺的Gutenberg中如何渲染和顯示Block,后者提供了如何在WordPress中將Block存儲和在前臺顯示。

Edit:

在這一個示例中,我創(chuàng)建了一個outerHtml來放置包含tips類型的div,內部的用戶編寫的內容則是用RichText創(chuàng)建的:

<div class="tips info">  <!-- 這是outerHtml -->
    <p>藍色效果示例</p>    <!-- 這是RichText -->
</div>

并且創(chuàng)建了4個button按鈕,在onClick點擊時觸發(fā)changeType事件,將按鈕的class添加到outerHtml的class里面去。在edit最后return的時候通過isSelected來判斷Block是否被用戶選中,只有被選中的情況下,才顯示Tips類型選擇的4個button按鈕。

SAVE:

保存和顯示時候的狀態(tài)就相對簡單多了,只需要用創(chuàng)建dom的createElement方法創(chuàng)建出最終結果的html即可。

以上就是開發(fā)這樣一個帶有選項功能的Gutenberg Block的簡單方式。由于大量運用了比較新的前端技術,因此WP開發(fā)者需要好好學習才可以跟上步伐咯。

參考文檔

聲明:本站所有文章,如無特殊說明或標注,均為本站原創(chuàng)發(fā)布。任何個人或組織,在未征得本站同意時,禁止復制、盜用、采集、發(fā)布本站內容到任何網站、書籍等各類媒體平臺。如若本站內容侵犯了原著者的合法權益,可聯系我們進行處理。

給TA打賞
共{{data.count}}人
人已打賞
歡迎關注WordPress大學公眾號 WPDAXUE
WordPress開發(fā)

WordPress 將參數傳遞給get_template_part()引入的模板

2019-9-8 11:11:08

WordPress開發(fā)

WordPress編輯器Gutenberg創(chuàng)建Format格式工具

2019-9-17 9:56:06

4 條回復 A文章作者 M管理員
  1. 風致

    似乎不行啊,添加后出現錯誤,顯示此區(qū)塊無法被預覽

  2. 縉哥哥

    好復雜的趕腳!

    • 網站編輯

      的確是比較復雜,涉及到編譯之類的

?
個人中心
購物車
優(yōu)惠劵
今日簽到
有新私信 私信列表
搜索

连江县| 水城县| 三河市| 卓尼县| 邯郸县| 双峰县| 普洱| 淮滨县| 阿巴嘎旗| 仁寿县| 教育| 南涧| 曲沃县| 东海县| 闻喜县| 东乌珠穆沁旗| 江油市| 乌什县| 台南市| 剑河县| 白玉县| 澄迈县| 通海县| 稻城县| 淮南市| 巴林左旗| 垣曲县| 敦煌市| 天全县| 辰溪县| 蓝山县| 当涂县| 潼关县| 湛江市| 四川省| 江陵县| 江门市| 广平县| 通山县| 右玉县| 泸西县|