add static page to reading settings for custom post type

I dont know if it is possible to add a new field directly under the “Posts page” dropdown field, atleast I found no way to do this.

But you could just add another dropdown menu to the reading settings page. This will be on the bottom thou.

To do this, first we need to register our new setting and add a new settings field to the default WordPress reading page:

/**
 * Register and define the settings
 */
add_action('admin_init', 'prfx_admin_init');
function prfx_admin_init(){

    // register our setting
    $args = array(
        'type' => 'string', 
        'sanitize_callback' => 'sanitize_text_field',
        'default' => NULL,
    );
    register_setting( 
        'reading', // option group "reading", default WP group
        'my_project_archive_page', // option name
        $args 
    );

    // add our new setting
    add_settings_field(
        'my_project_archive_page', // ID
        __('Project Archive Page', 'textdomain'), // Title
        'prfx_setting_callback_function', // Callback
        'reading', // page
        'default', // section
        array( 'label_for' => 'my_project_archive_page' )
    );
}

Now we can create the callback function for our custom field, which will hold our HTML markup:

/**
 * Custom field callback
 */
function prfx_setting_callback_function($args){
    // get saved project page ID
    $project_page_id = get_option('my_project_archive_page');

    // get all pages
    $args = array(
        'posts_per_page'   => -1,
        'orderby'          => 'name',
        'order'            => 'ASC',
        'post_type'        => 'page',
    );
    $items = get_posts( $args );

    echo '<select id="my_project_archive_page" name="my_project_archive_page">';
    // empty option as default
    echo '<option value="0">'.__('— Select —', 'wordpress').'</option>';

    // foreach page we create an option element, with the post-ID as value
    foreach($items as $item) {

        // add selected to the option if value is the same as $project_page_id
        $selected = ($project_page_id == $item->ID) ? 'selected="selected"' : '';

        echo '<option value="'.$item->ID.'" '.$selected.'>'.$item->post_title.'</option>';
    }

    echo '</select>';
}

After this you now have a new dropdown field under Settings > Reading.
The field is filled with all pages, you can select one and save the setting.


So now you want to mark this selected page on the page list in admin. These markings are called state/s. WordPress uses an filter to add these texts to the title called display_post_states.

/**
 * Add custom state to post/page list
 */
add_filter('display_post_states', 'prfx_add_custom_post_states');

function prfx_add_custom_post_states($states) {
    global $post;

    // get saved project page ID
    $project_page_id = get_option('my_project_archive_page');

    // add our custom state after the post title only,
    // if post-type is "page",
    // "$post->ID" matches the "$project_page_id",
    // and "$project_page_id" is not "0"
    if( 'page' == get_post_type($post->ID) && $post->ID == $project_page_id && $project_page_id != '0') {
        $states[] = __('My state', 'textdomain');
    }

    return $states;
}

Leave a Comment