How to create custom post states in WordPress admin post or page list view

How to create custom post states in WordPress admin post or page list view

Post states serve as labels displayed beside the title of a post or page within the WordPress admin post or page list view.

Home / Blog / Wordpress / How to create custom post states in WordPress admin post or page list view

Post states serve as labels displayed beside the title of a post or page within the WordPress admin post or page list view.

What are WordPress post states?

WordPress post states play a crucial role in managing content within the WordPress admin interface, offering labels that provide insights into the status or characteristics of each post or page. In this article, we’ll explore the significance of post states, understand how WordPress uses them, and learn how to add custom post states to enhance content management.

The default post states in WordPress include:

  1. Draft: A post that is not yet published and is still in the editing phase. It’s only visible to users with the appropriate permissions.
  2. Pending Review: A post that has been submitted for review but is not yet published. This status is often used in a multi-author environment where one user writes the post, and another reviews and publishes it.
  3. Scheduled: A post scheduled to be published at a future date and time. Once the scheduled time arrives, the post is automatically published.
  4. Published: A post that is live on the website and visible to the public.
  5. Private: A published post that is only visible to users who are logged in and have the necessary permissions.
  6. Trash: A post that has been deleted but is still recoverable. It is moved to the trash and can be restored or permanently deleted.
  7. Auto-Draft: A temporary auto-save of a post while it’s being edited. It is not an actual post state but is worth mentioning as it represents an unsaved draft that WordPress automatically saves in the background.

How to add a custom post state?

WordPress allows users to assign custom post states or labels to posts or specific types of posts. For example, when using Elementor, pages created or edited with this plugin receive the “Elementor” post label. This practice enhances user understanding of which pages leverage particular plugins.

The WooCommerce plugin leverages custom post states to indicate important pages such as the “Shop Page,” “Cart Page,” “Checkout Page,” “My Account Page,” and “Terms and Conditions Page.” This functionality streamlines the management of WooCommerce settings.

To add a custom post state in WordPress, you can use the display_post_states filter. This filter allows you to modify the array of post states associated with a particular post. Below is a step-by-step guide:

Open your theme’s functions.php file: Access the functions.php file in your WordPress theme directory. You can do this via your hosting file manager, FTP, or through the WordPress dashboard by navigating to “Appearance” -> “Theme Editor” and selecting the functions.php file.

Add the code: Insert the following code snippet into your functions.php file. This example adds a custom post state labeled “Custom State” to the post with ID 123.

add_filter('display_post_states', 'custom_add_post_state', 10, 2);

function custom_add_post_state($post_states, $post) {
    // Check if the post ID matches the desired post
    if ($post->ID === 123) {
        // Add a custom post state with the key 'custom-state' and value 'Custom State'
        $post_states['custom-state'] = __('Custom State', 'your-text-domain');
    }

    return $post_states;
}

Replace 123 with the actual ID of the post to which you want to add the custom state. Also, replace 'your-text-domain' with the text domain of your theme or plugin for translation purposes.

Verify the result: Go to the WordPress admin dashboard, navigate to the post or page list view, and find the post with the specified ID. You should see your custom post state (“Custom State”) displayed next to the post title.

Keep in mind that hardcoding post IDs may not be the most flexible approach in all cases. Depending on your needs, you might want to implement a more dynamic method to determine when to apply the custom post state.

Create a custom settings field in a settings page that can be used to assign a custom state to a page

This code defines a class Settings within the projectsengine namespace in WordPress. The class is responsible for managing custom settings related to a specific page on the WordPress dashboard.

<?php

namespace projectsengine;

class Settings {
	private $theme_domain;
	private $version;
	private $theme_name;
	private $namespace;

