{"id":895,"date":"2019-05-13T04:16:34","date_gmt":"2019-05-13T04:16:34","guid":{"rendered":"http:\/\/smohub.com\/blog\/?p=895"},"modified":"2019-05-13T04:16:34","modified_gmt":"2019-05-13T04:16:34","slug":"using-the-wordpress-settings-api-to-build-a-custom-admin-page","status":"publish","type":"post","link":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/","title":{"rendered":"Using the WordPress Settings API to Build a Custom Admin Page"},"content":{"rendered":"<p><strong>In this guide, we\u2019ll introduce the WordPress Settings API, and create a WordPress administration page where we demonstrate the use of this API.<\/strong><\/p>\n<p>For the purposes of this tutorial, we\u2019ll wrap this functionality into a plugin, but this can also be a part of a WordPress theme.<\/p>\n<p>As the WordPress Codex says, the Settings API was added in WordPress 2.7 to streamline adding different settings fields and sections in administration pages.<\/p>\n<h2 id=\"creatingtheplugin\">Creating the Plugin<\/h2>\n<p>To start, we\u2019ll create and activate a plugin to encapsulate our options page. We\u2019ll use WP CLI to simplify the creation, although this leaves us with way more files than this guide needs.<\/p>\n<div class=\"wp-video\">\n<div id=\"mep_0\" class=\"mejs-container mejs-container-keyboard-inactive wp-video-shortcode mejs-video\" tabindex=\"0\" role=\"application\" aria-label=\"Video Player\">\n<div class=\"mejs-inner\">\n<div class=\"mejs-controls\">\n<div class=\"mejs-button mejs-fullscreen-button\">As we can see, we use\u00a0<code class=\"  language-undefined\">wp scaffold plugin pluginname<\/code>\u00a0to create the plugin. Once it\u2019s created, we activate it \u2014 optionally also using WP CLI, with\u00a0<code class=\"  language-undefined\">wp plugin activate pluginname<\/code>.<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Once it\u2019s activated, we open the main plugin file \u2014 in this case\u00a0<code class=\"  language-undefined\">smohub-settings-api.php<\/code>.<\/p>\n<h2 id=\"creatingtheadminpage\">Creating the Admin Page<\/h2>\n<p>It isn\u2019t necessary to use WP CLI for this plugin. We could have simply created a directory with the name of the plugin, and the PHP file inside it with the same name. Anyhow, the creation of the plugin has left us with a\u00a0<code class=\"  language-undefined\">smohub-settings-api.php<\/code>\u00a0which looks like this:<\/p>\n<pre class=\"  language-php\"><code class=\"php  language-php\"><span class=\"token delimiter\">&lt;?php<\/span>\r\n<span class=\"token comment\" spellcheck=\"true\">\/**\r\n * Plugin Name:     Smohub Settings Api\r\n * Plugin URI:      PLUGIN SITE HERE\r\n * Description:     PLUGIN DESCRIPTION HERE\r\n * Author:          YOUR NAME HERE\r\n * Author URI:      YOUR SITE HERE\r\n * Domain Path:     \/languages\r\n * Version:         0.1.0\r\n *\r\n *\/<\/span>\r\n<span class=\"token operator\">~<\/span>    \r\n<\/code><\/pre>\n<p>Now we can simply add code after the comment end.<\/p>\n<p>To add our options page, we\u2019ll use\u00a0<code class=\"  language-undefined\">add_options_page()<\/code>\u00a0(more details about it\u00a0<a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/add_options_page\/\">here<\/a>). This function takes arguments as follows:<\/p>\n<pre class=\"  language-php\"><code class=\"php  language-php\"><span class=\"token function\">add_options_page<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token variable\">$page_title<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token variable\">$menu_title<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token variable\">$capability<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token variable\">$menu_slug<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token variable\">$function<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>All the arguments are self-explanatory.\u00a0<code class=\"  language-undefined\">$menu_slug<\/code>\u00a0must be a unique string that WordPress will use internally, but will also be reflected in the URL.\u00a0<code class=\"  language-undefined\">$function<\/code>\u00a0is a string with a name of the function that will provide HTML output for our admin page.<\/p>\n<p>We will, therefore, add the following code to our plugin file:<\/p>\n<pre class=\"  language-php\"><code class=\"php  language-php\"><span class=\"token function\">add_action<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'admin_menu'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'smohub_settings_page'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> smohub<span class=\"token function\">_settings_page<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token function\">add_options_page<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'Settings API Page'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'Settings API Page'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'manage_options'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'settings-api-page'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'settings_api_page'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>After we\u2019ve saved the file (presuming we activated our plugin), we\u2019ll open our administration dashboard, and we\u2019ll find our\u00a0<strong>Settings API Page<\/strong>\u00a0under\u00a0<strong>Settings<\/strong>\u00a0in the left side menu.<\/p>\n<p>We can control, to a degree, the order or position of the submenu item by adding a priority argument to our\u00a0<code class=\"  language-undefined\">add_action()<\/code>\u00a0function:<\/p>\n<div class=\"proper-ad-unit\"><a class=\"call-modal report-ad\" href=\"https:\/\/www.sitepoint.com\/wordpress-settings-api-build-custom-admin-page\/#report-ad\" data-aid=\"proper-ad-sitepoint_content_1-2\">Report Advertisement<\/a><\/div>\n<pre class=\"  language-undefined\"><code class=\"  language-undefined\">add_action( 'admin_menu', 'smohub_settings_page', 1 );\r\n<\/code><\/pre>\n<p>If we want to have our menu item to be in the root menu \u2014 rather than the\u00a0<strong>Settings<\/strong>submenu \u2014 we\u2019ll use\u00a0<code class=\"  language-undefined\">add_menu_page()<\/code>, which\u00a0<a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/add_menu_page\/\">takes similar arguments<\/a>.<\/p>\n<p>Now, if we open the page in our browser, all we\u2019ll see is an empty page, because we still haven\u2019t created the\u00a0<code class=\"  language-undefined\">settings_api_page()<\/code>\u00a0function that we specified:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-169925\" src=\"https:\/\/dab1nmslvvntp.cloudfront.net\/wp-content\/uploads\/2018\/11\/1541406530empty-admin.jpg\" alt=\"Currently our admin page is empty\" width=\"995\" height=\"744\" \/><\/p>\n<h2 id=\"thesettingsapi\">The Settings API<\/h2>\n<p>The WordPress Settings API is an intricate mechanism that attempts to provide an easy way for developers to create settings pages.<\/p>\n<p>Before we go into a full-fledged example of the settings page displaying and saving a setting to the WordPress database, we\u2019ll explain couple of crucial functions that WordPress provides as part of its\u00a0<a href=\"https:\/\/codex.wordpress.org\/Settings_API\">Settings API<\/a>.<\/p>\n<p><strong><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/register_setting\/\">register_setting()<\/a><\/strong>\u00a0is a function we use to register a setting, which equals a row in\u00a0<code class=\"  language-undefined\">wp_options<\/code>\u00a0table. Before we can create actual field (or fields, as setting can be an array of values), we need to register it. This way we\u2019ll leverage the WordPress\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Create,_read,_update_and_delete\">CRUD<\/a>\u00a0mechanism for settings. Function arguments are as follows:<\/p>\n<pre class=\"  language-php\"><code class=\"php  language-php\"><span class=\"token function\">register_setting<\/span><span class=\"token punctuation\">(<\/span> string <span class=\"token variable\">$option_group<\/span><span class=\"token punctuation\">,<\/span> string <span class=\"token variable\">$option_name<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">array<\/span> <span class=\"token variable\">$args<\/span> <span class=\"token operator\">=<\/span> <span class=\"token keyword\">array<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">)<\/span>\r\n<\/code><\/pre>\n<p>The first two arguments are mandatory, the first one allowing us to assign fields to it, and\u00a0<code class=\"  language-undefined\">$option_name<\/code>, as we\u2019ll see, is the actual option name in the WordPress database.<\/p>\n<p><strong><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/add_settings_section\/\">add_settings_section()<\/a><\/strong>\u00a0defines\/adds a section to an admin page. Its arguments are as follows:<\/p>\n<pre class=\"  language-undefined\"><code class=\"  language-undefined\">add_settings_section( string $id, string $title, callable $callback, string $page )\r\n<\/code><\/pre>\n<p><code class=\"  language-undefined\">$callback<\/code>\u00a0is a function that outputs an HTL header of the section (it can be empty), and\u00a0<code class=\"  language-undefined\">$page<\/code>\u00a0is the slug of the admin page we\u2019ll display it on.<\/p>\n<p><strong><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/add_settings_field\/\">add_settings_field()<\/a><\/strong>\u00a0defines a settings field within a settings section in an admin options page. Arguments for it are:<\/p>\n<pre class=\"  language-undefined\"><code class=\"  language-undefined\">add_settings_field( string $id, string $title, callable $callback, string $page, string $section = 'default', array $args = array()\r\n<\/code><\/pre>\n<p>Of these,\u00a0<code class=\"  language-undefined\">$id<\/code>,\u00a0<code class=\"  language-undefined\">$title<\/code>,\u00a0<code class=\"  language-undefined\">$callback<\/code>\u00a0and\u00a0<code class=\"  language-undefined\">$page<\/code>\u00a0are required. The\u00a0<code class=\"  language-undefined\">$callback<\/code>\u00a0function should output the HTML of the input field.<\/p>\n<p>The Settings API provides\u00a0<code class=\"  language-undefined\">$page<\/code>\u00a0argument for\u00a0<code class=\"  language-undefined\">add_settings_section<\/code>\u00a0and\u00a0<code class=\"  language-undefined\">add_settings_field<\/code>\u00a0as a means to add sections and fields to existing settings pages. We\u2019ll use\u00a0<code class=\"  language-undefined\">smoPlugin<\/code>\u00a0for both our option group \u2014 in\u00a0<code class=\"  language-undefined\">register_setting()<\/code>\u00a0\u2014 and for attaching the settings section and settings fields to a \u2018smoPlugin\u2019 page in the\u00a0<code class=\"  language-undefined\">add_settings_section()<\/code>\u00a0and\u00a0<code class=\"  language-undefined\">add_settings_field()<\/code>\u00a0functions. We\u2019ll then \u201cquote it\u201d in the next two functions in our example, to output relevant HTML.<\/p>\n<p><strong><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/settings_fields\/\">settings_fields()<\/a><\/strong>\u00a0outputs\u00a0<em>\u201cnonce, action, and option_page fields for a settings page\u201d.<\/em>\u00a0It takes the\u00a0<code class=\"  language-undefined\">$option_group<\/code>\u00a0argument, used in\u00a0<code class=\"  language-undefined\">register_setting()<\/code>.<\/p>\n<div class=\"proper-ad-unit\"><a class=\"call-modal report-ad\" href=\"https:\/\/www.sitepoint.com\/wordpress-settings-api-build-custom-admin-page\/#report-ad\" data-aid=\"proper-ad-sitepoint_content_1-3\">Report Advertisement<\/a><\/div>\n<p><strong><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/do_settings_sections\/\">do_settings_sections()<\/a><\/strong>\u00a0outputs all the sections, with their respective fields, registered for a specific $page.<\/p>\n<p><code class=\"  language-undefined\">$page<\/code>\u00a0is the only argument here.<\/p>\n<p>Having explained these functions, we now proceed to some actual code. The previous PHP code we added to the\u00a0<code class=\"  language-undefined\">smohub-settings-api.php<\/code>\u00a0file we replace with the following:<\/p>\n<pre class=\"  language-php\"><code class=\"php  language-php\"><span class=\"token function\">add_action<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'admin_menu'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'smo_api_add_admin_menu'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token function\">add_action<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'admin_init'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'smo_api_settings_init'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">smo_api_add_admin_menu<\/span><span class=\"token punctuation\">(<\/span>  <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token function\">add_options_page<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'Settings API Page'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'Settings API Page'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'manage_options'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'settings-api-page'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'smo_api_options_page'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">smo_api_settings_init<\/span><span class=\"token punctuation\">(<\/span>  <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token function\">register_setting<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'smoPlugin'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'smo_api_settings'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token function\">add_settings_section<\/span><span class=\"token punctuation\">(<\/span>\r\n        <span class=\"token string\">'smo_api_stpPlugin_section'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token function\">__<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'Our Section Title'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'wordpress'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smo_api_settings_section_callback'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smoPlugin'<\/span>\r\n    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n    <span class=\"token function\">add_settings_field<\/span><span class=\"token punctuation\">(<\/span>\r\n        <span class=\"token string\">'smo_api_text_field_0'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token function\">__<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'Our Field 0 Title'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'wordpress'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smo_api_text_field_0_render'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smoPlugin'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smo_api_stpPlugin_section'<\/span>\r\n    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n    <span class=\"token function\">add_settings_field<\/span><span class=\"token punctuation\">(<\/span>\r\n        <span class=\"token string\">'smo_api_select_field_1'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token function\">__<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'Our Field 1 Title'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'wordpress'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smo_api_select_field_1_render'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smoPlugin'<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">'smo_api_stpPlugin_section'<\/span>\r\n    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">smo_api_text_field_0_render<\/span><span class=\"token punctuation\">(<\/span>  <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token variable\">$options<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">get_option<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'smo_api_settings'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token delimiter\">?&gt;<\/span>\r\n    <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>input <span class=\"token attr-name\">type<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span>text<span class=\"token punctuation\">'<\/span><\/span> <span class=\"token attr-name\">name<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span>smo_api_settings[smo_api_text_field_0]<span class=\"token punctuation\">'<\/span><\/span> <span class=\"token attr-name\">value<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span><span class=\"token php\"><span class=\"token delimiter\">&lt;?php<\/span> <span class=\"token keyword\">echo<\/span> <span class=\"token variable\">$options<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">'smo_api_text_field_0'<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token delimiter\">?&gt;<\/span><\/span><span class=\"token punctuation\">'<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n    <span class=\"token php\"><span class=\"token delimiter\">&lt;?php<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">smo_api_select_field_1_render<\/span><span class=\"token punctuation\">(<\/span>  <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token variable\">$options<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">get_option<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'smo_api_settings'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token delimiter\">?&gt;<\/span><\/span>\r\n    <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>select <span class=\"token attr-name\">name<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span>smo_api_settings[smo_api_select_field_1]<span class=\"token punctuation\">'<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n        <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>option <span class=\"token attr-name\">value<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span>1<span class=\"token punctuation\">'<\/span><\/span> <span class=\"token attr-name\"><span class=\"token php\"><span class=\"token delimiter\">&lt;?php<\/span> <span class=\"token function\">selected<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token variable\">$options<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">'smo_api_select_field_1'<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">1<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token delimiter\">?&gt;<\/span><\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/span>Option <span class=\"token number\">1<\/span><span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>option<span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n        <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>option <span class=\"token attr-name\">value<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span>2<span class=\"token punctuation\">'<\/span><\/span> <span class=\"token attr-name\"><span class=\"token php\"><span class=\"token delimiter\">&lt;?php<\/span> <span class=\"token function\">selected<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token variable\">$options<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">'smo_api_select_field_1'<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">2<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token delimiter\">?&gt;<\/span><\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/span>Option <span class=\"token number\">2<\/span><span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>option<span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n    <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>select<span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n\r\n<span class=\"token php\"><span class=\"token delimiter\">&lt;?php<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">smo_api_settings_section_callback<\/span><span class=\"token punctuation\">(<\/span>  <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">echo<\/span> <span class=\"token function\">__<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'This Section Description'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">'wordpress'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">smo_api_options_page<\/span><span class=\"token punctuation\">(<\/span>  <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token delimiter\">?&gt;<\/span><\/span>\r\n    <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>form <span class=\"token attr-name\">action<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span>options.php<span class=\"token punctuation\">'<\/span><\/span> <span class=\"token attr-name\">method<\/span><span class=\"token attr-value\"><span class=\"token punctuation\">=<\/span><span class=\"token punctuation\">'<\/span>post<span class=\"token punctuation\">'<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n\r\n        <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>h2<span class=\"token punctuation\">&gt;<\/span><\/span><\/span>Sitepoint Settings <span class=\"token constant\">API<\/span> Admin Page<span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>h2<span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n\r\n        <span class=\"token php\"><span class=\"token delimiter\">&lt;?php<\/span>\r\n        <span class=\"token function\">settings_fields<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'smoPlugin'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n        <span class=\"token function\">do_settings_sections<\/span><span class=\"token punctuation\">(<\/span> <span class=\"token string\">'smoPlugin'<\/span> <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n        <span class=\"token function\">submit_button<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n        <span class=\"token delimiter\">?&gt;<\/span><\/span>\r\n\r\n    <span class=\"token markup\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>form<span class=\"token punctuation\">&gt;<\/span><\/span><\/span>\r\n    <span class=\"token delimiter\">&lt;?php<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>Here we hook the\u00a0<code class=\"  language-undefined\">smo_api_settings_init()<\/code>\u00a0function to the\u00a0<code class=\"  language-undefined\">admin_init<\/code>\u00a0hook. There we define and register our settings, sections and fields.<\/p>\n<p><code class=\"  language-undefined\">smo_api_text_field_0_render()<\/code>\u00a0and\u00a0<code class=\"  language-undefined\">smo_api_select_field_1_render()<\/code>\u00a0define HTML output of our two fields, text and select field, both belonging to the same\u00a0<code class=\"  language-undefined\">smoPlugin<\/code>group and\u00a0<code class=\"  language-undefined\">smo_api_settings<\/code>\u00a0option \u2014 or setting \u2014 in the\u00a0<code class=\"  language-undefined\">wp_options<\/code>\u00a0table in the database.<\/p>\n<p>Lastly, we define\u00a0<code class=\"  language-undefined\">smo_api_options_page()<\/code>, which outputs the HTML for our admin options page. We incorporate the settings sections and fields in it. We\u2019ve referred to this function at the top of our file, in the\u00a0<code class=\"  language-undefined\">smoapi_add_admin_menu()<\/code>\u00a0function, where we registered the admin (options) page.<\/p>\n<p>When we now go, again, to our settings page, we\u2019ll see that it\u2019s no longer empty:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-169926\" src=\"https:\/\/dab1nmslvvntp.cloudfront.net\/wp-content\/uploads\/2018\/11\/1541407216done.jpg\" alt=\"Our settings page now has content in it\" width=\"959\" height=\"716\" \/><\/p>\n<p>If we try changing and saving these fields, we will see, upon refresh, that it works! WordPress abstracts away the database transactions for us, nonces, etc.<\/p>\n<p>We could further add some validation functionality, further styling of this page, and other things.<\/p>\n<p>If we go to WP CLI and try to run\u00a0<code class=\"  language-undefined\">wp option get smo_api_settings<\/code>\u00a0\u2014 after we\u2019ve changed some values for these two fields \u2014 we\u2019ll get this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-169928\" src=\"https:\/\/dab1nmslvvntp.cloudfront.net\/wp-content\/uploads\/2018\/11\/1541407346cli-1024x817.jpg\" alt=\"The effect of running wp option get stp_api_settings in WP CLI\" width=\"1024\" height=\"817\" \/><\/p>\n<p>This shows us that these two fields were saved in our\u00a0<code class=\"  language-undefined\">wp_options<\/code>\u00a0database as fields of an array, as\u00a0<code class=\"  language-undefined\">smo_api_settings<\/code>\u00a0setting.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we\u2019ll introduce the WordPress Settings API, and create a WordPress administration page where we demonstrate the use of this API. For the purposes of this tutorial, we\u2019ll wrap this functionality into a plugin, but this can also be a part of a WordPress theme. As the WordPress Codex says, the Settings API [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":896,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-895","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-plugins-tips"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using the WordPress Settings API to Build a Custom Admin Page<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using the WordPress Settings API to Build a Custom Admin Page\" \/>\n<meta property=\"og:description\" content=\"In this guide, we\u2019ll introduce the WordPress Settings API, and create a WordPress administration page where we demonstrate the use of this API. For the purposes of this tutorial, we\u2019ll wrap this functionality into a plugin, but this can also be a part of a WordPress theme. As the WordPress Codex says, the Settings API [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/\" \/>\n<meta property=\"og:site_name\" content=\"Wordpress Development\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-13T04:16:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"448\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"smotiv\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"smotiv\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/\"},\"author\":{\"name\":\"smotiv\",\"@id\":\"https:\/\/smo.vn\/blog\/#\/schema\/person\/400886672daf89b093ef3bafdb0d052e\"},\"headline\":\"Using the WordPress Settings API to Build a Custom Admin Page\",\"datePublished\":\"2019-05-13T04:16:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/\"},\"wordCount\":946,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/smo.vn\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg\",\"articleSection\":[\"Plugins Tips\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/\",\"url\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/\",\"name\":\"Using the WordPress Settings API to Build a Custom Admin Page\",\"isPartOf\":{\"@id\":\"https:\/\/smo.vn\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg\",\"datePublished\":\"2019-05-13T04:16:34+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage\",\"url\":\"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg\",\"contentUrl\":\"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg\",\"width\":800,\"height\":448},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/smo.vn\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using the WordPress Settings API to Build a Custom Admin Page\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/smo.vn\/blog\/#website\",\"url\":\"https:\/\/smo.vn\/blog\/\",\"name\":\"Wordpress Development\",\"description\":\"Vietnam Out Sourcing Services !\",\"publisher\":{\"@id\":\"https:\/\/smo.vn\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/smo.vn\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/smo.vn\/blog\/#organization\",\"name\":\"Wordpress Development\",\"url\":\"https:\/\/smo.vn\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/smo.vn\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2020\/12\/cropped-smo-logo-e1609398962174.png\",\"contentUrl\":\"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2020\/12\/cropped-smo-logo-e1609398962174.png\",\"width\":240,\"height\":240,\"caption\":\"Wordpress Development\"},\"image\":{\"@id\":\"https:\/\/smo.vn\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/smo.vn\/blog\/#\/schema\/person\/400886672daf89b093ef3bafdb0d052e\",\"name\":\"smotiv\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/smo.vn\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/da6682d4b35f6fcd898942787ca2a1e1ca3522d990aee85547e1ae3664f7e8ae?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/da6682d4b35f6fcd898942787ca2a1e1ca3522d990aee85547e1ae3664f7e8ae?s=96&d=mm&r=g\",\"caption\":\"smotiv\"},\"url\":\"https:\/\/smo.vn\/blog\/author\/smohub\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using the WordPress Settings API to Build a Custom Admin Page","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/","og_locale":"en_US","og_type":"article","og_title":"Using the WordPress Settings API to Build a Custom Admin Page","og_description":"In this guide, we\u2019ll introduce the WordPress Settings API, and create a WordPress administration page where we demonstrate the use of this API. For the purposes of this tutorial, we\u2019ll wrap this functionality into a plugin, but this can also be a part of a WordPress theme. As the WordPress Codex says, the Settings API [&hellip;]","og_url":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/","og_site_name":"Wordpress Development","article_published_time":"2019-05-13T04:16:34+00:00","og_image":[{"width":800,"height":448,"url":"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg","type":"image\/jpeg"}],"author":"smotiv","twitter_card":"summary_large_image","twitter_misc":{"Written by":"smotiv","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#article","isPartOf":{"@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/"},"author":{"name":"smotiv","@id":"https:\/\/smo.vn\/blog\/#\/schema\/person\/400886672daf89b093ef3bafdb0d052e"},"headline":"Using the WordPress Settings API to Build a Custom Admin Page","datePublished":"2019-05-13T04:16:34+00:00","mainEntityOfPage":{"@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/"},"wordCount":946,"commentCount":0,"publisher":{"@id":"https:\/\/smo.vn\/blog\/#organization"},"image":{"@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage"},"thumbnailUrl":"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg","articleSection":["Plugins Tips"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/","url":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/","name":"Using the WordPress Settings API to Build a Custom Admin Page","isPartOf":{"@id":"https:\/\/smo.vn\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage"},"image":{"@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage"},"thumbnailUrl":"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg","datePublished":"2019-05-13T04:16:34+00:00","breadcrumb":{"@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#primaryimage","url":"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg","contentUrl":"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2019\/05\/ff431b58-d250-4e8b-93bf-ff796787cf9f.jpeg","width":800,"height":448},{"@type":"BreadcrumbList","@id":"https:\/\/smo.vn\/blog\/using-the-wordpress-settings-api-to-build-a-custom-admin-page\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/smo.vn\/blog\/"},{"@type":"ListItem","position":2,"name":"Using the WordPress Settings API to Build a Custom Admin Page"}]},{"@type":"WebSite","@id":"https:\/\/smo.vn\/blog\/#website","url":"https:\/\/smo.vn\/blog\/","name":"Wordpress Development","description":"Vietnam Out Sourcing Services !","publisher":{"@id":"https:\/\/smo.vn\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/smo.vn\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/smo.vn\/blog\/#organization","name":"Wordpress Development","url":"https:\/\/smo.vn\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/smo.vn\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2020\/12\/cropped-smo-logo-e1609398962174.png","contentUrl":"https:\/\/smo.vn\/blog\/wp-content\/uploads\/2020\/12\/cropped-smo-logo-e1609398962174.png","width":240,"height":240,"caption":"Wordpress Development"},"image":{"@id":"https:\/\/smo.vn\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/smo.vn\/blog\/#\/schema\/person\/400886672daf89b093ef3bafdb0d052e","name":"smotiv","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/smo.vn\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/da6682d4b35f6fcd898942787ca2a1e1ca3522d990aee85547e1ae3664f7e8ae?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/da6682d4b35f6fcd898942787ca2a1e1ca3522d990aee85547e1ae3664f7e8ae?s=96&d=mm&r=g","caption":"smotiv"},"url":"https:\/\/smo.vn\/blog\/author\/smohub\/"}]}},"_links":{"self":[{"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/posts\/895","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/comments?post=895"}],"version-history":[{"count":1,"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/posts\/895\/revisions"}],"predecessor-version":[{"id":897,"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/posts\/895\/revisions\/897"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/media\/896"}],"wp:attachment":[{"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/media?parent=895"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/categories?post=895"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smo.vn\/blog\/wp-json\/wp\/v2\/tags?post=895"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}