How to Create a Settings Page for Custom Post Types in WordPress


Adding a settings page for your custom post type is a powerful way to enhance your WordPress customization. However, to avoid feeling overwhelmed, it's best to approach this step by step, writing minimal code, checking your progress, and then building upon it.
This guide will walk you through the process interactively, where you write a little code, check the result in the WordPress dashboard, and proceed to the next step.
We’ll start with a very basic custom post type called Work in Progress
In your theme’s functions.php file add the following code:
function create_work_in_progress_post_type()
{
$args = array(
'public' => true,
'label' => __('Work in Progress', 'themeName'),
);
register_post_type('work_in_progress', $args);
}
add_action('init', 'create_work_in_progress_post_type');WordPress admin dashboard. Work in Progress. Now, let’s add more functionality, like labels, menu icons, and support for titles and thumbnails.
Update the previous code with this:
function create_work_in_progress_post_type()
{
$labels = array(
'name' => __('Work in Progress', 'themeName'),
'singular_name' => __('Work in Progress', 'themeName'),
'menu_name' => __('Work in Progress', 'themeName'),
);
$args = array(
'labels' => $labels,
'public' => true,
'menu_icon' => 'dashicons-hammer',
'supports' => array('title', 'editor', 'thumbnail'),
);
register_post_type('work_in_progress', $args);
}
add_action('init', 'create_work_in_progress_post_type');Now that your custom post type is set up, it’s time to add a settings page under the Work in Progress menu.
In your theme directory, create a new file, e.g., inc/settings-page.php, and add the following:
<?php
function add_wip_settings_page()
{
add_submenu_page(
'edit.php?post_type=work_in_progress', // Parent menu
__('Settings', 'themeName'), // Page title
__('Settings', 'themeName'), // Submenu title
'manage_options', // Capability
'wip_settings', // Menu slug
'render_wip_settings_page' // Callback function
);
}
add_action('admin_menu', 'add_wip_settings_page');
// Callback to display the settings page
function render_wip_settings_page()
{
echo '<div class="wrap"><h1>Work in Progress Settings</h1><p>Settings will go here.</p></div>';
}
?>Add this line to your functions.php file to load the settings page:
require_once get_template_directory() . '/inc/settings-page.php';Work in Progress > Settings. Work in Progress Settings Now that the settings page is visible, let’s add a form to save and retrieve a custom heading.
render_wip_settings_page Function:Replace the placeholder content with the following:
function render_wip_settings_page()
{
// Check if the user is allowed to access the page
if (!current_user_can('manage_options')) {
return;
}
// Save settings if the form is submitted
if (isset($_POST['save_wip_settings'])) {
update_option('wip_custom_heading', sanitize_text_field($_POST['wip_custom_heading']));
echo '<div class="updated"><p>Settings saved.</p></div>';
}
// Retrieve the current value
$heading = get_option('wip_custom_heading', 'Default Heading');
?>
<div class="wrap">
<h1><?php esc_html_e('Work in Progress Settings', 'themeName'); ?></h1>
<form method="post" action="">
<table class="form-table">
<tr>
<th>
<label for="wip_custom_heading"><?php esc_html_e('Custom Heading', 'themeName'); ?></label>
</th>
<td>
<input type="text" name="wip_custom_heading" id="wip_custom_heading" value="<?php echo esc_attr($heading); ?>" class="regular-text">
<p class="description"><?php esc_html_e('Enter a custom heading for the Work in Progress section.', 'themeName'); ?></p>
</td>
</tr>
</table>
<?php submit_button(__('Save Settings', 'themeName'), 'primary', 'save_wip_settings'); ?>
</form>
</div>
<?php
}Finally, let’s display the saved custom heading on the front end or admin area.
Use the following snippet wherever you want to display the saved heading:
<?php
$custom_heading = get_option('wip_custom_heading', 'Default Heading');
echo '<h1>' . esc_html($custom_heading) . '</h1>';
?>If you want to move the "Work in Progress" menu higher or lower on the dashboard, update the menu_position in your custom post type code.
'menu_position' => 20, // Places it below PagesCheck the WordPress dashboard and confirm the menu position.


Learn how to create a modern WordPress theme from scratch using TailwindCSS. Follow this step-by-step guide for developers and designers.

Learn how to set up WordPress on your local machine with LocalWP and WordPress Studio. Start your WordPress development journey today