    public function __construct() {
		$this->theme_domain = wp_get_theme()->get( 'TextDomain' );
		$this->version      = wp_get_theme()->get( 'Version' );
		$this->theme_name   = wp_get_theme()->get( 'Name' );
		$this->namespace    = $this->theme_domain . '-api/v1';

		add_action( 'admin_init', array( $this, 'pe_register_option_settings' ) );
        add_filter( 'whitelist_options', array( $this, 'whitelist_options') );
        add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2  );
		add_action( 'admin_menu', array( $this, 'pe_custom_settings_page' ) );
    }

	/**
	 * Settings page.
	 *
	 * @return void
	 */
	public function pe_register_option_settings() {
		add_settings_section(
			'pe_project_settings_section_post_state', // string $id
			__( 'Engine page', $this->get_theme_domain() ), // string $title
			array( $this, 'pe_project_settings_section_post_state_callback' ), // callable $callback
			'project-settings', // string $page
			array( 
				'before_section' => '',
				'after_section' => '',
				'section_class' => ''
			)
		);
	
		add_settings_field(
			'pe_post_state_page_field',
			__( 'Select page', $this->get_theme_domain() ),
			array( $this, 'pe_post_state_page_field_callback' ),
			'project-settings',
			'pe_project_settings_section_post_state'
		);
	
		register_setting( 'project-settings', 'pe_eninge_page_options' );
	}

	/**
	 * Settings section description.
	 *
	 */
	public function pe_project_settings_section_post_state_callback() {
		ob_start(); ?>

		<p>'"My Engine" is a centralized hub within the Projects Engine ecosystem where you can seamlessly manage your account information and oversee the progress of various projects and tickets associated with your company or organization.'</p>

		<?php

		$html = ob_get_contents();
		ob_get_clean();

		echo $html;
	}

	/**
	 * Renders the custom "Select page" field.
	 *
	 * @param array $args
	 */
	public function pe_post_state_page_field_callback( $args ) {
		$id = 'pe_post_state_page_field';
		
		wp_dropdown_pages( array(
			'name'              => $id,
			'show_option_none'  => '&mdash; Select &mdash;',
			'option_none_value' => '0',
			'selected'          => get_option( $id ),
		) );
	}

    /**
     * Filters the post states on the "Pages" edit page. Displays "Projects Page"
     * after the post/page title, if the current page is the Projects static page.
     *
     * @param array $states
     * @param WP_Post $post
     */
    public function display_post_states( $states, $post ) {
        if ( intval( get_option( 'pe_post_state_page_field' ) ) === $post->ID ) {
            $states['pe_post_state_page_field'] = __( 'My Engine Page' );
        }

        return $states;
    }

    /**
     * Adds pe_post_state_page_field to the white-listed options, which are automatically
     * updated by WordPress.
     *
     * @param array $options
     */
    public function whitelist_options( $options ) {
        $options['project-settings'][] = 'pe_post_state_page_field';

        return $options;
    }

	/**
	 * Create admin menu item in the dashboard.
	 *
	 * @return void
	 */
	function pe_custom_settings_page() {
		add_menu_page('Project settings', 'Project settings', 'manage_options', 'project-settings', array( $this, 'project_settings_callback' ) );
	}

	function project_settings_callback() {

		ob_start(); ?>
	
		<div class="wrap">
			<h2>Project settings</h2>
	
			<form action="options.php" method="post"> 
	
				<?php
	
				settings_fields('project-settings');
				do_settings_sections('project-settings');
	
				submit_button(); ?>
	
			</form>
	
		</div>
	
		<?php
	
		$html = ob_get_contents();
		ob_get_clean();
	
		echo $html;
	}

	/**
	 * Get the theme domain.
	 *
	 * @since    1.0.0
	 */
	private function get_theme_domain() {
		return $this->theme_domain;
	}

	/**
	 * Get the current version of the theme.
	 *
	 * @since    1.0.0
	 */
	private function get_version() {
		return $this->version;
	}

	/**
	 * Get the theme name (Avocet).
	 *
	 * @since    1.0.0
	 */
	private function get_theme_name() {
		return $this->theme_name;
	}

	/**
	 * API namespace.
	 *
	 * @return string
	 */
	private function get_namespace() {
		return $this->namespace;
	}
}

new Settings;

In summary, this code creates a settings page in the WordPress dashboard where users can select a specific page, and it will display a custom post state (“My Engine Page”) on the “Pages” edit page. The code also includes functionality to handle the saving of these settings and display them in the WordPress admin.