{"id":2547,"date":"2024-10-21T13:00:56","date_gmt":"2024-10-21T13:00:56","guid":{"rendered":"http:\/\/suimy.me\/?p=2547"},"modified":"2024-10-23T17:08:00","modified_gmt":"2024-10-23T17:08:00","slug":"how-to-create-a-wordpress-settings-page-with-react","status":"publish","type":"post","link":"http:\/\/suimy.me\/index.php\/2024\/10\/21\/how-to-create-a-wordpress-settings-page-with-react\/","title":{"rendered":"How to Create a WordPress Settings Page with React"},"content":{"rendered":"
While building some plugins, I figured creating dynamic applications in WordPress Admin<\/strong> is much easier with React<\/a> components compared to using PHP and jQuery like back in the old days. However, integrating React components with WordPress Admin can be a bit challenging, especially when it comes to styling and accessibility. This led me to create Kubrick UI<\/a>.<\/p>\n Kubrick UI is a React-based library offering pre-built, customizable components that seamlessly integrate with the WordPress admin area. It improves both visual consistency and accessibility, making it easier for you to create clean, dynamic interfaces in WordPress Admin, such as creating a Custom Settings Pages<\/a><\/strong>.<\/p>\n Before we go further, I\u2019d assume that you\u2019re already familiar with how WordPress plugins work. You\u2019re also familiar with JavaScript, React, and how to install Node.js packages with NPM as we won\u2019t dig into these fundamentals in this tutorial. Otherwise, check out our articles below to help you get up to speed.<\/p>\n If you\u2019re ready, we can now get started with our tutorial on how to create our WordPress Settings page.<\/p>\n First, we are going to create and organize the files required:<\/p>\n We have the Next, we are going to install the And the Within the The After running the script, you should find the compiled files in the There are several steps we are going to do and tie together to create the Settings Page.<\/p>\n First, we are going to update our \n \n <\/p>\n \n <\/div>\n 'string', \r\n 'sanitize_callback' => 'sanitize_text_field',\r\n 'default' => 'footer text',\r\n 'show_in_rest' => true,\r\n ] ); \r\n}\r\n\r\nadd_action('admin_init', 'register_settings');\r\nadd_action('rest_api_init', 'register_settings');\r\n<\/pre>\n Here, we are adding a submenu page under the Settings<\/strong> menu in WordPress Admin. We also register the settings and options for the page. The The next thing we are going to do is enqueue the stylesheet and JavaScript files that we have compiled in the If you load WordPress Admin, you should now see the new submenu under Settings<\/strong>. On the page of this submenu, we render a At this point, there\u2019s nothing to see on the page just yet. We will need to create a React component and render it on the page.<\/p>\n To create the React application, we first add the App function component in our Hello World from App<\/p>;\r\n};\r\n<\/pre>\n In the In this example, we\u2019d like to add a text input on the Settings Page which will allow the user to set the text that will be displayed in the admin footer.<\/p>\n Kubrick UI currently offers around 18 components. To create the example mentioned, we can use the \n
Project Structure<\/h4>\n
\r\n.\r\n|-- package.json\r\n|-- settings-page.php\r\n|-- src\r\n |-- index.js\r\n |-- App.js\r\n |-- styles.scss\r\n<\/pre>\n
src<\/code> directory containing the source files, stylesheet, and JavaScript files, which will contain the app components and the styles. We also created
settings-page.php<\/code>, which contains the WordPress plugin header<\/a> so that we can load our code as a plugin in WordPress. Lastly, we have
package.json<\/code> so we can install some NPM packages.<\/p>\n
NPM Packages<\/h4>\n
@syntatis\/kubrick<\/code> package for our UI components, as well as a few other packages that it depends on and some that we need to build the page:
@wordpress\/api-fetch<\/code>,
@wordpress\/dom-ready<\/code>,
react<\/code>, and
react-dom<\/code>.<\/p>\n
\r\nnpm i @syntatis\/kubrick @wordpress\/api-fetch @wordpress\/dom-ready react react-dom\r\n<\/pre>\n
@wordpress\/scripts<\/code> package as a development dependency, to allow us to compile the source files easily.<\/p>\n
\r\nnpm i @wordpress\/scripts -D\r\n<\/pre>\n
Running the Scripts<\/h4>\n
package.json<\/code>, we add a couple of custom scripts, as follows:<\/p>\n
\r\n{\r\n \"scripts\": {\r\n \"build\": \"wp-scripts build\",\r\n \"start\": \"wp-scripts start\"\r\n }\r\n}\r\n<\/pre>\n
build<\/code> script will allow us to compile the files within the
src<\/code> directory into files that we will load on the Settings Page. During development, we are going to run the
start<\/code> script.<\/p>\n
\r\nnpm run start\r\n<\/pre>\n
build<\/code> directory:<\/p>\n
\r\n.\r\n|-- index.asset.php\r\n|-- index.css\r\n|-- index.js\r\n<\/pre>\n
Create the Settings Page<\/h4>\n
settings-page.php<\/code> file to register our settings page in WordPress, and register the settings and the options for the page.<\/p>\n
\r\nadd_action('admin_menu', 'add_submenu');\r\n\r\nfunction add_submenu() {\r\n add_submenu_page( \r\n 'options-general.php', \/\/ Parent slug.\r\n 'Kubrick Settings',\r\n 'Kubrick',\r\n 'manage_options',\r\n 'kubrick-setting',\r\n function () { \r\n ?>\n
<\/h1>\n
register_setting<\/code> function is used to register the setting, and the
show_in_rest<\/code> parameter is set to
true<\/code>, which is important to make the setting and the option available in the WordPress
\/wp\/v2\/settings<\/code> REST API.<\/p>\n
build<\/code> directory. We are going to do this by adding an action hook to the
admin_enqueue_scripts<\/code> action.<\/p>\n
\r\nadd_action('admin_enqueue_scripts', function () {\r\n $assets = include plugin_dir_path(__FILE__) . 'build\/index.asset.php';\r\n\r\n wp_enqueue_script(\r\n 'kubrick-setting', \r\n plugin_dir_url(__FILE__) . 'build\/index.js',\r\n $assets['dependencies'], \r\n $assets['version'],\r\n true\r\n );\r\n\r\n wp_enqueue_style(\r\n 'kubrick-setting', \r\n plugin_dir_url(__FILE__) . 'build\/index.css',\r\n [], \r\n $assets['version']\r\n );\r\n});\r\n<\/pre>\n
div<\/code> with the ID
root<\/code> where we are going to render our React application.<\/p>\n
Creating a React component<\/h5>\n
App.js<\/code> file. We also import the
index.css<\/code> from the
@syntatis\/kubrick<\/code> package within this file to apply the basic styles to some of the components.<\/p>\n
\r\nimport '@syntatis\/kubrick\/dist\/index.css';\r\n \r\nexport const App = () => {\r\n return
index.js<\/code>, we load and render our
App<\/code> component with React.<\/p>\n
\r\nimport domReady from '@wordpress\/dom-ready';\r\nimport { createRoot } from 'react-dom\/client';\r\nimport { App } from '.\/App';\r\n\r\ndomReady( () => {\r\n const container = document.querySelector( '#root' );\r\n if ( container ) {\r\n createRoot( container ).render( );\r\n }\r\n} );\r\n<\/pre>\n
Using the UI components<\/h5>\n
TextField<\/a><\/code> component to create an input field for the \u201cAdmin Footer Text\u201d<\/strong> setting, allowing users to modify the text displayed in the WordPress admin footer. The Button component is used to submit the form and save the settings. We also use the
Notice<\/a><\/code> component to show feedback to the user, such as when the settings are successfully saved or if an error occurs during the process. The code fetches the current settings on page load and updates them via an API call when the form is submitted.<\/p>\n
\r\nimport { useEffect, useState } from 'react';\r\nimport apiFetch from '@wordpress\/api-fetch';\r\nimport { Button, TextField, Notice } from '@syntatis\/kubrick';\r\nimport '@syntatis\/kubrick\/dist\/index.css';\r\n\r\nexport const App = () => {\r\n const [status, setStatus] = useState(null);\r\n const [statusMessage, setStatusMessage] = useState(null);\r\n const [values, setValues] = useState();\r\n\r\n \/\/ Load the initial settings when the component mounts.\r\n useEffect(() => {\r\n apiFetch({ path: '\/wp\/v2\/settings' })\r\n .then((data) => {\r\n setValues({\r\n admin_footer_text: data?.admin_footer_text,\r\n });\r\n })\r\n .catch((error) => {\r\n setStatus('error');\r\n setStatusMessage('An error occurred. Please try to reload the page.');\r\n console.error(error);\r\n });\r\n }, []);\r\n\r\n \/\/ Handle the form submission.\r\n const handleSubmit = (e) => {\r\n e.preventDefault();\r\n const data = new FormData(e.target);\r\n\r\n apiFetch({\r\n path: '\/wp\/v2\/settings',\r\n method: 'POST',\r\n data: {\r\n admin_footer_text: data.get('admin_footer_text'),\r\n },\r\n })\r\n .then((data) => {\r\n setStatus('success');\r\n setStatusMessage('Settings saved.');\r\n setValues(data);\r\n })\r\n .catch((error) => {\r\n setStatus('error');\r\n setStatusMessage('An error occurred. Please try again.');\r\n console.error(error);\r\n });\r\n };\r\n\r\n if (!values) {\r\n return;\r\n }\r\n\r\n return (\r\n \n {status && setStatus(null)}>{statusMessage}}\n \n
\n \n
\n \n