當前位置:首頁>WordPress建站>WordPress開發(fā)>WordPress編輯器Gutenberg創(chuàng)建Format格式工具

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

WordPress新的Gutenberg編輯器是一個完全使用現(xiàn)代前端技術(shù)打造的編輯器。WordPress4.7引入的Rest API就奠定了WordPress的野心,Gutenberg也基于此技術(shù)。從前端的大潮流來看,經(jīng)典編輯器使用的舊技術(shù)勢必會被歷史淘汰。

Gutenberg從目前的進展來看,它包含了Block、Format、Sidebar三個部分。由于Gutenberg的開發(fā)很少有中文原創(chuàng)教程或心得,因此我便在博客中做了一些分享。例如之前分享過Block模塊的創(chuàng)建方法: http://www.ydqwiac.cn/how-to-creat-custom-block-type-in-gutenberg.html

Format是什么

Format顧名思義就是格式,它是在Gutenberg編輯器中的格式化工具。如段落上方的“對齊”、“加粗”等按鈕:

Format創(chuàng)建方法官方文檔用ES5已經(jīng)寫得非常詳細了,我這里不再重復(fù)。今天主要想分享的是:如何在Format中添加一個跟隨已選文本的Popover,并在里面做相關(guān)的設(shè)置。例如做一個文本色彩選擇器:

特別需要注意的是:這樣的一個寫法并非是我憑空杜撰,WordPress官方其實是有示例的,本文參考并致敬了“超鏈接”這個Format。

編寫一個Format

PHP部分

PHP的部分和Block的創(chuàng)建方法基本是一致的:大致邏輯是注冊一個腳本,在Block編輯器的鉤子上將腳本引入。

<?php
function register_pandastudio_block_format_mark() {
	wp_register_script(
		'pandastudio-block-format-mark-js',
		//根據(jù)實際位置引入文件
		get_stylesheet_directory_uri().'/pandastudio_plugins/format_mark/block.build.js',
		array( 'wp-rich-text' )
	);
}
add_action( 'init', 'register_pandastudio_block_format_mark' );
function register_pandastudio_block_format_mark_enqueue_assets_editor() {
	wp_enqueue_script( 'pandastudio-block-format-mark-js' );
}
add_action( 'enqueue_block_editor_assets', 'register_pandastudio_block_format_mark_enqueue_assets_editor' );

還可根據(jù)實際場景需要引入css文件,這里就不做示例了。引入js文件的時候注意一下編譯后的文件位置。

Javascript部分

在WordPress的官方文章中,F(xiàn)ormat的示例教程是一個使用ES5開發(fā)出來的教程,對于功能復(fù)雜的場景,編寫過程會變得異常繁瑣,而且不便于人類閱讀。因此本文中我將做一個ES Next的開發(fā)示例。

注冊 Format 的方法是提供在 wp.richText 里面的,引入后即可使用。注冊一個 Format 基本結(jié)構(gòu)是:

const {
	registerFormatType,
} = wp.richText;
 
registerFormatType( 'pandastudio/mark', {
	title: '標記',
	tagName: 'span',
	className: 'pandastudio-mark',
	attributes: {
		style: 'style',
		block: 'inline-block'
	},
	edit(){
		//...
	}
} );

由于我們的目的是點擊按鈕后,彈出一個Popover,而Popover有一個“顯示”和“未顯示”的狀態(tài)需要存儲。通過修改數(shù)據(jù)來控制Popover的顯示。而這個狀態(tài)數(shù)據(jù)在Format中默認是沒有辦法存儲的!因此,我們必須將edit方法擴展一下:

...
edit: class markEdit extends Component {
	constructor() {
		super( ...arguments );
		this.state = {
			modal_visibility: false,
		};
	}
	render() {
		//...
	}
}
...

現(xiàn)在,我們有了一個 state 來存儲狀態(tài),并且將 Popover 的顯示狀態(tài)存儲在了 modal_visibility 中。接下來我們需要:

  1. 當用戶選擇了文本之后,這個 Format 按鈕才可用,否則是灰色不可用狀態(tài)。因此創(chuàng)建了一個words_selected方法來進行判斷
  2. 對于 Popover,需要定位,查看 Popover 的文檔說明可以注意到有一個叫做 anchorRect 的參數(shù),因此編寫一個set_popover_rect方法來創(chuàng)建 anchorRect 并存儲到 state 中,并在 Popover 的參數(shù)中讀取它
  3. 在 Format 按鈕點擊后,修改 state 中的 modal_visibility 為 true 來顯示 popover,并同時讀取當前的選中位置來創(chuàng)建 anchorRect 給 Popover 定位
  4. 在點擊 Popover 的外部后,通過修改 state 中的 modal_visibility 為 false 來關(guān)閉Popover
