立即注册 找回密码

QQ登录

只需一步,快速开始

查看: 176|回复: 0

[Wordpress 通用教程] WordPress编辑器Gutenberg创建Format格式工具的方法

[复制链接]

977

主题

2132

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
16245

推广达人宣传达人突出贡献荣誉管理论坛元老

QQ
发表于 2019-12-24 09:55:58 | 显示全部楼层 |阅读模式
道勤网-数据www.daoqin.net

亲注册登录道勤网-可以查看更多帖子内容哦!(包涵精彩图片、文字详情等)请您及时注册登录-www.daoqin.net

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
wordpress新的Gutenberg编辑器是一个完全使用现代前端技术打造的编辑器。WordPress4.7引入的Rest API就奠定了WordPress的野心,Gutenberg也基于此技术。从前端的大潮流来看,经典编辑器使用的旧技术势必会被历史淘汰。
Gutenberg从目前的进展来看,它包含了Block、Format、Sidebar三个部分。由于Gutenberg的开发很少有中文原创教程或心得,因此道勤小编便在博客中做了一些分享。
Format是什么
Format顾名思义就是格式,它是在Gutenberg编辑器中的格式化工具。如段落上方的“对齐”、“加粗”等按钮

WordPress编辑器Gutenberg创建Format格式工具的方法

WordPress编辑器Gutenberg创建Format格式工具的方法
Format创建方法官方文档用ES5已经写得非常详细了,我这里不再重复。今天主要想分享的是:如何在Format中添加一个跟随已选文本的Popover,并在里面做相关的设置。例如做一个文本色彩选择器:

WordPress编辑器Gutenberg创建Format格式工具的方法

WordPress编辑器Gutenberg创建Format格式工具的方法
特别需要注意的是:这样的一个写法并非是我凭空杜撰,WordPress官方其实是有示例的,本文参考并致敬了“超链接”这个Format。
编写一个FormatPHP部分
PHP的部分和Block的创建方法基本是一致的:大致逻辑是注册一个脚本,在Block编辑器的钩子上将脚本引入。
  1. <?php
  2. function register_pandastudio_block_format_mark() {
  3.         wp_register_script(
  4.                 'pandastudio-block-format-mark-js',
  5.                 //根据实际位置引入文件
  6.                 get_stylesheet_directory_uri().'https://static.wpdaxue.com/pandastudio_plugins/format_mark/block.build.js',
  7.                 array( 'wp-rich-text' )
  8.         );
  9. }
  10. add_action( 'init', 'register_pandastudio_block_format_mark' );
  11. function register_pandastudio_block_format_mark_enqueue_assets_editor() {
  12.         wp_enqueue_script( 'pandastudio-block-format-mark-js' );
  13. }
  14. add_action( 'enqueue_block_editor_assets', 'register_pandastudio_block_format_mark_enqueue_assets_editor' );
复制代码
还可根据实际场景需要引入css文件,这里就不做示例了。引入js文件的时候注意一下编译后的文件位置。
Javascript部分
在WordPress的官方文章中,Format的示例教程是一个使用ES5开发出来的教程,对于功能复杂的场景,编写过程会变得异常繁琐,而且不便于人类阅读。因此本文中我将做一个ES Next的开发示例。
注册 Format 的方法是提供在 wp.richText 里面的,引入后即可使用。注册一个 Format 基本结构是:
  1. const {
  2.         registerFormatType,
  3. } = wp.richText;

  4. registerFormatType( 'pandastudio/mark', {
  5.         title: '标记',
  6.         tagName: 'span',
  7.         className: 'pandastudio-mark',
  8.         attributes: {
  9.                 style: 'style',
  10.                 block: 'inline-block'
  11.         },
  12.         edit(){
  13.                 //...
  14.         }
  15. } );
复制代码
由于我们的目的是点击按钮后,弹出一个Popover,而Popover有一个“显示”和“未显示”的状态需要存储。通过修改数据来控制Popover的显示。而这个状态数据在Format中默认是没有办法存储的!因此,我们必须将edit方法扩展一下:
  1. ...
  2. edit: class markEdit extends Component {
  3.         constructor() {
  4.                 super( ...arguments );
  5.                 this.state = {
  6.                         modal_visibility: false,
  7.                 };
  8.         }
  9.         render() {
  10.                 //...
  11.         }
  12. }
  13. ...
