
在建立一些外掛時,我發現使用 React 元件在 WordPress 管理後臺中建立動態應用程式要比以前使用 PHP 和 jQuery 容易得多。不過,將 React 元件與 WordPress 管理整合起來可能有點難度,尤其是在樣式和可訪問性方面。這就不產生了 Kubrick UI。
Kubrick UI 是一個基於 React 的庫,提供預構建的可定製元件,可與 WordPress 管理區無縫整合。它提高了視覺一致性和可訪問性,讓你能更輕鬆地在 WordPress 管理中建立簡潔、動態的介面,例如建立自定義設定頁面。
在進一步討論之前,我假設您已經熟悉 WordPress 外掛的工作原理及熟悉 JavaScript、React 以及如何使用 NPM 安裝 Node.js 軟體包,因為本教學不會深入探討這些基礎知識。否則,請檢視我們下面的文章,幫助您儘快掌握。
如果您已經準備好了,現在就可以開始學習如何建立 WordPress 設定頁面。
專案結構
首先,我們要建立和組織所需的檔案:
.
|-- package.json
|-- settings-page.php
|-- src
|-- index.js
|-- App.js
|-- styles.scss
.
|-- package.json
|-- settings-page.php
|-- src
|-- index.js
|-- App.js
|-- styles.scss
我們有一個包含原始檔、樣式表和 JavaScript 檔案的 src
目錄,其中將包含應用程式元件和樣式。我們還建立了 settings-page.php
,其中包含WordPress 外掛頭,這樣我們就能在 WordPress 中將程式碼作為外掛載入。最後,我們還建立了 package.json
,以便安裝一些 NPM 軟體包。
NPM 軟體包
接下來,我們要為使用者介面元件安裝 @syntatis/kubrick
包,以及其他一些依賴的包和一些構建頁面所需的包: @wordpress/api-fetch
, @wordpress/dom-ready
, react
, 和 react-dom
。
npm i @syntatis/kubrick @wordpress/api-fetch @wordpress/dom-ready react react-dom
npm i @syntatis/kubrick @wordpress/api-fetch @wordpress/dom-ready react react-dom
npm i @syntatis/kubrick @wordpress/api-fetch @wordpress/dom-ready react react-dom
並將 @wordpress/scripts
包作為開發依賴包,以便我們輕鬆編譯原始檔。
npm i @wordpress/scripts -D
npm i @wordpress/scripts -D
npm i @wordpress/scripts -D
執行指令碼
在package.json
中,我們新增了幾個自定義指令碼,如下所示:
"build": "wp-scripts build",
"start": "wp-scripts start"
{
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
}
}
{
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
}
}
build
指令碼將允許我們把 src
目錄中的檔案編譯成我們將在“設定”頁面上載入的檔案。在開發過程中,我們將執行 start
指令碼。
npm run start
執行指令碼後,您應該能在 build
目錄中找到編譯後的檔案:
.
|-- index.asset.php
|-- index.css
|-- index.js
.
|-- index.asset.php
|-- index.css
|-- index.js
建立設定頁面
建立設定頁面有幾個步驟。
首先,我們要更新 settings-page.php
檔案,在 WordPress 中註冊我們的設定頁面,並註冊頁面的設定和選項。
add_action('admin_menu', 'add_submenu');
'options-general.php', // Parent slug.
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<div id="kubrick-settings"></div>
<?php esc_html_e('This settings page requires JavaScript to be enabled in your browser. Please enable JavaScript and reload the page.', 'settings-page-example'); ?>
function register_settings() {
register_setting( 'kubrick_option_group', 'admin_footer_text', [
'sanitize_callback' => 'sanitize_text_field',
'default' => 'footer text',
add_action('admin_init', 'register_settings');
add_action('rest_api_init', 'register_settings');
add_action('admin_menu', 'add_submenu');
function add_submenu() {
add_submenu_page(
'options-general.php', // Parent slug.
'Kubrick Settings',
'Kubrick',
'manage_options',
'kubrick-setting',
function () {
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<div id="kubrick-settings"></div>
<noscript>
<p>
<?php esc_html_e('This settings page requires JavaScript to be enabled in your browser. Please enable JavaScript and reload the page.', 'settings-page-example'); ?>
</p>
</noscript>
</div>
<?php
},
);
}
function register_settings() {
register_setting( 'kubrick_option_group', 'admin_footer_text', [
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'default' => 'footer text',
'show_in_rest' => true,
] );
}
add_action('admin_init', 'register_settings');
add_action('rest_api_init', 'register_settings');
add_action('admin_menu', 'add_submenu');
function add_submenu() {
add_submenu_page(
'options-general.php', // Parent slug.
'Kubrick Settings',
'Kubrick',
'manage_options',
'kubrick-setting',
function () {
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<div id="kubrick-settings"></div>
<noscript>
<p>
<?php esc_html_e('This settings page requires JavaScript to be enabled in your browser. Please enable JavaScript and reload the page.', 'settings-page-example'); ?>
</p>
</noscript>
</div>
<?php
},
);
}
function register_settings() {
register_setting( 'kubrick_option_group', 'admin_footer_text', [
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'default' => 'footer text',
'show_in_rest' => true,
] );
}
add_action('admin_init', 'register_settings');
add_action('rest_api_init', 'register_settings');
在此,我們將在 WordPress 管理中的設定選單下新增一個子選單頁面。我們還要為頁面註冊設定和選項。register_setting
函式用於註冊設定,show_in_rest
引數設定為 true
,這對於在 WordPress REST API(/wp/v2/settings
)中使用設定和選項非常重要。
接下來,我們要做的事情是將編譯好的樣式表和 JavaScript 檔案排入 build
目錄。我們將在admin_enqueue_scripts
動作中新增一個動作鉤子。
add_action('admin_enqueue_scripts', function () {
$assets = include plugin_dir_path(__FILE__) . 'build/index.asset.php';
plugin_dir_url(__FILE__) . 'build/index.js',
plugin_dir_url(__FILE__) . 'build/index.css',
add_action('admin_enqueue_scripts', function () {
$assets = include plugin_dir_path(__FILE__) . 'build/index.asset.php';
wp_enqueue_script(
'kubrick-setting',
plugin_dir_url(__FILE__) . 'build/index.js',
$assets['dependencies'],
$assets['version'],
true
);
wp_enqueue_style(
'kubrick-setting',
plugin_dir_url(__FILE__) . 'build/index.css',
[],
$assets['version']
);
});
add_action('admin_enqueue_scripts', function () {
$assets = include plugin_dir_path(__FILE__) . 'build/index.asset.php';
wp_enqueue_script(
'kubrick-setting',
plugin_dir_url(__FILE__) . 'build/index.js',
$assets['dependencies'],
$assets['version'],
true
);
wp_enqueue_style(
'kubrick-setting',
plugin_dir_url(__FILE__) . 'build/index.css',
[],
$assets['version']
);
});
如果您載入了 WordPress 管理程式,現在應該可以在“設定”下看到新的子選單。在該子選單的頁面上,我們將呈現一個 ID 為 root
的 div
,並在其中呈現我們的 React 應用程式。

此時,頁面上還看不到任何東西。我們需要建立一個 React 元件,並將其呈現在頁面上。
建立 React 元件
要建立 React 應用程式,我們首先要在 App.js
檔案中新增 App 函式元件。我們還將從 @syntatis/kubrick
包中匯入 index.css
,以便為部分元件應用基本樣式。
import '@syntatis/kubrick/dist/index.css';
export const App = () => {
return <p>Hello World from App</p>;
import '@syntatis/kubrick/dist/index.css';
export const App = () => {
return <p>Hello World from App</p>;
};
import '@syntatis/kubrick/dist/index.css';
export const App = () => {
return <p>Hello World from App</p>;
};
在 index.js
中,我們使用 React 載入並呈現 App
元件。
import domReady from '@wordpress/dom-ready';
import { createRoot } from 'react-dom/client';
import { App } from './App';
const container = document.querySelector( '#root' );
createRoot( container ).render( <App /> );
import domReady from '@wordpress/dom-ready';
import { createRoot } from 'react-dom/client';
import { App } from './App';
domReady( () => {
const container = document.querySelector( '#root' );
if ( container ) {
createRoot( container ).render( <App /> );
}
} );
import domReady from '@wordpress/dom-ready';
import { createRoot } from 'react-dom/client';
import { App } from './App';
domReady( () => {
const container = document.querySelector( '#root' );
if ( container ) {
createRoot( container ).render( <App /> );
}
} );

使用使用者介面元件
在本例中,我們要在設定頁面上新增一個文字輸入,讓使用者可以設定顯示在管理頁尾的文字。
Kubrick UI 目前提供約 18 個元件。要建立上述示例,我們可以使用 TextField 元件為“管理頁尾文字”設定建立一個輸入框,允許使用者修改 WordPress 管理頁尾中顯示的文字。按鈕元件用於提交表單和儲存設定。我們還使用“通知”元件向使用者顯示反饋資訊,如成功儲存設定或在儲存過程中出現錯誤。程式碼會在頁面載入時獲取當前設定,並在提交表單時通過 API 呼叫進行更新。
import { useEffect, useState } from 'react';
import apiFetch from '@wordpress/api-fetch';
import { Button, TextField, Notice } from '@syntatis/kubrick';
import '@syntatis/kubrick/dist/index.css';
export const App = () => {
const [status, setStatus] = useState(null);
const [statusMessage, setStatusMessage] = useState(null);
const [values, setValues] = useState();
// Load the initial settings when the component mounts.
apiFetch({ path: '/wp/v2/settings' })
admin_footer_text: data?.admin_footer_text,
setStatusMessage('An error occurred. Please try to reload the page.');
// Handle the form submission.
const handleSubmit = (e) => {
const data = new FormData(e.target);
admin_footer_text: data.get('admin_footer_text'),
setStatusMessage('Settings saved.');
setStatusMessage('An error occurred. Please try again.');
{status && <Notice level={status} isDismissable onDismiss={() => setStatus(null)}>{statusMessage}</Notice>}
<form method="POST" onSubmit={handleSubmit}>
<table className="form-table" role="presentation">
htmlFor="admin-footer-text"
id="admin-footer-text-label"
aria-labelledby="admin-footer-text-label"
defaultValue={values?.admin_footer_text}
description="This text will be displayed in the admin footer."
<Button type="submit">Save Settings</Button>
import { useEffect, useState } from 'react';
import apiFetch from '@wordpress/api-fetch';
import { Button, TextField, Notice } from '@syntatis/kubrick';
import '@syntatis/kubrick/dist/index.css';
export const App = () => {
const [status, setStatus] = useState(null);
const [statusMessage, setStatusMessage] = useState(null);
const [values, setValues] = useState();
// Load the initial settings when the component mounts.
useEffect(() => {
apiFetch({ path: '/wp/v2/settings' })
.then((data) => {
setValues({
admin_footer_text: data?.admin_footer_text,
});
})
.catch((error) => {
setStatus('error');
setStatusMessage('An error occurred. Please try to reload the page.');
console.error(error);
});
}, []);
// Handle the form submission.
const handleSubmit = (e) => {
e.preventDefault();
const data = new FormData(e.target);
apiFetch({
path: '/wp/v2/settings',
method: 'POST',
data: {
admin_footer_text: data.get('admin_footer_text'),
},
})
.then((data) => {
setStatus('success');
setStatusMessage('Settings saved.');
setValues(data);
})
.catch((error) => {
setStatus('error');
setStatusMessage('An error occurred. Please try again.');
console.error(error);
});
};
if (!values) {
return;
}
return (
<>
{status && <Notice level={status} isDismissable onDismiss={() => setStatus(null)}>{statusMessage}</Notice>}
<form method="POST" onSubmit={handleSubmit}>
<table className="form-table" role="presentation">
<tbody>
<tr>
<th scope="row">
<label
htmlFor="admin-footer-text"
id="admin-footer-text-label"
>
Admin Footer Text
</label>
</th>
<td>
<TextField
aria-labelledby="admin-footer-text-label"
id="admin-footer-text"
className="regular-text"
defaultValue={values?.admin_footer_text}
name="admin_footer_text"
description="This text will be displayed in the admin footer."
/>
</td>
</tr>
</tbody>
</table>
<Button type="submit">Save Settings</Button>
</form>
</>
);
};
export default App;
import { useEffect, useState } from 'react';
import apiFetch from '@wordpress/api-fetch';
import { Button, TextField, Notice } from '@syntatis/kubrick';
import '@syntatis/kubrick/dist/index.css';
export const App = () => {
const [status, setStatus] = useState(null);
const [statusMessage, setStatusMessage] = useState(null);
const [values, setValues] = useState();
// Load the initial settings when the component mounts.
useEffect(() => {
apiFetch({ path: '/wp/v2/settings' })
.then((data) => {
setValues({
admin_footer_text: data?.admin_footer_text,
});
})
.catch((error) => {
setStatus('error');
setStatusMessage('An error occurred. Please try to reload the page.');
console.error(error);
});
}, []);
// Handle the form submission.
const handleSubmit = (e) => {
e.preventDefault();
const data = new FormData(e.target);
apiFetch({
path: '/wp/v2/settings',
method: 'POST',
data: {
admin_footer_text: data.get('admin_footer_text'),
},
})
.then((data) => {
setStatus('success');
setStatusMessage('Settings saved.');
setValues(data);
})
.catch((error) => {
setStatus('error');
setStatusMessage('An error occurred. Please try again.');
console.error(error);
});
};
if (!values) {
return;
}
return (
<>
{status && <Notice level={status} isDismissable onDismiss={() => setStatus(null)}>{statusMessage}</Notice>}
<form method="POST" onSubmit={handleSubmit}>
<table className="form-table" role="presentation">
<tbody>
<tr>
<th scope="row">
<label
htmlFor="admin-footer-text"
id="admin-footer-text-label"
>
Admin Footer Text
</label>
</th>
<td>
<TextField
aria-labelledby="admin-footer-text-label"
id="admin-footer-text"
className="regular-text"
defaultValue={values?.admin_footer_text}
name="admin_footer_text"
description="This text will be displayed in the admin footer."
/>
</td>
</tr>
</tbody>
</table>
<Button type="submit">Save Settings</Button>
</form>
</>
);
};
export default App;
小結
我們剛剛使用 React 元件和 Kubrick UI 庫在 WordPress 中建立了一個簡單的自定義設定頁面。
我們的設定頁面並不完美,還有很多地方可以改進。例如,我們可以新增更多元件,使頁面更易於訪問,或新增更多功能,使頁面更方便使用者使用。我們還可以新增更多錯誤處理,或者在儲存設定時向使用者新增更多反饋。由於我們使用的是 React,因此還可以讓頁面更具互動性和視覺吸引力。
希望本教學能幫助你開始使用 React 元件在 WordPress 中建立自定義設定頁面。您可以在 GitHub 上找到本教學的原始碼,也可以將其作為自己專案的起點。
評論留言