const { getRectangleFromRange } = wp.dom;
const { RichTextToolbarButton } = wp.editor;
const { Popover } = wp.components;
const { Fragment } = wp.element;
...
edit: class markEdit extends Component {
	constructor() {
		super( ...arguments );
		this.show_modal = this.show_modal.bind( this );
		this.close_modal = this.close_modal.bind( this );
		this.words_selected = this.words_selected.bind( this );
		this.set_popover_rect = this.set_popover_rect.bind( this );
		this.state = {
			modal_visibility: false,
		};
	}
	words_selected() {
		const { value } = this.props;
		return value.start !== value.end;
	}
	set_popover_rect() {
		const selection = window.getSelection();
		const range = selection.rangeCount > 0 ? selection.getRangeAt( 0 ) : null;
		var rectangle = getRectangleFromRange( range );
		this.setState( { popover_rect: rectangle } );
	}
	show_modal() {
		this.setState( { modal_visibility: true } );
		this.set_popover_rect();
	}
	close_modal() {
		this.setState( { modal_visibility: false } );
	}
	render() {
		let {
			isActive
		} = this.props;
		return (
			<Fragment>
				<RichTextToolbarButton
				icon='editor-code'
				title="標記"
				onClick={ this.show_modal }
				isActive={ isActive }
				isDisabled={ !this.words_selected() }
				/>
				{ this.state.modal_visibility && (
					<Popover
					anchorRect = { this.state.popover_rect }
					position = "bottom center"
					className = "pandastudio_mark_popover"
					onClickOutside = { this.close_modal }
					>
					Popover內(nèi)容
					</Popover>
				)}
			</Fragment>
		);
	}
}
...

需要注意的是,在set_popover_rect方法中使用到了另一個getRectangleFromRange方法,這個方法是 WordPress 在 wp.dom 中提供的,需要先引入。其他組件的引入我這里就不在多說了,詳見WordPress文檔即可。

這樣,一個 Format 和 Popover 融合的框架就完成了。當Popover彈出后需要操作的其他事情,就可以在Popover的內(nèi)容中去添加事件方法了。

總結(jié)

這個示例中,主要有兩個部分需要注意:

  1. 注冊 Format 的方法中 edit 參數(shù)需要擴展才可以存儲狀態(tài)數(shù)據(jù)
  2. Popover的定位方法使用了 wp.dom.getRectangleFromRange 并傳入了已選文本的位置參數(shù),這是難點。這個方法 WordPress 官方?jīng)]有文檔描述,我也不是憑空找到的,此處致敬了“超鏈接”的編寫方法

參考文獻

  1. WordPress Block編輯器手冊 – Introduction to the Format API
  2. WordPress Block編輯器手冊 – Popover
  3. WordPress Gutenberg Github

注:本文原創(chuàng)出自 http://panda.panda-studio.cn/how-to-creat-custom-format-type-in-gutenberg ,轉(zhuǎn)載請注明該出處!

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

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

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

2019-9-17 9:46:36

WordPress開發(fā)

Gutenberg Sidebar邊欄開發(fā)心得

2019-9-17 10:07:18

0 條回復(fù) A文章作者 M管理員
    暫無討論,說說你的看法吧
?
個人中心
購物車
優(yōu)惠劵
今日簽到
有新私信 私信列表
搜索

金门县| 南川市| 嘉禾县| 大渡口区| 高碑店市| 台前县| 祥云县| 晋中市| 曲麻莱县| 班玛县| 米泉市| 抚远县| 盱眙县| 新沂市| 全椒县| 镇江市| 余姚市| 朝阳县| 汶上县| 中宁县| 曲靖市| 南漳县| 盐源县| 台南市| 海口市| 桐乡市| 都昌县| 静安区| 叶城县| 凤凰县| 灵石县| 卢氏县| 额敏县| 从化市| 拜泉县| 白城市| 乌拉特前旗| 韩城市| 布拖县| 白河县| 改则县|