复制代码
现在,我们有了一个 state 来存储状态,并且将 Popover 的显示状态存储在了 modal_visibility 中。接下来我们需要:
  • 当用户选择了文本之后,这个 Format 按钮才可用,否则是灰色不可用状态。因此创建了一个words_selected方法来进行判断
  • 对于 Popover,需要定位,查看 Popover 的文档说明可以注意到有一个叫做 anchorRect 的参数,因此编写一个set_popover_rect方法来创建 anchorRect 并存储到 state 中,并在 Popover 的参数中读取它
  • 在 Format 按钮点击后,修改 state 中的 modal_visibility 为 true 来显示 popover,并同时读取当前的选中位置来创建 anchorRect 给 Popover 定位
  • 在点击 Popover 的外部后,通过修改 state 中的 modal_visibility 为 false 来关闭Popover
    1. const { getRectangleFromRange } = wp.dom;
    2. const { RichTextToolbarButton } = wp.editor;
    3. const { Popover } = wp.components;
    4. const { Fragment } = wp.element;
    5. ...
    6. edit: class markEdit extends Component {
    7.         constructor() {
    8.                 super( ...arguments );
    9.                 this.show_modal = this.show_modal.bind( this );
    10.                 this.close_modal = this.close_modal.bind( this );
    11.                 this.words_selected = this.words_selected.bind( this );
    12.                 this.set_popover_rect = this.set_popover_rect.bind( this );
    13.                 this.state = {
    14.                         modal_visibility: false,
    15.                 };
    16.         }
    17.         words_selected() {
    18.                 const { value } = this.props;
    19.                 return value.start !== value.end;
    20.         }
    21.         set_popover_rect() {
    22.                 const selection = window.getSelection();
    23.                 const range = selection.rangeCount > 0 ? selection.getRangeAt( 0 ) : null;
    24.                 var rectangle = getRectangleFromRange( range );
    25.                 this.setState( { popover_rect: rectangle } );
    26.         }
    27.         show_modal() {
    28.                 this.setState( { modal_visibility: true } );
    29.                 this.set_popover_rect();
    30.         }
    31.         close_modal() {
    32.                 this.setState( { modal_visibility: false } );
    33.         }
    34.         render() {
    35.                 let {
    36.                         isActive
    37.                 } = this.props;
    38.                 return (
    39.                         <Fragment>
    40.                                 <RichTextToolbarButton
    41.                                 icon='editor-code'
    42.                                 title="标记"
    43.                                 onClick={ this.show_modal }
    44.                                 isActive={ isActive }
    45.                                 isDisabled={ !this.words_selected() }
    46.                                 />
    47.                                 { this.state.modal_visibility && (
    48.                                         <Popover
    49.                                         anchorRect = { this.state.popover_rect }
    50.                                         position = "bottom center"
    51.                                         className = "pandastudio_mark_popover"
    52.                                         onClickOutside = { this.close_modal }
    53.                                         >
    54.                                         Popover内容
    55.                                         </Popover>
    56.                                 )}
    57.                         </Fragment>
    58.                 );
    59.         }
    60. }
    61. ...
    复制代码
    需要注意的是,在set_popover_rect方法中使用到了另一个getRectangleFromRange方法,这个方法是 WordPress 在 wp.dom 中提供的,需要先引入。其他组件的引入我这里就不在多说了,详见WordPress文档即可。
    这样,一个 Format 和 Popover 融合的框架就完成了。当Popover弹出后需要操作的其他事情,就可以在Popover的内容中去添加事件方法了。
    总结
    这个示例中,主要有两个部分需要注意:
    • 注册 Format 的方法中 edit 参数需要扩展才可以存储状态数据
    • Popover的定位方法使用了 wp.dom.getRectangleFromRange 并传入了已选文本的位置参数,这是难点。这个方法 WordPress 官方没有文档描述,我也不是凭空找到的,此处致敬了“超链接”的编写方法


道勤主机提供365天*24小时全年全天无休、实时在线、零等待的售后技术支持。竭力为您免费处理您在使用道勤主机过程中所遇到的一切问题! 如果您是道勤主机用户,那么您可以通过QQ【792472177】、售后QQ【59133755】、旺旺【诠释意念】、15056962695免费电话、后台提交工单这些方式联系道勤主机客服! 如果您不是我们的客户也没问题,点击页面最右边的企业QQ在线咨询图标联系我们并购买后,我们为您免费进行无缝搬家服务,让您享受网站零访问延迟的迁移到道勤主机的服务!


加入道勤网VIP-www.daoqin.net-享受建站指导服务!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

道勤网- 推荐内容!上一条 /2 下一条



 
 
技术支持
在线客服
点击这里给我发消息
点击这里给我发消息
道勤建站群:
3群建站-美工交流-道勤
道勤美工群:
3群建站-美工交流-道勤
工作时间:
8:00-18:00
客服热线:
15056962695
官方微信扫一扫
发布主题 上个主题 下个主题 快速回复 返回列表 联系我们 官方QQ群

关于我们|手机版|小黑屋|地图|【道勤网】-www.daoqin.net 软件视频自学教程|免费教程|自学电脑|3D教程|平面教程|影视动画教程|办公教程|机械设计教程|网站设计教程【道勤网】 ( 皖ICP备15000319号|赞助我们  

GMT+8, 2020-1-26 08:50

Powered by DaoQin! X3.2 © 2016-2063 Dao Qin & 道勤科技

快速回复 返回顶部 返回列表