如果您曾经觉得大多数WordPress管理区域似乎与现代且充满活力的帖子和现场编辑相比,您并不孤单。
但是有个好消息:这正在改变。随着WordPress进入 第三阶段:合作,正在进行的努力 改善整体管理员体验 并整合整个视觉语言。
WordPress生态系统也在发生变化。许多著名的插件已更新其设置页面。越来越多的开发人员选择对用户界面进行反应,以增强用户体验并加快新功能的引入。
如果您想做同样的事情怎么办?
本文将指导您通过使用WordPress React组件的插件创建一个基于React的设置页面。
目录
你要建造什么?
在本文中,您将构建一个插件,该插件在前端的标题上方显示公告栏。
它将包括一个设置页面,允许您自定义消息,切换条的可见性并调整其尺寸。
这是最终结果的偷看:
模块化体系结构的力量
与帖子和网站编辑器接触给人的印象。但是,它们是独立组件和包裹编排的产物。
从一开始,Gutenberg项目就开始了松散的耦合或完全脱钩 软件包。使用此模块化体系结构,可以创建不同的接口甚至应用程序。
您将使用这些软件包来创建一个设置页面,但是鉴于它们的可重复使用性和多功能性,您甚至可以将它们用于基于非媒介的项目。
假定的知识和先决条件
本文假设您对React有些熟悉。如果您曾经开发过 基本自定义块,因为技能和概念是高度转移的。
如果要遵循编码,请创建以下启动文件:
/plugins/unadorned-announcement-bar/
├── index.php
├── package.json
└── src/
├── index.js
└── index.scss
您也需要wp-scripts
对于JavaScript构建步骤。有关设置和使用的逐步演练,请查看 开始使用WP-Scripts。
如果您已经对此感到满意,这就是您所需要的package.json
开始:
{
"devDependencies": {
"@wordpress/scripts": "^27.0.0"
},
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
}
}
奠定基础
第一步与使用“传统”自定义设置页面创建插件没有区别。
本节保持不足,至关重要。如果您需要有关任何步骤的更多信息,则可以参考插件基础页面:
设置菜单和设置页面
首先,要开始,将最低要求的插件标题注释添加到index.php
文件,然后在“设置”菜单下注册一个子菜单:
<?php
/**
* Plugin Name: Unadorned Announcement Bar
*/
function unadorned_announcement_bar_settings_page() {
add_options_page(
__( 'Unadorned Announcement Bar', 'unadorned-announcement-bar' ),
__( 'Unadorned Announcement Bar', 'unadorned-announcement-bar' ),
'manage_options',
'unadorned-announcement-bar',
'unadorned_announcement_bar_settings_page_html'
);
}
add_action( 'admin_menu', 'unadorned_announcement_bar_settings_page' );
接下来,将回调函数添加到同一PHP文件:
function unadorned_announcement_bar_settings_page_html() {
printf(
'<div class="wrap" id="unadorned-announcement-bar-settings">%s</div>',
esc_html__( 'Loading…', 'unadorned-announcement-bar' )
);
}
足以输出具有唯一ID的HTML元素。您将使用此id
针对JavaScript中的元素。初始化JavaScript部分后,将更换“加载…”消息。
要访问您的设置页面,请转到 设置 进而 未经装饰的公告栏:
起诉javaScript以进行React
鉴于您正在构建基于React的设置页面,因此您必须提出必要的JavaScript文件。为此,将以下代码添加到index.php
文件:
function unadorned_announcement_bar_settings_page_enqueue_style_script( $admin_page ) {
if ( 'settings_page_unadorned-announcement-bar' !== $admin_page ) {
return;
}
$asset_file = plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
if ( ! file_exists( $asset_file ) ) {
return;
}
$asset = include $asset_file;
wp_enqueue_script(
'unadorned-announcement-bar-script',
plugins_url( 'build/index.js', __FILE__ ),
$asset['dependencies'],
$asset['version'],
array(
'in_footer' => true,
)
);
}
add_action( 'admin_enqueue_scripts', 'unadorned_announcement_bar_settings_page_enqueue_style_script' );
通过确保仅在设置页面上加载JavaScript,您正在遵循最佳实践,并且由于您正在设置依赖项和动态版本,因此您永远不必更新它们。
当构建文件夹及其内容是在 JavaScript已编译 和wp-scripts
。
启动React设置页面
随着前一步,现在是时候编写一些React代码了。
要确认所有事情,您已经完成了工作,从基本的东西开始,例如渲染占位符组件。
将此代码添加到您的src/index.js
文件:
import domReady from '@wordpress/dom-ready';
import { createRoot } from '@wordpress/element';
const SettingsPage = () => {
return <div>Placeholder for settings page</div>;
};
domReady( () => {
const root = createRoot(
document.getElementById( 'unadorned-announcement-bar-settings' )
);
root.render( <SettingsPage /> );
} );
切记安装上述软件包npm install {package}
。当您遇到对新软件包的引用时,也安装这些包。如果您还没有这样做,请开始wp-scripts
构建过程。
通过使用 domReady
,您确保DOM已准备好操纵。在回调中,带有 createRoot
,您告诉React接管指定元素的DOM。然后,这是渲染的问题SettingsPage
成分。
这些步骤对于所有反应应用都是常见的。初始化帖子和站点编辑器时,会发生非常相似的事情。
如果您刷新设置页面,则应查看显示的占位符消息:
可重复使用的UI元素,用于WordPress和其他地方
@wordpress/components
是基石包。它经常使用,因为它包含用于块和站点编辑器的常见UI元素,但是它们足够通用,可以在其他地方使用。
看到 WordPress故事书 有关可用组件的概述。故事书允许您隔离浏览单个组件,其控件,选项和设置。您可以修改其控件和参数,并立即查看更改。
有各种各样的组件可用,您可以期望此列表会随着WordPress的更多区域的大修而扩展
在故事书中,您与React互动代码组件,也存在视觉组件。这些准确地镜像代码中可用的内容。
视觉组件
视觉组件是可重复使用的UI位,可以在 无花果 用于创建模型并在编写任何代码之前尽早探索想法。
您只需从可用的视觉组件中选择即可为插件创建模型:
如果您想与WordPress的设计保持一致,则是组合和安排一些控件的问题,以及添加一个按钮和标题:
构建设置页面的UI
面板
基于模型,您的设置分为两个部分,外貌 默认情况下隐藏了部分。
这 Panel
组件非常适合此用例,因为它可以创建带有可选标头的容器并接受APanelBody
您可以崩溃的组件。
要整合它,您首先需要导入依赖项的顶部src/index.js
文件:
import { __ } from '@wordpress/i18n';
import { Panel, PanelBody, PanelRow } from '@wordpress/components';
请记住,导入语句始终位于文件的顶部。从现在开始,不会明确提及此细节以避免重复。
然后,修改您的SettingsPage
成分。目前,使用一个占位符消息最终将是:
const SettingsPage = () => {
return (
<Panel>
<PanelBody>
<PanelRow>
<div>Placeholder for message control</div>
</PanelRow>
<PanelRow>
<div>Placeholder for display control</div>
</PanelRow>
</PanelBody>
<PanelBody
title={ __( 'Appearance', 'unadorned-announcement-bar' ) }
initialOpen={ false }
>
<PanelRow>
<div>Placeholder for size control</div>
</PanelRow>
</PanelBody>
</Panel>
);
};
这Panel
,PanelBody
,和PanelRow
组件始终在一起使用。这些和随后的组件提供了各种选项,并不是本项目所需的所有选项。您可以通过探索故事书来发现其他可能性。
此时,如果您刷新设置页面,则应看到呈现的组件:
包括组件的样式
现在,事情看起来并不正确。这是因为,默认情况下,组件是未风格的,您仍然需要包括其CSS。
您可以通过吸引wp-components
样式表。在index.php
文件:
function unadorned_announcement_bar_settings_page_enqueue_style_script( $admin_page ) {
// ...
wp_enqueue_style( 'wp-components' );
}
现在,您的设置页面应该查看WordPressy:
管理控件状态
对于此插件,您不需要任何复杂的状态管理。只有三个控件和三个值可以跟踪,您可以从三个实例开始 useState
和一些默认值。
最好将其封装在 自定义钩 将状态与演示层分开。从这里开始,直到另外提到,将所有代码添加到src/index.js
文件:
import { useState } from '@wordpress/element';
const useSettings = () => {
const [ message, setMessage ] = useState('Hello, World!');
const [ display, setDisplay ] = useState(true);
const [ size, setSize ] = useState('medium');
return {
message,
setMessage,
display,
setDisplay,
size,
setSize,
};
};
虽然您的代码目前只有几行,但一旦您尝试从数据库保存或加载数据,它将不可避免地会增长。自定义挂钩和拥有国家管理的中心地位的好处将很快变得更加明显。请继续关注。
访问状态变量和设置器功能SettingsPage
组件,致电useSettings
并破坏返回的对象:
const SettingsPage = () => {
const {
message,
setMessage,
display,
setDisplay,
size,
setSize,
} = useSettings();
// ...
};
消息控制
为了允许发布较长的文本发布公告栏消息,您不会出错 TextareaControl
成分。
要使事情保持整洁,请将其包裹在单独的组件中:
import { TextareaControl } from '@wordpress/components';
const MessageControl = ( { value, onChange } ) => {
return (
<TextareaControl
label={ __( 'Message', 'unadorned-announcement-bar' ) }
value={ value }
onChange={ onChange }
__nextHasNoMarginBottom
/>
);
};
随着WordPress的发展,有时有必要 调整现有组件的样式。当引入新样式时,它们将被放在功能标志道具后面。__next
。这为第三方提供了一个必要的调整,为第三方提供了宽限期。
创建后,下一步是用MessageControl
成分。使用message
恒定为您在您的值及其设置器功能中的常数onChange
处理者:
const SettingsPage = () => {
const {
message,
setMessage,
// ...
} = useSettings();
return (
<Panel>
<PanelBody>
<PanelRow>
<MessageControl
value={ message }
onChange={ ( value ) => setMessage( value ) }
/>
</PanelRow>
<PanelRow></PanelRow>
</PanelBody>
<PanelBody></PanelBody>
</Panel>
);
};
经过所有这些工作,您的第一个控件正常工作,使您可以更新消息:
显示控件
要切换公告栏的可见性,您需要开/关开关。选择 ToggleControl
成分。
要保持一致性,请遵循与上一节相同的方法。首先,为控件创建一个单独的组件:
import { ToggleControl } from '@wordpress/components';
const DisplayControl = ( { value, onChange } ) => {
return (
<ToggleControl
label={ __( 'Display', 'unadorned-announcement-bar' ) }
checked={ value }
onChange={ onChange }
__nextHasNoMarginBottom
/>
);
};
然后,用您拥有的占位符DisplayControl
组件,并使用相应的常数和设置器函数onChange
处理者:
const SettingsPage = () => {
const {
// ...
display,
setDisplay,
// ...
} = useSettings();
return (
<Panel>
<PanelBody>
<PanelRow></PanelRow>
<PanelRow>
<DisplayControl
value={ display }
onChange={ ( value ) => setDisplay( value ) }
/>
</PanelRow>
</PanelBody>
<PanelBody></PanelBody>
</Panel>
);
};
大小控制
对于尺寸控制,您有几个不同的组件可供选择,但最合适的是多功能 FontSizePicker
成分。
与先前的控件类似,为其创建一个单独的组件。这里唯一的区别是您必须定义可能的选项列表:
import { FontSizePicker } from '@wordpress/components';
const SizeControl = ( { value, onChange } ) => {
return (
<FontSizePicker
fontSizes={ [
{
name: __( 'Small', 'unadorned-announcement-bar' ),
size: 'small',
slug: 'small',
},
{
name: __( 'Medium', 'unadorned-announcement-bar' ),
size: 'medium',
slug: 'medium',
},
{
name: __( 'Large', 'unadorned-announcement-bar' ),
size: 'large',
slug: 'large',
},
{
name: __( 'Extra Large', 'unadorned-announcement-bar' ),
size: 'x-large',
slug: 'x-large',
},
] }
value={ value }
onChange={ onChange }
disableCustomFontSizes={ true }
__nextHasNoMarginBottom
/>
);
};
默认情况下,您可以在预定义值列表之外选择任何尺寸disableCustomFontSizes
支柱。
最后一次,用实际的组件替换占位符文本,并配置value
和onChange
支柱:
const SettingsPage = () => {
const {
// ...
size,
setSize,
} = useSettings();
return (
<Panel>
<PanelBody></PanelBody>
<PanelBody
title={ __( 'Appearance', 'unadorned-announcement-bar' ) }
initialOpen={ false }
>
<PanelRow>
<SizeControl
value={ size }
onChange={ ( value ) => setSize( value ) }
/>
</PanelRow>
</PanelBody>
</Panel>
);
};
在这一点上,您的所有三个控件都可以正常工作,这是工作的一半。您的设置页面现在应该看起来像这样:
保存按钮
要完成设置页面的基础知识,您需要添加两个组件。
首先,您需要 Button
保存的组件。像您之前一样,为其创建包装组件:
import { Button } from '@wordpress/components';
const SaveButton = ( { onClick } ) => {
return (
<Button variant="primary" onClick={ onClick } __next40pxDefaultSize>
{ __( 'Save', 'unadorned-announcement-bar' ) }
</Button>
);
};
接下来,添加SaveButton
成分之后Panel
成分:
const SettingsPage = () => {
// ...
return (
<>
<Panel></Panel>
<SaveButton onClick={ () => {} } />
</>
);
};
单击时,如果目前没有做任何具体的事情,就可以了。您将稍后添加储蓄功能。
不要忘记将两个组件包裹在片段中(在<></>
),因为您只能在React中返回一个组件。
实验标题
您可能已经在故事书中注意到某些组件被标记为实验。
它们之所以被称为实验,是因为WordPress的向后兼容性保证不适用于它们。它们可以从一个版本更改为另一个版本,可能会破坏代码。
谨慎使用它们,但是要尝试一下,您可以使用 __experimentalHeading
标题的组成部分,而不是平原h1
标签:
import {
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
__experimentalHeading as Heading,
} from '@wordpress/components';
const SettingsTitle = () => {
return (
<Heading level={ 1 }>
{ __( 'Unadorned Announcement Bar', 'unadorned-announcement-bar' ) }
</Heading>
);
};
如果您用代码提起wp-scripts
,如果使用实验组件,这会触发警告。您可以表明您知道自己在做什么eslint-disable-next-line
。
这次,在Panel
将其渲染到页面顶部的组件:
const SettingsPage = () => {
// ...
return (
<>
<SettingsTitle />
<Panel></Panel>
<SaveButton />
</>
);
};
持续和加载设置
在常规的WordPress设置页面上,进行更改并保存它时,您提交表格,然后重新加载页面。
这种方法与React的动态交互模型不符。当将某些内容加载或保存在块和站点编辑器中时,这种情况会在后台执行许多REST API请求时无缝地发生。同样,您将使用REST API加载并保存设置。
你可以 存储状态 在选项表中,控件作为单独的单个值,但这将为每个值不必要地创建一个新记录。对于此插件,您应该选择其他选项:将它们存储为单个密钥下的值数组。
定义默认和模式
打电话时始终恢复预期价值get_option( 'unadorned_announcement_bar' )
,您应该为其定义默认值。
另外,如果您也 定义模式 严格来说,您不必担心使用REST API时的验证,WordPress将会照顾。
您同时使用 register_setting
功能。将以下代码放在您的index.php
文件:
function unadorned_announcement_bar_settings() {
$default = array(
'message' => __( 'Hello, World!', 'unadorned-announcement-bar' ),
'display' => true,
'size' => 'medium',
);
$schema = array(
'type' => 'object',
'properties' => array(
'message' => array(
'type' => 'string',
),
'display' => array(
'type' => 'boolean',
),
'size' => array(
'type' => 'string',
'enum' => array(
'small',
'medium',
'large',
'x-large',
),
),
),
);
register_setting(
'options',
'unadorned_announcement_bar',
array(
'type' => 'object',
'default' => $default,
'show_in_rest' => array(
'schema' => $schema,
),
)
);
}
add_action( 'init', 'unadorned_announcement_bar_settings' );
加载设置
到达设置页面后,您需要加载设置。
每当要触发组件一旦安装组件触发操作,就可以使用 useEffect
钩。在这种情况下,您想与 apiFetch
到 站点设置端点 加载并使用保存的设置。
由于所有这些都与国家管理有关,请修改您的useSettings
定制挂钩src/index.js
相应地文件:
import apiFetch from '@wordpress/api-fetch';
import { useEffect } from '@wordpress/element';
const useSettings = () => {
const [ message, setMessage ] = useState();
const [ display, setDisplay ] = useState();
const [ size, setSize ] = useState();
useEffect( () => {
apiFetch( { path: '/wp/v2/settings' } ).then( ( settings ) => {
setMessage( settings.unadorned_announcement_bar.message );
setDisplay( settings.unadorned_announcement_bar.display );
setSize( settings.unadorned_announcement_bar.size );
} );
}, [] );
// ...
};
在register_setting
由端点提供。因此,您不再需要在您的useState
呼叫。端点返回数据后,您可以使用Setter函数更新状态。这个过程几乎立即发生。
保存设置
就像您处理数据加载的方式一样,您可以使用站点设置端点来持续设置。
这次,REST API调用不应在页面加载上发生,但是当您单击SaveButton时。因此,首先封装apiFetch
在功能中useSettings
钩:
const useSettings = () => {
// ...
const saveSettings = () => {
apiFetch( {
path: '/wp/v2/settings',
method: 'POST',
data: {
unadorned_announcement_bar: {
message,
display,
size,
},
},
} );
};
return {
// ...
saveSettings,
};
};
然后,您可以使用导出saveSettings
充当onClick
在你的SaveButton
成分:
const SettingsPage = () => {
const {
// ...
saveSettings,
} = useSettings();
return (
<>
<SettingsTitle/>
<Panel></Panel>
<SaveButton onClick={ saveSettings } />
</>
);
};
现在,按下 节省 按钮,您可以坚持更改。如果刷新设置页面,则将加载保存的设置。
只有几件事缺少,其中之一就是前端功能。
在前端显示公告栏
显示公告栏的最直接方法是在body
标签。
您可以使用wp_body_open
Hook,如今预计将以任何主题存在。将以下代码添加到您的index.php
文件:
function unadorned_announcement_bar_front_page() {
$options = get_option( 'unadorned_announcement_bar' );
if ( ! $options['display'] ) {
return;
}
printf(
'<div>%s</div>',
esc_html( $options['message'] )
);
}
add_action( 'wp_body_open', 'unadorned_announcement_bar_front_page' );
由于公告栏所需的样式最少,因此您可以简单地将CSS嵌入其中。更新您刚刚创建的功能:
function unadorned_announcement_bar_front_page() {
// ...
printf(
'<div style="%s">%s</div>',
sprintf(
'background: var(--wp--preset--color--vivid-purple, #9b51e0); color: var(--wp--preset--color--white, #ffffff); padding: var(--wp--preset--spacing--20, 1.5rem); font-size: %s;',
esc_attr( $options['size'] )
),
esc_html( $options['message'] )
);
}
或者,如果您想避免使用冗长的内联CSS,则可以使用 compile_css
的方法WP_Style_Engine
:
function unadorned_announcement_bar_front_page() {
// ...
$css = WP_Style_Engine::compile_css(
array(
'background' => 'var(--wp--preset--color--vivid-purple, #9b51e0)',
'color' => 'var(--wp--preset--color--white, #ffffff)',
'padding' => 'var(--wp--preset--spacing--20, 1.5rem)',
'font-size' => $options['size'],
),
''
);
printf(
'<div style="%s">%s</div>',
esc_attr( $css ),
esc_html( $options['message'] )
);
}
结果是相同的:
最后的接触
此时,您可以显示公告栏并更改其设置。您的插件功能很正常,但是添加了更多详细信息,您可以使其更加抛光。
添加通知
保存设置时,没有视觉迹象表明该过程成功。为了改善这种情况,添加通知系统将消除任何猜测。
它超出了本介绍性文章的目标,可以解释通知实施的一些细节。但是,您会在文章末尾提到的一门课程详细解释。您将获得很多收益。
本质上,这归结为两件事。首先,您必须触发某种类型的通知。
您可以对您的自定义挂钩进行以下更改src/index.js
文件:
import { useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
const useSettings = () => {
// ...
const { createSuccessNotice } = useDispatch( noticesStore );
// ...
const saveSettings = () => {
apiFetch( {
// ...
} ).then( () => {
createSuccessNotice(
__( 'Settings saved.', 'unadorned-announcement-bar' )
);
} );
};
// ...
};
在下一步中,WordPress提供了一些组件来抽象大多数复杂性。
只需几行,您就可以创建一个呈现通知的组件,如果有的话。您可以使用以下代码并将其添加到src/index.js
文件:
import { useDispatch, useSelect } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import { NoticeList } from '@wordpress/components';
const Notices = () => {
const { removeNotice } = useDispatch( noticesStore );
const notices = useSelect( ( select ) =>
select( noticesStore ).getNotices()
);
if ( notices.length === 0 ) {
return null;
}
return <NoticeList notices={ notices } onRemove={ removeNotice } />;
};
作为最后一步,包括Notices
现有的组件SettingsPage
。根据模型,您应该在SettingsTitle
:
const SettingsPage = () => {
// ...
return (
<>
<SettingsTitle/>
<Notices />
<Panel></Panel>
<SaveButton />
</>
);
};
现在,每当保存设置时,都应该看到显示的通知。
添加自定义样式
没有任何自定义CSS,当前的设置页面看起来还不错。但是,需要进行一些较小的调整以与设计紧密匹配。
首先,您必须导入index.scss
到index.js
将SASS文件编译到常规CSS:
import './index.scss';
// ..
domReady( () => {
// ...
} );
然后,您必须加入CSS文件。添加wp_enqueue_style
到现有unadorned_announcement_bar_settings_page_enqueue_style_script
功能位于index.php
文件:
function unadorned_announcement_bar_settings_page_enqueue_style_script( $admin_page ) {
// ...
wp_enqueue_style(
'unadorned-announcement-bar-style',
plugins_url( 'build/index.css', __FILE__ ),
array_filter(
$asset['dependencies'],
function ( $style ) {
return wp_style_is( $style, 'registered' );
}
),
$asset['version'],
);
}
您可以安全地删除wp_enqueue_style( 'wp-components' )
,因为它已经包含在依赖项列表中。
您需要做的就是调整一些间距和宽度。将以下样式添加到src/index.scss
文件:
#unadorned-announcement-bar-settings {
max-width: 800px;
h1 {
padding-block: 8px;
}
.components-base-control:has(textarea) {
flex-basis: 400px;
}
.components-notice {
&, &__content {
margin: 0;
}
}
.components-notice-list {
display: flex;
flex-direction: column;
gap: 8px;
margin-block-end: 16px;
}
.components-panel {
margin-block-end: 8px;
}
}
添加了样式,您的设置页面应该更加安排:
下一步
存储库和操场
您可以检查 github上的存储库 一起查看整个代码。
如果您跟随并逐步创建插件,您知道完全有可能在src/index.js
。在存储库中,JavaScript分为多个文件,以展示如何组织更复杂的React应用程序。但是,从本质上讲,这是相同的代码。
如果您想与插件进行交互并在没有下载和安装的情况下看到它在行动中,请转到准备的 WordPress操场。
改进的想法
虽然插件是完整的,但总有改进的余地。
到目前为止,您已经实施了成功的通知,但是处理其余API的错误又如何呢?
该代码还可以说明返回错误数据类型的情况,因为unadorned_announcement_bar
选项表中的选项可以通过其他方式以外的其他方式更新。
或者,您可以探索添加更多设置。例如,可以添加控件以更改公告栏的颜色。您可以使用 ColorPalette
组件。
潜水更深
要了解有关使用WordPress React组件创建动态用户界面的更多信息,您应该继续进行 使用WordPress数据层 课程。
它为数据层提供了逐步且全面的介绍,并指导您创建一个更复杂的React应用程序来管理WordPress页面。您可以了解其他组件,并深入了解通知。
道具 @Greenshady,@BPH 进行编辑评论,并 @carmen222,@strangerkir 特别是为了他们的道德支持。